From eeb2ec7871363089b3c0b98d4f5ca4cd2a7adb30 Mon Sep 17 00:00:00 2001 From: Rodrigo Faselli <162915171+RF47@users.noreply.github.com> Date: Mon, 23 Feb 2026 11:48:24 -0300 Subject: [PATCH] Added Junction Deviation support to time estimation (#12417) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description This PR enhances the GCodeProcessor's time estimation by incorporating Junction Deviation (JD) into the jerk calculations, providing more accurate print time predictions for firmwares that use JD (like modern Marlin). Key Changes: - Added JD support to time estimation - Reads machine_max_junction_deviation (machine limits) and default_junction_deviation (print profile) - When JD is enabled (>0), replaces traditional X/Y jerk values with JD-based calculation: $Jerk = \sqrt{2.5\cdot JD \cdot acceleration }$ - Falls back to traditional jerk when JD is not used # Test: JD:0.0256mm Accel.: 1000 mm/s² image Jerk: 8mm/s (equivalent) image JD:0.0128mm (4mm/s jerk) image --- src/libslic3r/GCode/GCodeProcessor.cpp | 42 ++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 8203dabab2..c90680b219 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -5581,9 +5581,45 @@ float GCodeProcessor::get_axis_max_jerk(PrintEstimatedStatistics::ETimeMode mode Vec3f GCodeProcessor::get_xyz_max_jerk(PrintEstimatedStatistics::ETimeMode mode) const { - return Vec3f(get_option_value(m_time_processor.machine_limits.machine_max_jerk_x, static_cast(mode)), - get_option_value(m_time_processor.machine_limits.machine_max_jerk_y, static_cast(mode)), - get_option_value(m_time_processor.machine_limits.machine_max_jerk_z, static_cast(mode))); + // Default values from config + const size_t id = static_cast(mode); + float jx = get_option_value(m_time_processor.machine_limits.machine_max_jerk_x, id); + float jy = get_option_value(m_time_processor.machine_limits.machine_max_jerk_y, id); + const float jz = get_option_value(m_time_processor.machine_limits.machine_max_jerk_z, id); + const float machine_jd = get_option_value(m_time_processor.machine_limits.machine_max_junction_deviation, id); + + // early exit: Junction Deviation is only supported by Marlin firmware + if (m_flavor != gcfMarlinFirmware || machine_jd <= 0.0f) { + return Vec3f(jx, jy, jz); + } + + // default junction deviation: + const ConfigOptionFloat* opt = nullptr; + + if (m_print) { + const auto& config = m_print->full_print_config(); + opt = config.option("default_junction_deviation"); + } + + const float default_jd = opt ? opt->value : 0.0f; + + // If default_jd is specified (>0), use the smaller of machine_jd and default_jd. + const float jd = (default_jd > 0.0f) ? std::min(machine_jd, default_jd) : machine_jd; + + // Use per-axis acceleration when available; fall back to generic acceleration. + // If axis-specific acceleration not provided (zero), use general acceleration + const PrintEstimatedStatistics::ETimeMode emode = static_cast(id); + const float max_acc_x = get_axis_max_acceleration(emode, X); + const float max_acc_y = get_axis_max_acceleration(emode, Y); + const float generic_acc = get_acceleration(emode); + const float acc_x = max_acc_x > 0.0f ? max_acc_x : generic_acc; + const float acc_y = max_acc_y > 0.0f ? max_acc_y : generic_acc; + + // Jerk = sqrt(2.5 * jd * acc) as per Marlin's junction deviation implementation + jx = std::sqrt(jd * acc_x * 2.5f); + jy = std::sqrt(jd * acc_y * 2.5f); + + return Vec3f(jx, jy, jz); } float GCodeProcessor::get_retract_acceleration(PrintEstimatedStatistics::ETimeMode mode) const