Added Junction Deviation support to time estimation (#12417)

# 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²
<img width="2560" height="1392" alt="image" src="https://github.com/user-attachments/assets/f0e95294-bfca-400e-bffc-8d615d051b70" />

Jerk: 8mm/s  (equivalent)
<img width="2560" height="1392" alt="image" src="https://github.com/user-attachments/assets/8508727e-70f6-49ed-ac19-002db73e957b" />

JD:0.0128mm (4mm/s jerk)
<img width="2560" height="1392" alt="image" src="https://github.com/user-attachments/assets/91b04d3b-1b9e-48f4-b4b4-5addda2eff57" />
This commit is contained in:
Rodrigo Faselli 2026-02-23 11:48:24 -03:00 committed by GitHub
parent 1f4fce974f
commit eeb2ec7871
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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<size_t>(mode)),
get_option_value(m_time_processor.machine_limits.machine_max_jerk_y, static_cast<size_t>(mode)),
get_option_value(m_time_processor.machine_limits.machine_max_jerk_z, static_cast<size_t>(mode)));
// Default values from config
const size_t id = static_cast<size_t>(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<ConfigOptionFloat>("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<PrintEstimatedStatistics::ETimeMode>(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