Skip to content

Commit

Permalink
idsp 0.14
Browse files Browse the repository at this point in the history
  • Loading branch information
jordens committed Feb 1, 2024
1 parent e8ed72b commit 6f89dea
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 41 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ num-traits = { version = "0.2", default-features = false, features = ["libm"] }
byteorder = { version = "1", default-features = false }
smlang = "0.6.0"
enum-iterator = "1.5.0"
idsp = "0.9.2"
idsp = "0.14.1"

# Note: Keep in-sync with `py/setup.py`
miniconf = "0.9"
Expand Down
6 changes: 3 additions & 3 deletions py/thermostat/configure_output_ch.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,9 @@ async def configure():
f"/output_channel/{args.channel}/iir",
{
"ba": coefficients,
"y_offset": args.y_offset + forward_gain * args.x_offset,
"y_min": args.y_min,
"y_max": args.y_max,
"u": args.y_offset + forward_gain * args.x_offset,
"min": args.y_min,
"max": args.y_max,
},
)
for i, weight in enumerate(args.input_weights):
Expand Down
23 changes: 12 additions & 11 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ use hardware::{
system_timer::SystemTimer,
OutputChannelIdx,
};
use idsp::iir;
use miniconf::Tree;
use net::{Alarm, NetworkState, NetworkUsers};
use serde::Serialize;
Expand Down Expand Up @@ -134,7 +133,7 @@ mod app {
dac: Dac,
pwm: Pwm,
adc_internal: AdcInternal,
iir_state: [iir::Vec5<f64>; 4],
iir_state: [[f64; 4]; 4],
}

#[init]
Expand Down Expand Up @@ -231,14 +230,16 @@ mod app {
fn settings_update(mut c: settings_update::Context, mut settings: Settings) {
// Limit y_min and y_max values here. Will be incorporated into miniconf response later.
for ch in settings.output_channel.iter_mut() {
ch.iir.y_max = ch
.iir
.y_max
.clamp(-DacCode::MAX_CURRENT as _, DacCode::MAX_CURRENT as _);
ch.iir.y_min = ch
.iir
.y_min
.clamp(-DacCode::MAX_CURRENT as _, DacCode::MAX_CURRENT as _);
ch.iir.set_max(
ch.iir
.max()
.clamp(-DacCode::MAX_CURRENT as _, DacCode::MAX_CURRENT as _),
);
ch.iir.set_min(
ch.iir
.min()
.clamp(-DacCode::MAX_CURRENT as _, DacCode::MAX_CURRENT as _),
);
}

let pwm = c.local.pwm;
Expand Down Expand Up @@ -345,7 +346,7 @@ mod app {
fn process_output_channel(mut c: process_output_channel::Context, output_ch: OutputChannelIdx) {
let idx = output_ch as usize;
let current = (c.shared.settings, c.shared.temperature).lock(|settings, temperature| {
settings.output_channel[idx].update(temperature, &mut c.local.iir_state[idx], false)
settings.output_channel[idx].update(temperature, &mut c.local.iir_state[idx])
});
c.shared
.telemetry
Expand Down
41 changes: 17 additions & 24 deletions src/output_channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub struct OutputChannel {
///
/// # Value
/// See [iir::IIR#tree]
pub iir: iir::IIR<f64>,
pub iir: iir::Biquad<f64>,

/// Thermostat input channel weights. Each input temperature of an enabled channel
/// is multiplied by its weight and the accumulated output is fed into the IIR.
Expand All @@ -55,27 +55,18 @@ impl Default for OutputChannel {
shutdown: true,
hold: false,
voltage_limit: 0.0,
iir: iir::IIR::default(),
iir: iir::Biquad::default(),
weights: [[None; 4]; 4],
}
}
}

// Global "hold" IIR to apply to a channel iir state [x0,x1,x2,y0,y1] when the output should hold.
const IIR_HOLD: iir::IIR<f64> = iir::IIR {
ba: [0., 0., 0., 1., 0.],
y_offset: 0.,
y_min: f64::MIN,
y_max: f64::MAX,
};

impl OutputChannel {
/// compute weighted iir input, iir state and return the new output
pub fn update(
&mut self,
channel_temperatures: &[[f64; 4]; 4],
iir_state: &mut iir::Vec5<f64>,
hold: bool,
iir_state: &mut [f64; 4],
) -> f32 {
let weighted_temperature = channel_temperatures
.iter()
Expand All @@ -85,9 +76,9 @@ impl OutputChannel {
.map(|(t, w)| t * w.unwrap_or(0.) as f64)
.sum();
if self.shutdown || self.hold {
IIR_HOLD.update(iir_state, weighted_temperature, hold) as f32
iir::Biquad::HOLD.update(iir_state, weighted_temperature) as f32
} else {
self.iir.update(iir_state, weighted_temperature, hold) as f32
self.iir.update(iir_state, weighted_temperature) as f32
}
}

Expand All @@ -96,14 +87,16 @@ impl OutputChannel {
/// - Normalization of the weights
/// Returns the current limits.
pub fn finalize_settings(&mut self) -> [f32; 2] {
self.iir.y_max = self
.iir
.y_max
.clamp(-Pwm::MAX_CURRENT_LIMIT, Pwm::MAX_CURRENT_LIMIT);
self.iir.y_min = self
.iir
.y_min
.clamp(-Pwm::MAX_CURRENT_LIMIT, Pwm::MAX_CURRENT_LIMIT);
self.iir.set_max(
self.iir
.max()
.clamp(-Pwm::MAX_CURRENT_LIMIT, Pwm::MAX_CURRENT_LIMIT),
);
self.iir.set_min(
self.iir
.min()
.clamp(-Pwm::MAX_CURRENT_LIMIT, Pwm::MAX_CURRENT_LIMIT),
);
self.voltage_limit = self.voltage_limit.clamp(0.0, Pwm::MAX_VOLTAGE_LIMIT);
let divisor: f32 = self
.weights
Expand All @@ -121,8 +114,8 @@ impl OutputChannel {
[
// [Pwm::MAX_CURRENT_LIMIT] + 5% is still below 100% duty cycle for the PWM limits and therefore OK.
// Might not be OK for a different shunt resistor or different PWM setup.
(self.iir.y_max + 0.05 * Pwm::MAX_CURRENT_LIMIT).max(0.) as f32,
(self.iir.y_min - 0.05 * Pwm::MAX_CURRENT_LIMIT).min(0.) as f32,
(self.iir.max() + 0.05 * Pwm::MAX_CURRENT_LIMIT).max(0.) as f32,
(self.iir.min() - 0.05 * Pwm::MAX_CURRENT_LIMIT).min(0.) as f32,
]
}
}

0 comments on commit 6f89dea

Please sign in to comment.