Skip to content

Commit

Permalink
thermal: add PID term to apply offset to output values
Browse files Browse the repository at this point in the history
When output value is used as fan duty cycle directly, only positive error
values are meaningful.  This prevents the PID loop from engaging until
the set point is already reached.  By offsetting the output values,
negative errors are meaningful and the PID loop can engage control
during the initial rise toward the set point.
  • Loading branch information
mx-shift committed Oct 31, 2022
1 parent ebe530b commit b568a1d
Show file tree
Hide file tree
Showing 5 changed files with 9 additions and 2 deletions.
1 change: 1 addition & 0 deletions idl/thermal.idol
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ Interface(
),
"set_pid": (
args: {
"z": "f32",
"p": "f32",
"i": "f32",
"d": "f32",
Expand Down
1 change: 1 addition & 0 deletions task/thermal/src/bsp/gimlet_bc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ impl Bsp {
pid_config: PidConfig {
// If we're > 10 degrees from the target temperature, fans
// should be on at full power.
zero: 0.0,
gain_p: 10.0,
gain_i: 0.5,
gain_d: 10.0,
Expand Down
1 change: 1 addition & 0 deletions task/thermal/src/bsp/sidecar_ab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ impl Bsp {
pid_config: PidConfig {
// If we're > 10 degrees from the target temperature, fans
// should be on at full power.
zero: 0.0,
gain_p: 10.0,
gain_i: 0.0,
gain_d: 0.0,
Expand Down
5 changes: 4 additions & 1 deletion task/thermal/src/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ enum TemperatureReading {
/// Configuration for a PID controller
#[derive(Copy, Clone)]
pub struct PidConfig {
pub zero: f32,
pub gain_p: f32,
pub gain_i: f32,
pub gain_d: f32,
Expand Down Expand Up @@ -330,7 +331,7 @@ impl OneSidedPidState {
// Calculate the P+D contribution separately, which is used to clamp the
// integral term.
let pd_contribution = p_contribution + d_contribution;
let out = pd_contribution + self.integral;
let out = cfg.zero + pd_contribution + self.integral;

if out > output_limit {
// Clamp the integral to the maximum value at which it can
Expand Down Expand Up @@ -456,6 +457,7 @@ impl<'a> ThermalControl<'a> {

pub fn set_pid(
&mut self,
z: f32,
p: f32,
i: f32,
d: f32,
Expand All @@ -479,6 +481,7 @@ impl<'a> ThermalControl<'a> {
}
}

self.pid_config.zero = z;
self.pid_config.gain_p = p;
self.pid_config.gain_i = i;
self.pid_config.gain_d = d;
Expand Down
3 changes: 2 additions & 1 deletion task/thermal/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,14 +200,15 @@ impl<'a> idl::InOrderThermalImpl for ServerImpl<'a> {
fn set_pid(
&mut self,
_: &RecvMessage,
z: f32,
p: f32,
i: f32,
d: f32,
) -> Result<(), RequestError<ThermalError>> {
if self.mode != ThermalMode::Auto {
return Err(ThermalError::NotInAutoMode.into());
}
self.control.set_pid(p, i, d)?;
self.control.set_pid(z, p, i, d)?;
Ok(())
}

Expand Down

0 comments on commit b568a1d

Please sign in to comment.