Skip to content

Commit

Permalink
Add min and max output bounds to PidConfig (#1883)
Browse files Browse the repository at this point in the history
The EMC2305 on Grapefruit doesn't turn on the fans at 0 PWM, and we want
some airflow to get better readings from the temperature sensor. Might
as well make the lower and upper bounds fully parameterized by the PID
config!
  • Loading branch information
mkeeter authored Sep 30, 2024
1 parent 2b4835f commit b6e4a37
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 8 deletions.
2 changes: 2 additions & 0 deletions task/thermal/src/bsp/gimlet_bcdef.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ impl Bsp {
gain_p: 1.75,
gain_i: 0.0135,
gain_d: 0.4,
min_output: 0.0,
max_output: 100.0,
},

inputs: &INPUTS,
Expand Down
2 changes: 2 additions & 0 deletions task/thermal/src/bsp/grapefruit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ impl Bsp {
gain_p: 1.75,
gain_i: 0.0135,
gain_d: 0.4,
min_output: 15.0,
max_output: 100.0,
},

inputs: &INPUTS,
Expand Down
2 changes: 2 additions & 0 deletions task/thermal/src/bsp/medusa_a.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ impl Bsp {
gain_p: 0.,
gain_i: 0.,
gain_d: 0.,
min_output: 0.,
max_output: 100.,
},

inputs: &INPUTS,
Expand Down
2 changes: 2 additions & 0 deletions task/thermal/src/bsp/sidecar_bcd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ impl Bsp {
gain_p: 1.75,
gain_i: 0.0135,
gain_d: 0.4,
min_output: 0.0,
max_output: 100.0,
},

inputs: &INPUTS,
Expand Down
15 changes: 7 additions & 8 deletions task/thermal/src/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,8 @@ pub struct PidConfig {
pub gain_p: f32,
pub gain_i: f32,
pub gain_d: f32,
pub min_output: f32,
pub max_output: f32,
}

/// Represents a PID controller that can only push in one direction (i.e. the
Expand All @@ -557,7 +559,7 @@ impl OneSidedPidState {
///
/// The error and output are expected to have the same signs, i.e. a large
/// positive error will produce a large positive output.
fn run(&mut self, cfg: &PidConfig, error: f32, output_limit: f32) -> f32 {
fn run(&mut self, cfg: &PidConfig, error: f32) -> f32 {
let p_contribution = cfg.gain_p * error;

// Pre-multiply accumulated integral by gain, to make clamping easier
Expand All @@ -575,12 +577,12 @@ impl OneSidedPidState {
// To prevent integral windup, integral term needs to be clamped to values
// can effect the output.
let out_pd = cfg.zero + p_contribution + d_contribution;
let (integral_min, integral_max) = if out_pd > output_limit {
let (integral_min, integral_max) = if out_pd > cfg.max_output {
(-out_pd, 0.0)
} else if out_pd < 0.0 {
(0.0, -out_pd + output_limit)
(0.0, -out_pd + cfg.max_output)
} else {
(-out_pd, output_limit - out_pd)
(-out_pd, cfg.max_output - out_pd)
};
// f32::clamp is not inlining well as of 2024-04 so we do it by hand
// here and below.
Expand All @@ -589,7 +591,7 @@ impl OneSidedPidState {
// Clamp output values to valid range.
let out = out_pd + self.integral;
// same issue with f32::clamp (above)
out.max(0.0).min(output_limit)
out.max(cfg.min_output).min(cfg.max_output)
}
}

Expand Down Expand Up @@ -1045,7 +1047,6 @@ impl<'a> ThermalControl<'a> {
let pwm = pid.run(
&self.pid_config,
self.target_margin.0 - worst_margin,
100.0,
);
self.state = ThermalControlState::Running {
values: values.map(Option::unwrap),
Expand Down Expand Up @@ -1104,7 +1105,6 @@ impl<'a> ThermalControl<'a> {
let pwm = pid.run(
&self.pid_config,
self.target_margin.0 - worst_margin,
100.0,
);
ControlResult::Pwm(PWMDuty(pwm as u8))
}
Expand Down Expand Up @@ -1139,7 +1139,6 @@ impl<'a> ThermalControl<'a> {
let pwm = pid.run(
&self.pid_config,
self.target_margin.0 - worst_margin,
100.0,
);
self.state = ThermalControlState::Running {
values: *values,
Expand Down

0 comments on commit b6e4a37

Please sign in to comment.