forked from M-Labs/thermostat
switch pid+steinhart_hart parameters from f32 to f64
This commit is contained in:
parent
1ad821299b
commit
0f4442b124
|
@ -1,4 +1,5 @@
|
|||
use core::fmt;
|
||||
use lexical_core::Float;
|
||||
use stm32f4xx_hal::{
|
||||
time::{MegaHertz, U32Ext},
|
||||
spi,
|
||||
|
@ -146,18 +147,9 @@ impl PostFilter {
|
|||
];
|
||||
|
||||
pub fn closest(rate: f32) -> Option<Self> {
|
||||
/// (x - y).abs()
|
||||
fn d(x: f32, y: f32) -> f32 {
|
||||
if x >= y {
|
||||
x - y
|
||||
} else {
|
||||
y - x
|
||||
}
|
||||
}
|
||||
|
||||
let mut best: Option<(f32, Self)> = None;
|
||||
for value in Self::VALID_VALUES {
|
||||
let error = d(rate, value.output_rate().unwrap());
|
||||
let error = (rate - value.output_rate().unwrap()).abs();
|
||||
let better = best
|
||||
.map(|(best_error, _)| error < best_error)
|
||||
.unwrap_or(true);
|
||||
|
|
|
@ -123,12 +123,12 @@ pub enum Command {
|
|||
Pid {
|
||||
channel: usize,
|
||||
parameter: PidParameter,
|
||||
value: f32,
|
||||
value: f64,
|
||||
},
|
||||
SteinhartHart {
|
||||
channel: usize,
|
||||
parameter: ShParameter,
|
||||
value: f32,
|
||||
value: f64,
|
||||
},
|
||||
PostFilter {
|
||||
channel: usize,
|
||||
|
@ -158,12 +158,12 @@ fn unsigned(input: &[u8]) -> IResult<&[u8], Result<u16, Error>> {
|
|||
})
|
||||
}
|
||||
|
||||
fn float(input: &[u8]) -> IResult<&[u8], Result<f32, Error>> {
|
||||
fn float(input: &[u8]) -> IResult<&[u8], Result<f64, Error>> {
|
||||
let (input, sign) = opt(is_a("-"))(input)?;
|
||||
let negative = sign.is_some();
|
||||
let (input, digits) = take_while1(|c| is_digit(c) || c == '.' as u8)(input)?;
|
||||
let result = lexical::parse(digits)
|
||||
.map(|result: f32| if negative { -result } else { result })
|
||||
.map(|result: f64| if negative { -result } else { result })
|
||||
.map_err(|e| e.into());
|
||||
Ok((input, result))
|
||||
}
|
||||
|
@ -357,7 +357,8 @@ fn postfilter(input: &[u8]) -> IResult<&[u8], Result<Command, Error>> {
|
|||
let (input, rate) = float(input)?;
|
||||
let result = rate
|
||||
.map(|rate| Command::PostFilter {
|
||||
channel, rate,
|
||||
channel,
|
||||
rate: rate as f32,
|
||||
});
|
||||
Ok((input, result))
|
||||
}
|
||||
|
|
32
src/pid.rs
32
src/pid.rs
|
@ -1,20 +1,20 @@
|
|||
#[derive(Clone, Copy)]
|
||||
pub struct Parameters {
|
||||
pub kp: f32,
|
||||
pub ki: f32,
|
||||
pub kd: f32,
|
||||
pub output_min: f32,
|
||||
pub output_max: f32,
|
||||
pub integral_min: f32,
|
||||
pub integral_max: f32
|
||||
pub kp: f64,
|
||||
pub ki: f64,
|
||||
pub kd: f64,
|
||||
pub output_min: f64,
|
||||
pub output_max: f64,
|
||||
pub integral_min: f64,
|
||||
pub integral_max: f64
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Controller {
|
||||
parameters: Parameters,
|
||||
target: f32,
|
||||
integral: f32,
|
||||
last_input: Option<f32>
|
||||
target: f64,
|
||||
integral: f64,
|
||||
last_input: Option<f64>
|
||||
}
|
||||
|
||||
impl Controller {
|
||||
|
@ -27,7 +27,7 @@ impl Controller {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn update(&mut self, input: f32) -> f32 {
|
||||
pub fn update(&mut self, input: f64) -> f64 {
|
||||
let error = self.target - input;
|
||||
|
||||
let p = self.parameters.kp * error;
|
||||
|
@ -57,11 +57,11 @@ impl Controller {
|
|||
output
|
||||
}
|
||||
|
||||
pub fn get_target(&self) -> f32 {
|
||||
pub fn get_target(&self) -> f64 {
|
||||
self.target
|
||||
}
|
||||
|
||||
pub fn set_target(&mut self, target: f32) {
|
||||
pub fn set_target(&mut self, target: f64) {
|
||||
self.target = target;
|
||||
}
|
||||
|
||||
|
@ -96,9 +96,9 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn test_controller() {
|
||||
const DEFAULT: f32 = 0.0;
|
||||
const TARGET: f32 = 1234.56;
|
||||
const ERROR: f32 = 0.01;
|
||||
const DEFAULT: f64 = 0.0;
|
||||
const TARGET: f64 = 1234.56;
|
||||
const ERROR: f64 = 0.01;
|
||||
const DELAY: usize = 10;
|
||||
|
||||
let mut pid = Controller::new(PARAMETERS.clone());
|
||||
|
|
|
@ -3,14 +3,14 @@ use lexical_core::Float;
|
|||
/// Steinhart-Hart equation parameters
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Parameters {
|
||||
pub a: f32,
|
||||
pub b: f32,
|
||||
pub c: f32,
|
||||
pub a: f64,
|
||||
pub b: f64,
|
||||
pub c: f64,
|
||||
/// Parallel resistance
|
||||
///
|
||||
/// Not truly part of the equation but required to calculate
|
||||
/// resistance from voltage.
|
||||
pub parallel_r: f32,
|
||||
pub parallel_r: f64,
|
||||
}
|
||||
|
||||
impl Parameters {
|
||||
|
@ -19,7 +19,7 @@ impl Parameters {
|
|||
/// Result unit: Kelvin
|
||||
///
|
||||
/// TODO: verify
|
||||
pub fn get_temperature(&self, voltage: f32) -> f32 {
|
||||
pub fn get_temperature(&self, voltage: f64) -> f64 {
|
||||
let r = self.parallel_r * voltage;
|
||||
let ln_r = r.abs().ln();
|
||||
let inv_temp = self.a +
|
||||
|
|
Loading…
Reference in New Issue