Overhaul of the planner (#11578)
- Move FWRETRACT to the planner - Combine leveling, skew, etc. in a single modifier method - Have kinematic and non-kinematic moves call one planner method
This commit is contained in:
parent
8323a08642
commit
c437bb08f1
39 changed files with 655 additions and 597 deletions
|
@ -275,7 +275,7 @@ void quickstop_stepper() {
|
||||||
planner.quick_stop();
|
planner.quick_stop();
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
set_current_from_steppers_for_axis(ALL_AXES);
|
set_current_from_steppers_for_axis(ALL_AXES);
|
||||||
SYNC_PLAN_POSITION_KINEMATIC();
|
sync_plan_position();
|
||||||
}
|
}
|
||||||
|
|
||||||
void enable_all_steppers() {
|
void enable_all_steppers() {
|
||||||
|
@ -465,7 +465,7 @@ void manage_inactivity(const bool ignore_stepper_queue/*=false*/) {
|
||||||
|
|
||||||
const float olde = current_position[E_AXIS];
|
const float olde = current_position[E_AXIS];
|
||||||
current_position[E_AXIS] += EXTRUDER_RUNOUT_EXTRUDE;
|
current_position[E_AXIS] += EXTRUDER_RUNOUT_EXTRUDE;
|
||||||
planner.buffer_line_kinematic(current_position, MMM_TO_MMS(EXTRUDER_RUNOUT_SPEED), active_extruder);
|
planner.buffer_line(current_position, MMM_TO_MMS(EXTRUDER_RUNOUT_SPEED), active_extruder);
|
||||||
current_position[E_AXIS] = olde;
|
current_position[E_AXIS] = olde;
|
||||||
planner.set_e_position_mm(olde);
|
planner.set_e_position_mm(olde);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
|
@ -766,7 +766,7 @@ void setup() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Vital to init stepper/planner equivalent for current_position
|
// Vital to init stepper/planner equivalent for current_position
|
||||||
SYNC_PLAN_POSITION_KINEMATIC();
|
sync_plan_position();
|
||||||
|
|
||||||
thermalManager.init(); // Initialize temperature loop
|
thermalManager.init(); // Initialize temperature loop
|
||||||
|
|
||||||
|
|
|
@ -539,9 +539,6 @@
|
||||||
// and processor overload (too many expensive sqrt calls).
|
// and processor overload (too many expensive sqrt calls).
|
||||||
#define DELTA_SEGMENTS_PER_SECOND 160
|
#define DELTA_SEGMENTS_PER_SECOND 160
|
||||||
|
|
||||||
// Convert feedrates to apply to the Effector instead of the Carriages
|
|
||||||
#define DELTA_FEEDRATE_SCALING
|
|
||||||
|
|
||||||
// After homing move down to a height where XY movement is unconstrained
|
// After homing move down to a height where XY movement is unconstrained
|
||||||
//#define DELTA_HOME_TO_SAFE_ZONE
|
//#define DELTA_HOME_TO_SAFE_ZONE
|
||||||
|
|
||||||
|
|
|
@ -539,9 +539,6 @@
|
||||||
// and processor overload (too many expensive sqrt calls).
|
// and processor overload (too many expensive sqrt calls).
|
||||||
#define DELTA_SEGMENTS_PER_SECOND 160
|
#define DELTA_SEGMENTS_PER_SECOND 160
|
||||||
|
|
||||||
// Convert feedrates to apply to the Effector instead of the Carriages
|
|
||||||
#define DELTA_FEEDRATE_SCALING
|
|
||||||
|
|
||||||
// After homing move down to a height where XY movement is unconstrained
|
// After homing move down to a height where XY movement is unconstrained
|
||||||
//#define DELTA_HOME_TO_SAFE_ZONE
|
//#define DELTA_HOME_TO_SAFE_ZONE
|
||||||
|
|
||||||
|
|
|
@ -539,9 +539,6 @@
|
||||||
// and processor overload (too many expensive sqrt calls).
|
// and processor overload (too many expensive sqrt calls).
|
||||||
#define DELTA_SEGMENTS_PER_SECOND 160
|
#define DELTA_SEGMENTS_PER_SECOND 160
|
||||||
|
|
||||||
// Convert feedrates to apply to the Effector instead of the Carriages
|
|
||||||
#define DELTA_FEEDRATE_SCALING
|
|
||||||
|
|
||||||
// After homing move down to a height where XY movement is unconstrained
|
// After homing move down to a height where XY movement is unconstrained
|
||||||
//#define DELTA_HOME_TO_SAFE_ZONE
|
//#define DELTA_HOME_TO_SAFE_ZONE
|
||||||
|
|
||||||
|
|
|
@ -544,9 +544,6 @@
|
||||||
// and processor overload (too many expensive sqrt calls).
|
// and processor overload (too many expensive sqrt calls).
|
||||||
#define DELTA_SEGMENTS_PER_SECOND 200
|
#define DELTA_SEGMENTS_PER_SECOND 200
|
||||||
|
|
||||||
// Convert feedrates to apply to the Effector instead of the Carriages
|
|
||||||
#define DELTA_FEEDRATE_SCALING
|
|
||||||
|
|
||||||
// After homing move down to a height where XY movement is unconstrained
|
// After homing move down to a height where XY movement is unconstrained
|
||||||
//#define DELTA_HOME_TO_SAFE_ZONE
|
//#define DELTA_HOME_TO_SAFE_ZONE
|
||||||
|
|
||||||
|
|
|
@ -529,9 +529,6 @@
|
||||||
// and processor overload (too many expensive sqrt calls).
|
// and processor overload (too many expensive sqrt calls).
|
||||||
#define DELTA_SEGMENTS_PER_SECOND 200
|
#define DELTA_SEGMENTS_PER_SECOND 200
|
||||||
|
|
||||||
// Convert feedrates to apply to the Effector instead of the Carriages
|
|
||||||
#define DELTA_FEEDRATE_SCALING
|
|
||||||
|
|
||||||
// After homing move down to a height where XY movement is unconstrained
|
// After homing move down to a height where XY movement is unconstrained
|
||||||
//#define DELTA_HOME_TO_SAFE_ZONE
|
//#define DELTA_HOME_TO_SAFE_ZONE
|
||||||
|
|
||||||
|
|
|
@ -529,9 +529,6 @@
|
||||||
// and processor overload (too many expensive sqrt calls).
|
// and processor overload (too many expensive sqrt calls).
|
||||||
#define DELTA_SEGMENTS_PER_SECOND 200
|
#define DELTA_SEGMENTS_PER_SECOND 200
|
||||||
|
|
||||||
// Convert feedrates to apply to the Effector instead of the Carriages
|
|
||||||
#define DELTA_FEEDRATE_SCALING
|
|
||||||
|
|
||||||
// After homing move down to a height where XY movement is unconstrained
|
// After homing move down to a height where XY movement is unconstrained
|
||||||
//#define DELTA_HOME_TO_SAFE_ZONE
|
//#define DELTA_HOME_TO_SAFE_ZONE
|
||||||
|
|
||||||
|
|
|
@ -515,9 +515,6 @@
|
||||||
// and processor overload (too many expensive sqrt calls).
|
// and processor overload (too many expensive sqrt calls).
|
||||||
#define DELTA_SEGMENTS_PER_SECOND 160
|
#define DELTA_SEGMENTS_PER_SECOND 160
|
||||||
|
|
||||||
// Convert feedrates to apply to the Effector instead of the Carriages
|
|
||||||
#define DELTA_FEEDRATE_SCALING
|
|
||||||
|
|
||||||
// After homing move down to a height where XY movement is unconstrained
|
// After homing move down to a height where XY movement is unconstrained
|
||||||
//#define DELTA_HOME_TO_SAFE_ZONE
|
//#define DELTA_HOME_TO_SAFE_ZONE
|
||||||
|
|
||||||
|
|
|
@ -533,9 +533,6 @@
|
||||||
// and processor overload (too many expensive sqrt calls).
|
// and processor overload (too many expensive sqrt calls).
|
||||||
#define DELTA_SEGMENTS_PER_SECOND 160
|
#define DELTA_SEGMENTS_PER_SECOND 160
|
||||||
|
|
||||||
// Convert feedrates to apply to the Effector instead of the Carriages
|
|
||||||
#define DELTA_FEEDRATE_SCALING
|
|
||||||
|
|
||||||
// After homing move down to a height where XY movement is unconstrained
|
// After homing move down to a height where XY movement is unconstrained
|
||||||
//#define DELTA_HOME_TO_SAFE_ZONE
|
//#define DELTA_HOME_TO_SAFE_ZONE
|
||||||
|
|
||||||
|
|
|
@ -25,15 +25,12 @@
|
||||||
#if HAS_LEVELING
|
#if HAS_LEVELING
|
||||||
|
|
||||||
#include "bedlevel.h"
|
#include "bedlevel.h"
|
||||||
|
#include "../../module/planner.h"
|
||||||
|
|
||||||
#if ENABLED(MESH_BED_LEVELING) || ENABLED(PROBE_MANUALLY)
|
#if ENABLED(MESH_BED_LEVELING) || ENABLED(PROBE_MANUALLY)
|
||||||
#include "../../module/motion.h"
|
#include "../../module/motion.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PLANNER_LEVELING
|
|
||||||
#include "../../module/planner.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ENABLED(PROBE_MANUALLY)
|
#if ENABLED(PROBE_MANUALLY)
|
||||||
bool g29_in_progress = false;
|
bool g29_in_progress = false;
|
||||||
#endif
|
#endif
|
||||||
|
@ -79,17 +76,12 @@ void set_bed_leveling_enabled(const bool enable/*=true*/) {
|
||||||
|
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
|
|
||||||
#if ENABLED(MESH_BED_LEVELING)
|
#if ENABLED(AUTO_BED_LEVELING_BILINEAR)
|
||||||
|
// Force bilinear_z_offset to re-calculate next time
|
||||||
|
const float reset[XYZ] = { -9999.999, -9999.999, 0 };
|
||||||
|
(void)bilinear_z_offset(reset);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!enable)
|
|
||||||
planner.apply_leveling(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS]);
|
|
||||||
|
|
||||||
const bool enabling = enable && leveling_is_valid();
|
|
||||||
planner.leveling_active = enabling;
|
|
||||||
if (enabling) planner.unapply_leveling(current_position);
|
|
||||||
|
|
||||||
#elif ENABLED(AUTO_BED_LEVELING_UBL)
|
|
||||||
#if PLANNER_LEVELING
|
|
||||||
if (planner.leveling_active) { // leveling from on to off
|
if (planner.leveling_active) { // leveling from on to off
|
||||||
// change unleveled current_position to physical current_position without moving steppers.
|
// change unleveled current_position to physical current_position without moving steppers.
|
||||||
planner.apply_leveling(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS]);
|
planner.apply_leveling(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS]);
|
||||||
|
@ -100,53 +92,8 @@ void set_bed_leveling_enabled(const bool enable/*=true*/) {
|
||||||
// change physical current_position to unleveled current_position without moving steppers.
|
// change physical current_position to unleveled current_position without moving steppers.
|
||||||
planner.unapply_leveling(current_position);
|
planner.unapply_leveling(current_position);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
// UBL equivalents for apply/unapply_leveling
|
|
||||||
#if ENABLED(SKEW_CORRECTION)
|
|
||||||
float pos[XYZ] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] };
|
|
||||||
planner.skew(pos[X_AXIS], pos[Y_AXIS], pos[Z_AXIS]);
|
|
||||||
#else
|
|
||||||
const float (&pos)[XYZE] = current_position;
|
|
||||||
#endif
|
|
||||||
if (planner.leveling_active) {
|
|
||||||
current_position[Z_AXIS] += ubl.get_z_correction(pos[X_AXIS], pos[Y_AXIS]);
|
|
||||||
planner.leveling_active = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
planner.leveling_active = true;
|
|
||||||
current_position[Z_AXIS] -= ubl.get_z_correction(pos[X_AXIS], pos[Y_AXIS]);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else // OLDSCHOOL_ABL
|
sync_plan_position();
|
||||||
|
|
||||||
#if ENABLED(AUTO_BED_LEVELING_BILINEAR)
|
|
||||||
// Force bilinear_z_offset to re-calculate next time
|
|
||||||
const float reset[XYZ] = { -9999.999, -9999.999, 0 };
|
|
||||||
(void)bilinear_z_offset(reset);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Enable or disable leveling compensation in the planner
|
|
||||||
planner.leveling_active = enable;
|
|
||||||
|
|
||||||
if (!enable)
|
|
||||||
// When disabling just get the current position from the steppers.
|
|
||||||
// This will yield the smallest error when first converted back to steps.
|
|
||||||
set_current_from_steppers_for_axis(
|
|
||||||
#if ABL_PLANAR
|
|
||||||
ALL_AXES
|
|
||||||
#else
|
|
||||||
Z_AXIS
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
else
|
|
||||||
// When enabling, remove compensation from the current position,
|
|
||||||
// so compensation will give the right stepper counts.
|
|
||||||
planner.unapply_leveling(current_position);
|
|
||||||
|
|
||||||
SYNC_PLAN_POSITION_KINEMATIC();
|
|
||||||
|
|
||||||
#endif // OLDSCHOOL_ABL
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,12 +49,11 @@
|
||||||
* as possible to determine if this is the case. If this move is within the same cell, we will
|
* as possible to determine if this is the case. If this move is within the same cell, we will
|
||||||
* just do the required Z-Height correction, call the Planner's buffer_line() routine, and leave
|
* just do the required Z-Height correction, call the Planner's buffer_line() routine, and leave
|
||||||
*/
|
*/
|
||||||
#if ENABLED(SKEW_CORRECTION)
|
#if HAS_POSITION_MODIFIERS
|
||||||
// For skew correction just adjust the destination point and we're done
|
|
||||||
float start[XYZE] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS] },
|
float start[XYZE] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS] },
|
||||||
end[XYZE] = { destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS] };
|
end[XYZE] = { destination[X_AXIS], destination[Y_AXIS], destination[Z_AXIS], destination[E_AXIS] };
|
||||||
planner.skew(start[X_AXIS], start[Y_AXIS], start[Z_AXIS]);
|
planner.apply_modifiers(start);
|
||||||
planner.skew(end[X_AXIS], end[Y_AXIS], end[Z_AXIS]);
|
planner.apply_modifiers(end);
|
||||||
#else
|
#else
|
||||||
const float (&start)[XYZE] = current_position,
|
const float (&start)[XYZE] = current_position,
|
||||||
(&end)[XYZE] = destination;
|
(&end)[XYZE] = destination;
|
||||||
|
@ -364,47 +363,6 @@
|
||||||
|
|
||||||
#else // UBL_SEGMENTED
|
#else // UBL_SEGMENTED
|
||||||
|
|
||||||
#if IS_SCARA // scale the feed rate from mm/s to degrees/s
|
|
||||||
static float scara_feed_factor, scara_oldA, scara_oldB;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// We don't want additional apply_leveling() performed by regular buffer_line or buffer_line_kinematic,
|
|
||||||
// so we call buffer_segment directly here. Per-segmented leveling and kinematics performed first.
|
|
||||||
|
|
||||||
inline void _O2 ubl_buffer_segment_raw(const float (&in_raw)[XYZE], const float &fr) {
|
|
||||||
|
|
||||||
#if ENABLED(SKEW_CORRECTION)
|
|
||||||
float raw[XYZE] = { in_raw[X_AXIS], in_raw[Y_AXIS], in_raw[Z_AXIS] };
|
|
||||||
planner.skew(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS]);
|
|
||||||
#else
|
|
||||||
const float (&raw)[XYZE] = in_raw;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ENABLED(DELTA) // apply delta inverse_kinematics
|
|
||||||
|
|
||||||
DELTA_IK(raw);
|
|
||||||
planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], in_raw[E_AXIS], fr, active_extruder);
|
|
||||||
|
|
||||||
#elif IS_SCARA // apply scara inverse_kinematics (should be changed to save raw->logical->raw)
|
|
||||||
|
|
||||||
inverse_kinematics(raw); // this writes delta[ABC] from raw[XYZE]
|
|
||||||
// should move the feedrate scaling to scara inverse_kinematics
|
|
||||||
|
|
||||||
const float adiff = ABS(delta[A_AXIS] - scara_oldA),
|
|
||||||
bdiff = ABS(delta[B_AXIS] - scara_oldB);
|
|
||||||
scara_oldA = delta[A_AXIS];
|
|
||||||
scara_oldB = delta[B_AXIS];
|
|
||||||
float s_feedrate = MAX(adiff, bdiff) * scara_feed_factor;
|
|
||||||
|
|
||||||
planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], in_raw[E_AXIS], s_feedrate, active_extruder);
|
|
||||||
|
|
||||||
#else // CARTESIAN
|
|
||||||
|
|
||||||
planner.buffer_segment(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], in_raw[E_AXIS], fr, active_extruder);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if IS_SCARA
|
#if IS_SCARA
|
||||||
#define DELTA_SEGMENT_MIN_LENGTH 0.25 // SCARA minimum segment size is 0.25mm
|
#define DELTA_SEGMENT_MIN_LENGTH 0.25 // SCARA minimum segment size is 0.25mm
|
||||||
#elif ENABLED(DELTA)
|
#elif ENABLED(DELTA)
|
||||||
|
@ -449,10 +407,9 @@
|
||||||
NOLESS(segments, 1U); // must have at least one segment
|
NOLESS(segments, 1U); // must have at least one segment
|
||||||
const float inv_segments = 1.0f / segments; // divide once, multiply thereafter
|
const float inv_segments = 1.0f / segments; // divide once, multiply thereafter
|
||||||
|
|
||||||
#if IS_SCARA // scale the feed rate from mm/s to degrees/s
|
const float segment_xyz_mm = HYPOT(cartesian_xy_mm, total[Z_AXIS]) * inv_segments; // length of each segment
|
||||||
scara_feed_factor = cartesian_xy_mm * inv_segments * feedrate;
|
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||||
scara_oldA = planner.get_axis_position_degrees(A_AXIS);
|
const float inv_duration = feedrate / segment_xyz_mm;
|
||||||
scara_oldB = planner.get_axis_position_degrees(B_AXIS);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const float diff[XYZE] = {
|
const float diff[XYZE] = {
|
||||||
|
@ -476,9 +433,17 @@
|
||||||
if (!planner.leveling_active || !planner.leveling_active_at_z(rtarget[Z_AXIS])) { // no mesh leveling
|
if (!planner.leveling_active || !planner.leveling_active_at_z(rtarget[Z_AXIS])) { // no mesh leveling
|
||||||
while (--segments) {
|
while (--segments) {
|
||||||
LOOP_XYZE(i) raw[i] += diff[i];
|
LOOP_XYZE(i) raw[i] += diff[i];
|
||||||
ubl_buffer_segment_raw(raw, feedrate);
|
planner.buffer_line(raw, feedrate, active_extruder, segment_xyz_mm
|
||||||
|
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||||
|
, inv_duration
|
||||||
|
#endif
|
||||||
|
);
|
||||||
}
|
}
|
||||||
ubl_buffer_segment_raw(rtarget, feedrate);
|
planner.buffer_line(rtarget, feedrate, active_extruder, segment_xyz_mm
|
||||||
|
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||||
|
, inv_duration
|
||||||
|
#endif
|
||||||
|
);
|
||||||
return false; // moved but did not set_current_from_destination();
|
return false; // moved but did not set_current_from_destination();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,7 +519,11 @@
|
||||||
|
|
||||||
const float z = raw[Z_AXIS];
|
const float z = raw[Z_AXIS];
|
||||||
raw[Z_AXIS] += z_cxcy;
|
raw[Z_AXIS] += z_cxcy;
|
||||||
ubl_buffer_segment_raw(raw, feedrate);
|
planner.buffer_line(raw, feedrate, active_extruder, segment_xyz_mm
|
||||||
|
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||||
|
, inv_duration
|
||||||
|
#endif
|
||||||
|
);
|
||||||
raw[Z_AXIS] = z;
|
raw[Z_AXIS] = z;
|
||||||
|
|
||||||
if (segments == 0) // done with last segment
|
if (segments == 0) // done with last segment
|
||||||
|
|
|
@ -54,6 +54,7 @@ float FWRetract::retract_length, // M207 S - G10 Retract len
|
||||||
FWRetract::swap_retract_length, // M207 W - G10 Swap Retract length
|
FWRetract::swap_retract_length, // M207 W - G10 Swap Retract length
|
||||||
FWRetract::swap_retract_recover_length, // M208 W - G11 Swap Recover length
|
FWRetract::swap_retract_recover_length, // M208 W - G11 Swap Recover length
|
||||||
FWRetract::swap_retract_recover_feedrate_mm_s, // M208 R - G11 Swap Recover feedrate
|
FWRetract::swap_retract_recover_feedrate_mm_s, // M208 R - G11 Swap Recover feedrate
|
||||||
|
FWRetract::current_retract[EXTRUDERS], // Retract value used by planner
|
||||||
FWRetract::current_hop;
|
FWRetract::current_hop;
|
||||||
|
|
||||||
void FWRetract::reset() {
|
void FWRetract::reset() {
|
||||||
|
@ -73,6 +74,7 @@ void FWRetract::reset() {
|
||||||
#if EXTRUDERS > 1
|
#if EXTRUDERS > 1
|
||||||
retracted_swap[i] = false;
|
retracted_swap[i] = false;
|
||||||
#endif
|
#endif
|
||||||
|
current_retract[i] = 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,9 +86,6 @@ void FWRetract::reset() {
|
||||||
*
|
*
|
||||||
* To simplify the logic, doubled retract/recover moves are ignored.
|
* To simplify the logic, doubled retract/recover moves are ignored.
|
||||||
*
|
*
|
||||||
* Note: Z lift is done transparently to the planner. Aborting
|
|
||||||
* a print between G10 and G11 may corrupt the Z position.
|
|
||||||
*
|
|
||||||
* Note: Auto-retract will apply the set Z hop in addition to any Z hop
|
* Note: Auto-retract will apply the set Z hop in addition to any Z hop
|
||||||
* included in the G-code. Use M207 Z0 to to prevent double hop.
|
* included in the G-code. Use M207 Z0 to to prevent double hop.
|
||||||
*/
|
*/
|
||||||
|
@ -95,9 +94,6 @@ void FWRetract::retract(const bool retracting
|
||||||
, bool swapping /* =false */
|
, bool swapping /* =false */
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
|
|
||||||
static float current_hop = 0.0; // Total amount lifted, for use in recover
|
|
||||||
|
|
||||||
// Prevent two retracts or recovers in a row
|
// Prevent two retracts or recovers in a row
|
||||||
if (retracted[active_extruder] == retracting) return;
|
if (retracted[active_extruder] == retracting) return;
|
||||||
|
|
||||||
|
@ -129,48 +125,50 @@ void FWRetract::retract(const bool retracting
|
||||||
//*/
|
//*/
|
||||||
|
|
||||||
const float old_feedrate_mm_s = feedrate_mm_s,
|
const float old_feedrate_mm_s = feedrate_mm_s,
|
||||||
renormalize = RECIPROCAL(planner.e_factor[active_extruder]),
|
unscale_e = RECIPROCAL(planner.e_factor[active_extruder]),
|
||||||
base_retract = swapping ? swap_retract_length : retract_length,
|
unscale_fr = 100.0 / feedrate_percentage, // Disable feedrate scaling for retract moves
|
||||||
old_z = current_position[Z_AXIS],
|
base_retract = swapping ? swap_retract_length : retract_length;
|
||||||
old_e = current_position[E_AXIS];
|
|
||||||
|
|
||||||
// The current position will be the destination for E and Z moves
|
// The current position will be the destination for E and Z moves
|
||||||
set_destination_from_current();
|
set_destination_from_current();
|
||||||
|
|
||||||
if (retracting) {
|
if (retracting) {
|
||||||
// Retract by moving from a faux E position back to the current E position
|
// Retract by moving from a faux E position back to the current E position
|
||||||
feedrate_mm_s = retract_feedrate_mm_s;
|
feedrate_mm_s = retract_feedrate_mm_s * unscale_fr;
|
||||||
destination[E_AXIS] -= base_retract * renormalize;
|
current_retract[active_extruder] = base_retract * unscale_e;
|
||||||
prepare_move_to_destination(); // set_current_to_destination
|
prepare_move_to_destination(); // set_current_to_destination
|
||||||
|
planner.synchronize(); // Wait for move to complete
|
||||||
|
|
||||||
// Is a Z hop set, and has the hop not yet been done?
|
// Is a Z hop set, and has the hop not yet been done?
|
||||||
if (retract_zlift > 0.01 && !current_hop) { // Apply hop only once
|
if (retract_zlift > 0.01 && !current_hop) { // Apply hop only once
|
||||||
current_hop += retract_zlift; // Add to the hop total (again, only once)
|
current_hop += retract_zlift; // Add to the hop total (again, only once)
|
||||||
destination[Z_AXIS] += retract_zlift; // Raise Z by the zlift (M207 Z) amount
|
feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS] * unscale_fr; // Maximum Z feedrate
|
||||||
feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS]; // Maximum Z feedrate
|
|
||||||
prepare_move_to_destination(); // Raise up, set_current_to_destination
|
prepare_move_to_destination(); // Raise up, set_current_to_destination
|
||||||
|
planner.synchronize(); // Wait for move to complete
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// If a hop was done and Z hasn't changed, undo the Z hop
|
// If a hop was done and Z hasn't changed, undo the Z hop
|
||||||
if (current_hop) {
|
if (current_hop) {
|
||||||
current_position[Z_AXIS] += current_hop; // Restore the actual Z position
|
current_hop = 0.0;
|
||||||
SYNC_PLAN_POSITION_KINEMATIC(); // Unspoof the position planner
|
feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS] * unscale_fr; // Z feedrate to max
|
||||||
feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS]; // Z feedrate to max
|
|
||||||
prepare_move_to_destination(); // Lower Z, set_current_to_destination
|
prepare_move_to_destination(); // Lower Z, set_current_to_destination
|
||||||
current_hop = 0.0; // Clear the hop amount
|
planner.synchronize(); // Wait for move to complete
|
||||||
}
|
}
|
||||||
|
|
||||||
destination[E_AXIS] += (base_retract + (swapping ? swap_retract_recover_length : retract_recover_length)) * renormalize;
|
const float extra_recover = swapping ? swap_retract_recover_length : retract_recover_length;
|
||||||
feedrate_mm_s = swapping ? swap_retract_recover_feedrate_mm_s : retract_recover_feedrate_mm_s;
|
if (extra_recover != 0.0) {
|
||||||
|
current_position[E_AXIS] -= extra_recover; // Adjust the current E position by the extra amount to recover
|
||||||
|
sync_plan_position_e(); // Sync the planner position so the extra amount is recovered
|
||||||
|
}
|
||||||
|
|
||||||
|
current_retract[active_extruder] = 0.0;
|
||||||
|
feedrate_mm_s = (swapping ? swap_retract_recover_feedrate_mm_s : retract_recover_feedrate_mm_s) * unscale_fr;
|
||||||
prepare_move_to_destination(); // Recover E, set_current_to_destination
|
prepare_move_to_destination(); // Recover E, set_current_to_destination
|
||||||
|
planner.synchronize(); // Wait for move to complete
|
||||||
}
|
}
|
||||||
|
|
||||||
feedrate_mm_s = old_feedrate_mm_s; // Restore original feedrate
|
feedrate_mm_s = old_feedrate_mm_s; // Restore original feedrate
|
||||||
current_position[Z_AXIS] = old_z; // Restore Z and E positions
|
|
||||||
current_position[E_AXIS] = old_e;
|
|
||||||
SYNC_PLAN_POSITION_KINEMATIC(); // As if the move never took place
|
|
||||||
|
|
||||||
retracted[active_extruder] = retracting; // Active extruder now retracted / recovered
|
retracted[active_extruder] = retracting; // Active extruder now retracted / recovered
|
||||||
|
|
||||||
// If swap retract/recover update the retracted_swap flag too
|
// If swap retract/recover update the retracted_swap flag too
|
||||||
|
@ -194,7 +192,6 @@ void FWRetract::retract(const bool retracting
|
||||||
SERIAL_ECHOLNPAIR("current_position[e] ", current_position[E_AXIS]);
|
SERIAL_ECHOLNPAIR("current_position[e] ", current_position[E_AXIS]);
|
||||||
SERIAL_ECHOLNPAIR("current_hop ", current_hop);
|
SERIAL_ECHOLNPAIR("current_hop ", current_hop);
|
||||||
//*/
|
//*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // FWRETRACT
|
#endif // FWRETRACT
|
||||||
|
|
|
@ -46,7 +46,8 @@ public:
|
||||||
swap_retract_length, // M207 W - G10 Swap Retract length
|
swap_retract_length, // M207 W - G10 Swap Retract length
|
||||||
swap_retract_recover_length, // M208 W - G11 Swap Recover length
|
swap_retract_recover_length, // M208 W - G11 Swap Recover length
|
||||||
swap_retract_recover_feedrate_mm_s, // M208 R - G11 Swap Recover feedrate
|
swap_retract_recover_feedrate_mm_s, // M208 R - G11 Swap Recover feedrate
|
||||||
current_hop;
|
current_retract[EXTRUDERS], // Retract value used by planner
|
||||||
|
current_hop; // Hop value used by planner
|
||||||
|
|
||||||
FWRetract() { reset(); }
|
FWRetract() { reset(); }
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,7 @@ static bool ensure_safe_temperature(const AdvancedPauseMode mode=ADVANCED_PAUSE_
|
||||||
static void do_pause_e_move(const float &length, const float &fr) {
|
static void do_pause_e_move(const float &length, const float &fr) {
|
||||||
set_destination_from_current();
|
set_destination_from_current();
|
||||||
destination[E_AXIS] += length / planner.e_factor[active_extruder];
|
destination[E_AXIS] += length / planner.e_factor[active_extruder];
|
||||||
planner.buffer_line_kinematic(destination, fr, active_extruder);
|
planner.buffer_line(destination, fr, active_extruder);
|
||||||
set_current_from_destination();
|
set_current_from_destination();
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,10 @@
|
||||||
#include "../sd/cardreader.h"
|
#include "../sd/cardreader.h"
|
||||||
#include "../core/serial.h"
|
#include "../core/serial.h"
|
||||||
|
|
||||||
|
#if ENABLED(FWRETRACT)
|
||||||
|
#include "fwretract.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// Recovery data
|
// Recovery data
|
||||||
job_recovery_info_t job_recovery_info;
|
job_recovery_info_t job_recovery_info;
|
||||||
JobRecoveryPhase job_recovery_phase = JOB_RECOVERY_IDLE;
|
JobRecoveryPhase job_recovery_phase = JOB_RECOVERY_IDLE;
|
||||||
|
@ -90,6 +94,15 @@ extern uint8_t commands_in_queue, cmd_queue_index_r;
|
||||||
SERIAL_PROTOCOLPAIR("leveling: ", int(job_recovery_info.leveling));
|
SERIAL_PROTOCOLPAIR("leveling: ", int(job_recovery_info.leveling));
|
||||||
SERIAL_PROTOCOLLNPAIR(" fade: ", int(job_recovery_info.fade));
|
SERIAL_PROTOCOLLNPAIR(" fade: ", int(job_recovery_info.fade));
|
||||||
#endif
|
#endif
|
||||||
|
#if ENABLED(FWRETRACT)
|
||||||
|
SERIAL_PROTOCOLPGM("retract: ");
|
||||||
|
for (int8_t e = 0; e < EXTRUDERS; e++) {
|
||||||
|
SERIAL_PROTOCOL(job_recovery_info.retract[e]);
|
||||||
|
if (e < EXTRUDERS - 1) SERIAL_CHAR(',');
|
||||||
|
}
|
||||||
|
SERIAL_EOL();
|
||||||
|
SERIAL_PROTOCOLLNPAIR("retract_hop: ", job_recovery_info.retract_hop);
|
||||||
|
#endif
|
||||||
SERIAL_PROTOCOLLNPAIR("cmd_queue_index_r: ", int(job_recovery_info.cmd_queue_index_r));
|
SERIAL_PROTOCOLLNPAIR("cmd_queue_index_r: ", int(job_recovery_info.cmd_queue_index_r));
|
||||||
SERIAL_PROTOCOLLNPAIR("commands_in_queue: ", int(job_recovery_info.commands_in_queue));
|
SERIAL_PROTOCOLLNPAIR("commands_in_queue: ", int(job_recovery_info.commands_in_queue));
|
||||||
if (recovery)
|
if (recovery)
|
||||||
|
@ -160,6 +173,15 @@ void check_print_job_recovery() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(FWRETRACT)
|
||||||
|
for (uint8_t e = 0; e < EXTRUDERS; e++) {
|
||||||
|
if (job_recovery_info.retract[e] != 0.0)
|
||||||
|
fwretract.current_retract[e] = job_recovery_info.retract[e];
|
||||||
|
fwretract.retracted[e] = true;
|
||||||
|
}
|
||||||
|
fwretract.current_hop = job_recovery_info.retract_hop;
|
||||||
|
#endif
|
||||||
|
|
||||||
dtostrf(job_recovery_info.current_position[Z_AXIS] + 2, 1, 3, str_1);
|
dtostrf(job_recovery_info.current_position[Z_AXIS] + 2, 1, 3, str_1);
|
||||||
dtostrf(job_recovery_info.current_position[E_AXIS]
|
dtostrf(job_recovery_info.current_position[E_AXIS]
|
||||||
#if ENABLED(SAVE_EACH_CMD_MODE)
|
#if ENABLED(SAVE_EACH_CMD_MODE)
|
||||||
|
@ -256,6 +278,11 @@ void save_job_recovery_info() {
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(FWRETRACT)
|
||||||
|
COPY(job_recovery_info.retract, fwretract.current_retract);
|
||||||
|
job_recovery_info.retract_hop = fwretract.current_hop;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Commands in the queue
|
// Commands in the queue
|
||||||
job_recovery_info.cmd_queue_index_r = cmd_queue_index_r;
|
job_recovery_info.cmd_queue_index_r = cmd_queue_index_r;
|
||||||
job_recovery_info.commands_in_queue = commands_in_queue;
|
job_recovery_info.commands_in_queue = commands_in_queue;
|
||||||
|
|
|
@ -60,6 +60,10 @@ typedef struct {
|
||||||
float fade;
|
float fade;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(FWRETRACT)
|
||||||
|
float retract[EXTRUDERS], retract_hop;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Command queue
|
// Command queue
|
||||||
uint8_t cmd_queue_index_r, commands_in_queue;
|
uint8_t cmd_queue_index_r, commands_in_queue;
|
||||||
char command_queue[BUFSIZE][MAX_CMD_SIZE];
|
char command_queue[BUFSIZE][MAX_CMD_SIZE];
|
||||||
|
|
|
@ -989,7 +989,7 @@ G29_TYPE GcodeSuite::G29() {
|
||||||
KEEPALIVE_STATE(IN_HANDLER);
|
KEEPALIVE_STATE(IN_HANDLER);
|
||||||
|
|
||||||
if (planner.leveling_active)
|
if (planner.leveling_active)
|
||||||
SYNC_PLAN_POSITION_KINEMATIC();
|
sync_plan_position();
|
||||||
|
|
||||||
#if HAS_BED_PROBE && defined(Z_AFTER_PROBING)
|
#if HAS_BED_PROBE && defined(Z_AFTER_PROBING)
|
||||||
move_z_after_probing();
|
move_z_after_probing();
|
||||||
|
|
|
@ -101,7 +101,7 @@
|
||||||
if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("Z_SAFE_HOMING >>>");
|
if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("Z_SAFE_HOMING >>>");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SYNC_PLAN_POSITION_KINEMATIC();
|
sync_plan_position();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move the Z probe (or just the nozzle) to the safe homing point
|
* Move the Z probe (or just the nozzle) to the safe homing point
|
||||||
|
@ -182,7 +182,7 @@ void GcodeSuite::G28(const bool always_home_all) {
|
||||||
#if ENABLED(MARLIN_DEV_MODE)
|
#if ENABLED(MARLIN_DEV_MODE)
|
||||||
if (parser.seen('S')) {
|
if (parser.seen('S')) {
|
||||||
LOOP_XYZ(a) set_axis_is_at_home((AxisEnum)a);
|
LOOP_XYZ(a) set_axis_is_at_home((AxisEnum)a);
|
||||||
SYNC_PLAN_POSITION_KINEMATIC();
|
sync_plan_position();
|
||||||
SERIAL_ECHOLNPGM("Simulated Homing");
|
SERIAL_ECHOLNPGM("Simulated Homing");
|
||||||
report_current_position();
|
report_current_position();
|
||||||
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
||||||
|
@ -357,7 +357,7 @@ void GcodeSuite::G28(const bool always_home_all) {
|
||||||
} // home_all || homeZ
|
} // home_all || homeZ
|
||||||
#endif // Z_HOME_DIR < 0
|
#endif // Z_HOME_DIR < 0
|
||||||
|
|
||||||
SYNC_PLAN_POSITION_KINEMATIC();
|
sync_plan_position();
|
||||||
|
|
||||||
#endif // !DELTA (G28)
|
#endif // !DELTA (G28)
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ void GcodeSuite::M852() {
|
||||||
// When skew is changed the current position changes
|
// When skew is changed the current position changes
|
||||||
if (setval) {
|
if (setval) {
|
||||||
set_current_from_steppers_for_axis(ALL_AXES);
|
set_current_from_steppers_for_axis(ALL_AXES);
|
||||||
SYNC_PLAN_POSITION_KINEMATIC();
|
sync_plan_position();
|
||||||
report_current_position();
|
report_current_position();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,14 +136,17 @@ void GcodeSuite::M205() {
|
||||||
const float junc_dev = parser.value_linear_units();
|
const float junc_dev = parser.value_linear_units();
|
||||||
if (WITHIN(junc_dev, 0.01f, 0.3f)) {
|
if (WITHIN(junc_dev, 0.01f, 0.3f)) {
|
||||||
planner.junction_deviation_mm = junc_dev;
|
planner.junction_deviation_mm = junc_dev;
|
||||||
|
#if ENABLED(LIN_ADVANCE)
|
||||||
planner.recalculate_max_e_jerk();
|
planner.recalculate_max_e_jerk();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SERIAL_ERROR_START();
|
SERIAL_ERROR_START();
|
||||||
SERIAL_ERRORLNPGM("?J out of range (0.01 to 0.3)");
|
SERIAL_ERRORLNPGM("?J out of range (0.01 to 0.3)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#endif
|
||||||
|
#if HAS_CLASSIC_JERK
|
||||||
if (parser.seen('X')) planner.max_jerk[X_AXIS] = parser.value_linear_units();
|
if (parser.seen('X')) planner.max_jerk[X_AXIS] = parser.value_linear_units();
|
||||||
if (parser.seen('Y')) planner.max_jerk[Y_AXIS] = parser.value_linear_units();
|
if (parser.seen('Y')) planner.max_jerk[Y_AXIS] = parser.value_linear_units();
|
||||||
if (parser.seen('Z')) {
|
if (parser.seen('Z')) {
|
||||||
|
@ -153,6 +156,8 @@ void GcodeSuite::M205() {
|
||||||
SERIAL_ECHOLNPGM("WARNING! Low Z Jerk may lead to unwanted pauses.");
|
SERIAL_ECHOLNPGM("WARNING! Low Z Jerk may lead to unwanted pauses.");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#if DISABLED(JUNCTION_DEVIATION) || DISABLED(LIN_ADVANCE)
|
||||||
if (parser.seen('E')) planner.max_jerk[E_AXIS] = parser.value_linear_units();
|
if (parser.seen('E')) planner.max_jerk[E_AXIS] = parser.value_linear_units();
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ void GcodeSuite::M92() {
|
||||||
const float value = parser.value_per_axis_unit((AxisEnum)(E_AXIS + TARGET_EXTRUDER));
|
const float value = parser.value_per_axis_unit((AxisEnum)(E_AXIS + TARGET_EXTRUDER));
|
||||||
if (value < 20) {
|
if (value < 20) {
|
||||||
float factor = planner.axis_steps_per_mm[E_AXIS + TARGET_EXTRUDER] / value; // increase e constants if M92 E14 is given for netfab.
|
float factor = planner.axis_steps_per_mm[E_AXIS + TARGET_EXTRUDER] / value; // increase e constants if M92 E14 is given for netfab.
|
||||||
#if DISABLED(JUNCTION_DEVIATION)
|
#if HAS_CLASSIC_JERK && (DISABLED(JUNCTION_DEVIATION) || DISABLED(LIN_ADVANCE))
|
||||||
planner.max_jerk[E_AXIS] *= factor;
|
planner.max_jerk[E_AXIS] *= factor;
|
||||||
#endif
|
#endif
|
||||||
planner.max_feedrate_mm_s[E_AXIS + TARGET_EXTRUDER] *= factor;
|
planner.max_feedrate_mm_s[E_AXIS + TARGET_EXTRUDER] *= factor;
|
||||||
|
|
|
@ -92,7 +92,7 @@ void GcodeSuite::G92() {
|
||||||
COPY(coordinate_system[active_coordinate_system], position_shift);
|
COPY(coordinate_system[active_coordinate_system], position_shift);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (didXYZ) SYNC_PLAN_POSITION_KINEMATIC();
|
if (didXYZ) sync_plan_position();
|
||||||
else if (didE) sync_plan_position_e();
|
else if (didE) sync_plan_position_e();
|
||||||
|
|
||||||
report_current_position();
|
report_current_position();
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
|
|
||||||
float leveled[XYZ] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] };
|
float leveled[XYZ] = { current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] };
|
||||||
|
|
||||||
#if PLANNER_LEVELING
|
#if HAS_LEVELING
|
||||||
SERIAL_PROTOCOLPGM("Leveled:");
|
SERIAL_PROTOCOLPGM("Leveled:");
|
||||||
planner.apply_leveling(leveled);
|
planner.apply_leveling(leveled);
|
||||||
report_xyz(leveled);
|
report_xyz(leveled);
|
||||||
|
|
|
@ -35,10 +35,6 @@
|
||||||
#include "../../module/scara.h"
|
#include "../../module/scara.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_FEEDRATE_SCALING && ENABLED(AUTO_BED_LEVELING_BILINEAR)
|
|
||||||
#include "../../feature/bedlevel/abl/abl.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if N_ARC_CORRECTION < 1
|
#if N_ARC_CORRECTION < 1
|
||||||
#undef N_ARC_CORRECTION
|
#undef N_ARC_CORRECTION
|
||||||
#define N_ARC_CORRECTION 1
|
#define N_ARC_CORRECTION 1
|
||||||
|
@ -139,19 +135,11 @@ void plan_arc(
|
||||||
|
|
||||||
const float fr_mm_s = MMS_SCALED(feedrate_mm_s);
|
const float fr_mm_s = MMS_SCALED(feedrate_mm_s);
|
||||||
|
|
||||||
millis_t next_idle_ms = millis() + 200UL;
|
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||||
|
const float inv_duration = fr_mm_s / MM_PER_ARC_SEGMENT;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if HAS_FEEDRATE_SCALING
|
millis_t next_idle_ms = millis() + 200UL;
|
||||||
// SCARA needs to scale the feed rate from mm/s to degrees/s
|
|
||||||
const float inv_segment_length = 1.0f / float(MM_PER_ARC_SEGMENT),
|
|
||||||
inverse_secs = inv_segment_length * fr_mm_s;
|
|
||||||
float oldA = planner.position_float[A_AXIS],
|
|
||||||
oldB = planner.position_float[B_AXIS]
|
|
||||||
#if ENABLED(DELTA_FEEDRATE_SCALING)
|
|
||||||
, oldC = planner.position_float[C_AXIS]
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if N_ARC_CORRECTION > 1
|
#if N_ARC_CORRECTION > 1
|
||||||
int8_t arc_recalc_count = N_ARC_CORRECTION;
|
int8_t arc_recalc_count = N_ARC_CORRECTION;
|
||||||
|
@ -196,57 +184,32 @@ void plan_arc(
|
||||||
|
|
||||||
clamp_to_software_endstops(raw);
|
clamp_to_software_endstops(raw);
|
||||||
|
|
||||||
#if HAS_FEEDRATE_SCALING
|
#if HAS_LEVELING && !PLANNER_LEVELING
|
||||||
inverse_kinematics(raw);
|
planner.apply_leveling(raw);
|
||||||
ADJUST_DELTA(raw);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (!planner.buffer_line(raw, fr_mm_s, active_extruder, MM_PER_ARC_SEGMENT
|
||||||
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||||
// For SCARA scale the feed rate from mm/s to degrees/s
|
, inv_duration
|
||||||
// i.e., Complete the angular vector in the given time.
|
|
||||||
if (!planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], raw[Z_AXIS], raw[E_AXIS], HYPOT(delta[A_AXIS] - oldA, delta[B_AXIS] - oldB) * inverse_secs, active_extruder, MM_PER_ARC_SEGMENT))
|
|
||||||
break;
|
|
||||||
oldA = delta[A_AXIS]; oldB = delta[B_AXIS];
|
|
||||||
#elif ENABLED(DELTA_FEEDRATE_SCALING)
|
|
||||||
// For DELTA scale the feed rate from Effector mm/s to Carriage mm/s
|
|
||||||
// i.e., Complete the linear vector in the given time.
|
|
||||||
if (!planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], raw[E_AXIS], SQRT(sq(delta[A_AXIS] - oldA) + sq(delta[B_AXIS] - oldB) + sq(delta[C_AXIS] - oldC)) * inverse_secs, active_extruder, MM_PER_ARC_SEGMENT))
|
|
||||||
break;
|
|
||||||
oldA = delta[A_AXIS]; oldB = delta[B_AXIS]; oldC = delta[C_AXIS];
|
|
||||||
#elif HAS_UBL_AND_CURVES
|
|
||||||
float pos[XYZ] = { raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS] };
|
|
||||||
planner.apply_leveling(pos);
|
|
||||||
if (!planner.buffer_segment(pos[X_AXIS], pos[Y_AXIS], pos[Z_AXIS], raw[E_AXIS], fr_mm_s, active_extruder, MM_PER_ARC_SEGMENT))
|
|
||||||
break;
|
|
||||||
#else
|
|
||||||
if (!planner.buffer_line_kinematic(raw, fr_mm_s, active_extruder))
|
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
|
))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure last segment arrives at target location.
|
// Ensure last segment arrives at target location.
|
||||||
#if HAS_FEEDRATE_SCALING
|
COPY(raw, cart);
|
||||||
inverse_kinematics(cart);
|
|
||||||
ADJUST_DELTA(cart);
|
#if HAS_LEVELING && !PLANNER_LEVELING
|
||||||
|
planner.apply_leveling(raw);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
planner.buffer_line(raw, fr_mm_s, active_extruder, MM_PER_ARC_SEGMENT
|
||||||
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||||
const float diff2 = HYPOT2(delta[A_AXIS] - oldA, delta[B_AXIS] - oldB);
|
, inv_duration
|
||||||
if (diff2)
|
|
||||||
planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], cart[Z_AXIS], cart[E_AXIS], SQRT(diff2) * inverse_secs, active_extruder, MM_PER_ARC_SEGMENT);
|
|
||||||
#elif ENABLED(DELTA_FEEDRATE_SCALING)
|
|
||||||
const float diff2 = sq(delta[A_AXIS] - oldA) + sq(delta[B_AXIS] - oldB) + sq(delta[C_AXIS] - oldC);
|
|
||||||
if (diff2)
|
|
||||||
planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], cart[E_AXIS], SQRT(diff2) * inverse_secs, active_extruder, MM_PER_ARC_SEGMENT);
|
|
||||||
#elif HAS_UBL_AND_CURVES
|
|
||||||
float pos[XYZ] = { cart[X_AXIS], cart[Y_AXIS], cart[Z_AXIS] };
|
|
||||||
planner.apply_leveling(pos);
|
|
||||||
planner.buffer_segment(pos[X_AXIS], pos[Y_AXIS], pos[Z_AXIS], cart[E_AXIS], fr_mm_s, active_extruder, MM_PER_ARC_SEGMENT);
|
|
||||||
#else
|
|
||||||
planner.buffer_line_kinematic(cart, fr_mm_s, active_extruder);
|
|
||||||
#endif
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
COPY(current_position, cart);
|
COPY(current_position, raw);
|
||||||
} // plan_arc
|
} // plan_arc
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -56,7 +56,7 @@ static bool G38_run_probe() {
|
||||||
|
|
||||||
endstops.hit_on_purpose();
|
endstops.hit_on_purpose();
|
||||||
set_current_from_steppers_for_axis(ALL_AXES);
|
set_current_from_steppers_for_axis(ALL_AXES);
|
||||||
SYNC_PLAN_POSITION_KINEMATIC();
|
sync_plan_position();
|
||||||
|
|
||||||
if (G38_endstop_hit) {
|
if (G38_endstop_hit) {
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ static bool G38_run_probe() {
|
||||||
G38_move = false;
|
G38_move = false;
|
||||||
|
|
||||||
set_current_from_steppers_for_axis(ALL_AXES);
|
set_current_from_steppers_for_axis(ALL_AXES);
|
||||||
SYNC_PLAN_POSITION_KINEMATIC();
|
sync_plan_position();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,8 @@
|
||||||
#define IS_KINEMATIC (ENABLED(DELTA) || IS_SCARA)
|
#define IS_KINEMATIC (ENABLED(DELTA) || IS_SCARA)
|
||||||
#define IS_CARTESIAN !IS_KINEMATIC
|
#define IS_CARTESIAN !IS_KINEMATIC
|
||||||
|
|
||||||
|
#define HAS_CLASSIC_JERK (IS_KINEMATIC || DISABLED(JUNCTION_DEVIATION))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Axis lengths and center
|
* Axis lengths and center
|
||||||
*/
|
*/
|
||||||
|
@ -1173,10 +1175,9 @@
|
||||||
#define HAS_LEVELING (HAS_ABL || ENABLED(MESH_BED_LEVELING))
|
#define HAS_LEVELING (HAS_ABL || ENABLED(MESH_BED_LEVELING))
|
||||||
#define HAS_AUTOLEVEL (HAS_ABL && DISABLED(PROBE_MANUALLY))
|
#define HAS_AUTOLEVEL (HAS_ABL && DISABLED(PROBE_MANUALLY))
|
||||||
#define HAS_MESH (ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(MESH_BED_LEVELING))
|
#define HAS_MESH (ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(MESH_BED_LEVELING))
|
||||||
#define PLANNER_LEVELING (OLDSCHOOL_ABL || ENABLED(MESH_BED_LEVELING) || UBL_SEGMENTED || ENABLED(SKEW_CORRECTION))
|
#define PLANNER_LEVELING (HAS_LEVELING && DISABLED(AUTO_BED_LEVELING_UBL))
|
||||||
#define HAS_PROBING_PROCEDURE (HAS_ABL || ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST))
|
#define HAS_PROBING_PROCEDURE (HAS_ABL || ENABLED(Z_MIN_PROBE_REPEATABILITY_TEST))
|
||||||
#define HAS_UBL_AND_CURVES (ENABLED(AUTO_BED_LEVELING_UBL) && !PLANNER_LEVELING && (ENABLED(ARC_SUPPORT) || ENABLED(BEZIER_CURVE_SUPPORT)))
|
#define HAS_POSITION_MODIFIERS (ENABLED(FWRETRACT) || HAS_LEVELING || ENABLED(SKEW_CORRECTION))
|
||||||
#define HAS_FEEDRATE_SCALING (ENABLED(SCARA_FEEDRATE_SCALING) || ENABLED(DELTA_FEEDRATE_SCALING))
|
|
||||||
|
|
||||||
#if ENABLED(AUTO_BED_LEVELING_UBL)
|
#if ENABLED(AUTO_BED_LEVELING_UBL)
|
||||||
#undef LCD_BED_LEVELING
|
#undef LCD_BED_LEVELING
|
||||||
|
|
|
@ -841,7 +841,7 @@ void lcd_quick_feedback(const bool clear_buttons) {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void line_to_current_z() {
|
inline void line_to_current_z() {
|
||||||
planner.buffer_line_kinematic(current_position, MMM_TO_MMS(manual_feedrate_mm_m[Z_AXIS]), active_extruder);
|
planner.buffer_line(current_position, MMM_TO_MMS(manual_feedrate_mm_m[Z_AXIS]), active_extruder);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void line_to_z(const float &z) {
|
inline void line_to_z(const float &z) {
|
||||||
|
@ -1892,7 +1892,7 @@ void lcd_quick_feedback(const bool clear_buttons) {
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
planner.buffer_line_kinematic(current_position, MMM_TO_MMS(manual_feedrate_mm_m[X_AXIS]), active_extruder);
|
planner.buffer_line(current_position, MMM_TO_MMS(manual_feedrate_mm_m[X_AXIS]), active_extruder);
|
||||||
line_to_z(0.0);
|
line_to_z(0.0);
|
||||||
if (++bed_corner > 3
|
if (++bed_corner > 3
|
||||||
#if ENABLED(LEVEL_CENTER_TOO)
|
#if ENABLED(LEVEL_CENTER_TOO)
|
||||||
|
@ -2432,7 +2432,7 @@ void lcd_quick_feedback(const bool clear_buttons) {
|
||||||
void ubl_map_move_to_xy() {
|
void ubl_map_move_to_xy() {
|
||||||
current_position[X_AXIS] = pgm_read_float(&ubl._mesh_index_to_xpos[x_plot]);
|
current_position[X_AXIS] = pgm_read_float(&ubl._mesh_index_to_xpos[x_plot]);
|
||||||
current_position[Y_AXIS] = pgm_read_float(&ubl._mesh_index_to_ypos[y_plot]);
|
current_position[Y_AXIS] = pgm_read_float(&ubl._mesh_index_to_ypos[y_plot]);
|
||||||
planner.buffer_line_kinematic(current_position, MMM_TO_MMS(XY_PROBE_SPEED), active_extruder);
|
planner.buffer_line(current_position, MMM_TO_MMS(XY_PROBE_SPEED), active_extruder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2911,7 +2911,7 @@ void lcd_quick_feedback(const bool clear_buttons) {
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
planner.buffer_line_kinematic(current_position, MMM_TO_MMS(manual_feedrate_mm_m[manual_move_axis]), manual_move_axis == E_AXIS ? manual_move_e_index : active_extruder);
|
planner.buffer_line(current_position, MMM_TO_MMS(manual_feedrate_mm_m[manual_move_axis]), manual_move_axis == E_AXIS ? manual_move_e_index : active_extruder);
|
||||||
manual_move_axis = (int8_t)NO_AXIS;
|
manual_move_axis = (int8_t)NO_AXIS;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3746,8 +3746,13 @@ void lcd_quick_feedback(const bool clear_buttons) {
|
||||||
MENU_BACK(MSG_ADVANCED_SETTINGS);
|
MENU_BACK(MSG_ADVANCED_SETTINGS);
|
||||||
|
|
||||||
#if ENABLED(JUNCTION_DEVIATION)
|
#if ENABLED(JUNCTION_DEVIATION)
|
||||||
|
#if ENABLED(LIN_ADVANCE)
|
||||||
MENU_ITEM_EDIT_CALLBACK(float43, MSG_JUNCTION_DEVIATION, &planner.junction_deviation_mm, 0.01f, 0.3f, planner.recalculate_max_e_jerk);
|
MENU_ITEM_EDIT_CALLBACK(float43, MSG_JUNCTION_DEVIATION, &planner.junction_deviation_mm, 0.01f, 0.3f, planner.recalculate_max_e_jerk);
|
||||||
#else
|
#else
|
||||||
|
MENU_ITEM_EDIT(float43, MSG_JUNCTION_DEVIATION, &planner.junction_deviation_mm, 0.01f, 0.3f);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if HAS_CLASSIC_JERK
|
||||||
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VA_JERK, &planner.max_jerk[A_AXIS], 1, 990);
|
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VA_JERK, &planner.max_jerk[A_AXIS], 1, 990);
|
||||||
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VB_JERK, &planner.max_jerk[B_AXIS], 1, 990);
|
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VB_JERK, &planner.max_jerk[B_AXIS], 1, 990);
|
||||||
#if ENABLED(DELTA)
|
#if ENABLED(DELTA)
|
||||||
|
@ -3755,8 +3760,10 @@ void lcd_quick_feedback(const bool clear_buttons) {
|
||||||
#else
|
#else
|
||||||
MENU_MULTIPLIER_ITEM_EDIT(float52sign, MSG_VC_JERK, &planner.max_jerk[C_AXIS], 0.1f, 990);
|
MENU_MULTIPLIER_ITEM_EDIT(float52sign, MSG_VC_JERK, &planner.max_jerk[C_AXIS], 0.1f, 990);
|
||||||
#endif
|
#endif
|
||||||
|
#if DISABLED(JUNCTION_DEVIATION) || DISABLED(LIN_ADVANCE)
|
||||||
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VE_JERK, &planner.max_jerk[E_AXIS], 1, 990);
|
MENU_MULTIPLIER_ITEM_EDIT(float3, MSG_VE_JERK, &planner.max_jerk[E_AXIS], 1, 990);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
END_MENU();
|
END_MENU();
|
||||||
}
|
}
|
||||||
|
|
|
@ -428,12 +428,20 @@ void MarlinSettings::postprocess() {
|
||||||
EEPROM_WRITE(planner.min_feedrate_mm_s);
|
EEPROM_WRITE(planner.min_feedrate_mm_s);
|
||||||
EEPROM_WRITE(planner.min_travel_feedrate_mm_s);
|
EEPROM_WRITE(planner.min_travel_feedrate_mm_s);
|
||||||
|
|
||||||
#if ENABLED(JUNCTION_DEVIATION)
|
#if HAS_CLASSIC_JERK
|
||||||
|
EEPROM_WRITE(planner.max_jerk);
|
||||||
|
#if ENABLED(JUNCTION_DEVIATION) && ENABLED(LIN_ADVANCE)
|
||||||
|
dummy = float(DEFAULT_EJERK);
|
||||||
|
EEPROM_WRITE(dummy);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
const float planner_max_jerk[] = { float(DEFAULT_XJERK), float(DEFAULT_YJERK), float(DEFAULT_ZJERK), float(DEFAULT_EJERK) };
|
const float planner_max_jerk[] = { float(DEFAULT_XJERK), float(DEFAULT_YJERK), float(DEFAULT_ZJERK), float(DEFAULT_EJERK) };
|
||||||
EEPROM_WRITE(planner_max_jerk);
|
EEPROM_WRITE(planner_max_jerk);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(JUNCTION_DEVIATION)
|
||||||
EEPROM_WRITE(planner.junction_deviation_mm);
|
EEPROM_WRITE(planner.junction_deviation_mm);
|
||||||
#else
|
#else
|
||||||
EEPROM_WRITE(planner.max_jerk);
|
|
||||||
dummy = 0.02f;
|
dummy = 0.02f;
|
||||||
EEPROM_WRITE(dummy);
|
EEPROM_WRITE(dummy);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1062,11 +1070,18 @@ void MarlinSettings::postprocess() {
|
||||||
EEPROM_READ(planner.min_feedrate_mm_s);
|
EEPROM_READ(planner.min_feedrate_mm_s);
|
||||||
EEPROM_READ(planner.min_travel_feedrate_mm_s);
|
EEPROM_READ(planner.min_travel_feedrate_mm_s);
|
||||||
|
|
||||||
#if ENABLED(JUNCTION_DEVIATION)
|
#if HAS_CLASSIC_JERK
|
||||||
|
EEPROM_READ(planner.max_jerk);
|
||||||
|
#if ENABLED(JUNCTION_DEVIATION) && ENABLED(LIN_ADVANCE)
|
||||||
|
EEPROM_READ(dummy);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
for (uint8_t q = 4; q--;) EEPROM_READ(dummy);
|
for (uint8_t q = 4; q--;) EEPROM_READ(dummy);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(JUNCTION_DEVIATION)
|
||||||
EEPROM_READ(planner.junction_deviation_mm);
|
EEPROM_READ(planner.junction_deviation_mm);
|
||||||
#else
|
#else
|
||||||
EEPROM_READ(planner.max_jerk);
|
|
||||||
EEPROM_READ(dummy);
|
EEPROM_READ(dummy);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1808,12 +1823,16 @@ void MarlinSettings::reset(PORTARG_SOLO) {
|
||||||
|
|
||||||
#if ENABLED(JUNCTION_DEVIATION)
|
#if ENABLED(JUNCTION_DEVIATION)
|
||||||
planner.junction_deviation_mm = float(JUNCTION_DEVIATION_MM);
|
planner.junction_deviation_mm = float(JUNCTION_DEVIATION_MM);
|
||||||
#else
|
#endif
|
||||||
|
|
||||||
|
#if HAS_CLASSIC_JERK
|
||||||
planner.max_jerk[X_AXIS] = DEFAULT_XJERK;
|
planner.max_jerk[X_AXIS] = DEFAULT_XJERK;
|
||||||
planner.max_jerk[Y_AXIS] = DEFAULT_YJERK;
|
planner.max_jerk[Y_AXIS] = DEFAULT_YJERK;
|
||||||
planner.max_jerk[Z_AXIS] = DEFAULT_ZJERK;
|
planner.max_jerk[Z_AXIS] = DEFAULT_ZJERK;
|
||||||
|
#if DISABLED(JUNCTION_DEVIATION) || DISABLED(LIN_ADVANCE)
|
||||||
planner.max_jerk[E_AXIS] = DEFAULT_EJERK;
|
planner.max_jerk[E_AXIS] = DEFAULT_EJERK;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if HAS_HOME_OFFSET
|
#if HAS_HOME_OFFSET
|
||||||
ZERO(home_offset);
|
ZERO(home_offset);
|
||||||
|
@ -2243,12 +2262,13 @@ void MarlinSettings::reset(PORTARG_SOLO) {
|
||||||
SERIAL_ECHOPGM_P(port, "Advanced: B<min_segment_time_us> S<min_feedrate> T<min_travel_feedrate>");
|
SERIAL_ECHOPGM_P(port, "Advanced: B<min_segment_time_us> S<min_feedrate> T<min_travel_feedrate>");
|
||||||
#if ENABLED(JUNCTION_DEVIATION)
|
#if ENABLED(JUNCTION_DEVIATION)
|
||||||
SERIAL_ECHOPGM_P(port, " J<junc_dev>");
|
SERIAL_ECHOPGM_P(port, " J<junc_dev>");
|
||||||
#else
|
|
||||||
SERIAL_ECHOPGM_P(port, " X<max_x_jerk> Y<max_y_jerk> Z<max_z_jerk>");
|
|
||||||
#endif
|
#endif
|
||||||
#if DISABLED(JUNCTION_DEVIATION) || ENABLED(LIN_ADVANCE)
|
#if HAS_CLASSIC_JERK
|
||||||
|
SERIAL_ECHOPGM_P(port, " X<max_x_jerk> Y<max_y_jerk> Z<max_z_jerk>");
|
||||||
|
#if DISABLED(JUNCTION_DEVIATION) || DISABLED(LIN_ADVANCE)
|
||||||
SERIAL_ECHOPGM_P(port, " E<max_e_jerk>");
|
SERIAL_ECHOPGM_P(port, " E<max_e_jerk>");
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
SERIAL_EOL_P(port);
|
SERIAL_EOL_P(port);
|
||||||
}
|
}
|
||||||
CONFIG_ECHO_START;
|
CONFIG_ECHO_START;
|
||||||
|
@ -2258,12 +2278,15 @@ void MarlinSettings::reset(PORTARG_SOLO) {
|
||||||
|
|
||||||
#if ENABLED(JUNCTION_DEVIATION)
|
#if ENABLED(JUNCTION_DEVIATION)
|
||||||
SERIAL_ECHOPAIR_P(port, " J", LINEAR_UNIT(planner.junction_deviation_mm));
|
SERIAL_ECHOPAIR_P(port, " J", LINEAR_UNIT(planner.junction_deviation_mm));
|
||||||
#else
|
#endif
|
||||||
|
#if HAS_CLASSIC_JERK
|
||||||
SERIAL_ECHOPAIR_P(port, " X", LINEAR_UNIT(planner.max_jerk[X_AXIS]));
|
SERIAL_ECHOPAIR_P(port, " X", LINEAR_UNIT(planner.max_jerk[X_AXIS]));
|
||||||
SERIAL_ECHOPAIR_P(port, " Y", LINEAR_UNIT(planner.max_jerk[Y_AXIS]));
|
SERIAL_ECHOPAIR_P(port, " Y", LINEAR_UNIT(planner.max_jerk[Y_AXIS]));
|
||||||
SERIAL_ECHOPAIR_P(port, " Z", LINEAR_UNIT(planner.max_jerk[Z_AXIS]));
|
SERIAL_ECHOPAIR_P(port, " Z", LINEAR_UNIT(planner.max_jerk[Z_AXIS]));
|
||||||
|
#if DISABLED(JUNCTION_DEVIATION) || DISABLED(LIN_ADVANCE)
|
||||||
SERIAL_ECHOPAIR_P(port, " E", LINEAR_UNIT(planner.max_jerk[E_AXIS]));
|
SERIAL_ECHOPAIR_P(port, " E", LINEAR_UNIT(planner.max_jerk[E_AXIS]));
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
SERIAL_EOL_P(port);
|
SERIAL_EOL_P(port);
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ void recalc_delta_settings() {
|
||||||
SERIAL_ECHOLNPAIR(" C:", delta[C_AXIS]); \
|
SERIAL_ECHOLNPAIR(" C:", delta[C_AXIS]); \
|
||||||
}while(0)
|
}while(0)
|
||||||
|
|
||||||
void inverse_kinematics(const float raw[XYZ]) {
|
void inverse_kinematics(const float (&raw)[XYZ]) {
|
||||||
#if HAS_HOTEND_OFFSET
|
#if HAS_HOTEND_OFFSET
|
||||||
// Delta hotend offsets must be applied in Cartesian space with no "spoofing"
|
// Delta hotend offsets must be applied in Cartesian space with no "spoofing"
|
||||||
const float pos[XYZ] = {
|
const float pos[XYZ] = {
|
||||||
|
@ -224,6 +224,7 @@ void home_delta() {
|
||||||
#endif
|
#endif
|
||||||
// Init the current position of all carriages to 0,0,0
|
// Init the current position of all carriages to 0,0,0
|
||||||
ZERO(current_position);
|
ZERO(current_position);
|
||||||
|
ZERO(destination);
|
||||||
sync_plan_position();
|
sync_plan_position();
|
||||||
|
|
||||||
// Disable stealthChop if used. Enable diag1 pin on driver.
|
// Disable stealthChop if used. Enable diag1 pin on driver.
|
||||||
|
@ -232,9 +233,8 @@ void home_delta() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Move all carriages together linearly until an endstop is hit.
|
// Move all carriages together linearly until an endstop is hit.
|
||||||
current_position[X_AXIS] = current_position[Y_AXIS] = current_position[Z_AXIS] = (delta_height + 10);
|
destination[Z_AXIS] = (delta_height + 10);
|
||||||
feedrate_mm_s = homing_feedrate(X_AXIS);
|
buffer_line_to_destination(homing_feedrate(X_AXIS));
|
||||||
line_to_current_position();
|
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
|
|
||||||
// Re-enable stealthChop if used. Disable diag1 pin on driver.
|
// Re-enable stealthChop if used. Disable diag1 pin on driver.
|
||||||
|
@ -256,7 +256,7 @@ void home_delta() {
|
||||||
// give the impression that they are the same.
|
// give the impression that they are the same.
|
||||||
LOOP_XYZ(i) set_axis_is_at_home((AxisEnum)i);
|
LOOP_XYZ(i) set_axis_is_at_home((AxisEnum)i);
|
||||||
|
|
||||||
SYNC_PLAN_POSITION_KINEMATIC();
|
sync_plan_position();
|
||||||
|
|
||||||
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
||||||
if (DEBUGGING(LEVELING)) DEBUG_POS("<<< home_delta", current_position);
|
if (DEBUGGING(LEVELING)) DEBUG_POS("<<< home_delta", current_position);
|
||||||
|
|
|
@ -24,8 +24,7 @@
|
||||||
* delta.h - Delta-specific functions
|
* delta.h - Delta-specific functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DELTA_H__
|
#pragma once
|
||||||
#define __DELTA_H__
|
|
||||||
|
|
||||||
extern float delta_height,
|
extern float delta_height,
|
||||||
delta_endstop_adj[ABC],
|
delta_endstop_adj[ABC],
|
||||||
|
@ -78,7 +77,11 @@ void recalc_delta_settings();
|
||||||
delta[C_AXIS] = DELTA_Z(V, C_AXIS); \
|
delta[C_AXIS] = DELTA_Z(V, C_AXIS); \
|
||||||
}while(0)
|
}while(0)
|
||||||
|
|
||||||
void inverse_kinematics(const float raw[XYZ]);
|
void inverse_kinematics(const float (&raw)[XYZ]);
|
||||||
|
FORCE_INLINE void inverse_kinematics(const float (&raw)[XYZE]) {
|
||||||
|
const float raw_xyz[XYZ] = { raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS] };
|
||||||
|
inverse_kinematics(raw_xyz);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the highest Z position where the
|
* Calculate the highest Z position where the
|
||||||
|
@ -118,5 +121,3 @@ FORCE_INLINE void forward_kinematics_DELTA(const float (&point)[ABC]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void home_delta();
|
void home_delta();
|
||||||
|
|
||||||
#endif // __DELTA_H__
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ bool relative_mode; // = false;
|
||||||
* Cartesian Current Position
|
* Cartesian Current Position
|
||||||
* Used to track the native machine position as moves are queued.
|
* Used to track the native machine position as moves are queued.
|
||||||
* Used by 'buffer_line_to_current_position' to do a move after changing it.
|
* Used by 'buffer_line_to_current_position' to do a move after changing it.
|
||||||
* Used by 'SYNC_PLAN_POSITION_KINEMATIC' to update 'planner.position'.
|
* Used by 'sync_plan_position' to update 'planner.position'.
|
||||||
*/
|
*/
|
||||||
float current_position[XYZE] = { 0 };
|
float current_position[XYZE] = { 0 };
|
||||||
|
|
||||||
|
@ -218,15 +218,22 @@ void get_cartesian_from_steppers() {
|
||||||
* may have been applied.
|
* may have been applied.
|
||||||
*
|
*
|
||||||
* To prevent small shifts in axis position always call
|
* To prevent small shifts in axis position always call
|
||||||
* SYNC_PLAN_POSITION_KINEMATIC after updating axes with this.
|
* sync_plan_position after updating axes with this.
|
||||||
*
|
*
|
||||||
* To keep hosts in sync, always call report_current_position
|
* To keep hosts in sync, always call report_current_position
|
||||||
* after updating the current_position.
|
* after updating the current_position.
|
||||||
*/
|
*/
|
||||||
void set_current_from_steppers_for_axis(const AxisEnum axis) {
|
void set_current_from_steppers_for_axis(const AxisEnum axis) {
|
||||||
get_cartesian_from_steppers();
|
get_cartesian_from_steppers();
|
||||||
#if PLANNER_LEVELING
|
|
||||||
planner.unapply_leveling(cartes);
|
#if HAS_POSITION_MODIFIERS
|
||||||
|
float pos[XYZE] = { cartes[X_AXIS], cartes[Y_AXIS], cartes[Z_AXIS], current_position[E_AXIS] };
|
||||||
|
planner.unapply_modifiers(pos
|
||||||
|
#if HAS_LEVELING
|
||||||
|
, true
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
const float (&cartes)[XYZE] = pos;
|
||||||
#endif
|
#endif
|
||||||
if (axis == ALL_AXES)
|
if (axis == ALL_AXES)
|
||||||
COPY(current_position, cartes);
|
COPY(current_position, cartes);
|
||||||
|
@ -252,13 +259,6 @@ void buffer_line_to_destination(const float fr_mm_s) {
|
||||||
|
|
||||||
#if IS_KINEMATIC
|
#if IS_KINEMATIC
|
||||||
|
|
||||||
void sync_plan_position_kinematic() {
|
|
||||||
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
|
||||||
if (DEBUGGING(LEVELING)) DEBUG_POS("sync_plan_position_kinematic", current_position);
|
|
||||||
#endif
|
|
||||||
planner.set_position_mm_kinematic(current_position);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate delta, start a line, and set current_position to destination
|
* Calculate delta, start a line, and set current_position to destination
|
||||||
*/
|
*/
|
||||||
|
@ -277,7 +277,7 @@ void buffer_line_to_destination(const float fr_mm_s) {
|
||||||
&& current_position[E_AXIS] == destination[E_AXIS]
|
&& current_position[E_AXIS] == destination[E_AXIS]
|
||||||
) return;
|
) return;
|
||||||
|
|
||||||
planner.buffer_line_kinematic(destination, MMS_SCALED(fr_mm_s ? fr_mm_s : feedrate_mm_s), active_extruder);
|
planner.buffer_line(destination, MMS_SCALED(fr_mm_s ? fr_mm_s : feedrate_mm_s), active_extruder);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
set_current_from_destination();
|
set_current_from_destination();
|
||||||
|
@ -538,7 +538,7 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
|
||||||
|
|
||||||
// If the move is only in Z/E don't split up the move
|
// If the move is only in Z/E don't split up the move
|
||||||
if (!xdiff && !ydiff) {
|
if (!xdiff && !ydiff) {
|
||||||
planner.buffer_line_kinematic(rtarget, _feedrate_mm_s, active_extruder);
|
planner.buffer_line(rtarget, _feedrate_mm_s, active_extruder);
|
||||||
return false; // caller will update current_position
|
return false; // caller will update current_position
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -580,52 +580,21 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
|
||||||
ydiff * inv_segments,
|
ydiff * inv_segments,
|
||||||
zdiff * inv_segments,
|
zdiff * inv_segments,
|
||||||
ediff * inv_segments
|
ediff * inv_segments
|
||||||
};
|
},
|
||||||
|
cartesian_segment_mm = cartesian_mm * inv_segments;
|
||||||
|
|
||||||
#if !HAS_FEEDRATE_SCALING
|
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||||
const float cartesian_segment_mm = cartesian_mm * inv_segments;
|
const float inv_duration = _feedrate_mm_s / cartesian_segment_mm;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SERIAL_ECHOPAIR("mm=", cartesian_mm);
|
SERIAL_ECHOPAIR("mm=", cartesian_mm);
|
||||||
SERIAL_ECHOPAIR(" seconds=", seconds);
|
SERIAL_ECHOPAIR(" seconds=", seconds);
|
||||||
SERIAL_ECHOPAIR(" segments=", segments);
|
SERIAL_ECHOPAIR(" segments=", segments);
|
||||||
#if !HAS_FEEDRATE_SCALING
|
|
||||||
SERIAL_ECHOPAIR(" segment_mm=", cartesian_segment_mm);
|
SERIAL_ECHOPAIR(" segment_mm=", cartesian_segment_mm);
|
||||||
#endif
|
|
||||||
SERIAL_EOL();
|
SERIAL_EOL();
|
||||||
//*/
|
//*/
|
||||||
|
|
||||||
#if HAS_FEEDRATE_SCALING
|
|
||||||
// SCARA needs to scale the feed rate from mm/s to degrees/s
|
|
||||||
// i.e., Complete the angular vector in the given time.
|
|
||||||
const float segment_length = cartesian_mm * inv_segments,
|
|
||||||
inv_segment_length = 1.0f / segment_length, // 1/mm/segs
|
|
||||||
inverse_secs = inv_segment_length * _feedrate_mm_s;
|
|
||||||
|
|
||||||
float oldA = planner.position_float[A_AXIS],
|
|
||||||
oldB = planner.position_float[B_AXIS]
|
|
||||||
#if ENABLED(DELTA_FEEDRATE_SCALING)
|
|
||||||
, oldC = planner.position_float[C_AXIS]
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
|
|
||||||
/*
|
|
||||||
SERIAL_ECHOPGM("Scaled kinematic move: ");
|
|
||||||
SERIAL_ECHOPAIR(" segment_length (inv)=", segment_length);
|
|
||||||
SERIAL_ECHOPAIR(" (", inv_segment_length);
|
|
||||||
SERIAL_ECHOPAIR(") _feedrate_mm_s=", _feedrate_mm_s);
|
|
||||||
SERIAL_ECHOPAIR(" inverse_secs=", inverse_secs);
|
|
||||||
SERIAL_ECHOPAIR(" oldA=", oldA);
|
|
||||||
SERIAL_ECHOPAIR(" oldB=", oldB);
|
|
||||||
#if ENABLED(DELTA_FEEDRATE_SCALING)
|
|
||||||
SERIAL_ECHOPAIR(" oldC=", oldC);
|
|
||||||
#endif
|
|
||||||
SERIAL_EOL();
|
|
||||||
safe_delay(5);
|
|
||||||
//*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Get the current position as starting point
|
// Get the current position as starting point
|
||||||
float raw[XYZE];
|
float raw[XYZE];
|
||||||
COPY(raw, current_position);
|
COPY(raw, current_position);
|
||||||
|
@ -642,78 +611,20 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
|
||||||
|
|
||||||
LOOP_XYZE(i) raw[i] += segment_distance[i];
|
LOOP_XYZE(i) raw[i] += segment_distance[i];
|
||||||
|
|
||||||
#if ENABLED(DELTA) && HOTENDS < 2
|
if (!planner.buffer_line(raw, _feedrate_mm_s, active_extruder, cartesian_segment_mm
|
||||||
DELTA_IK(raw); // Delta can inline its kinematics
|
|
||||||
#else
|
|
||||||
inverse_kinematics(raw);
|
|
||||||
#endif
|
|
||||||
ADJUST_DELTA(raw); // Adjust Z if bed leveling is enabled
|
|
||||||
|
|
||||||
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||||
// For SCARA scale the feed rate from mm/s to degrees/s
|
, inv_duration
|
||||||
// i.e., Complete the angular vector in the given time.
|
|
||||||
if (!planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], raw[Z_AXIS], raw[E_AXIS], HYPOT(delta[A_AXIS] - oldA, delta[B_AXIS] - oldB) * inverse_secs, active_extruder, segment_length))
|
|
||||||
break;
|
|
||||||
/*
|
|
||||||
SERIAL_ECHO(segments);
|
|
||||||
SERIAL_ECHOPAIR(": X=", raw[X_AXIS]); SERIAL_ECHOPAIR(" Y=", raw[Y_AXIS]);
|
|
||||||
SERIAL_ECHOPAIR(" A=", delta[A_AXIS]); SERIAL_ECHOPAIR(" B=", delta[B_AXIS]);
|
|
||||||
SERIAL_ECHOLNPAIR(" F", HYPOT(delta[A_AXIS] - oldA, delta[B_AXIS] - oldB) * inverse_secs * 60);
|
|
||||||
safe_delay(5);
|
|
||||||
//*/
|
|
||||||
oldA = delta[A_AXIS]; oldB = delta[B_AXIS];
|
|
||||||
#elif ENABLED(DELTA_FEEDRATE_SCALING)
|
|
||||||
// For DELTA scale the feed rate from Effector mm/s to Carriage mm/s
|
|
||||||
// i.e., Complete the linear vector in the given time.
|
|
||||||
if (!planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], raw[E_AXIS], SQRT(sq(delta[A_AXIS] - oldA) + sq(delta[B_AXIS] - oldB) + sq(delta[C_AXIS] - oldC)) * inverse_secs, active_extruder, segment_length))
|
|
||||||
break;
|
|
||||||
/*
|
|
||||||
SERIAL_ECHO(segments);
|
|
||||||
SERIAL_ECHOPAIR(": X=", raw[X_AXIS]); SERIAL_ECHOPAIR(" Y=", raw[Y_AXIS]);
|
|
||||||
SERIAL_ECHOPAIR(" A=", delta[A_AXIS]); SERIAL_ECHOPAIR(" B=", delta[B_AXIS]); SERIAL_ECHOPAIR(" C=", delta[C_AXIS]);
|
|
||||||
SERIAL_ECHOLNPAIR(" F", SQRT(sq(delta[A_AXIS] - oldA) + sq(delta[B_AXIS] - oldB) + sq(delta[C_AXIS] - oldC)) * inverse_secs * 60);
|
|
||||||
safe_delay(5);
|
|
||||||
//*/
|
|
||||||
oldA = delta[A_AXIS]; oldB = delta[B_AXIS]; oldC = delta[C_AXIS];
|
|
||||||
#else
|
|
||||||
if (!planner.buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], raw[E_AXIS], _feedrate_mm_s, active_extruder, cartesian_segment_mm))
|
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
|
))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure last segment arrives at target location.
|
// Ensure last segment arrives at target location.
|
||||||
#if HAS_FEEDRATE_SCALING
|
planner.buffer_line(rtarget, _feedrate_mm_s, active_extruder, cartesian_segment_mm
|
||||||
inverse_kinematics(rtarget);
|
|
||||||
ADJUST_DELTA(rtarget);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||||
const float diff2 = HYPOT2(delta[A_AXIS] - oldA, delta[B_AXIS] - oldB);
|
, inv_duration
|
||||||
if (diff2) {
|
|
||||||
planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], rtarget[Z_AXIS], rtarget[E_AXIS], SQRT(diff2) * inverse_secs, active_extruder, segment_length);
|
|
||||||
/*
|
|
||||||
SERIAL_ECHOPAIR("final: A=", delta[A_AXIS]); SERIAL_ECHOPAIR(" B=", delta[B_AXIS]);
|
|
||||||
SERIAL_ECHOPAIR(" adiff=", delta[A_AXIS] - oldA); SERIAL_ECHOPAIR(" bdiff=", delta[B_AXIS] - oldB);
|
|
||||||
SERIAL_ECHOLNPAIR(" F", SQRT(diff2) * inverse_secs * 60);
|
|
||||||
SERIAL_EOL();
|
|
||||||
safe_delay(5);
|
|
||||||
//*/
|
|
||||||
}
|
|
||||||
#elif ENABLED(DELTA_FEEDRATE_SCALING)
|
|
||||||
const float diff2 = sq(delta[A_AXIS] - oldA) + sq(delta[B_AXIS] - oldB) + sq(delta[C_AXIS] - oldC);
|
|
||||||
if (diff2) {
|
|
||||||
planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], rtarget[E_AXIS], SQRT(diff2) * inverse_secs, active_extruder, segment_length);
|
|
||||||
/*
|
|
||||||
SERIAL_ECHOPAIR("final: A=", delta[A_AXIS]); SERIAL_ECHOPAIR(" B=", delta[B_AXIS]); SERIAL_ECHOPAIR(" C=", delta[C_AXIS]);
|
|
||||||
SERIAL_ECHOPAIR(" adiff=", delta[A_AXIS] - oldA); SERIAL_ECHOPAIR(" bdiff=", delta[B_AXIS] - oldB); SERIAL_ECHOPAIR(" cdiff=", delta[C_AXIS] - oldC);
|
|
||||||
SERIAL_ECHOLNPAIR(" F", SQRT(diff2) * inverse_secs * 60);
|
|
||||||
SERIAL_EOL();
|
|
||||||
safe_delay(5);
|
|
||||||
//*/
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
planner.buffer_line_kinematic(rtarget, _feedrate_mm_s, active_extruder, cartesian_segment_mm);
|
|
||||||
#endif
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
return false; // caller will update current_position
|
return false; // caller will update current_position
|
||||||
}
|
}
|
||||||
|
@ -736,7 +647,7 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
|
||||||
|
|
||||||
// If the move is only in Z/E don't split up the move
|
// If the move is only in Z/E don't split up the move
|
||||||
if (!xdiff && !ydiff) {
|
if (!xdiff && !ydiff) {
|
||||||
planner.buffer_line_kinematic(destination, fr_mm_s, active_extruder);
|
planner.buffer_line(destination, fr_mm_s, active_extruder);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -766,6 +677,10 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
|
||||||
ediff * inv_segments
|
ediff * inv_segments
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||||
|
const float inv_duration = _feedrate_mm_s / cartesian_segment_mm;
|
||||||
|
#endif
|
||||||
|
|
||||||
// SERIAL_ECHOPAIR("mm=", cartesian_mm);
|
// SERIAL_ECHOPAIR("mm=", cartesian_mm);
|
||||||
// SERIAL_ECHOLNPAIR(" segments=", segments);
|
// SERIAL_ECHOLNPAIR(" segments=", segments);
|
||||||
// SERIAL_ECHOLNPAIR(" segment_mm=", cartesian_segment_mm);
|
// SERIAL_ECHOLNPAIR(" segment_mm=", cartesian_segment_mm);
|
||||||
|
@ -783,13 +698,21 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
|
||||||
idle();
|
idle();
|
||||||
}
|
}
|
||||||
LOOP_XYZE(i) raw[i] += segment_distance[i];
|
LOOP_XYZE(i) raw[i] += segment_distance[i];
|
||||||
if (!planner.buffer_line_kinematic(raw, fr_mm_s, active_extruder, cartesian_segment_mm))
|
if (!planner.buffer_line(raw, fr_mm_s, active_extruder, cartesian_segment_mm
|
||||||
|
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||||
|
, inv_duration
|
||||||
|
#endif
|
||||||
|
))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Since segment_distance is only approximate,
|
// Since segment_distance is only approximate,
|
||||||
// the final move must be to the exact destination.
|
// the final move must be to the exact destination.
|
||||||
planner.buffer_line_kinematic(destination, fr_mm_s, active_extruder, cartesian_segment_mm);
|
planner.buffer_line(destination, fr_mm_s, active_extruder, cartesian_segment_mm
|
||||||
|
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||||
|
, inv_duration
|
||||||
|
#endif
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // SEGMENT_LEVELED_MOVES
|
#endif // SEGMENT_LEVELED_MOVES
|
||||||
|
@ -922,7 +845,7 @@ float soft_endstop_min[XYZ] = { X_MIN_BED, Y_MIN_BED, Z_MIN_POS },
|
||||||
planner.max_feedrate_mm_s[X_AXIS], 1)
|
planner.max_feedrate_mm_s[X_AXIS], 1)
|
||||||
) break;
|
) break;
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
SYNC_PLAN_POSITION_KINEMATIC();
|
sync_plan_position();
|
||||||
extruder_duplication_enabled = true;
|
extruder_duplication_enabled = true;
|
||||||
active_extruder_parked = false;
|
active_extruder_parked = false;
|
||||||
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
||||||
|
@ -1092,7 +1015,7 @@ inline float get_homing_bump_feedrate(const AxisEnum axis) {
|
||||||
/**
|
/**
|
||||||
* Home an individual linear axis
|
* Home an individual linear axis
|
||||||
*/
|
*/
|
||||||
static void do_homing_move(const AxisEnum axis, const float distance, const float fr_mm_s=0.0) {
|
void do_homing_move(const AxisEnum axis, const float distance, const float fr_mm_s=0.0) {
|
||||||
|
|
||||||
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
||||||
if (DEBUGGING(LEVELING)) {
|
if (DEBUGGING(LEVELING)) {
|
||||||
|
@ -1139,18 +1062,29 @@ static void do_homing_move(const AxisEnum axis, const float distance, const floa
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if IS_SCARA
|
||||||
// Tell the planner the axis is at 0
|
// Tell the planner the axis is at 0
|
||||||
current_position[axis] = 0;
|
current_position[axis] = 0;
|
||||||
|
|
||||||
#if IS_SCARA
|
|
||||||
SYNC_PLAN_POSITION_KINEMATIC();
|
|
||||||
current_position[axis] = distance;
|
|
||||||
inverse_kinematics(current_position);
|
|
||||||
planner.buffer_line(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], current_position[E_AXIS], fr_mm_s ? fr_mm_s : homing_feedrate(axis), active_extruder);
|
|
||||||
#else
|
|
||||||
sync_plan_position();
|
sync_plan_position();
|
||||||
current_position[axis] = distance; // Set delta/cartesian axes directly
|
current_position[axis] = distance;
|
||||||
planner.buffer_line(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS], current_position[E_AXIS], fr_mm_s ? fr_mm_s : homing_feedrate(axis), active_extruder);
|
planner.buffer_line(current_position, fr_mm_s ? fr_mm_s : homing_feedrate(axis), active_extruder);
|
||||||
|
#else
|
||||||
|
float target[ABCE] = { planner.get_axis_position_mm(A_AXIS), planner.get_axis_position_mm(B_AXIS), planner.get_axis_position_mm(C_AXIS), planner.get_axis_position_mm(E_AXIS) };
|
||||||
|
target[axis] = 0;
|
||||||
|
planner.set_machine_position_mm(target);
|
||||||
|
target[axis] = distance;
|
||||||
|
|
||||||
|
#if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
|
||||||
|
const float delta_mm_cart[XYZE] = {0, 0, 0, 0};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Set delta/cartesian axes directly
|
||||||
|
planner.buffer_segment(target
|
||||||
|
#if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
|
||||||
|
, delta_mm_cart
|
||||||
|
#endif
|
||||||
|
, fr_mm_s ? fr_mm_s : homing_feedrate(axis), active_extruder
|
||||||
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
|
@ -1349,7 +1283,14 @@ void homeaxis(const AxisEnum axis) {
|
||||||
if (axis == Z_AXIS && set_bltouch_deployed(true)) return;
|
if (axis == Z_AXIS && set_bltouch_deployed(true)) return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
do_homing_move(axis, 1.5f * max_length(axis) * axis_home_dir);
|
do_homing_move(axis, 1.5f * max_length(
|
||||||
|
#if ENABLED(DELTA)
|
||||||
|
Z_AXIS
|
||||||
|
#else
|
||||||
|
axis
|
||||||
|
#endif
|
||||||
|
) * axis_home_dir
|
||||||
|
);
|
||||||
|
|
||||||
#if HOMING_Z_WITH_PROBE && ENABLED(BLTOUCH)
|
#if HOMING_Z_WITH_PROBE && ENABLED(BLTOUCH)
|
||||||
// BLTOUCH needs to be stowed after trigger to rearm itself
|
// BLTOUCH needs to be stowed after trigger to rearm itself
|
||||||
|
@ -1481,7 +1422,7 @@ void homeaxis(const AxisEnum axis) {
|
||||||
#if IS_SCARA
|
#if IS_SCARA
|
||||||
|
|
||||||
set_axis_is_at_home(axis);
|
set_axis_is_at_home(axis);
|
||||||
SYNC_PLAN_POSITION_KINEMATIC();
|
sync_plan_position();
|
||||||
|
|
||||||
#elif ENABLED(DELTA)
|
#elif ENABLED(DELTA)
|
||||||
|
|
||||||
|
|
|
@ -129,13 +129,6 @@ void set_current_from_steppers_for_axis(const AxisEnum axis);
|
||||||
void sync_plan_position();
|
void sync_plan_position();
|
||||||
void sync_plan_position_e();
|
void sync_plan_position_e();
|
||||||
|
|
||||||
#if IS_KINEMATIC
|
|
||||||
void sync_plan_position_kinematic();
|
|
||||||
#define SYNC_PLAN_POSITION_KINEMATIC() sync_plan_position_kinematic()
|
|
||||||
#else
|
|
||||||
#define SYNC_PLAN_POSITION_KINEMATIC() sync_plan_position()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move the planner to the current position from wherever it last moved
|
* Move the planner to the current position from wherever it last moved
|
||||||
* (or from wherever it has been told it is located).
|
* (or from wherever it has been told it is located).
|
||||||
|
@ -354,20 +347,4 @@ void homeaxis(const AxisEnum axis);
|
||||||
void set_home_offset(const AxisEnum axis, const float v);
|
void set_home_offset(const AxisEnum axis, const float v);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(AUTO_BED_LEVELING_BILINEAR)
|
|
||||||
#if ENABLED(DELTA)
|
|
||||||
#define ADJUST_DELTA(V) \
|
|
||||||
if (planner.leveling_active) { \
|
|
||||||
const float zadj = bilinear_z_offset(V); \
|
|
||||||
delta[A_AXIS] += zadj; \
|
|
||||||
delta[B_AXIS] += zadj; \
|
|
||||||
delta[C_AXIS] += zadj; \
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define ADJUST_DELTA(V) if (planner.leveling_active) { delta[Z_AXIS] += bilinear_z_offset(V); }
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#define ADJUST_DELTA(V) NOOP
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // MOTION_H
|
#endif // MOTION_H
|
||||||
|
|
|
@ -133,8 +133,13 @@ float Planner::max_feedrate_mm_s[XYZE_N], // (mm/s) M203 XYZE - Max speeds
|
||||||
float Planner::max_e_jerk;
|
float Planner::max_e_jerk;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#else
|
#endif
|
||||||
|
#if HAS_CLASSIC_JERK
|
||||||
|
#if ENABLED(JUNCTION_DEVIATION) && ENABLED(LIN_ADVANCE)
|
||||||
|
float Planner::max_jerk[XYZ]; // (mm/s^2) M205 XYZ - The largest speed change requiring no acceleration.
|
||||||
|
#else
|
||||||
float Planner::max_jerk[XYZE]; // (mm/s^2) M205 XYZE - The largest speed change requiring no acceleration.
|
float Planner::max_jerk[XYZE]; // (mm/s^2) M205 XYZE - The largest speed change requiring no acceleration.
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
|
#if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED)
|
||||||
|
@ -220,6 +225,10 @@ float Planner::previous_speed[NUM_AXIS],
|
||||||
float Planner::position_float[XYZE]; // Needed for accurate maths. Steps cannot be used!
|
float Planner::position_float[XYZE]; // Needed for accurate maths. Steps cannot be used!
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if IS_KINEMATIC
|
||||||
|
float Planner::position_cart[XYZE];
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ENABLED(ULTRA_LCD)
|
#if ENABLED(ULTRA_LCD)
|
||||||
volatile uint32_t Planner::block_buffer_runtime_us = 0;
|
volatile uint32_t Planner::block_buffer_runtime_us = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -235,6 +244,9 @@ void Planner::init() {
|
||||||
#if HAS_POSITION_FLOAT
|
#if HAS_POSITION_FLOAT
|
||||||
ZERO(position_float);
|
ZERO(position_float);
|
||||||
#endif
|
#endif
|
||||||
|
#if IS_KINEMATIC
|
||||||
|
ZERO(position_cart);
|
||||||
|
#endif
|
||||||
ZERO(previous_speed);
|
ZERO(previous_speed);
|
||||||
previous_nominal_speed_sqr = 0;
|
previous_nominal_speed_sqr = 0;
|
||||||
#if ABL_PLANAR
|
#if ABL_PLANAR
|
||||||
|
@ -1354,17 +1366,12 @@ void Planner::check_axes_activity() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PLANNER_LEVELING || HAS_UBL_AND_CURVES
|
#if HAS_LEVELING
|
||||||
/**
|
/**
|
||||||
* rx, ry, rz - Cartesian positions in mm
|
* rx, ry, rz - Cartesian positions in mm
|
||||||
* Leveled XYZ on completion
|
* Leveled XYZ on completion
|
||||||
*/
|
*/
|
||||||
void Planner::apply_leveling(float &rx, float &ry, float &rz) {
|
void Planner::apply_leveling(float &rx, float &ry, float &rz) {
|
||||||
|
|
||||||
#if ENABLED(SKEW_CORRECTION)
|
|
||||||
skew(rx, ry, rz);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!leveling_active) return;
|
if (!leveling_active) return;
|
||||||
|
|
||||||
#if ABL_PLANAR
|
#if ABL_PLANAR
|
||||||
|
@ -1406,10 +1413,6 @@ void Planner::check_axes_activity() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if PLANNER_LEVELING
|
|
||||||
|
|
||||||
void Planner::unapply_leveling(float raw[XYZ]) {
|
void Planner::unapply_leveling(float raw[XYZ]) {
|
||||||
|
|
||||||
if (leveling_active) {
|
if (leveling_active) {
|
||||||
|
@ -1456,7 +1459,23 @@ void Planner::check_axes_activity() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // PLANNER_LEVELING
|
#endif // HAS_LEVELING
|
||||||
|
|
||||||
|
#if ENABLED(FWRETRACT)
|
||||||
|
/**
|
||||||
|
* rz, e - Cartesian positions in mm
|
||||||
|
*/
|
||||||
|
void Planner::apply_retract(float &rz, float &e) {
|
||||||
|
rz += fwretract.current_hop;
|
||||||
|
e -= fwretract.current_retract[active_extruder];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Planner::unapply_retract(float &rz, float &e) {
|
||||||
|
rz -= fwretract.current_hop;
|
||||||
|
e += fwretract.current_retract[active_extruder];
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void Planner::quick_stop() {
|
void Planner::quick_stop() {
|
||||||
|
|
||||||
|
@ -1554,6 +1573,7 @@ void Planner::synchronize() {
|
||||||
* Add a new linear movement to the planner queue (in terms of steps).
|
* Add a new linear movement to the planner queue (in terms of steps).
|
||||||
*
|
*
|
||||||
* target - target position in steps units
|
* target - target position in steps units
|
||||||
|
* target_float - target position in direct (mm, degrees) units. optional
|
||||||
* fr_mm_s - (target) speed of the move
|
* fr_mm_s - (target) speed of the move
|
||||||
* extruder - target extruder
|
* extruder - target extruder
|
||||||
* millimeters - the length of the movement, if known
|
* millimeters - the length of the movement, if known
|
||||||
|
@ -1562,7 +1582,10 @@ void Planner::synchronize() {
|
||||||
*/
|
*/
|
||||||
bool Planner::_buffer_steps(const int32_t (&target)[XYZE]
|
bool Planner::_buffer_steps(const int32_t (&target)[XYZE]
|
||||||
#if HAS_POSITION_FLOAT
|
#if HAS_POSITION_FLOAT
|
||||||
, const float (&target_float)[XYZE]
|
, const float (&target_float)[ABCE]
|
||||||
|
#endif
|
||||||
|
#if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
|
||||||
|
, const float (&delta_mm_cart)[XYZE]
|
||||||
#endif
|
#endif
|
||||||
, float fr_mm_s, const uint8_t extruder, const float &millimeters
|
, float fr_mm_s, const uint8_t extruder, const float &millimeters
|
||||||
) {
|
) {
|
||||||
|
@ -1579,6 +1602,9 @@ bool Planner::_buffer_steps(const int32_t (&target)[XYZE]
|
||||||
#if HAS_POSITION_FLOAT
|
#if HAS_POSITION_FLOAT
|
||||||
, target_float
|
, target_float
|
||||||
#endif
|
#endif
|
||||||
|
#if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
|
||||||
|
, delta_mm_cart
|
||||||
|
#endif
|
||||||
, fr_mm_s, extruder, millimeters
|
, fr_mm_s, extruder, millimeters
|
||||||
)) {
|
)) {
|
||||||
// Movement was not queued, probably because it was too short.
|
// Movement was not queued, probably because it was too short.
|
||||||
|
@ -1618,9 +1644,12 @@ bool Planner::_buffer_steps(const int32_t (&target)[XYZE]
|
||||||
* Returns true is movement is acceptable, false otherwise
|
* Returns true is movement is acceptable, false otherwise
|
||||||
*/
|
*/
|
||||||
bool Planner::_populate_block(block_t * const block, bool split_move,
|
bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||||
const int32_t (&target)[XYZE]
|
const int32_t (&target)[ABCE]
|
||||||
#if HAS_POSITION_FLOAT
|
#if HAS_POSITION_FLOAT
|
||||||
, const float (&target_float)[XYZE]
|
, const float (&target_float)[ABCE]
|
||||||
|
#endif
|
||||||
|
#if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
|
||||||
|
, const float (&delta_mm_cart)[XYZE]
|
||||||
#endif
|
#endif
|
||||||
, float fr_mm_s, const uint8_t extruder, const float &millimeters/*=0.0*/
|
, float fr_mm_s, const uint8_t extruder, const float &millimeters/*=0.0*/
|
||||||
) {
|
) {
|
||||||
|
@ -2243,12 +2272,21 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||||
// Unit vector of previous path line segment
|
// Unit vector of previous path line segment
|
||||||
static float previous_unit_vec[XYZE];
|
static float previous_unit_vec[XYZE];
|
||||||
|
|
||||||
|
#if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
|
||||||
float unit_vec[] = {
|
float unit_vec[] = {
|
||||||
delta_mm[A_AXIS] * inverse_millimeters,
|
delta_mm_cart[X_AXIS] * inverse_millimeters,
|
||||||
delta_mm[B_AXIS] * inverse_millimeters,
|
delta_mm_cart[Y_AXIS] * inverse_millimeters,
|
||||||
delta_mm[C_AXIS] * inverse_millimeters,
|
delta_mm_cart[Z_AXIS] * inverse_millimeters,
|
||||||
|
delta_mm_cart[E_AXIS] * inverse_millimeters
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
float unit_vec[] = {
|
||||||
|
delta_mm[X_AXIS] * inverse_millimeters,
|
||||||
|
delta_mm[Y_AXIS] * inverse_millimeters,
|
||||||
|
delta_mm[Z_AXIS] * inverse_millimeters,
|
||||||
delta_mm[E_AXIS] * inverse_millimeters
|
delta_mm[E_AXIS] * inverse_millimeters
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
// Skip first block or when previous_nominal_speed is used as a flag for homing and offset cycles.
|
// Skip first block or when previous_nominal_speed is used as a flag for homing and offset cycles.
|
||||||
if (moves_queued && !UNEAR_ZERO(previous_nominal_speed_sqr)) {
|
if (moves_queued && !UNEAR_ZERO(previous_nominal_speed_sqr)) {
|
||||||
|
@ -2302,7 +2340,9 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||||
|
|
||||||
COPY(previous_unit_vec, unit_vec);
|
COPY(previous_unit_vec, unit_vec);
|
||||||
|
|
||||||
#else // Classic Jerk Limiting
|
#endif
|
||||||
|
|
||||||
|
#if HAS_CLASSIC_JERK
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapted from Průša MKS firmware
|
* Adapted from Průša MKS firmware
|
||||||
|
@ -2317,7 +2357,12 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||||
float safe_speed = nominal_speed;
|
float safe_speed = nominal_speed;
|
||||||
|
|
||||||
uint8_t limited = 0;
|
uint8_t limited = 0;
|
||||||
LOOP_XYZE(i) {
|
#if ENABLED(JUNCTION_DEVIATION) && ENABLED(LIN_ADVANCE)
|
||||||
|
LOOP_XYZ(i)
|
||||||
|
#else
|
||||||
|
LOOP_XYZE(i)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
const float jerk = ABS(current_speed[i]), // cs : Starting from zero, change in speed for this axis
|
const float jerk = ABS(current_speed[i]), // cs : Starting from zero, change in speed for this axis
|
||||||
maxj = max_jerk[i]; // mj : The max jerk setting for this axis
|
maxj = max_jerk[i]; // mj : The max jerk setting for this axis
|
||||||
if (jerk > maxj) { // cs > mj : New current speed too fast?
|
if (jerk > maxj) { // cs > mj : New current speed too fast?
|
||||||
|
@ -2349,7 +2394,12 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||||
|
|
||||||
// Now limit the jerk in all axes.
|
// Now limit the jerk in all axes.
|
||||||
const float smaller_speed_factor = vmax_junction / previous_nominal_speed;
|
const float smaller_speed_factor = vmax_junction / previous_nominal_speed;
|
||||||
LOOP_XYZE(axis) {
|
#if ENABLED(JUNCTION_DEVIATION) && ENABLED(LIN_ADVANCE)
|
||||||
|
LOOP_XYZ(axis)
|
||||||
|
#else
|
||||||
|
LOOP_XYZE(axis)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
// Limit an axis. We have to differentiate: coasting, reversal of an axis, full stop.
|
// Limit an axis. We have to differentiate: coasting, reversal of an axis, full stop.
|
||||||
float v_exit = previous_speed[axis] * smaller_speed_factor,
|
float v_exit = previous_speed[axis] * smaller_speed_factor,
|
||||||
v_entry = current_speed[axis];
|
v_entry = current_speed[axis];
|
||||||
|
@ -2381,7 +2431,12 @@ bool Planner::_populate_block(block_t * const block, bool split_move,
|
||||||
vmax_junction = safe_speed;
|
vmax_junction = safe_speed;
|
||||||
|
|
||||||
previous_safe_speed = safe_speed;
|
previous_safe_speed = safe_speed;
|
||||||
|
|
||||||
|
#if ENABLED(JUNCTION_DEVIATION)
|
||||||
|
vmax_junction_sqr = MIN(vmax_junction_sqr, sq(vmax_junction));
|
||||||
|
#else
|
||||||
vmax_junction_sqr = sq(vmax_junction);
|
vmax_junction_sqr = sq(vmax_junction);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // Classic Jerk Limiting
|
#endif // Classic Jerk Limiting
|
||||||
|
|
||||||
|
@ -2466,7 +2521,12 @@ void Planner::buffer_sync_block() {
|
||||||
* extruder - target extruder
|
* extruder - target extruder
|
||||||
* millimeters - the length of the movement, if known
|
* millimeters - the length of the movement, if known
|
||||||
*/
|
*/
|
||||||
bool Planner::buffer_segment(const float &a, const float &b, const float &c, const float &e, const float &fr_mm_s, const uint8_t extruder, const float &millimeters/*=0.0*/) {
|
bool Planner::buffer_segment(const float &a, const float &b, const float &c, const float &e
|
||||||
|
#if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
|
||||||
|
, const float (&delta_mm_cart)[XYZE]
|
||||||
|
#endif
|
||||||
|
, const float &fr_mm_s, const uint8_t extruder, const float &millimeters/*=0.0*/
|
||||||
|
) {
|
||||||
|
|
||||||
// If we are cleaning, do not accept queuing of movements
|
// If we are cleaning, do not accept queuing of movements
|
||||||
if (cleaning_buffer_counter) return false;
|
if (cleaning_buffer_counter) return false;
|
||||||
|
@ -2534,6 +2594,9 @@ bool Planner::buffer_segment(const float &a, const float &b, const float &c, con
|
||||||
#if HAS_POSITION_FLOAT
|
#if HAS_POSITION_FLOAT
|
||||||
, target_float
|
, target_float
|
||||||
#endif
|
#endif
|
||||||
|
#if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
|
||||||
|
, delta_mm_cart
|
||||||
|
#endif
|
||||||
, fr_mm_s, extruder, millimeters
|
, fr_mm_s, extruder, millimeters
|
||||||
)
|
)
|
||||||
) return false;
|
) return false;
|
||||||
|
@ -2543,24 +2606,84 @@ bool Planner::buffer_segment(const float &a, const float &b, const float &c, con
|
||||||
} // buffer_segment()
|
} // buffer_segment()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Directly set the planner XYZ position (and stepper positions)
|
* Add a new linear movement to the buffer.
|
||||||
|
* The target is cartesian, it's translated to delta/scara if
|
||||||
|
* needed.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* rx,ry,rz,e - target position in mm or degrees
|
||||||
|
* fr_mm_s - (target) speed of the move (mm/s)
|
||||||
|
* extruder - target extruder
|
||||||
|
* millimeters - the length of the movement, if known
|
||||||
|
* inv_duration - the reciprocal if the duration of the movement, if known (kinematic only if feeedrate scaling is enabled)
|
||||||
|
*/
|
||||||
|
bool Planner::buffer_line(const float &rx, const float &ry, const float &rz, const float &e, const float &fr_mm_s, const uint8_t extruder, const float millimeters
|
||||||
|
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||||
|
, const float &inv_duration
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
float raw[XYZE] = { rx, ry, rz, e };
|
||||||
|
#if HAS_POSITION_MODIFIERS
|
||||||
|
apply_modifiers(raw);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if IS_KINEMATIC
|
||||||
|
const float delta_mm_cart[] = {
|
||||||
|
rx - position_cart[X_AXIS],
|
||||||
|
ry - position_cart[Y_AXIS],
|
||||||
|
rz - position_cart[Z_AXIS]
|
||||||
|
#if ENABLED(JUNCTION_DEVIATION)
|
||||||
|
, e - position_cart[E_AXIS]
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
float mm = millimeters;
|
||||||
|
if (mm == 0.0)
|
||||||
|
mm = (delta_mm_cart[X_AXIS] != 0.0 || delta_mm_cart[Y_AXIS] != 0.0) ? SQRT(sq(delta_mm_cart[X_AXIS]) + sq(delta_mm_cart[Y_AXIS]) + sq(delta_mm_cart[Z_AXIS])) : fabs(delta_mm_cart[Z_AXIS]);
|
||||||
|
|
||||||
|
inverse_kinematics(raw);
|
||||||
|
|
||||||
|
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||||
|
// For SCARA scale the feed rate from mm/s to degrees/s
|
||||||
|
// i.e., Complete the angular vector in the given time.
|
||||||
|
const float duration_recip = inv_duration ? inv_duration : fr_mm_s / mm,
|
||||||
|
feedrate = HYPOT(delta[A_AXIS] - position_float[A_AXIS], delta[B_AXIS] - position_float[B_AXIS]) * duration_recip;
|
||||||
|
#else
|
||||||
|
const float feedrate = fr_mm_s;
|
||||||
|
#endif
|
||||||
|
if (buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], raw[E_AXIS]
|
||||||
|
#if ENABLED(JUNCTION_DEVIATION)
|
||||||
|
, delta_mm_cart
|
||||||
|
#endif
|
||||||
|
, feedrate, extruder, mm
|
||||||
|
)) {
|
||||||
|
position_cart[X_AXIS] = rx;
|
||||||
|
position_cart[Y_AXIS] = ry;
|
||||||
|
position_cart[Z_AXIS] = rz;
|
||||||
|
position_cart[E_AXIS] = e;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
return buffer_segment(raw, fr_mm_s, extruder, millimeters);
|
||||||
|
#endif
|
||||||
|
} // buffer_line()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directly set the planner ABC position (and stepper positions)
|
||||||
* converting mm (or angles for SCARA) into steps.
|
* converting mm (or angles for SCARA) into steps.
|
||||||
*
|
*
|
||||||
* On CORE machines stepper ABC will be translated from the given XYZ.
|
* The provided ABC position is in machine units.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Planner::_set_position_mm(const float &a, const float &b, const float &c, const float &e) {
|
void Planner::set_machine_position_mm(const float &a, const float &b, const float &c, const float &e) {
|
||||||
#if ENABLED(DISTINCT_E_FACTORS)
|
#if ENABLED(DISTINCT_E_FACTORS)
|
||||||
last_extruder = active_extruder;
|
last_extruder = active_extruder;
|
||||||
#endif
|
#endif
|
||||||
position[A_AXIS] = LROUND(a * axis_steps_per_mm[A_AXIS]);
|
position[A_AXIS] = LROUND(a * axis_steps_per_mm[A_AXIS]);
|
||||||
position[B_AXIS] = LROUND(b * axis_steps_per_mm[B_AXIS]);
|
position[B_AXIS] = LROUND(b * axis_steps_per_mm[B_AXIS]);
|
||||||
position[C_AXIS] = LROUND(axis_steps_per_mm[C_AXIS] * (c +(
|
position[C_AXIS] = LROUND(c * axis_steps_per_mm[C_AXIS]);
|
||||||
#if !IS_KINEMATIC && ENABLED(AUTO_BED_LEVELING_UBL)
|
|
||||||
leveling_active ? ubl.get_z_correction(a, b) :
|
|
||||||
#endif
|
|
||||||
0)
|
|
||||||
));
|
|
||||||
position[E_AXIS] = LROUND(e * axis_steps_per_mm[_EINDEX]);
|
position[E_AXIS] = LROUND(e * axis_steps_per_mm[_EINDEX]);
|
||||||
#if HAS_POSITION_FLOAT
|
#if HAS_POSITION_FLOAT
|
||||||
position_float[A_AXIS] = a;
|
position_float[A_AXIS] = a;
|
||||||
|
@ -2577,44 +2700,54 @@ void Planner::_set_position_mm(const float &a, const float &b, const float &c, c
|
||||||
stepper.set_position(position[A_AXIS], position[B_AXIS], position[C_AXIS], position[E_AXIS]);
|
stepper.set_position(position[A_AXIS], position[B_AXIS], position[C_AXIS], position[E_AXIS]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Planner::set_position_mm_kinematic(const float (&cart)[XYZE]) {
|
void Planner::set_position_mm(const float &rx, const float &ry, const float &rz, const float &e) {
|
||||||
#if PLANNER_LEVELING
|
float raw[XYZE] = { rx, ry, rz, e };
|
||||||
float raw[XYZ] = { cart[X_AXIS], cart[Y_AXIS], cart[Z_AXIS] };
|
#if HAS_POSITION_MODIFIERS
|
||||||
apply_leveling(raw);
|
apply_modifiers(raw
|
||||||
#else
|
#if HAS_LEVELING
|
||||||
const float (&raw)[XYZE] = cart;
|
, true
|
||||||
|
#endif
|
||||||
|
);
|
||||||
#endif
|
#endif
|
||||||
#if IS_KINEMATIC
|
#if IS_KINEMATIC
|
||||||
|
position_cart[X_AXIS] = rx;
|
||||||
|
position_cart[Y_AXIS] = ry;
|
||||||
|
position_cart[Z_AXIS] = rz;
|
||||||
|
position_cart[E_AXIS] = e;
|
||||||
|
|
||||||
inverse_kinematics(raw);
|
inverse_kinematics(raw);
|
||||||
_set_position_mm(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], cart[E_AXIS]);
|
set_machine_position_mm(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], raw[E_AXIS]);
|
||||||
#else
|
#else
|
||||||
_set_position_mm(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], cart[E_AXIS]);
|
set_machine_position_mm(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], raw[E_AXIS]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setters for planner position (also setting stepper position).
|
* Setters for planner position (also setting stepper position).
|
||||||
*/
|
*/
|
||||||
void Planner::set_position_mm(const AxisEnum axis, const float &v) {
|
void Planner::set_e_position_mm(const float &e) {
|
||||||
#if ENABLED(DISTINCT_E_FACTORS)
|
#if ENABLED(DISTINCT_E_FACTORS)
|
||||||
const uint8_t axis_index = axis + (axis == E_AXIS ? active_extruder : 0);
|
const uint8_t axis_index = E_AXIS + active_extruder;
|
||||||
last_extruder = active_extruder;
|
last_extruder = active_extruder;
|
||||||
#else
|
#else
|
||||||
const uint8_t axis_index = axis;
|
const uint8_t axis_index = E_AXIS;
|
||||||
#endif
|
#endif
|
||||||
position[axis] = LROUND(axis_steps_per_mm[axis_index] * (v + (
|
#if ENABLED(FWRETRACT)
|
||||||
#if ENABLED(AUTO_BED_LEVELING_UBL)
|
float e_new = e - fwretract.current_retract[active_extruder];
|
||||||
axis == Z_AXIS && leveling_active ? ubl.get_z_correction(current_position[X_AXIS], current_position[Y_AXIS]) :
|
#else
|
||||||
|
const float e_new = e;
|
||||||
#endif
|
#endif
|
||||||
0)
|
position[E_AXIS] = LROUND(axis_steps_per_mm[axis_index] * e_new);
|
||||||
));
|
|
||||||
#if HAS_POSITION_FLOAT
|
#if HAS_POSITION_FLOAT
|
||||||
position_float[axis] = v;
|
position_float[E_AXIS] = e_new;
|
||||||
|
#endif
|
||||||
|
#if IS_KINEMATIC
|
||||||
|
position_cart[E_AXIS] = e;
|
||||||
#endif
|
#endif
|
||||||
if (has_blocks_queued())
|
if (has_blocks_queued())
|
||||||
buffer_sync_block();
|
buffer_sync_block();
|
||||||
else
|
else
|
||||||
stepper.set_position(axis, position[axis]);
|
stepper.set_position(E_AXIS, position[E_AXIS]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recalculate the steps/s^2 acceleration rates, based on the mm/s^2
|
// Recalculate the steps/s^2 acceleration rates, based on the mm/s^2
|
||||||
|
@ -2638,7 +2771,7 @@ void Planner::reset_acceleration_rates() {
|
||||||
// Recalculate position, steps_to_mm if axis_steps_per_mm changes!
|
// Recalculate position, steps_to_mm if axis_steps_per_mm changes!
|
||||||
void Planner::refresh_positioning() {
|
void Planner::refresh_positioning() {
|
||||||
LOOP_XYZE_N(i) steps_to_mm[i] = 1.0f / axis_steps_per_mm[i];
|
LOOP_XYZE_N(i) steps_to_mm[i] = 1.0f / axis_steps_per_mm[i];
|
||||||
set_position_mm_kinematic(current_position);
|
set_position_mm(current_position);
|
||||||
reset_acceleration_rates();
|
reset_acceleration_rates();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,10 @@
|
||||||
#include "../libs/vector_3.h"
|
#include "../libs/vector_3.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(FWRETRACT)
|
||||||
|
#include "../feature/fwretract.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
enum BlockFlagBit : char {
|
enum BlockFlagBit : char {
|
||||||
// Recalculate trapezoids on entry junction. For optimization.
|
// Recalculate trapezoids on entry junction. For optimization.
|
||||||
BLOCK_BIT_RECALCULATE,
|
BLOCK_BIT_RECALCULATE,
|
||||||
|
@ -151,7 +155,7 @@ typedef struct {
|
||||||
|
|
||||||
} block_t;
|
} block_t;
|
||||||
|
|
||||||
#define HAS_POSITION_FLOAT (ENABLED(LIN_ADVANCE) || HAS_FEEDRATE_SCALING)
|
#define HAS_POSITION_FLOAT (ENABLED(LIN_ADVANCE) || ENABLED(SCARA_FEEDRATE_SCALING))
|
||||||
|
|
||||||
#define BLOCK_MOD(n) ((n)&(BLOCK_BUFFER_SIZE-1))
|
#define BLOCK_MOD(n) ((n)&(BLOCK_BUFFER_SIZE-1))
|
||||||
|
|
||||||
|
@ -210,14 +214,22 @@ class Planner {
|
||||||
#if ENABLED(JUNCTION_DEVIATION)
|
#if ENABLED(JUNCTION_DEVIATION)
|
||||||
static float junction_deviation_mm; // (mm) M205 J
|
static float junction_deviation_mm; // (mm) M205 J
|
||||||
#if ENABLED(LIN_ADVANCE)
|
#if ENABLED(LIN_ADVANCE)
|
||||||
|
static float max_e_jerk // Calculated from junction_deviation_mm
|
||||||
#if ENABLED(DISTINCT_E_FACTORS)
|
#if ENABLED(DISTINCT_E_FACTORS)
|
||||||
static float max_e_jerk[EXTRUDERS]; // Calculated from junction_deviation_mm
|
[EXTRUDERS]
|
||||||
#else
|
#endif
|
||||||
static float max_e_jerk;
|
;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAS_CLASSIC_JERK
|
||||||
|
static float max_jerk[
|
||||||
|
#if ENABLED(JUNCTION_DEVIATION) && ENABLED(LIN_ADVANCE)
|
||||||
|
XYZ // (mm/s^2) M205 XYZ - The largest speed change requiring no acceleration.
|
||||||
#else
|
#else
|
||||||
static float max_jerk[XYZE]; // (mm/s^2) M205 XYZE - The largest speed change requiring no acceleration.
|
XYZE // (mm/s^2) M205 XYZE - The largest speed change requiring no acceleration.
|
||||||
|
#endif
|
||||||
|
];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_LEVELING
|
#if HAS_LEVELING
|
||||||
|
@ -240,6 +252,10 @@ class Planner {
|
||||||
static float position_float[XYZE];
|
static float position_float[XYZE];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if IS_KINEMATIC
|
||||||
|
static float position_cart[XYZE];
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ENABLED(SKEW_CORRECTION)
|
#if ENABLED(SKEW_CORRECTION)
|
||||||
#if ENABLED(SKEW_CORRECTION_GCODE)
|
#if ENABLED(SKEW_CORRECTION_GCODE)
|
||||||
static float xy_skew_factor;
|
static float xy_skew_factor;
|
||||||
|
@ -410,6 +426,8 @@ class Planner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
FORCE_INLINE static void skew(float (&raw)[XYZ]) { skew(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS]); }
|
||||||
|
FORCE_INLINE static void skew(float (&raw)[XYZE]) { skew(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS]); }
|
||||||
|
|
||||||
FORCE_INLINE static void unskew(float &cx, float &cy, const float &cz) {
|
FORCE_INLINE static void unskew(float &cx, float &cy, const float &cz) {
|
||||||
if (WITHIN(cx, X_MIN_POS, X_MAX_POS) && WITHIN(cy, Y_MIN_POS, Y_MAX_POS)) {
|
if (WITHIN(cx, X_MIN_POS, X_MAX_POS) && WITHIN(cy, Y_MIN_POS, Y_MAX_POS)) {
|
||||||
|
@ -420,29 +438,76 @@ class Planner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
FORCE_INLINE static void unskew(float (&raw)[XYZ]) { unskew(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS]); }
|
||||||
|
FORCE_INLINE static void unskew(float (&raw)[XYZE]) { unskew(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS]); }
|
||||||
|
|
||||||
#endif // SKEW_CORRECTION
|
#endif // SKEW_CORRECTION
|
||||||
|
|
||||||
#if PLANNER_LEVELING || HAS_UBL_AND_CURVES
|
#if HAS_LEVELING
|
||||||
/**
|
/**
|
||||||
* Apply leveling to transform a cartesian position
|
* Apply leveling to transform a cartesian position
|
||||||
* as it will be given to the planner and steppers.
|
* as it will be given to the planner and steppers.
|
||||||
*/
|
*/
|
||||||
static void apply_leveling(float &rx, float &ry, float &rz);
|
static void apply_leveling(float &rx, float &ry, float &rz);
|
||||||
FORCE_INLINE static void apply_leveling(float (&raw)[XYZ]) { apply_leveling(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS]); }
|
FORCE_INLINE static void apply_leveling(float (&raw)[XYZ]) { apply_leveling(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS]); }
|
||||||
|
FORCE_INLINE static void apply_leveling(float (&raw)[XYZE]) { apply_leveling(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS]); }
|
||||||
|
|
||||||
|
static void unapply_leveling(float raw[XYZ]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PLANNER_LEVELING
|
#if ENABLED(FWRETRACT)
|
||||||
#define ARG_X float rx
|
static void apply_retract(float &rz, float &e);
|
||||||
#define ARG_Y float ry
|
FORCE_INLINE static void apply_retract(float (&raw)[XYZE]) { apply_retract(raw[Z_AXIS], raw[E_AXIS]); }
|
||||||
#define ARG_Z float rz
|
static void unapply_retract(float &rz, float &e);
|
||||||
static void unapply_leveling(float raw[XYZ]);
|
FORCE_INLINE static void unapply_retract(float (&raw)[XYZE]) { unapply_retract(raw[Z_AXIS], raw[E_AXIS]); }
|
||||||
#else
|
|
||||||
#define ARG_X const float &rx
|
|
||||||
#define ARG_Y const float &ry
|
|
||||||
#define ARG_Z const float &rz
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAS_POSITION_MODIFIERS
|
||||||
|
FORCE_INLINE static void apply_modifiers(float (&pos)[XYZE]
|
||||||
|
#if HAS_LEVELING
|
||||||
|
, bool leveling =
|
||||||
|
#if PLANNER_LEVELING
|
||||||
|
true
|
||||||
|
#else
|
||||||
|
false
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
#if ENABLED(SKEW_CORRECTION)
|
||||||
|
skew(pos);
|
||||||
|
#endif
|
||||||
|
#if HAS_LEVELING
|
||||||
|
if (leveling)
|
||||||
|
apply_leveling(pos);
|
||||||
|
#endif
|
||||||
|
#if ENABLED(FWRETRACT)
|
||||||
|
apply_retract(pos);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCE_INLINE static void unapply_modifiers(float (&pos)[XYZE]
|
||||||
|
#if HAS_LEVELING
|
||||||
|
, bool leveling =
|
||||||
|
#if PLANNER_LEVELING
|
||||||
|
true
|
||||||
|
#else
|
||||||
|
false
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
#if ENABLED(FWRETRACT)
|
||||||
|
unapply_retract(pos);
|
||||||
|
#endif
|
||||||
|
#if HAS_LEVELING
|
||||||
|
if (leveling)
|
||||||
|
unapply_leveling(pos);
|
||||||
|
#endif
|
||||||
|
#if ENABLED(SKEW_CORRECTION)
|
||||||
|
unskew(pos);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif // HAS_POSITION_MODIFIERS
|
||||||
|
|
||||||
// Number of moves currently in the planner including the busy block, if any
|
// Number of moves currently in the planner including the busy block, if any
|
||||||
FORCE_INLINE static uint8_t movesplanned() { return BLOCK_MOD(block_buffer_head - block_buffer_tail); }
|
FORCE_INLINE static uint8_t movesplanned() { return BLOCK_MOD(block_buffer_head - block_buffer_tail); }
|
||||||
|
|
||||||
|
@ -489,7 +554,10 @@ class Planner {
|
||||||
*/
|
*/
|
||||||
static bool _buffer_steps(const int32_t (&target)[XYZE]
|
static bool _buffer_steps(const int32_t (&target)[XYZE]
|
||||||
#if HAS_POSITION_FLOAT
|
#if HAS_POSITION_FLOAT
|
||||||
, const float (&target_float)[XYZE]
|
, const float (&target_float)[ABCE]
|
||||||
|
#endif
|
||||||
|
#if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
|
||||||
|
, const float (&delta_mm_cart)[XYZE]
|
||||||
#endif
|
#endif
|
||||||
, float fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
|
, float fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
|
||||||
);
|
);
|
||||||
|
@ -511,6 +579,9 @@ class Planner {
|
||||||
#if HAS_POSITION_FLOAT
|
#if HAS_POSITION_FLOAT
|
||||||
, const float (&target_float)[XYZE]
|
, const float (&target_float)[XYZE]
|
||||||
#endif
|
#endif
|
||||||
|
#if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
|
||||||
|
, const float (&delta_mm_cart)[XYZE]
|
||||||
|
#endif
|
||||||
, float fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
|
, float fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -520,6 +591,13 @@ class Planner {
|
||||||
*/
|
*/
|
||||||
static void buffer_sync_block();
|
static void buffer_sync_block();
|
||||||
|
|
||||||
|
#if IS_KINEMATIC
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Allow do_homing_move to access internal functions, such as buffer_segment.
|
||||||
|
friend void do_homing_move(const AxisEnum, const float, const float);
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Planner::buffer_segment
|
* Planner::buffer_segment
|
||||||
*
|
*
|
||||||
|
@ -532,74 +610,83 @@ class Planner {
|
||||||
* extruder - target extruder
|
* extruder - target extruder
|
||||||
* millimeters - the length of the movement, if known
|
* millimeters - the length of the movement, if known
|
||||||
*/
|
*/
|
||||||
static bool buffer_segment(const float &a, const float &b, const float &c, const float &e, const float &fr_mm_s, const uint8_t extruder, const float &millimeters=0.0);
|
static bool buffer_segment(const float &a, const float &b, const float &c, const float &e
|
||||||
|
#if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
|
||||||
static void _set_position_mm(const float &a, const float &b, const float &c, const float &e);
|
, const float (&delta_mm_cart)[XYZE]
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a new linear movement to the buffer.
|
|
||||||
* The target is NOT translated to delta/scara
|
|
||||||
*
|
|
||||||
* Leveling will be applied to input on cartesians.
|
|
||||||
* Kinematic machines should call buffer_line_kinematic (for leveled moves).
|
|
||||||
* (Cartesians may also call buffer_line_kinematic.)
|
|
||||||
*
|
|
||||||
* rx,ry,rz,e - target position in mm or degrees
|
|
||||||
* fr_mm_s - (target) speed of the move (mm/s)
|
|
||||||
* extruder - target extruder
|
|
||||||
* millimeters - the length of the movement, if known
|
|
||||||
*/
|
|
||||||
FORCE_INLINE static bool buffer_line(ARG_X, ARG_Y, ARG_Z, const float &e, const float &fr_mm_s, const uint8_t extruder, const float millimeters = 0.0) {
|
|
||||||
#if PLANNER_LEVELING && IS_CARTESIAN
|
|
||||||
apply_leveling(rx, ry, rz);
|
|
||||||
#endif
|
#endif
|
||||||
return buffer_segment(rx, ry, rz, e, fr_mm_s, extruder, millimeters);
|
, const float &fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
|
||||||
|
);
|
||||||
|
|
||||||
|
FORCE_INLINE static bool buffer_segment(const float (&abce)[ABCE]
|
||||||
|
#if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
|
||||||
|
, const float (&delta_mm_cart)[XYZE]
|
||||||
|
#endif
|
||||||
|
, const float &fr_mm_s, const uint8_t extruder, const float &millimeters=0.0
|
||||||
|
) {
|
||||||
|
return buffer_segment(abce[A_AXIS], abce[B_AXIS], abce[C_AXIS], abce[E_AXIS]
|
||||||
|
#if IS_KINEMATIC && ENABLED(JUNCTION_DEVIATION)
|
||||||
|
, delta_mm_cart
|
||||||
|
#endif
|
||||||
|
, fr_mm_s, extruder, millimeters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new linear movement to the buffer.
|
* Add a new linear movement to the buffer.
|
||||||
* The target is cartesian, it's translated to delta/scara if
|
* The target is cartesian, it's translated to delta/scara if
|
||||||
* needed.
|
* needed.
|
||||||
*
|
*
|
||||||
* cart - x,y,z,e CARTESIAN target in mm
|
*
|
||||||
|
* rx,ry,rz,e - target position in mm or degrees
|
||||||
* fr_mm_s - (target) speed of the move (mm/s)
|
* fr_mm_s - (target) speed of the move (mm/s)
|
||||||
* extruder - target extruder
|
* extruder - target extruder
|
||||||
* millimeters - the length of the movement, if known
|
* millimeters - the length of the movement, if known
|
||||||
|
* inv_duration - the reciprocal if the duration of the movement, if known (kinematic only if feeedrate scaling is enabled)
|
||||||
*/
|
*/
|
||||||
FORCE_INLINE static bool buffer_line_kinematic(const float (&cart)[XYZE], const float &fr_mm_s, const uint8_t extruder, const float millimeters = 0.0) {
|
static bool buffer_line(const float &rx, const float &ry, const float &rz, const float &e, const float &fr_mm_s, const uint8_t extruder, const float millimeters=0.0
|
||||||
#if PLANNER_LEVELING
|
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||||
float raw[XYZ] = { cart[X_AXIS], cart[Y_AXIS], cart[Z_AXIS] };
|
, const float &inv_duration=0.0
|
||||||
apply_leveling(raw);
|
|
||||||
#else
|
|
||||||
const float (&raw)[XYZE] = cart;
|
|
||||||
#endif
|
#endif
|
||||||
#if IS_KINEMATIC
|
);
|
||||||
inverse_kinematics(raw);
|
|
||||||
return buffer_segment(delta[A_AXIS], delta[B_AXIS], delta[C_AXIS], cart[E_AXIS], fr_mm_s, extruder, millimeters);
|
FORCE_INLINE static bool buffer_line(const float (&cart)[XYZE], const float &fr_mm_s, const uint8_t extruder, const float millimeters=0.0
|
||||||
#else
|
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||||
return buffer_segment(raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS], cart[E_AXIS], fr_mm_s, extruder, millimeters);
|
, const float &inv_duration=0.0
|
||||||
#endif
|
#endif
|
||||||
|
) {
|
||||||
|
return buffer_line(cart[X_AXIS], cart[Y_AXIS], cart[Z_AXIS], cart[E_AXIS], fr_mm_s, extruder, millimeters
|
||||||
|
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||||
|
, inv_duration
|
||||||
|
#endif
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the planner.position and individual stepper positions.
|
* Set the planner.position and individual stepper positions.
|
||||||
* Used by G92, G28, G29, and other procedures.
|
* Used by G92, G28, G29, and other procedures.
|
||||||
*
|
*
|
||||||
|
* The supplied position is in the cartesian coordinate space and is
|
||||||
|
* translated in to machine space as needed. Modifiers such as leveling
|
||||||
|
* and skew are also applied.
|
||||||
|
*
|
||||||
* Multiplies by axis_steps_per_mm[] and does necessary conversion
|
* Multiplies by axis_steps_per_mm[] and does necessary conversion
|
||||||
* for COREXY / COREXZ / COREYZ to set the corresponding stepper positions.
|
* for COREXY / COREXZ / COREYZ to set the corresponding stepper positions.
|
||||||
*
|
*
|
||||||
* Clears previous speed values.
|
* Clears previous speed values.
|
||||||
*/
|
*/
|
||||||
FORCE_INLINE static void set_position_mm(ARG_X, ARG_Y, ARG_Z, const float &e) {
|
static void set_position_mm(const float &rx, const float &ry, const float &rz, const float &e);
|
||||||
#if PLANNER_LEVELING && IS_CARTESIAN
|
FORCE_INLINE static void set_position_mm(const float (&cart)[XYZE]) { set_position_mm(cart[X_AXIS], cart[Y_AXIS], cart[Z_AXIS], cart[E_AXIS]); }
|
||||||
apply_leveling(rx, ry, rz);
|
static void set_e_position_mm(const float &e);
|
||||||
#endif
|
|
||||||
_set_position_mm(rx, ry, rz, e);
|
/**
|
||||||
}
|
* Set the planner.position and individual stepper positions.
|
||||||
static void set_position_mm_kinematic(const float (&cart)[XYZE]);
|
*
|
||||||
static void set_position_mm(const AxisEnum axis, const float &v);
|
* The supplied position is in machine space, and no additional
|
||||||
FORCE_INLINE static void set_z_position_mm(const float &z) { set_position_mm(Z_AXIS, z); }
|
* conversions are applied.
|
||||||
FORCE_INLINE static void set_e_position_mm(const float &e) { set_position_mm(E_AXIS, e); }
|
*/
|
||||||
|
static void set_machine_position_mm(const float &a, const float &b, const float &c, const float &e);
|
||||||
|
FORCE_INLINE static void set_machine_position_mm(const float (&abce)[ABCE]) { set_machine_position_mm(abce[A_AXIS], abce[B_AXIS], abce[C_AXIS], abce[E_AXIS]); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an axis position according to stepper position(s)
|
* Get an axis position according to stepper position(s)
|
||||||
|
@ -756,17 +843,15 @@ class Planner {
|
||||||
static void autotemp_M104_M109();
|
static void autotemp_M104_M109();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(JUNCTION_DEVIATION)
|
#if ENABLED(JUNCTION_DEVIATION) && ENABLED(LIN_ADVANCE)
|
||||||
FORCE_INLINE static void recalculate_max_e_jerk() {
|
FORCE_INLINE static void recalculate_max_e_jerk() {
|
||||||
#define GET_MAX_E_JERK(N) SQRT(SQRT(0.5) * junction_deviation_mm * (N) * RECIPROCAL(1.0 - SQRT(0.5)))
|
#define GET_MAX_E_JERK(N) SQRT(SQRT(0.5) * junction_deviation_mm * (N) * RECIPROCAL(1.0 - SQRT(0.5)))
|
||||||
#if ENABLED(LIN_ADVANCE)
|
|
||||||
#if ENABLED(DISTINCT_E_FACTORS)
|
#if ENABLED(DISTINCT_E_FACTORS)
|
||||||
for (uint8_t i = 0; i < EXTRUDERS; i++)
|
for (uint8_t i = 0; i < EXTRUDERS; i++)
|
||||||
max_e_jerk[i] = GET_MAX_E_JERK(max_acceleration_mm_per_s2[E_AXIS + i]);
|
max_e_jerk[i] = GET_MAX_E_JERK(max_acceleration_mm_per_s2[E_AXIS + i]);
|
||||||
#else
|
#else
|
||||||
max_e_jerk = GET_MAX_E_JERK(max_acceleration_mm_per_s2[E_AXIS]);
|
max_e_jerk = GET_MAX_E_JERK(max_acceleration_mm_per_s2[E_AXIS]);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -190,15 +190,15 @@ void cubic_b_spline(const float position[NUM_AXIS], const float target[NUM_AXIS]
|
||||||
bez_target[E_AXIS] = interp(position[E_AXIS], target[E_AXIS], t);
|
bez_target[E_AXIS] = interp(position[E_AXIS], target[E_AXIS], t);
|
||||||
clamp_to_software_endstops(bez_target);
|
clamp_to_software_endstops(bez_target);
|
||||||
|
|
||||||
#if HAS_UBL_AND_CURVES
|
#if HAS_LEVELING && !PLANNER_LEVELING
|
||||||
float pos[XYZ] = { bez_target[X_AXIS], bez_target[Y_AXIS], bez_target[Z_AXIS] };
|
float pos[XYZE] = { bez_target[X_AXIS], bez_target[Y_AXIS], bez_target[Z_AXIS], bez_target[E_AXIS] };
|
||||||
planner.apply_leveling(pos);
|
planner.apply_leveling(pos);
|
||||||
if (!planner.buffer_segment(pos[X_AXIS], pos[Y_AXIS], pos[Z_AXIS], bez_target[E_AXIS], fr_mm_s, active_extruder))
|
|
||||||
break;
|
|
||||||
#else
|
#else
|
||||||
if (!planner.buffer_line_kinematic(bez_target, fr_mm_s, extruder))
|
const float (&pos)[XYZE] = bez_target;
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (!planner.buffer_line(pos, fr_mm_s, active_extruder, step))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -537,7 +537,7 @@ static bool do_probe_move(const float z, const float fr_mm_s) {
|
||||||
set_current_from_steppers_for_axis(Z_AXIS);
|
set_current_from_steppers_for_axis(Z_AXIS);
|
||||||
|
|
||||||
// Tell the planner where we actually are
|
// Tell the planner where we actually are
|
||||||
SYNC_PLAN_POSITION_KINEMATIC();
|
sync_plan_position();
|
||||||
|
|
||||||
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
||||||
if (DEBUGGING(LEVELING)) DEBUG_POS("<<< do_probe_move", current_position);
|
if (DEBUGGING(LEVELING)) DEBUG_POS("<<< do_probe_move", current_position);
|
||||||
|
|
|
@ -104,7 +104,7 @@ void forward_kinematics_SCARA(const float &a, const float &b) {
|
||||||
* Maths and first version by QHARLEY.
|
* Maths and first version by QHARLEY.
|
||||||
* Integrated into Marlin and slightly restructured by Joachim Cerny.
|
* Integrated into Marlin and slightly restructured by Joachim Cerny.
|
||||||
*/
|
*/
|
||||||
void inverse_kinematics(const float raw[XYZ]) {
|
void inverse_kinematics(const float (&raw)[XYZ]) {
|
||||||
|
|
||||||
static float C2, S2, SK1, SK2, THETA, PSI;
|
static float C2, S2, SK1, SK2, THETA, PSI;
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,7 @@
|
||||||
* scara.h - SCARA-specific functions
|
* scara.h - SCARA-specific functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __SCARA_H__
|
#pragma once
|
||||||
#define __SCARA_H__
|
|
||||||
|
|
||||||
#include "../core/macros.h"
|
#include "../core/macros.h"
|
||||||
|
|
||||||
|
@ -38,9 +37,11 @@ float constexpr L1 = SCARA_LINKAGE_1, L2 = SCARA_LINKAGE_2,
|
||||||
|
|
||||||
void scara_set_axis_is_at_home(const AxisEnum axis);
|
void scara_set_axis_is_at_home(const AxisEnum axis);
|
||||||
|
|
||||||
void inverse_kinematics(const float raw[XYZ]);
|
void inverse_kinematics(const float (&raw)[XYZ]);
|
||||||
|
FORCE_INLINE void inverse_kinematics(const float (&raw)[XYZE]) {
|
||||||
|
const float raw_xyz[XYZ] = { raw[X_AXIS], raw[Y_AXIS], raw[Z_AXIS] };
|
||||||
|
inverse_kinematics(raw_xyz);
|
||||||
|
}
|
||||||
void forward_kinematics_SCARA(const float &a, const float &b);
|
void forward_kinematics_SCARA(const float &a, const float &b);
|
||||||
|
|
||||||
void scara_report_positions();
|
void scara_report_positions();
|
||||||
|
|
||||||
#endif // __SCARA_H__
|
|
||||||
|
|
|
@ -134,7 +134,7 @@
|
||||||
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
||||||
if (DEBUGGING(LEVELING)) DEBUG_POS("(1) Raise Z-Axis", current_position);
|
if (DEBUGGING(LEVELING)) DEBUG_POS("(1) Raise Z-Axis", current_position);
|
||||||
#endif
|
#endif
|
||||||
planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
|
planner.buffer_line(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
|
|
||||||
// STEP 2
|
// STEP 2
|
||||||
|
@ -145,7 +145,7 @@
|
||||||
DEBUG_POS("Moving ParkPos", current_position);
|
DEBUG_POS("Moving ParkPos", current_position);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
|
planner.buffer_line(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
|
|
||||||
// STEP 3
|
// STEP 3
|
||||||
|
@ -163,7 +163,7 @@
|
||||||
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
||||||
if (DEBUGGING(LEVELING)) DEBUG_POS("Move away from parked extruder", current_position);
|
if (DEBUGGING(LEVELING)) DEBUG_POS("Move away from parked extruder", current_position);
|
||||||
#endif
|
#endif
|
||||||
planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
|
planner.buffer_line(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
|
|
||||||
// STEP 5
|
// STEP 5
|
||||||
|
@ -178,12 +178,12 @@
|
||||||
|
|
||||||
// STEP 6
|
// STEP 6
|
||||||
current_position[X_AXIS] = grabpos + (tmp_extruder ? -10 : 10);
|
current_position[X_AXIS] = grabpos + (tmp_extruder ? -10 : 10);
|
||||||
planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
|
planner.buffer_line(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
|
||||||
current_position[X_AXIS] = grabpos;
|
current_position[X_AXIS] = grabpos;
|
||||||
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
||||||
if (DEBUGGING(LEVELING)) DEBUG_POS("(6) Unpark extruder", current_position);
|
if (DEBUGGING(LEVELING)) DEBUG_POS("(6) Unpark extruder", current_position);
|
||||||
#endif
|
#endif
|
||||||
planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[X_AXIS]/2, active_extruder);
|
planner.buffer_line(current_position, planner.max_feedrate_mm_s[X_AXIS]/2, active_extruder);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
|
|
||||||
// Step 7
|
// Step 7
|
||||||
|
@ -191,7 +191,7 @@
|
||||||
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
||||||
if (DEBUGGING(LEVELING)) DEBUG_POS("(7) Move midway between hotends", current_position);
|
if (DEBUGGING(LEVELING)) DEBUG_POS("(7) Move midway between hotends", current_position);
|
||||||
#endif
|
#endif
|
||||||
planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
|
planner.buffer_line(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
||||||
SERIAL_ECHOLNPGM("Autopark done.");
|
SERIAL_ECHOLNPGM("Autopark done.");
|
||||||
|
@ -241,7 +241,7 @@
|
||||||
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
||||||
if (DEBUGGING(LEVELING)) DEBUG_POS("(1) Raise Z-Axis", current_position);
|
if (DEBUGGING(LEVELING)) DEBUG_POS("(1) Raise Z-Axis", current_position);
|
||||||
#endif
|
#endif
|
||||||
planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
|
planner.buffer_line(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
|
|
||||||
// STEP 2
|
// STEP 2
|
||||||
|
@ -252,14 +252,14 @@
|
||||||
DEBUG_POS("Move X SwitchPos", current_position);
|
DEBUG_POS("Move X SwitchPos", current_position);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
|
planner.buffer_line(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
|
|
||||||
current_position[Y_AXIS] = SWITCHING_TOOLHEAD_Y_POS - SWITCHING_TOOLHEAD_Y_SECURITY;
|
current_position[Y_AXIS] = SWITCHING_TOOLHEAD_Y_POS - SWITCHING_TOOLHEAD_Y_SECURITY;
|
||||||
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
||||||
if (DEBUGGING(LEVELING)) DEBUG_POS("Move Y SwitchPos + Security", current_position);
|
if (DEBUGGING(LEVELING)) DEBUG_POS("Move Y SwitchPos + Security", current_position);
|
||||||
#endif
|
#endif
|
||||||
planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[Y_AXIS], active_extruder);
|
planner.buffer_line(current_position, planner.max_feedrate_mm_s[Y_AXIS], active_extruder);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
|
|
||||||
// STEP 3
|
// STEP 3
|
||||||
|
@ -273,14 +273,14 @@
|
||||||
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
||||||
if (DEBUGGING(LEVELING)) DEBUG_POS("Move Y SwitchPos", current_position);
|
if (DEBUGGING(LEVELING)) DEBUG_POS("Move Y SwitchPos", current_position);
|
||||||
#endif
|
#endif
|
||||||
planner.buffer_line_kinematic(current_position,(planner.max_feedrate_mm_s[Y_AXIS] * 0.5), active_extruder);
|
planner.buffer_line(current_position,(planner.max_feedrate_mm_s[Y_AXIS] * 0.5), active_extruder);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
safe_delay(200);
|
safe_delay(200);
|
||||||
current_position[Y_AXIS] -= SWITCHING_TOOLHEAD_Y_CLEAR;
|
current_position[Y_AXIS] -= SWITCHING_TOOLHEAD_Y_CLEAR;
|
||||||
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
||||||
if (DEBUGGING(LEVELING)) DEBUG_POS("Move back Y clear", current_position);
|
if (DEBUGGING(LEVELING)) DEBUG_POS("Move back Y clear", current_position);
|
||||||
#endif
|
#endif
|
||||||
planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[Y_AXIS], active_extruder); // move away from docked toolhead
|
planner.buffer_line(current_position, planner.max_feedrate_mm_s[Y_AXIS], active_extruder); // move away from docked toolhead
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
|
|
||||||
// STEP 4
|
// STEP 4
|
||||||
|
@ -291,13 +291,13 @@
|
||||||
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
||||||
if (DEBUGGING(LEVELING)) DEBUG_POS("Move to new toolhead X", current_position);
|
if (DEBUGGING(LEVELING)) DEBUG_POS("Move to new toolhead X", current_position);
|
||||||
#endif
|
#endif
|
||||||
planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
|
planner.buffer_line(current_position, planner.max_feedrate_mm_s[X_AXIS], active_extruder);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
current_position[Y_AXIS] = SWITCHING_TOOLHEAD_Y_POS - SWITCHING_TOOLHEAD_Y_SECURITY;
|
current_position[Y_AXIS] = SWITCHING_TOOLHEAD_Y_POS - SWITCHING_TOOLHEAD_Y_SECURITY;
|
||||||
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
||||||
if (DEBUGGING(LEVELING)) DEBUG_POS("Move Y SwitchPos + Security", current_position);
|
if (DEBUGGING(LEVELING)) DEBUG_POS("Move Y SwitchPos + Security", current_position);
|
||||||
#endif
|
#endif
|
||||||
planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[Y_AXIS], active_extruder);
|
planner.buffer_line(current_position, planner.max_feedrate_mm_s[Y_AXIS], active_extruder);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
|
|
||||||
// STEP 5
|
// STEP 5
|
||||||
|
@ -308,7 +308,7 @@
|
||||||
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
||||||
if (DEBUGGING(LEVELING)) DEBUG_POS("Move Y SwitchPos", current_position);
|
if (DEBUGGING(LEVELING)) DEBUG_POS("Move Y SwitchPos", current_position);
|
||||||
#endif
|
#endif
|
||||||
planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[Y_AXIS] * 0.5, active_extruder);
|
planner.buffer_line(current_position, planner.max_feedrate_mm_s[Y_AXIS] * 0.5, active_extruder);
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
|
|
||||||
safe_delay(200);
|
safe_delay(200);
|
||||||
|
@ -319,7 +319,7 @@
|
||||||
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
||||||
if (DEBUGGING(LEVELING)) DEBUG_POS("Move back Y clear", current_position);
|
if (DEBUGGING(LEVELING)) DEBUG_POS("Move back Y clear", current_position);
|
||||||
#endif
|
#endif
|
||||||
planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[Y_AXIS], active_extruder); // move away from docked toolhead
|
planner.buffer_line(current_position, planner.max_feedrate_mm_s[Y_AXIS], active_extruder); // move away from docked toolhead
|
||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
|
|
||||||
// STEP 6
|
// STEP 6
|
||||||
|
@ -524,7 +524,7 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n
|
||||||
#if ENABLED(SWITCHING_NOZZLE)
|
#if ENABLED(SWITCHING_NOZZLE)
|
||||||
// Always raise by at least 1 to avoid workpiece
|
// Always raise by at least 1 to avoid workpiece
|
||||||
current_position[Z_AXIS] += MAX(-zdiff, 0.0) + 1;
|
current_position[Z_AXIS] += MAX(-zdiff, 0.0) + 1;
|
||||||
planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
|
planner.buffer_line(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
|
||||||
move_nozzle_servo(tmp_extruder);
|
move_nozzle_servo(tmp_extruder);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -549,7 +549,7 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n
|
||||||
#endif // !DUAL_X_CARRIAGE
|
#endif // !DUAL_X_CARRIAGE
|
||||||
|
|
||||||
// Tell the planner the new "current position"
|
// Tell the planner the new "current position"
|
||||||
SYNC_PLAN_POSITION_KINEMATIC();
|
sync_plan_position();
|
||||||
|
|
||||||
#if ENABLED(DELTA)
|
#if ENABLED(DELTA)
|
||||||
//LOOP_XYZ(i) update_software_endstops(i); // or modify the constrain function
|
//LOOP_XYZ(i) update_software_endstops(i); // or modify the constrain function
|
||||||
|
@ -563,7 +563,7 @@ void tool_change(const uint8_t tmp_extruder, const float fr_mm_s/*=0.0*/, bool n
|
||||||
#if DISABLED(SWITCHING_NOZZLE)
|
#if DISABLED(SWITCHING_NOZZLE)
|
||||||
// Do a small lift to avoid the workpiece in the move back (below)
|
// Do a small lift to avoid the workpiece in the move back (below)
|
||||||
current_position[Z_AXIS] += 1.0;
|
current_position[Z_AXIS] += 1.0;
|
||||||
planner.buffer_line_kinematic(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
|
planner.buffer_line(current_position, planner.max_feedrate_mm_s[Z_AXIS], active_extruder);
|
||||||
#endif
|
#endif
|
||||||
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
#if ENABLED(DEBUG_LEVELING_FEATURE)
|
||||||
if (DEBUGGING(LEVELING)) DEBUG_POS("Move back", destination);
|
if (DEBUGGING(LEVELING)) DEBUG_POS("Move back", destination);
|
||||||
|
|
Reference in a new issue