|
@@ -410,6 +410,8 @@ bool target_direction;
|
410
|
410
|
|
411
|
411
|
void process_next_command();
|
412
|
412
|
|
|
413
|
+void plan_arc(float target[NUM_AXIS], float *offset, uint8_t clockwise);
|
|
414
|
+
|
413
|
415
|
bool setTargetedHotend(int code);
|
414
|
416
|
|
415
|
417
|
void serial_echopair_P(const char *s_P, float v) { serialprintPGM(s_P); SERIAL_ECHO(v); }
|
|
@@ -1886,130 +1888,6 @@ inline void gcode_G0_G1() {
|
1886
|
1888
|
}
|
1887
|
1889
|
|
1888
|
1890
|
/**
|
1889
|
|
- * Plan an arc in 2 dimensions
|
1890
|
|
- *
|
1891
|
|
- * The arc is approximated by generating many small linear segments.
|
1892
|
|
- * The length of each segment is configured in MM_PER_ARC_SEGMENT (Default 1mm)
|
1893
|
|
- * Arcs should only be made relatively large (over 5mm), as larger arcs with
|
1894
|
|
- * larger segments will tend to be more efficient. Your slicer should have
|
1895
|
|
- * options for G2/G3 arc generation. In future these options may be GCode tunable.
|
1896
|
|
- */
|
1897
|
|
-void plan_arc(
|
1898
|
|
- float *target, // Destination position
|
1899
|
|
- float *offset, // Center of rotation relative to current_position
|
1900
|
|
- uint8_t clockwise // Clockwise?
|
1901
|
|
-) {
|
1902
|
|
-
|
1903
|
|
- float radius = hypot(offset[X_AXIS], offset[Y_AXIS]),
|
1904
|
|
- center_axis0 = current_position[X_AXIS] + offset[X_AXIS],
|
1905
|
|
- center_axis1 = current_position[Y_AXIS] + offset[Y_AXIS],
|
1906
|
|
- linear_travel = target[Z_AXIS] - current_position[Z_AXIS],
|
1907
|
|
- extruder_travel = target[E_AXIS] - current_position[E_AXIS],
|
1908
|
|
- r_axis0 = -offset[X_AXIS], // Radius vector from center to current location
|
1909
|
|
- r_axis1 = -offset[Y_AXIS],
|
1910
|
|
- rt_axis0 = target[X_AXIS] - center_axis0,
|
1911
|
|
- rt_axis1 = target[Y_AXIS] - center_axis1;
|
1912
|
|
-
|
1913
|
|
- // CCW angle of rotation between position and target from the circle center. Only one atan2() trig computation required.
|
1914
|
|
- float angular_travel = atan2(r_axis0*rt_axis1-r_axis1*rt_axis0, r_axis0*rt_axis0+r_axis1*rt_axis1);
|
1915
|
|
- if (angular_travel < 0) { angular_travel += RADIANS(360); }
|
1916
|
|
- if (clockwise) { angular_travel -= RADIANS(360); }
|
1917
|
|
-
|
1918
|
|
- // Make a circle if the angular rotation is 0
|
1919
|
|
- if (current_position[X_AXIS] == target[X_AXIS] && current_position[Y_AXIS] == target[Y_AXIS] && angular_travel == 0)
|
1920
|
|
- angular_travel += RADIANS(360);
|
1921
|
|
-
|
1922
|
|
- float mm_of_travel = hypot(angular_travel*radius, fabs(linear_travel));
|
1923
|
|
- if (mm_of_travel < 0.001) { return; }
|
1924
|
|
- uint16_t segments = floor(mm_of_travel / MM_PER_ARC_SEGMENT);
|
1925
|
|
- if (segments == 0) segments = 1;
|
1926
|
|
-
|
1927
|
|
- float theta_per_segment = angular_travel/segments;
|
1928
|
|
- float linear_per_segment = linear_travel/segments;
|
1929
|
|
- float extruder_per_segment = extruder_travel/segments;
|
1930
|
|
-
|
1931
|
|
- /* Vector rotation by transformation matrix: r is the original vector, r_T is the rotated vector,
|
1932
|
|
- and phi is the angle of rotation. Based on the solution approach by Jens Geisler.
|
1933
|
|
- r_T = [cos(phi) -sin(phi);
|
1934
|
|
- sin(phi) cos(phi] * r ;
|
1935
|
|
-
|
1936
|
|
- For arc generation, the center of the circle is the axis of rotation and the radius vector is
|
1937
|
|
- defined from the circle center to the initial position. Each line segment is formed by successive
|
1938
|
|
- vector rotations. This requires only two cos() and sin() computations to form the rotation
|
1939
|
|
- matrix for the duration of the entire arc. Error may accumulate from numerical round-off, since
|
1940
|
|
- all double numbers are single precision on the Arduino. (True double precision will not have
|
1941
|
|
- round off issues for CNC applications.) Single precision error can accumulate to be greater than
|
1942
|
|
- tool precision in some cases. Therefore, arc path correction is implemented.
|
1943
|
|
-
|
1944
|
|
- Small angle approximation may be used to reduce computation overhead further. This approximation
|
1945
|
|
- holds for everything, but very small circles and large MM_PER_ARC_SEGMENT values. In other words,
|
1946
|
|
- theta_per_segment would need to be greater than 0.1 rad and N_ARC_CORRECTION would need to be large
|
1947
|
|
- to cause an appreciable drift error. N_ARC_CORRECTION~=25 is more than small enough to correct for
|
1948
|
|
- numerical drift error. N_ARC_CORRECTION may be on the order a hundred(s) before error becomes an
|
1949
|
|
- issue for CNC machines with the single precision Arduino calculations.
|
1950
|
|
-
|
1951
|
|
- This approximation also allows plan_arc to immediately insert a line segment into the planner
|
1952
|
|
- without the initial overhead of computing cos() or sin(). By the time the arc needs to be applied
|
1953
|
|
- a correction, the planner should have caught up to the lag caused by the initial plan_arc overhead.
|
1954
|
|
- This is important when there are successive arc motions.
|
1955
|
|
- */
|
1956
|
|
- // Vector rotation matrix values
|
1957
|
|
- float cos_T = 1-0.5*theta_per_segment*theta_per_segment; // Small angle approximation
|
1958
|
|
- float sin_T = theta_per_segment;
|
1959
|
|
-
|
1960
|
|
- float arc_target[4];
|
1961
|
|
- float sin_Ti;
|
1962
|
|
- float cos_Ti;
|
1963
|
|
- float r_axisi;
|
1964
|
|
- uint16_t i;
|
1965
|
|
- int8_t count = 0;
|
1966
|
|
-
|
1967
|
|
- // Initialize the linear axis
|
1968
|
|
- arc_target[Z_AXIS] = current_position[Z_AXIS];
|
1969
|
|
-
|
1970
|
|
- // Initialize the extruder axis
|
1971
|
|
- arc_target[E_AXIS] = current_position[E_AXIS];
|
1972
|
|
-
|
1973
|
|
- float feed_rate = feedrate*feedrate_multiplier/60/100.0;
|
1974
|
|
-
|
1975
|
|
- for (i = 1; i < segments; i++) { // Increment (segments-1)
|
1976
|
|
-
|
1977
|
|
- if (count < N_ARC_CORRECTION) {
|
1978
|
|
- // Apply vector rotation matrix to previous r_axis0 / 1
|
1979
|
|
- r_axisi = r_axis0*sin_T + r_axis1*cos_T;
|
1980
|
|
- r_axis0 = r_axis0*cos_T - r_axis1*sin_T;
|
1981
|
|
- r_axis1 = r_axisi;
|
1982
|
|
- count++;
|
1983
|
|
- }
|
1984
|
|
- else {
|
1985
|
|
- // Arc correction to radius vector. Computed only every N_ARC_CORRECTION increments.
|
1986
|
|
- // Compute exact location by applying transformation matrix from initial radius vector(=-offset).
|
1987
|
|
- cos_Ti = cos(i*theta_per_segment);
|
1988
|
|
- sin_Ti = sin(i*theta_per_segment);
|
1989
|
|
- r_axis0 = -offset[X_AXIS]*cos_Ti + offset[Y_AXIS]*sin_Ti;
|
1990
|
|
- r_axis1 = -offset[X_AXIS]*sin_Ti - offset[Y_AXIS]*cos_Ti;
|
1991
|
|
- count = 0;
|
1992
|
|
- }
|
1993
|
|
-
|
1994
|
|
- // Update arc_target location
|
1995
|
|
- arc_target[X_AXIS] = center_axis0 + r_axis0;
|
1996
|
|
- arc_target[Y_AXIS] = center_axis1 + r_axis1;
|
1997
|
|
- arc_target[Z_AXIS] += linear_per_segment;
|
1998
|
|
- arc_target[E_AXIS] += extruder_per_segment;
|
1999
|
|
-
|
2000
|
|
- clamp_to_software_endstops(arc_target);
|
2001
|
|
- plan_buffer_line(arc_target[X_AXIS], arc_target[Y_AXIS], arc_target[Z_AXIS], arc_target[E_AXIS], feed_rate, active_extruder);
|
2002
|
|
- }
|
2003
|
|
- // Ensure last segment arrives at target location.
|
2004
|
|
- plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], feed_rate, active_extruder);
|
2005
|
|
-
|
2006
|
|
- // As far as the parser is concerned, the position is now == target. In reality the
|
2007
|
|
- // motion control system might still be processing the action and the real tool position
|
2008
|
|
- // in any intermediate location.
|
2009
|
|
- set_current_to_destination();
|
2010
|
|
-}
|
2011
|
|
-
|
2012
|
|
-/**
|
2013
|
1891
|
* G2: Clockwise Arc
|
2014
|
1892
|
* G3: Counterclockwise Arc
|
2015
|
1893
|
*/
|
|
@@ -6074,9 +5952,9 @@ void mesh_plan_buffer_line(float x, float y, float z, const float e, float feed_
|
6074
|
5952
|
|
6075
|
5953
|
#if defined(DELTA) || defined(SCARA)
|
6076
|
5954
|
|
6077
|
|
- inline bool prepare_move_delta() {
|
|
5955
|
+ inline bool prepare_move_delta(float target[NUM_AXIS]) {
|
6078
|
5956
|
float difference[NUM_AXIS];
|
6079
|
|
- for (int8_t i=0; i < NUM_AXIS; i++) difference[i] = destination[i] - current_position[i];
|
|
5957
|
+ for (int8_t i=0; i < NUM_AXIS; i++) difference[i] = target[i] - current_position[i];
|
6080
|
5958
|
|
6081
|
5959
|
float cartesian_mm = sqrt(sq(difference[X_AXIS]) + sq(difference[Y_AXIS]) + sq(difference[Z_AXIS]));
|
6082
|
5960
|
if (cartesian_mm < 0.000001) cartesian_mm = abs(difference[E_AXIS]);
|
|
@@ -6093,22 +5971,22 @@ void mesh_plan_buffer_line(float x, float y, float z, const float e, float feed_
|
6093
|
5971
|
float fraction = float(s) / float(steps);
|
6094
|
5972
|
|
6095
|
5973
|
for (int8_t i = 0; i < NUM_AXIS; i++)
|
6096
|
|
- destination[i] = current_position[i] + difference[i] * fraction;
|
|
5974
|
+ target[i] = current_position[i] + difference[i] * fraction;
|
6097
|
5975
|
|
6098
|
|
- calculate_delta(destination);
|
|
5976
|
+ calculate_delta(target);
|
6099
|
5977
|
|
6100
|
5978
|
#ifdef ENABLE_AUTO_BED_LEVELING
|
6101
|
|
- adjust_delta(destination);
|
|
5979
|
+ adjust_delta(target);
|
6102
|
5980
|
#endif
|
6103
|
5981
|
|
6104
|
|
- //SERIAL_ECHOPGM("destination[X_AXIS]="); SERIAL_ECHOLN(destination[X_AXIS]);
|
6105
|
|
- //SERIAL_ECHOPGM("destination[Y_AXIS]="); SERIAL_ECHOLN(destination[Y_AXIS]);
|
6106
|
|
- //SERIAL_ECHOPGM("destination[Z_AXIS]="); SERIAL_ECHOLN(destination[Z_AXIS]);
|
|
5982
|
+ //SERIAL_ECHOPGM("target[X_AXIS]="); SERIAL_ECHOLN(target[X_AXIS]);
|
|
5983
|
+ //SERIAL_ECHOPGM("target[Y_AXIS]="); SERIAL_ECHOLN(target[Y_AXIS]);
|
|
5984
|
+ //SERIAL_ECHOPGM("target[Z_AXIS]="); SERIAL_ECHOLN(target[Z_AXIS]);
|
6107
|
5985
|
//SERIAL_ECHOPGM("delta[X_AXIS]="); SERIAL_ECHOLN(delta[X_AXIS]);
|
6108
|
5986
|
//SERIAL_ECHOPGM("delta[Y_AXIS]="); SERIAL_ECHOLN(delta[Y_AXIS]);
|
6109
|
5987
|
//SERIAL_ECHOPGM("delta[Z_AXIS]="); SERIAL_ECHOLN(delta[Z_AXIS]);
|
6110
|
5988
|
|
6111
|
|
- plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], destination[E_AXIS], feedrate/60*feedrate_multiplier/100.0, active_extruder);
|
|
5989
|
+ plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], target[E_AXIS], feedrate/60*feedrate_multiplier/100.0, active_extruder);
|
6112
|
5990
|
}
|
6113
|
5991
|
return true;
|
6114
|
5992
|
}
|
|
@@ -6116,7 +5994,7 @@ void mesh_plan_buffer_line(float x, float y, float z, const float e, float feed_
|
6116
|
5994
|
#endif // DELTA || SCARA
|
6117
|
5995
|
|
6118
|
5996
|
#ifdef SCARA
|
6119
|
|
- inline bool prepare_move_scara() { return prepare_move_delta(); }
|
|
5997
|
+ inline bool prepare_move_scara(float target[NUM_AXIS]) { return prepare_move_delta(target); }
|
6120
|
5998
|
#endif
|
6121
|
5999
|
|
6122
|
6000
|
#ifdef DUAL_X_CARRIAGE
|
|
@@ -6193,9 +6071,9 @@ void prepare_move() {
|
6193
|
6071
|
#endif
|
6194
|
6072
|
|
6195
|
6073
|
#ifdef SCARA
|
6196
|
|
- if (!prepare_move_scara()) return;
|
|
6074
|
+ if (!prepare_move_scara(destination)) return;
|
6197
|
6075
|
#elif defined(DELTA)
|
6198
|
|
- if (!prepare_move_delta()) return;
|
|
6076
|
+ if (!prepare_move_delta(destination)) return;
|
6199
|
6077
|
#endif
|
6200
|
6078
|
|
6201
|
6079
|
#ifdef DUAL_X_CARRIAGE
|
|
@@ -6209,6 +6087,148 @@ void prepare_move() {
|
6209
|
6087
|
set_current_to_destination();
|
6210
|
6088
|
}
|
6211
|
6089
|
|
|
6090
|
+/**
|
|
6091
|
+ * Plan an arc in 2 dimensions
|
|
6092
|
+ *
|
|
6093
|
+ * The arc is approximated by generating many small linear segments.
|
|
6094
|
+ * The length of each segment is configured in MM_PER_ARC_SEGMENT (Default 1mm)
|
|
6095
|
+ * Arcs should only be made relatively large (over 5mm), as larger arcs with
|
|
6096
|
+ * larger segments will tend to be more efficient. Your slicer should have
|
|
6097
|
+ * options for G2/G3 arc generation. In future these options may be GCode tunable.
|
|
6098
|
+ */
|
|
6099
|
+void plan_arc(
|
|
6100
|
+ float target[NUM_AXIS], // Destination position
|
|
6101
|
+ float *offset, // Center of rotation relative to current_position
|
|
6102
|
+ uint8_t clockwise // Clockwise?
|
|
6103
|
+) {
|
|
6104
|
+
|
|
6105
|
+ float radius = hypot(offset[X_AXIS], offset[Y_AXIS]),
|
|
6106
|
+ center_axis0 = current_position[X_AXIS] + offset[X_AXIS],
|
|
6107
|
+ center_axis1 = current_position[Y_AXIS] + offset[Y_AXIS],
|
|
6108
|
+ linear_travel = target[Z_AXIS] - current_position[Z_AXIS],
|
|
6109
|
+ extruder_travel = target[E_AXIS] - current_position[E_AXIS],
|
|
6110
|
+ r_axis0 = -offset[X_AXIS], // Radius vector from center to current location
|
|
6111
|
+ r_axis1 = -offset[Y_AXIS],
|
|
6112
|
+ rt_axis0 = target[X_AXIS] - center_axis0,
|
|
6113
|
+ rt_axis1 = target[Y_AXIS] - center_axis1;
|
|
6114
|
+
|
|
6115
|
+ // CCW angle of rotation between position and target from the circle center. Only one atan2() trig computation required.
|
|
6116
|
+ float angular_travel = atan2(r_axis0*rt_axis1-r_axis1*rt_axis0, r_axis0*rt_axis0+r_axis1*rt_axis1);
|
|
6117
|
+ if (angular_travel < 0) { angular_travel += RADIANS(360); }
|
|
6118
|
+ if (clockwise) { angular_travel -= RADIANS(360); }
|
|
6119
|
+
|
|
6120
|
+ // Make a circle if the angular rotation is 0
|
|
6121
|
+ if (current_position[X_AXIS] == target[X_AXIS] && current_position[Y_AXIS] == target[Y_AXIS] && angular_travel == 0)
|
|
6122
|
+ angular_travel += RADIANS(360);
|
|
6123
|
+
|
|
6124
|
+ float mm_of_travel = hypot(angular_travel*radius, fabs(linear_travel));
|
|
6125
|
+ if (mm_of_travel < 0.001) { return; }
|
|
6126
|
+ uint16_t segments = floor(mm_of_travel / MM_PER_ARC_SEGMENT);
|
|
6127
|
+ if (segments == 0) segments = 1;
|
|
6128
|
+
|
|
6129
|
+ float theta_per_segment = angular_travel/segments;
|
|
6130
|
+ float linear_per_segment = linear_travel/segments;
|
|
6131
|
+ float extruder_per_segment = extruder_travel/segments;
|
|
6132
|
+
|
|
6133
|
+ /* Vector rotation by transformation matrix: r is the original vector, r_T is the rotated vector,
|
|
6134
|
+ and phi is the angle of rotation. Based on the solution approach by Jens Geisler.
|
|
6135
|
+ r_T = [cos(phi) -sin(phi);
|
|
6136
|
+ sin(phi) cos(phi] * r ;
|
|
6137
|
+
|
|
6138
|
+ For arc generation, the center of the circle is the axis of rotation and the radius vector is
|
|
6139
|
+ defined from the circle center to the initial position. Each line segment is formed by successive
|
|
6140
|
+ vector rotations. This requires only two cos() and sin() computations to form the rotation
|
|
6141
|
+ matrix for the duration of the entire arc. Error may accumulate from numerical round-off, since
|
|
6142
|
+ all double numbers are single precision on the Arduino. (True double precision will not have
|
|
6143
|
+ round off issues for CNC applications.) Single precision error can accumulate to be greater than
|
|
6144
|
+ tool precision in some cases. Therefore, arc path correction is implemented.
|
|
6145
|
+
|
|
6146
|
+ Small angle approximation may be used to reduce computation overhead further. This approximation
|
|
6147
|
+ holds for everything, but very small circles and large MM_PER_ARC_SEGMENT values. In other words,
|
|
6148
|
+ theta_per_segment would need to be greater than 0.1 rad and N_ARC_CORRECTION would need to be large
|
|
6149
|
+ to cause an appreciable drift error. N_ARC_CORRECTION~=25 is more than small enough to correct for
|
|
6150
|
+ numerical drift error. N_ARC_CORRECTION may be on the order a hundred(s) before error becomes an
|
|
6151
|
+ issue for CNC machines with the single precision Arduino calculations.
|
|
6152
|
+
|
|
6153
|
+ This approximation also allows plan_arc to immediately insert a line segment into the planner
|
|
6154
|
+ without the initial overhead of computing cos() or sin(). By the time the arc needs to be applied
|
|
6155
|
+ a correction, the planner should have caught up to the lag caused by the initial plan_arc overhead.
|
|
6156
|
+ This is important when there are successive arc motions.
|
|
6157
|
+ */
|
|
6158
|
+ // Vector rotation matrix values
|
|
6159
|
+ float cos_T = 1-0.5*theta_per_segment*theta_per_segment; // Small angle approximation
|
|
6160
|
+ float sin_T = theta_per_segment;
|
|
6161
|
+
|
|
6162
|
+ float arc_target[NUM_AXIS];
|
|
6163
|
+ float sin_Ti;
|
|
6164
|
+ float cos_Ti;
|
|
6165
|
+ float r_axisi;
|
|
6166
|
+ uint16_t i;
|
|
6167
|
+ int8_t count = 0;
|
|
6168
|
+
|
|
6169
|
+ // Initialize the linear axis
|
|
6170
|
+ arc_target[Z_AXIS] = current_position[Z_AXIS];
|
|
6171
|
+
|
|
6172
|
+ // Initialize the extruder axis
|
|
6173
|
+ arc_target[E_AXIS] = current_position[E_AXIS];
|
|
6174
|
+
|
|
6175
|
+ float feed_rate = feedrate*feedrate_multiplier/60/100.0;
|
|
6176
|
+
|
|
6177
|
+ for (i = 1; i < segments; i++) { // Increment (segments-1)
|
|
6178
|
+
|
|
6179
|
+ if (count < N_ARC_CORRECTION) {
|
|
6180
|
+ // Apply vector rotation matrix to previous r_axis0 / 1
|
|
6181
|
+ r_axisi = r_axis0*sin_T + r_axis1*cos_T;
|
|
6182
|
+ r_axis0 = r_axis0*cos_T - r_axis1*sin_T;
|
|
6183
|
+ r_axis1 = r_axisi;
|
|
6184
|
+ count++;
|
|
6185
|
+ }
|
|
6186
|
+ else {
|
|
6187
|
+ // Arc correction to radius vector. Computed only every N_ARC_CORRECTION increments.
|
|
6188
|
+ // Compute exact location by applying transformation matrix from initial radius vector(=-offset).
|
|
6189
|
+ cos_Ti = cos(i*theta_per_segment);
|
|
6190
|
+ sin_Ti = sin(i*theta_per_segment);
|
|
6191
|
+ r_axis0 = -offset[X_AXIS]*cos_Ti + offset[Y_AXIS]*sin_Ti;
|
|
6192
|
+ r_axis1 = -offset[X_AXIS]*sin_Ti - offset[Y_AXIS]*cos_Ti;
|
|
6193
|
+ count = 0;
|
|
6194
|
+ }
|
|
6195
|
+
|
|
6196
|
+ // Update arc_target location
|
|
6197
|
+ arc_target[X_AXIS] = center_axis0 + r_axis0;
|
|
6198
|
+ arc_target[Y_AXIS] = center_axis1 + r_axis1;
|
|
6199
|
+ arc_target[Z_AXIS] += linear_per_segment;
|
|
6200
|
+ arc_target[E_AXIS] += extruder_per_segment;
|
|
6201
|
+
|
|
6202
|
+ clamp_to_software_endstops(arc_target);
|
|
6203
|
+
|
|
6204
|
+ #if defined(DELTA) || defined(SCARA)
|
|
6205
|
+ calculate_delta(arc_target);
|
|
6206
|
+ #ifdef ENABLE_AUTO_BED_LEVELING
|
|
6207
|
+ adjust_delta(arc_target);
|
|
6208
|
+ #endif
|
|
6209
|
+ plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], arc_target[E_AXIS], feed_rate, active_extruder);
|
|
6210
|
+ #else
|
|
6211
|
+ plan_buffer_line(arc_target[X_AXIS], arc_target[Y_AXIS], arc_target[Z_AXIS], arc_target[E_AXIS], feed_rate, active_extruder);
|
|
6212
|
+ #endif
|
|
6213
|
+ }
|
|
6214
|
+
|
|
6215
|
+ // Ensure last segment arrives at target location.
|
|
6216
|
+ #if defined(DELTA) || defined(SCARA)
|
|
6217
|
+ calculate_delta(target);
|
|
6218
|
+ #ifdef ENABLE_AUTO_BED_LEVELING
|
|
6219
|
+ adjust_delta(target);
|
|
6220
|
+ #endif
|
|
6221
|
+ plan_buffer_line(delta[X_AXIS], delta[Y_AXIS], delta[Z_AXIS], target[E_AXIS], feed_rate, active_extruder);
|
|
6222
|
+ #else
|
|
6223
|
+ plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], target[E_AXIS], feed_rate, active_extruder);
|
|
6224
|
+ #endif
|
|
6225
|
+
|
|
6226
|
+ // As far as the parser is concerned, the position is now == target. In reality the
|
|
6227
|
+ // motion control system might still be processing the action and the real tool position
|
|
6228
|
+ // in any intermediate location.
|
|
6229
|
+ set_current_to_destination();
|
|
6230
|
+}
|
|
6231
|
+
|
6212
|
6232
|
#if HAS_CONTROLLERFAN
|
6213
|
6233
|
|
6214
|
6234
|
void controllerFan() {
|