Skip to content

Commit

Permalink
cleanup, code style
Browse files Browse the repository at this point in the history
  • Loading branch information
jordens committed Oct 25, 2024
1 parent 3690f4e commit 58d14db
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 45 deletions.
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ idsp = "0.15.0"
embedded-hal = "0.2.7"
bitbybit = "1.3.2"
arbitrary-int = "1.2.7"
# stabilizer = "0.9.0"
lm75 = "0.2"
bytemuck = { version = "1.19.0", features = [
"derive",
Expand Down Expand Up @@ -86,7 +85,7 @@ incremental = false
opt-level = 3

[profile.release]
opt-level = 3
opt-level = "s"
debug = true
lto = true
codegen-units = 1
Expand Down
18 changes: 10 additions & 8 deletions src/hardware/adc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ pub trait Convert {
fn convert(&self, code: AdcCode) -> f64;
}

/// relative_voltage * gain + offset
/// Relative_voltage * gain + offset
///
/// Use also for RTD
#[derive(Clone, Copy, Debug, Tree)]
pub struct Linear {
/// Units: output
Expand Down Expand Up @@ -180,20 +182,20 @@ pub struct Dt670 {

impl Default for Dt670 {
fn default() -> Self {
Self { v_ref: 5.0.into() }
Self { v_ref: 2.5.into() }
}
}

impl Convert for Dt670 {
fn convert(&self, code: AdcCode) -> f64 {
let voltage = f32::from(code) * *self.v_ref;
const CURVE: &[(f32, f32, f32)] = &super::dt670::CURVE;
let idx = CURVE.partition_point(|&(_t, v, _dvdt)| v < voltage);
CURVE
.get(idx)
.or(CURVE.last())
.map(|&(t, v, dvdt)| (t + (voltage - v) * 1.0e3 / dvdt) as f64)
.unwrap()
// This is clearly simplistic.
// It is discontinuous at LUT jumps due to dvdt precision.
// Should use proper interpolation, there are some crates.
let idx = CURVE.partition_point(|&(_, v, _)| v < voltage);
let (t, v, dvdt) = CURVE.get(idx).or(CURVE.last()).unwrap();
(t + (voltage - v) * 1.0e3 / dvdt) as f64
}
}

Expand Down
33 changes: 16 additions & 17 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use strum::IntoEnumIterator;

use hardware::{
adc::AdcPhy,
adc::{sm::StateMachine, Adc, AdcCode, Sensor},
adc::{sm::StateMachine, Adc, AdcCode, Ntc, Sensor},
adc_internal::AdcInternal,
dac::{Dac, DacCode},
gpio::{Gpio, PoePower},
Expand Down Expand Up @@ -172,8 +172,6 @@ struct Data {

#[rtic::app(device = hal::stm32, peripherals = true, dispatchers=[DCMI, JPEG, SDMMC])]
mod app {
use hardware::adc::Ntc;

use super::*;

#[shared]
Expand Down Expand Up @@ -211,13 +209,14 @@ mod app {
.settings
.thermostat_eem
.input
.as_flattened_mut()
.iter_mut()
.flatten()
.zip(thermostat.adc_input_config.iter_mut().flatten())
.zip(thermostat.adc_input_config.as_flattened().iter())
{
if let Some(mux) = mux {
let r_ref = if mux.is_single_ended() { 5.0e3 } else { 10.0e3 };
*channel = Some(InputChannel {
// This isn't ideal as it confilcts with the default/clear notion of serial-settings.
sensor: Sensor::Ntc(Ntc::new(25.0, 10.0e3, r_ref, 3988.0)).into(),
..Default::default()
});
Expand Down Expand Up @@ -354,16 +353,16 @@ mod app {
if *alarm.armed {
let temperatures = c.shared.temperature.lock(|temp| *temp);
let mut alarms = [[None; 4]; 4];
let mut alarm_state = false;
for phy_i in 0..4 {
for cfg_i in 0..4 {
if let Some(l) = &alarm.temperature_limits[phy_i][cfg_i] {
let a = !(*l[0]..*l[1]).contains(&(temperatures[phy_i][cfg_i] as _));
alarms[phy_i][cfg_i] = Some(a);
alarm_state |= a;
}
}
}
let alarm_state = alarm
.temperature_limits
.as_flattened()
.iter()
.zip(temperatures.as_flattened().iter())
.zip(alarms.as_flattened_mut().iter_mut())
.any(|((l, t), a)| {
*a = l.map(|l| !(*l[0]..*l[1]).contains(&(*t as _)));
a.unwrap_or_default()
});
c.shared
.telemetry
.lock(|telemetry| telemetry.alarm = alarms);
Expand Down Expand Up @@ -416,9 +415,9 @@ mod app {
};
for (t, u) in s
.temperature
.as_flattened_mut()
.iter_mut()
.flatten()
.zip(temperature.iter().flatten())
.zip(temperature.as_flattened().iter())
{
*t = *u as _;
}
Expand Down
52 changes: 34 additions & 18 deletions src/output_channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,39 @@ use num_traits::Float;

#[derive(Copy, Clone, Debug, Tree)]
pub struct Pid {
/// Integral gain
///
/// Units: output/input per second
pub ki: Leaf<f32>,
pub kp: Leaf<f32>, // sign reference for all gains and limits
/// Proportional gain
///
/// Note that this is the sign reference for all gains and limits
///
/// Units: output/input
pub kp: Leaf<f32>,
/// Derivative gain
///
/// Units: output/input*second
pub kd: Leaf<f32>,
/// Integral gain limit
///
/// Units: output/input
pub li: Leaf<f32>,
/// Derivative gain limit
///
/// Units: output/input
pub ld: Leaf<f32>,
/// Setpoint
///
/// Units: input
pub setpoint: Leaf<f32>,
/// Output lower limit
///
/// Units: output
pub min: Leaf<f32>,
/// Output upper limit
///
/// Units: output
pub max: Leaf<f32>,
}

Expand Down Expand Up @@ -100,28 +126,18 @@ pub struct OutputChannel {
/// 0.0 to 4.3
pub voltage_limit: Leaf<f32>,

/// PID/Biquad/IIR filter parameters
///
/// The y limits will be clamped to the maximum output current of +-3 A.
pub pid: Pid,

/// IIR filter parameters.
/// The y limits will be clamped to the maximum output current of +-3 A.
///
/// # Value
/// See [iir::Biquad]
#[tree(skip)]
pub iir: iir::Biquad<f64>,

/// Thermostat input channel weights. Each input temperature of an enabled channel
/// Thermostat input channel weights. Each input of an enabled input channel
/// is multiplied by its weight and the accumulated output is fed into the IIR.
/// The weights will be internally normalized to one (sum of the absolute values)
/// if they are not all zero.
///
/// # Path
/// `weights/<adc>/<channel>`
/// * `<adc> := [0, 1, 2, 3]` specifies which adc to configure.
/// * `<channel>` specifies which channel of an ADC to configure. Only the enabled channels for the specific ADC are available.
///
/// # Value
/// f32
pub weights: Leaf<[[f32; 4]; 4]>,
}

Expand All @@ -141,9 +157,9 @@ impl OutputChannel {
/// compute weighted iir input, iir state and return the new output
pub fn update(&mut self, temperatures: &[[f64; 4]; 4], iir_state: &mut [f64; 4]) -> f64 {
let temperature = temperatures
.as_flattened()
.iter()
.flatten()
.zip(self.weights.iter().flatten())
.zip(self.weights.as_flattened().iter())
.map(|(t, w)| t * *w as f64)
.sum();
let iir = if *self.state == State::On {
Expand Down Expand Up @@ -175,7 +191,7 @@ impl OutputChannel {
// Note: The weights which are not 'None' should always affect an enabled channel and therefore count for normalization.
if divisor != 0.0 {
let n = divisor.recip();
for w in self.weights.iter_mut().flatten() {
for w in self.weights.as_flattened_mut().iter_mut() {
*w *= n;
}
}
Expand Down

0 comments on commit 58d14db

Please sign in to comment.