From e58ae317f28ba51a866193dde77db1cb6269a10f Mon Sep 17 00:00:00 2001 From: David Buezas Date: Sun, 28 Jun 2026 22:43:50 +0200 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9C=A8=20FTMotion=20Constant=20Jolt=20Tr?= =?UTF-8?q?ajectory=20planner=20(#28476)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/Configuration_adv.h | 27 +- Marlin/src/gcode/feature/ft_motion/M494.cpp | 45 +- Marlin/src/inc/Conditionals-4-adv.h | 7 + Marlin/src/lcd/language/language_en.h | 2 + Marlin/src/lcd/menu/menu_motion.cpp | 75 ++- Marlin/src/module/ft_motion.cpp | 50 +- Marlin/src/module/ft_motion.h | 28 +- .../src/module/ft_motion/constant_jolt_math.h | 353 +++++++++++++ .../ft_motion/constant_jolt_planner.cpp | 431 ++++++++++++++++ .../module/ft_motion/constant_jolt_planner.h | 187 +++++++ .../ft_motion/trajectory_constant_jolt.cpp | 465 ++++++++++++++++++ .../ft_motion/trajectory_constant_jolt.h | 224 +++++++++ .../module/ft_motion/trajectory_generator.h | 1 + Marlin/src/module/planner.cpp | 16 +- Marlin/src/module/planner.h | 4 + buildroot/tests/I3DBEEZ9_V1/config-02.ini | 2 + 16 files changed, 1858 insertions(+), 59 deletions(-) create mode 100644 Marlin/src/module/ft_motion/constant_jolt_math.h create mode 100644 Marlin/src/module/ft_motion/constant_jolt_planner.cpp create mode 100644 Marlin/src/module/ft_motion/constant_jolt_planner.h create mode 100644 Marlin/src/module/ft_motion/trajectory_constant_jolt.cpp create mode 100644 Marlin/src/module/ft_motion/trajectory_constant_jolt.h diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h index 38859c314ea7..979576c8ae6b 100644 --- a/Marlin/Configuration_adv.h +++ b/Marlin/Configuration_adv.h @@ -1237,16 +1237,29 @@ #define FTM_POLYS // Disable POLY5/6 to save ~3k of Flash. Preserves TRAPEZOIDAL. #if ENABLED(FTM_POLYS) - #define FTM_TRAJECTORY_TYPE TRAPEZOIDAL // Block acceleration profile (TRAPEZOIDAL, POLY5, POLY6) - // TRAPEZOIDAL: Continuous Velocity. Max acceleration is respected. - // POLY5: Like POLY6 with 1.5x but uses less CPU. - // POLY6: Continuous Acceleration (aka S_CURVE). - // POLY trajectories not only reduce resonances without rounding corners, but also - // reduce extruder strain due to linear advance. - #define FTM_POLY6_ACCELERATION_OVERSHOOT 1.875f // Max acceleration overshoot factor for POLY6 (1.25 to 1.875) #endif + /** + * FTM Constant-Jolt Trajectory (7-phase S-curve). + * Jolt is the rate of change of acceleration, not related to Marlin's "classic jerk." + * Ramps acceleration gradually so max acceleration is limited by max speed and distance traveled. + */ + //#define FTM_CONSTANT_JOLT + #if ENABLED(FTM_CONSTANT_JOLT) + #define FTM_DEFAULT_JOLT 250.0f // (m/s³) Default jolt for constant-jolt trajectory. + // Higher values print faster at the cost of increased resonance and extruder stress + #endif + + // Block acceleration profile + // :[ 'TRAPEZOIDAL', 'POLY5', 'POLY6', 'CONSTANT_JOLT' ] + #define FTM_TRAJECTORY_TYPE TRAPEZOIDAL // TRAPEZOIDAL: Continuous Velocity. Max acceleration is respected. + // POLY5: Like POLY6 with 1.5x but uses less CPU. Requires FTM_POLYS. + // POLY6: Continuous Acceleration (aka S_CURVE). Requires FTM_POLYS. + // CONSTANT_JOLT: 7-phase S-curve. Requires FTM_CONSTANT_JOLT. + // POLY trajectories not only reduce resonances without rounding corners, but + // also reduce extruder strain due to linear advance. + /** * Advanced configuration */ diff --git a/Marlin/src/gcode/feature/ft_motion/M494.cpp b/Marlin/src/gcode/feature/ft_motion/M494.cpp index d6161a957473..0c0250f6a6a4 100644 --- a/Marlin/src/gcode/feature/ft_motion/M494.cpp +++ b/Marlin/src/gcode/feature/ft_motion/M494.cpp @@ -30,14 +30,20 @@ #include "../../../lcd/marlinui.h" void say_ftm_settings() { - #if ANY(FTM_POLYS, FTM_SMOOTHING) + #if ANY(FTM_POLYS, FTM_SMOOTHING, FTM_CONSTANT_JOLT) const ft_config_t &c = ftMotion.cfg; #endif - #if ENABLED(FTM_POLYS) + #if HAS_FTM_TRAJECTORY_SELECTION SERIAL_ECHOLN(F(" Trajectory: "), ftMotion.getTrajectoryName(), C('('), (uint8_t)ftMotion.getTrajectoryType(), C(')')); - if (ftMotion.getTrajectoryType() == TrajectoryType::POLY6) - SERIAL_ECHOLNPGM(" Poly6 Overshoot: ", p_float_t(c.poly6_acceleration_overshoot, 3)); + #if ENABLED(FTM_POLYS) + if (ftMotion.getTrajectoryType() == TrajectoryType::POLY6) + SERIAL_ECHOLNPGM(" Poly6 Overshoot: ", p_float_t(c.poly6_acceleration_overshoot, 3)); + #endif + #if ENABLED(FTM_CONSTANT_JOLT) + if (ftMotion.getTrajectoryType() == TrajectoryType::CONSTANT_JOLT) + SERIAL_ECHOLNPGM(" Jolt: ", p_float_t(c.jolt / 1000.0f, 1), " m/s^3"); + #endif #endif #if ENABLED(FTM_SMOOTHING) @@ -52,7 +58,7 @@ void GcodeSuite::M494_report(const bool forReplay/*=true*/) { report_heading_etc(forReplay, F("FT Motion")); SERIAL_ECHOPGM(" M494 T", (uint8_t)ftMotion.getTrajectoryType()); - #if ANY(FTM_POLYS, FTM_SMOOTHING) + #if ANY(FTM_POLYS, FTM_SMOOTHING, FTM_CONSTANT_JOLT) const ft_config_t &c = ftMotion.cfg; #endif @@ -70,6 +76,11 @@ void GcodeSuite::M494_report(const bool forReplay/*=true*/) { SERIAL_ECHOPGM(" O", c.poly6_acceleration_overshoot); #endif + #if ENABLED(FTM_CONSTANT_JOLT) + if (ftMotion.getTrajectoryType() == TrajectoryType::CONSTANT_JOLT) + SERIAL_ECHOPGM(" J", c.jolt / 1000.0f); + #endif + SERIAL_EOL(); } @@ -77,8 +88,9 @@ void GcodeSuite::M494_report(const bool forReplay/*=true*/) { * M494: Set Fixed-time Motion Control parameters * * Parameters: - * T Set trajectory generator type (0=TRAPEZOIDAL, 1=POLY5, 2=POLY6) + * T Set trajectory generator type (0=TRAPEZOIDAL, 1=POLY5, 2=POLY6, 3=CONSTANT_JOLT) * O Set acceleration overshoot for POLY6 (1.25-1.875) + * J Set maximum jolt for CONSTANT_JOLT (m/s³, positive) * X