diff --git a/Marlin/Conditionals_post.h b/Marlin/Conditionals_post.h index 54f8925ff09..924ac46ba6f 100644 --- a/Marlin/Conditionals_post.h +++ b/Marlin/Conditionals_post.h @@ -978,6 +978,7 @@ #define PLANNER_LEVELING (OLDSCHOOL_ABL || ENABLED(MESH_BED_LEVELING) || UBL_SEGMENTED || ENABLED(SKEW_CORRECTION)) #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_FEEDRATE_SCALING (ENABLED(SCARA_FEEDRATE_SCALING) || ENABLED(DELTA_FEEDRATE_SCALING)) #if ENABLED(AUTO_BED_LEVELING_UBL) #undef LCD_BED_LEVELING diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp index 22b7704fa6d..d1b264899b4 100644 --- a/Marlin/Marlin_main.cpp +++ b/Marlin/Marlin_main.cpp @@ -13348,7 +13348,7 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) { ediff * inv_segments }; - #if DISABLED(SCARA_FEEDRATE_SCALING) + #if !HAS_FEEDRATE_SCALING const float cartesian_segment_mm = cartesian_mm * inv_segments; #endif @@ -13356,14 +13356,13 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) { SERIAL_ECHOPAIR("mm=", cartesian_mm); SERIAL_ECHOPAIR(" seconds=", seconds); SERIAL_ECHOPAIR(" segments=", segments); - #if DISABLED(SCARA_FEEDRATE_SCALING) - SERIAL_ECHOLNPAIR(" segment_mm=", cartesian_segment_mm); - #else - SERIAL_EOL(); + #if !HAS_FEEDRATE_SCALING + SERIAL_ECHOPAIR(" segment_mm=", cartesian_segment_mm); #endif + SERIAL_EOL(); //*/ - #if ENABLED(SCARA_FEEDRATE_SCALING) + #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, @@ -13371,7 +13370,11 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) { inverse_secs = inv_segment_length * _feedrate_mm_s; float oldA = planner.position_float[A_AXIS], - oldB = planner.position_float[B_AXIS]; + oldB = planner.position_float[B_AXIS] + #if ENABLED(DELTA_FEEDRATE_SCALING) + , oldC = planner.position_float[C_AXIS] + #endif + ; /* SERIAL_ECHOPGM("Scaled kinematic move: "); @@ -13380,7 +13383,11 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) { SERIAL_ECHOPAIR(") _feedrate_mm_s=", _feedrate_mm_s); SERIAL_ECHOPAIR(" inverse_secs=", inverse_secs); SERIAL_ECHOPAIR(" oldA=", oldA); - SERIAL_ECHOLNPAIR(" oldB=", oldB); + SERIAL_ECHOPAIR(" oldB=", oldB); + #if ENABLED(DELTA_FEEDRATE_SCALING) + SERIAL_ECHOPAIR(" oldC=", oldC); + #endif + SERIAL_EOL(); safe_delay(5); //*/ #endif @@ -13421,6 +13428,19 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) { 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)) + 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; @@ -13428,16 +13448,31 @@ void set_current_from_steppers_for_axis(const AxisEnum axis) { } // Ensure last segment arrives at target location. - #if ENABLED(SCARA_FEEDRATE_SCALING) + #if HAS_FEEDRATE_SCALING inverse_kinematics(rtarget); ADJUST_DELTA(rtarget); + #endif + + #if ENABLED(SCARA_FEEDRATE_SCALING) const float diff2 = HYPOT2(delta[A_AXIS] - oldA, delta[B_AXIS] - oldB); if (diff2) { planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], rtarget[Z_AXIS], rtarget[E_AXIS], SQRT(diff2) * inverse_secs, active_extruder); /* 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_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); + /* + 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); //*/ @@ -13723,12 +13758,16 @@ void prepare_move_to_destination() { millis_t next_idle_ms = millis() + 200UL; - #if ENABLED(SCARA_FEEDRATE_SCALING) + #if HAS_FEEDRATE_SCALING // SCARA needs to scale the feed rate from mm/s to degrees/s const float inv_segment_length = 1.0 / (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]; + oldB = planner.position_float[B_AXIS] + #if ENABLED(DELTA_FEEDRATE_SCALING) + , oldC = planner.position_float[C_AXIS] + #endif + ; #endif #if N_ARC_CORRECTION > 1 @@ -13774,14 +13813,23 @@ void prepare_move_to_destination() { clamp_to_software_endstops(raw); + #if HAS_FEEDRATE_SCALING + inverse_kinematics(raw); + ADJUST_DELTA(raw); + #endif + #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. - inverse_kinematics(raw); - ADJUST_DELTA(raw); 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)) 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)) + 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); @@ -13794,12 +13842,19 @@ void prepare_move_to_destination() { } // Ensure last segment arrives at target location. - #if ENABLED(SCARA_FEEDRATE_SCALING) + #if HAS_FEEDRATE_SCALING inverse_kinematics(cart); ADJUST_DELTA(cart); + #endif + + #if ENABLED(SCARA_FEEDRATE_SCALING) const float diff2 = HYPOT2(delta[A_AXIS] - oldA, delta[B_AXIS] - oldB); if (diff2) planner.buffer_segment(delta[A_AXIS], delta[B_AXIS], cart[Z_AXIS], cart[E_AXIS], SQRT(diff2) * inverse_secs, active_extruder); + #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); #elif HAS_UBL_AND_CURVES float pos[XYZ] = { cart[X_AXIS], cart[Y_AXIS], cart[Z_AXIS] }; planner.apply_leveling(pos); diff --git a/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration.h b/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration.h index 69771cfca8e..cc5b592be72 100644 --- a/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration.h +++ b/Marlin/example_configurations/delta/FLSUN/auto_calibrate/Configuration.h @@ -513,6 +513,9 @@ // and processor overload (too many expensive sqrt calls). #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 //#define DELTA_HOME_TO_SAFE_ZONE diff --git a/Marlin/example_configurations/delta/FLSUN/kossel/Configuration.h b/Marlin/example_configurations/delta/FLSUN/kossel/Configuration.h index 3bea5acc5f9..0e09ab6971b 100644 --- a/Marlin/example_configurations/delta/FLSUN/kossel/Configuration.h +++ b/Marlin/example_configurations/delta/FLSUN/kossel/Configuration.h @@ -513,6 +513,9 @@ // and processor overload (too many expensive sqrt calls). #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 //#define DELTA_HOME_TO_SAFE_ZONE diff --git a/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration.h b/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration.h index 58750f4323c..4306ced11e5 100644 --- a/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration.h +++ b/Marlin/example_configurations/delta/FLSUN/kossel_mini/Configuration.h @@ -513,6 +513,9 @@ // and processor overload (too many expensive sqrt calls). #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 //#define DELTA_HOME_TO_SAFE_ZONE diff --git a/Marlin/example_configurations/delta/Hatchbox_Alpha/Configuration.h b/Marlin/example_configurations/delta/Hatchbox_Alpha/Configuration.h index c40186801c9..6512e307fa0 100644 --- a/Marlin/example_configurations/delta/Hatchbox_Alpha/Configuration.h +++ b/Marlin/example_configurations/delta/Hatchbox_Alpha/Configuration.h @@ -518,6 +518,9 @@ // and processor overload (too many expensive sqrt calls). #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 //#define DELTA_HOME_TO_SAFE_ZONE diff --git a/Marlin/example_configurations/delta/generic/Configuration.h b/Marlin/example_configurations/delta/generic/Configuration.h index a8d9131d2ea..83ab271990e 100644 --- a/Marlin/example_configurations/delta/generic/Configuration.h +++ b/Marlin/example_configurations/delta/generic/Configuration.h @@ -503,6 +503,9 @@ // and processor overload (too many expensive sqrt calls). #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 //#define DELTA_HOME_TO_SAFE_ZONE diff --git a/Marlin/example_configurations/delta/kossel_mini/Configuration.h b/Marlin/example_configurations/delta/kossel_mini/Configuration.h index 2cc55ce53c8..52008eaab88 100644 --- a/Marlin/example_configurations/delta/kossel_mini/Configuration.h +++ b/Marlin/example_configurations/delta/kossel_mini/Configuration.h @@ -503,6 +503,9 @@ // and processor overload (too many expensive sqrt calls). #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 //#define DELTA_HOME_TO_SAFE_ZONE diff --git a/Marlin/example_configurations/delta/kossel_pro/Configuration.h b/Marlin/example_configurations/delta/kossel_pro/Configuration.h index 381b20f8bde..0e3173a7db9 100644 --- a/Marlin/example_configurations/delta/kossel_pro/Configuration.h +++ b/Marlin/example_configurations/delta/kossel_pro/Configuration.h @@ -489,6 +489,9 @@ // and processor overload (too many expensive sqrt calls). #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 //#define DELTA_HOME_TO_SAFE_ZONE diff --git a/Marlin/example_configurations/delta/kossel_xl/Configuration.h b/Marlin/example_configurations/delta/kossel_xl/Configuration.h index 23417c83f0f..1066fd8867d 100644 --- a/Marlin/example_configurations/delta/kossel_xl/Configuration.h +++ b/Marlin/example_configurations/delta/kossel_xl/Configuration.h @@ -507,6 +507,9 @@ // and processor overload (too many expensive sqrt calls). #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 //#define DELTA_HOME_TO_SAFE_ZONE diff --git a/Marlin/planner.cpp b/Marlin/planner.cpp index 1ca9f51c38f..96668da9abd 100644 --- a/Marlin/planner.cpp +++ b/Marlin/planner.cpp @@ -1550,9 +1550,9 @@ bool Planner::_buffer_steps(const int32_t (&target)[XYZE] // Fill the block with the specified movement if (!_populate_block(block, false, target - #if HAS_POSITION_FLOAT - , target_float - #endif + #if HAS_POSITION_FLOAT + , target_float + #endif , fr_mm_s, extruder, millimeters )) { // Movement was not queued, probably because it was too short. diff --git a/Marlin/planner.h b/Marlin/planner.h index 1c98d44c37b..3255a2cf3db 100644 --- a/Marlin/planner.h +++ b/Marlin/planner.h @@ -144,7 +144,7 @@ typedef struct { } block_t; -#define HAS_POSITION_FLOAT (ENABLED(LIN_ADVANCE) || ENABLED(SCARA_FEEDRATE_SCALING)) +#define HAS_POSITION_FLOAT (ENABLED(LIN_ADVANCE) || HAS_FEEDRATE_SCALING) #define BLOCK_MOD(n) ((n)&(BLOCK_BUFFER_SIZE-1))