diff --git a/Marlin/src/inc/SanityCheck.h b/Marlin/src/inc/SanityCheck.h index 1aadbb19e3e2..d571ddd7f4a2 100644 --- a/Marlin/src/inc/SanityCheck.h +++ b/Marlin/src/inc/SanityCheck.h @@ -4379,10 +4379,17 @@ static_assert(_PLUS_TEST(4), "HOMING_FEEDRATE_MM_M values must be positive."); #error "Input Shaping is not compatible with POLARGRAPH kinematics." #elif ENABLED(DIRECT_STEPPING) #error "Input Shaping is not compatible with DIRECT_STEPPING." - #elif ENABLED(INPUT_SHAPING_X) && ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY, MARKFORGED_YX) - #error "INPUT_SHAPING_X is not supported with COREXY, COREYX, COREXZ, COREZX, or MARKFORGED_*." - #elif ENABLED(INPUT_SHAPING_Y) && ANY(CORE_IS_XY, CORE_IS_YZ, MARKFORGED_XY, MARKFORGED_YX) - #error "INPUT_SHAPING_Y is not supported with COREXY, COREYX, COREYZ, COREZY, or MARKFORGED_*." + #elif BOTH(INPUT_SHAPING_X, CORE_IS_XZ) + #error "INPUT_SHAPING_X is not supported with COREXZ." + #elif BOTH(INPUT_SHAPING_Y, CORE_IS_YZ) + #error "INPUT_SHAPING_Y is not supported with COREYZ." + #elif ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) + #if !BOTH(INPUT_SHAPING_X, INPUT_SHAPING_Y) + #error "INPUT_SHAPING_X and INPUT_SHAPING_Y must both be enabled for COREXY, COREYX, or MARKFORGED_*." + #else + static_assert(SHAPING_FREQ_X == SHAPING_FREQ_Y, "SHAPING_FREQ_X and SHAPING_FREQ_Y must be the same for COREXY / COREYX / MARKFORGED_*."); + static_assert(SHAPING_ZETA_X == SHAPING_ZETA_Y, "SHAPING_ZETA_X and SHAPING_ZETA_Y must be the same for COREXY / COREYX / MARKFORGED_*."); + #endif #endif #ifdef __AVR__ diff --git a/Marlin/src/inc/Warnings.cpp b/Marlin/src/inc/Warnings.cpp index 561c8f43a34e..1d1426936f95 100644 --- a/Marlin/src/inc/Warnings.cpp +++ b/Marlin/src/inc/Warnings.cpp @@ -790,3 +790,10 @@ #if BOTH(POLAR, S_CURVE_ACCELERATION) #warning "POLAR kinematics may not work well with S_CURVE_ACCELERATION." #endif + +/** + * Input Shaping + */ +#if HAS_SHAPING && ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX) + #warning "Input Shaping for CORE / MARKFORGED kinematic axes is still experimental." +#endif diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp index 2a9487f09697..54b52cd16e0a 100644 --- a/Marlin/src/module/stepper.cpp +++ b/Marlin/src/module/stepper.cpp @@ -3020,7 +3020,7 @@ void Stepper::init() { * Calculate a fixed point factor to apply to the signal and its echo * when shaping an axis. */ - void Stepper::set_shaping_damping_ratio(const AxisEnum axis, const float zeta) { + void Stepper::set_shaping_damping_ratio(const AxisEnum axis, const_float_t zeta) { // from the damping ratio, get a factor that can be applied to advance_dividend for fixed point maths // for ZV, we use amplitudes 1/(1+K) and K/(1+K) where K = exp(-zeta * M_PI / sqrt(1.0f - zeta * zeta)) // which can be converted to 1:7 fixed point with an excellent fit with a 3rd order polynomial @@ -3029,9 +3029,9 @@ void Stepper::init() { else if (zeta >= 1.0f) factor2 = 0.0f; else { factor2 = 64.44056192 + -99.02008832 * zeta; - const float zeta2 = zeta * zeta; + const_float_t zeta2 = zeta * zeta; factor2 += -7.58095488 * zeta2; - const float zeta3 = zeta2 * zeta; + const_float_t zeta3 = zeta2 * zeta; factor2 += 43.073216 * zeta3; factor2 = floor(factor2); } @@ -3049,7 +3049,7 @@ void Stepper::init() { return -1; } - void Stepper::set_shaping_frequency(const AxisEnum axis, const float freq) { + void Stepper::set_shaping_frequency(const AxisEnum axis, const_float_t freq) { // enabling or disabling shaping whilst moving can result in lost steps planner.synchronize(); diff --git a/Marlin/src/module/stepper.h b/Marlin/src/module/stepper.h index e86498e841da..3bbfeac9cab8 100644 --- a/Marlin/src/module/stepper.h +++ b/Marlin/src/module/stepper.h @@ -154,38 +154,39 @@ // Add time for each stepper #if HAS_X_STEP - #define ISR_X_STEPPER_CYCLES ISR_STEPPER_CYCLES + #define ISR_X_STEPPER_CYCLES ISR_STEPPER_CYCLES #endif #if HAS_Y_STEP - #define ISR_Y_STEPPER_CYCLES ISR_STEPPER_CYCLES + #define ISR_Y_STEPPER_CYCLES ISR_STEPPER_CYCLES #endif #if HAS_Z_STEP - #define ISR_Z_STEPPER_CYCLES ISR_STEPPER_CYCLES + #define ISR_Z_STEPPER_CYCLES ISR_STEPPER_CYCLES #endif #if HAS_I_STEP - #define ISR_I_STEPPER_CYCLES ISR_STEPPER_CYCLES + #define ISR_I_STEPPER_CYCLES ISR_STEPPER_CYCLES #endif #if HAS_J_STEP - #define ISR_J_STEPPER_CYCLES ISR_STEPPER_CYCLES + #define ISR_J_STEPPER_CYCLES ISR_STEPPER_CYCLES #endif #if HAS_K_STEP - #define ISR_K_STEPPER_CYCLES ISR_STEPPER_CYCLES + #define ISR_K_STEPPER_CYCLES ISR_STEPPER_CYCLES #endif #if HAS_U_STEP - #define ISR_U_STEPPER_CYCLES ISR_STEPPER_CYCLES + #define ISR_U_STEPPER_CYCLES ISR_STEPPER_CYCLES #endif #if HAS_V_STEP - #define ISR_V_STEPPER_CYCLES ISR_STEPPER_CYCLES + #define ISR_V_STEPPER_CYCLES ISR_STEPPER_CYCLES #endif #if HAS_W_STEP - #define ISR_W_STEPPER_CYCLES ISR_STEPPER_CYCLES + #define ISR_W_STEPPER_CYCLES ISR_STEPPER_CYCLES #endif #if HAS_EXTRUDERS - #define ISR_E_STEPPER_CYCLES ISR_STEPPER_CYCLES // E is always interpolated, even for mixing extruders + #define ISR_E_STEPPER_CYCLES ISR_STEPPER_CYCLES // E is always interpolated, even for mixing extruders #endif // And the total minimum loop time, not including the base -#define MIN_ISR_LOOP_CYCLES (ISR_MIXING_STEPPER_CYCLES LOGICAL_AXIS_GANG(+ ISR_E_STEPPER_CYCLES, + ISR_X_STEPPER_CYCLES, + ISR_Y_STEPPER_CYCLES, + ISR_Z_STEPPER_CYCLES, + ISR_I_STEPPER_CYCLES, + ISR_J_STEPPER_CYCLES, + ISR_K_STEPPER_CYCLES, + ISR_U_STEPPER_CYCLES, + ISR_V_STEPPER_CYCLES, + ISR_W_STEPPER_CYCLES)) +#define _PLUS_AXIS_CYCLES(A) + (ISR_##A##_STEPPER_CYCLES) +#define MIN_ISR_LOOP_CYCLES (ISR_MIXING_STEPPER_CYCLES LOGICAL_AXIS_MAP(_PLUS_AXIS_CYCLES)) // Calculate the minimum MPU cycles needed per pulse to enforce, limited to the max stepper rate #define _MIN_STEPPER_PULSE_CYCLES(N) _MAX(uint32_t((F_CPU) / (MAXIMUM_STEPPER_RATE)), ((F_CPU) / 500000UL) * (N)) @@ -802,9 +803,9 @@ class Stepper { } #if HAS_SHAPING - static void set_shaping_damping_ratio(const AxisEnum axis, const float zeta); + static void set_shaping_damping_ratio(const AxisEnum axis, const_float_t zeta); static float get_shaping_damping_ratio(const AxisEnum axis); - static void set_shaping_frequency(const AxisEnum axis, const float freq); + static void set_shaping_frequency(const AxisEnum axis, const_float_t freq); static float get_shaping_frequency(const AxisEnum axis); #endif