🧑‍💻 Clarify PID tuning macros

This commit is contained in:
Scott Lahteine
2025-11-28 19:57:52 -06:00
parent 58bce3781e
commit 7b70e39ff6
2 changed files with 47 additions and 68 deletions
+2 -12
View File
@@ -2519,18 +2519,8 @@ bool Planner::_populate_block(
if (moves_queued && !UNEAR_ZERO(previous_nominal_speed)) {
// Compute cosine of angle between previous and current path. (prev_unit_vec is negative)
// NOTE: Max junction velocity is computed without sin() or acos() by trig half angle identity.
float junction_cos_theta = LOGICAL_AXIS_GANG(
+ (-prev_unit_vec.e * unit_vec.e),
+ (-prev_unit_vec.x * unit_vec.x),
+ (-prev_unit_vec.y * unit_vec.y),
+ (-prev_unit_vec.z * unit_vec.z),
+ (-prev_unit_vec.i * unit_vec.i),
+ (-prev_unit_vec.j * unit_vec.j),
+ (-prev_unit_vec.k * unit_vec.k),
+ (-prev_unit_vec.u * unit_vec.u),
+ (-prev_unit_vec.v * unit_vec.v),
+ (-prev_unit_vec.w * unit_vec.w)
);
#define _UNIT_VEC(A) + (-prev_unit_vec.A * unit_vec.A)
float junction_cos_theta = LOGICAL_AXIS_MAP(_UNIT_VEC);
// NOTE: Computed without any expensive trig, sin() or acos(), by trig half angle identity of cos(theta).
if (junction_cos_theta > 0.999999f) {
+45 -56
View File
@@ -824,41 +824,34 @@ void Temperature::factory_reset() {
raw_pid_t tune_pid = { 0, 0, 0 };
celsius_float_t maxT = 0, minT = 10000;
const bool isbed = (heater_id == H_BED),
ischamber = (heater_id == H_CHAMBER);
const bool isbed = TERN0(PIDTEMPBED, heater_id == H_BED),
ischamber = TERN0(PIDTEMPCHAMBER, heater_id == H_CHAMBER);
#if ENABLED(PIDTEMPCHAMBER)
#define C_TERN(T,A,B) ((T) ? (A) : (B))
#else
#define C_TERN(T,A,B) (B)
#endif
#if ENABLED(PIDTEMPBED)
#define B_TERN(T,A,B) ((T) ? (A) : (B))
#else
#define B_TERN(T,A,B) (B)
#endif
#define GHV(C,B,H) C_TERN(ischamber, C, B_TERN(isbed, B, H))
#define SHV(V) C_TERN(ischamber, temp_chamber.soft_pwm_amount = V, B_TERN(isbed, temp_bed.soft_pwm_amount = V, temp_hotend[heater_id].soft_pwm_amount = V))
#define ONHEATINGSTART() C_TERN(ischamber, printerEventLEDs.onChamberHeatingStart(), B_TERN(isbed, printerEventLEDs.onBedHeatingStart(), printerEventLEDs.onHotendHeatingStart()))
#define ONHEATING(S,C,T) C_TERN(ischamber, printerEventLEDs.onChamberHeating(S,C,T), B_TERN(isbed, printerEventLEDs.onBedHeating(S,C,T), printerEventLEDs.onHotendHeating(S,C,T)))
// BED TEST ; BED VALUE ; HOTEND VALUE
#define T_BH(T,B,H) TERN(PIDTEMPBED, ((T) ? (B) : (H)), (H))
// CHAMBER TEST ; CHAMBER VALUE ; T_BH(...)
#define T_CBH(T,C,BH) TERN(PIDTEMPCHAMBER, ((T) ? (C) : (BH)), (BH))
// CHAMBER VALUE ; BED VALUE ; HOTEND VALUE
#define PER_CBH(C,B,H) T_CBH(ischamber, C, T_BH(isbed, B, H))
// Set a field value in the pertinent Temp Monitor
#define SET_CBH(F,V) PER_CBH(temp_chamber.F = V, temp_bed.F = V, temp_hotend[heater_id].F = V)
#define ONHEATINGSTART() PER_CBH(printerEventLEDs.onChamberHeatingStart(), printerEventLEDs.onBedHeatingStart(), printerEventLEDs.onHotendHeatingStart())
#define ONHEATING(S,C,T) PER_CBH(printerEventLEDs.onChamberHeating(S,C,T), printerEventLEDs.onBedHeating(S,C,T), printerEventLEDs.onHotendHeating(S,C,T))
#define WATCH_PID DISABLED(NO_WATCH_PID_TUNING) && (ALL(WATCH_CHAMBER, PIDTEMPCHAMBER) || ALL(WATCH_BED, PIDTEMPBED) || ALL(WATCH_HOTENDS, PIDTEMP))
#if WATCH_PID
#if ALL(THERMAL_PROTECTION_CHAMBER, PIDTEMPCHAMBER)
#define C_GTV(T,A,B) ((T) ? (A) : (B))
#else
#define C_GTV(T,A,B) (B)
#endif
#if ALL(THERMAL_PROTECTION_BED, PIDTEMPBED)
#define B_GTV(T,A,B) ((T) ? (A) : (B))
#else
#define B_GTV(T,A,B) (B)
#endif
#define GTV(C,B,H) C_GTV(ischamber, C, B_GTV(isbed, B, H))
const uint16_t watch_temp_period = GTV(WATCH_CHAMBER_TEMP_PERIOD, WATCH_BED_TEMP_PERIOD, WATCH_TEMP_PERIOD);
const uint8_t watch_temp_increase = GTV(WATCH_CHAMBER_TEMP_INCREASE, WATCH_BED_TEMP_INCREASE, WATCH_TEMP_INCREASE);
const celsius_float_t watch_temp_target = celsius_float_t(target - (watch_temp_increase + GTV(TEMP_CHAMBER_HYSTERESIS, TEMP_BED_HYSTERESIS, TEMP_HYSTERESIS) + 1));
// BED TEST ; BED VALUE ; HOTEND VALUE
#define W_BH(T,B,H) TERN(THERMAL_PROTECTION_BED, T_BH(T,B,H), (H))
// CHAMBER TEST ; CHAMBER VALUE ; W_BH(...)
#define W_CBH(T,C,BH) TERN(THERMAL_PROTECTION_CHAMBER, T_CBH(T,C,BH), (BH))
// CHAMBER VALUE ; BED VALUE ; HOTEND VALUE
#define PER_WATCH_CBH(C,B,H) W_CBH(ischamber, C, W_BH(isbed, B, H))
const uint16_t watch_temp_period = PER_WATCH_CBH(WATCH_CHAMBER_TEMP_PERIOD, WATCH_BED_TEMP_PERIOD, WATCH_TEMP_PERIOD);
const uint8_t watch_temp_increase = PER_WATCH_CBH(WATCH_CHAMBER_TEMP_INCREASE, WATCH_BED_TEMP_INCREASE, WATCH_TEMP_INCREASE);
const celsius_float_t watch_hysteresis = PER_WATCH_CBH(TEMP_CHAMBER_HYSTERESIS, TEMP_BED_HYSTERESIS, TEMP_HYSTERESIS),
watch_temp_target = celsius_float_t(target - (watch_temp_increase + watch_hysteresis + 1));
millis_t temp_change_ms = next_temp_ms + SEC_TO_MS(watch_temp_period);
celsius_float_t next_watch_temp = 0.0;
bool heated = false;
@@ -866,9 +859,9 @@ void Temperature::factory_reset() {
TERN_(HAS_FAN_LOGIC, fan_update_ms = next_temp_ms + fan_update_interval_ms);
TERN_(EXTENSIBLE_UI, ExtUI::onPIDTuning(ischamber ? ExtUI::pidresult_t::PID_CHAMBER_STARTED : isbed ? ExtUI::pidresult_t::PID_BED_STARTED : ExtUI::pidresult_t::PID_STARTED));
TERN_(EXTENSIBLE_UI, ExtUI::onPIDTuning(PER_CBH(ExtUI::pidresult_t::PID_CHAMBER_STARTED, ExtUI::pidresult_t::PID_BED_STARTED, ExtUI::pidresult_t::PID_STARTED)));
if (target > GHV(CHAMBER_MAX_TARGET, BED_MAX_TARGET, hotend_max_target(heater_id))) {
if (target > PER_CBH(CHAMBER_MAX_TARGET, BED_MAX_TARGET, hotend_max_target(heater_id))) {
SERIAL_ECHOPGM(STR_PID_AUTOTUNE); SERIAL_ECHOLNPGM(STR_PID_TEMP_TOO_HIGH);
TERN_(EXTENSIBLE_UI, ExtUI::onPIDTuning(ExtUI::pidresult_t::PID_TEMP_TOO_HIGH));
TERN_(HOST_PROMPT_SUPPORT, hostui.notify(GET_TEXT_F(MSG_PID_TEMP_TOO_HIGH)));
@@ -880,11 +873,11 @@ void Temperature::factory_reset() {
disable_all_heaters();
TERN_(AUTO_POWER_CONTROL, powerManager.power_on());
long bias = GHV(MAX_CHAMBER_POWER, MAX_BED_POWER, PID_MAX) >> 1, d = bias;
SHV(bias);
long bias = PER_CBH(MAX_CHAMBER_POWER, MAX_BED_POWER, PID_MAX) >> 1, d = bias;
SET_CBH(soft_pwm_amount, bias);
#if ENABLED(PRINTER_EVENT_LEDS)
const celsius_float_t start_temp = GHV(degChamber(), degBed(), degHotend(heater_id));
const celsius_float_t start_temp = PER_CBH(degChamber(), degBed(), degHotend(heater_id));
const LED1Color_t oldcolor = ONHEATINGSTART();
#endif
@@ -905,7 +898,7 @@ void Temperature::factory_reset() {
if (temp_ready) {
// Get the current temperature and constrain it
current_temp = GHV(degChamber(), degBed(), degHotend(heater_id));
current_temp = PER_CBH(degChamber(), degBed(), degHotend(heater_id));
NOLESS(maxT, current_temp);
NOMORE(minT, current_temp);
@@ -915,7 +908,7 @@ void Temperature::factory_reset() {
if (heating && current_temp > target && ELAPSED(ms, t2, 5000UL)) {
heating = false;
SHV((bias - d) >> 1);
SET_CBH(soft_pwm_amount, (bias - d) >> 1);
t1 = ms;
t_high = t1 - t2;
maxT = target;
@@ -926,7 +919,7 @@ void Temperature::factory_reset() {
t2 = ms;
t_low = t2 - t1;
if (cycles > 0) {
const long max_pow = GHV(MAX_CHAMBER_POWER, MAX_BED_POWER, PID_MAX);
const long max_pow = PER_CBH(MAX_CHAMBER_POWER, MAX_BED_POWER, PID_MAX);
bias += (d * (t_high - t_low)) / (t_low + t_high);
LIMIT(bias, 20, max_pow - 20);
d = (bias > max_pow >> 1) ? max_pow - 1 - bias : bias;
@@ -950,7 +943,7 @@ void Temperature::factory_reset() {
SERIAL_ECHOLNPGM(STR_KP, tune_pid.p, STR_KI, tune_pid.i, STR_KD, tune_pid.d);
}
}
SHV((bias + d) >> 1);
SET_CBH(soft_pwm_amount, (bias + d) >> 1);
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_PID_CYCLE), cycles, ncycles));
cycles++;
minT = target;
@@ -1016,7 +1009,7 @@ void Temperature::factory_reset() {
TERN_(HOST_PROMPT_SUPPORT, hostui.notify(GET_TEXT_F(MSG_PID_AUTOTUNE_DONE)));
#if ANY(PIDTEMPBED, PIDTEMPCHAMBER)
FSTR_P const estring = GHV(F("chamber"), F("bed"), FPSTR(NUL_STR));
FSTR_P const estring = PER_CBH(F("chamber"), F("bed"), FPSTR(NUL_STR));
say_default_(); SERIAL_ECHOLN(estring, F("Kp "), tune_pid.p);
say_default_(); SERIAL_ECHOLN(estring, F("Ki "), tune_pid.i);
say_default_(); SERIAL_ECHOLN(estring, F("Kd "), tune_pid.d);
@@ -1052,7 +1045,7 @@ void Temperature::factory_reset() {
// Use the result? (As with "M303 U1")
if (set_result)
GHV(_set_chamber_pid(tune_pid), _set_bed_pid(tune_pid), _set_hotend_pid(heater_id, tune_pid));
PER_CBH(_set_chamber_pid(tune_pid), _set_bed_pid(tune_pid), _set_hotend_pid(heater_id, tune_pid));
goto EXIT_M303;
}
@@ -1136,9 +1129,8 @@ void Temperature::factory_reset() {
wait_for_heatup = false;
#if ENABLED(MPC_AUTOTUNE_DEBUG)
SERIAL_ECHOLNPGM("MPC_autotuner::measure_ambient_temp() Completed");
SERIAL_ECHOLNPGM("=====");
SERIAL_ECHOLNPGM("ambient_temp ", get_ambient_temp());
SERIAL_ECHOLNPGM("MPC_autotuner::measure_ambient_temp() Completed\n=====\n"
"ambient_temp ", get_ambient_temp());
#endif
return SUCCESS;
@@ -1223,11 +1215,8 @@ void Temperature::factory_reset() {
#if ENABLED(MPC_AUTOTUNE_DEBUG)
SERIAL_ECHOLNPGM("MPC_autotuner::measure_heatup() Completed");
SERIAL_ECHOLNPGM("=====");
SERIAL_ECHOLNPGM("t1_time ", t1_time);
SERIAL_ECHOLNPGM("sample_count ", sample_count);
SERIAL_ECHOLNPGM("sample_distance ", sample_distance);
for (uint8_t i = 0; i < sample_count; i++)
SERIAL_ECHOLNPGM("sample ", i, " : ", temp_samples[i]);
SERIAL_ECHOLNPGM("t1_time ", t1_time, " sample_count ", sample_count, " sample_distance ", sample_distance);
for (uint8_t i = 0; i < sample_count; i++) SERIAL_ECHOLNPGM("sample ", i, " : ", temp_samples[i]);
SERIAL_ECHOLNPGM("t1 ", get_sample_1_temp(), " t2 ", get_sample_2_temp(), " t3 ", get_sample_3_temp());
#endif
@@ -1390,9 +1379,9 @@ void Temperature::factory_reset() {
if (tuning_type == FORCE_DIFFERENTIAL) {
#if ENABLED(MPC_AUTOTUNE_DEBUG)
SERIAL_ECHOLNPGM("rate_fastest ", tuner.get_rate_fastest());
SERIAL_ECHOLNPGM("time_fastest ", tuner.get_time_fastest());
SERIAL_ECHOLNPGM("temp_fastest ", tuner.get_temp_fastest());
SERIAL_ECHOLNPGM("Fastest rate=", tuner.get_rate_fastest(),
" time=", tuner.get_time_fastest(),
"temp=", tuner.get_temp_fastest());
#endif
// Differential tuning
mpc.block_heat_capacity = mpc.heater_power / tuner.get_rate_fastest();
@@ -1435,9 +1424,9 @@ void Temperature::factory_reset() {
// Check again: If analytic tuning fails, fall back to differential tuning
if (tuning_type == AUTO && (mpc.sensor_responsiveness <= 0 || mpc.block_heat_capacity <= 0)) {
#if ENABLED(MPC_AUTOTUNE_DEBUG)
SERIAL_ECHOLNPGM("rate_fastest ", tuner.get_rate_fastest());
SERIAL_ECHOLNPGM("time_fastest ", tuner.get_time_fastest());
SERIAL_ECHOLNPGM("temp_fastest ", tuner.get_temp_fastest());
SERIAL_ECHOLNPGM("Fastest rate=", tuner.get_rate_fastest(),
" time=", tuner.get_time_fastest(),
"temp=", tuner.get_temp_fastest());
#endif
tuning_type = FORCE_DIFFERENTIAL;
mpc.block_heat_capacity = mpc.heater_power / tuner.get_rate_fastest();