From 0019db3394725952ae605e6eb8734ffbfa432874 Mon Sep 17 00:00:00 2001 From: "93094049+kraemr@users.noreply.github.com" <93094049+kraemr@users.noreply.github.com> Date: Thu, 29 May 2025 14:02:13 +0200 Subject: [PATCH 1/7] pressure readout is now accurate and shows up in frontend --- server/src/machines/extruder1/screw_speed_controller.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/server/src/machines/extruder1/screw_speed_controller.rs b/server/src/machines/extruder1/screw_speed_controller.rs index 867db6e2..76ecf601 100644 --- a/server/src/machines/extruder1/screw_speed_controller.rs +++ b/server/src/machines/extruder1/screw_speed_controller.rs @@ -142,13 +142,15 @@ impl ScrewSpeedController { Some(normalized) => normalized, None => 0.0, }; - // assuming full scale pressure of 10 bar - let pressure: f64 = normalized as f64 * 10.0; + // assuming full scale pressure of 350 bar, which is the max range of our sensors + let pressure: f64 = normalized as f64 * 350.0; return Pressure::new::(pressure); } pub async fn update(&mut self, now: Instant) { self.inverter.act(now).await; + self.pressure_sensor.act(now).await; + if !self.uses_rpm { let measured_pressure = self.get_pressure(); let error = self.target_pressure - measured_pressure; From 17934bdf08a80d8a0e0249cdbd888943813fdc46 Mon Sep 17 00:00:00 2001 From: "93094049+kraemr@users.noreply.github.com" <93094049+kraemr@users.noreply.github.com> Date: Thu, 29 May 2025 17:58:35 +0200 Subject: [PATCH 2/7] added min_raw max_raw to AnalogInputRange --- ethercat-hal/src/devices/el3001.rs | 2 + ethercat-hal/src/devices/el3021.rs | 2 + ethercat-hal/src/devices/el3024.rs | 2 + ethercat-hal/src/devices/el7031_0030/mod.rs | 4 +- ethercat-hal/src/io/analog_input/physical.rs | 103 +++++++++++-------- ethercat-hal/src/io/analog_input_dummy.rs | 2 + 6 files changed, 72 insertions(+), 43 deletions(-) diff --git a/ethercat-hal/src/devices/el3001.rs b/ethercat-hal/src/devices/el3001.rs index dc5b9c02..5fc230a3 100644 --- a/ethercat-hal/src/devices/el3001.rs +++ b/ethercat-hal/src/devices/el3001.rs @@ -82,6 +82,8 @@ impl AnalogInputDevice for EL3001 { AnalogInputRange::Potential { min: ElectricPotential::new::(-10.0), max: ElectricPotential::new::(10.0), + min_raw: i16::MIN, + max_raw: i16::MAX, } } } diff --git a/ethercat-hal/src/devices/el3021.rs b/ethercat-hal/src/devices/el3021.rs index 46fbc3c7..9ff1450b 100644 --- a/ethercat-hal/src/devices/el3021.rs +++ b/ethercat-hal/src/devices/el3021.rs @@ -107,6 +107,8 @@ impl AnalogInputDevice for EL3021 { AnalogInputRange::Current { min: ElectricCurrent::new::(4.0), max: ElectricCurrent::new::(20.0), + min_raw: 0, + max_raw: i16::MAX, } } } diff --git a/ethercat-hal/src/devices/el3024.rs b/ethercat-hal/src/devices/el3024.rs index 108263b8..880899ab 100644 --- a/ethercat-hal/src/devices/el3024.rs +++ b/ethercat-hal/src/devices/el3024.rs @@ -152,6 +152,8 @@ impl AnalogInputDevice for EL3024 { AnalogInputRange::Current { min: ElectricCurrent::new::(4.0), max: ElectricCurrent::new::(20.0), + min_raw: 0, + max_raw: 32767, } } } diff --git a/ethercat-hal/src/devices/el7031_0030/mod.rs b/ethercat-hal/src/devices/el7031_0030/mod.rs index 10fa2be3..63be93af 100644 --- a/ethercat-hal/src/devices/el7031_0030/mod.rs +++ b/ethercat-hal/src/devices/el7031_0030/mod.rs @@ -304,8 +304,10 @@ impl AnalogInputDevice for EL7031_0030 { fn analog_input_range(&self) -> AnalogInputRange { AnalogInputRange::Potential { - min: ElectricPotential::new::(-10.0), + min: ElectricPotential::new::(0.0), max: ElectricPotential::new::(10.0), + min_raw: 0, + max_raw: i16::MAX, } } } diff --git a/ethercat-hal/src/io/analog_input/physical.rs b/ethercat-hal/src/io/analog_input/physical.rs index 46ace793..1725eb17 100644 --- a/ethercat-hal/src/io/analog_input/physical.rs +++ b/ethercat-hal/src/io/analog_input/physical.rs @@ -11,33 +11,67 @@ pub enum AnalogInputRange { Potential { min: ElectricPotential, max: ElectricPotential, + min_raw: i16, + max_raw: i16, }, Current { min: ElectricCurrent, max: ElectricCurrent, + min_raw: i16, + max_raw: i16, }, } impl AnalogInputRange { - /// Convert a normalized value (-1.0 to 1.0) to a physical value - pub fn normalized_to_physical(&self, normalized: f32) -> AnalogInputValue { - // map -1/1 to 0/1 - let clipped = normalized as f64 / 2.0 + 0.5; + pub fn get_min_raw(&self) -> i16 { + return match self { + AnalogInputRange::Potential { min_raw, .. } => *min_raw, + AnalogInputRange::Current { min_raw, .. } => *min_raw, + }; + } + + pub fn get_max_raw(&self) -> i16 { + return match self { + AnalogInputRange::Potential { max_raw, .. } => *max_raw, + AnalogInputRange::Current { max_raw, .. } => *max_raw, + }; + } + + pub fn raw_to_normalized(&self, raw_value: i16) -> f32 { + let range = (self.get_max_raw() - self.get_min_raw()) as f32; + return (raw_value - self.get_min_raw()) as f32 / range; + } + + pub fn raw_to_physical(&self, raw_value: i16) -> AnalogInputValue { + let normalized = self.raw_to_normalized(raw_value); match self { - AnalogInputRange::Potential { min, max } => { - let value = *min + (*max - *min).abs() * clipped; + AnalogInputRange::Potential { min, max, .. } => { + let value = *min + (*max - *min).abs() * normalized as f64; AnalogInputValue::Potential(value) } - AnalogInputRange::Current { min, max } => { - let value = *min + (*max - *min).abs() * clipped; + AnalogInputRange::Current { min, max, .. } => { + let value = *min + (*max - *min).abs() * normalized as f64; + AnalogInputValue::Current(value) + } + } + } + + /// Convert a normalized value (0 to 1.0) to a physical value + pub fn normalized_to_physical(&self, normalized: f32) -> AnalogInputValue { + match self { + AnalogInputRange::Potential { min, max, .. } => { + let value = *min + (*max - *min).abs() * normalized as f64; + AnalogInputValue::Potential(value) + } + AnalogInputRange::Current { min, max, .. } => { + let value = *min + (*max - *min).abs() * normalized as f64; AnalogInputValue::Current(value) } } } } -// test using AnalogInputRange not AnalogInputGetter #[cfg(test)] mod tests { use core::f64; @@ -53,10 +87,12 @@ mod tests { let analog_input_getter = AnalogInputRange::Potential { min: ElectricPotential::new::(-10.0), max: ElectricPotential::new::(10.0), + min_raw: i16::MIN, + max_raw: i16::MAX, }; - // Check that normalized -1.0 is -10V - let value = analog_input_getter.normalized_to_physical(-1.0); + // 0 raw = -10V + let value = analog_input_getter.raw_to_physical(0); match value { AnalogInputValue::Potential(v) => { assert_relative_eq!(v.get::(), -10.0, epsilon = f64::EPSILON); @@ -64,26 +100,17 @@ mod tests { _ => panic!("Expected a potential value"), } - // Check that normalized 0.0 is 0V - let value = analog_input_getter.normalized_to_physical(0.0); + // 2047 raw ~ 0V + let value = analog_input_getter.raw_to_physical(2047); match value { AnalogInputValue::Potential(v) => { - assert_relative_eq!(v.get::(), 0.0, epsilon = f64::EPSILON); + assert_relative_eq!(v.get::(), 0.0, epsilon = 0.01); } _ => panic!("Expected a potential value"), } - // Check that normalized 0.5 is 5V - let value = analog_input_getter.normalized_to_physical(0.5); - match value { - AnalogInputValue::Potential(v) => { - assert_relative_eq!(v.get::(), 5.0, epsilon = f64::EPSILON); - } - _ => panic!("Expected a potential value"), - } - - // Check that normalized 1.0 is 10V - let value = analog_input_getter.normalized_to_physical(1.0); + // 4095 raw = 10V + let value = analog_input_getter.raw_to_physical(4095); match value { AnalogInputValue::Potential(v) => { assert_relative_eq!(v.get::(), 10.0, epsilon = f64::EPSILON); @@ -93,15 +120,16 @@ mod tests { } #[test] - // 4mA to 20mA fn test_analog_input_getter_current() { let analog_input_getter = AnalogInputRange::Current { min: ElectricCurrent::new::(4.0), max: ElectricCurrent::new::(20.0), + min_raw: 0, + max_raw: i16::MAX, }; - // Check that normalized -1.0 is 4mA - let value = analog_input_getter.normalized_to_physical(-1.0); + // 0 raw = 4mA + let value = analog_input_getter.raw_to_physical(0); match value { AnalogInputValue::Current(v) => { assert_relative_eq!(v.get::(), 4.0, epsilon = f64::EPSILON); @@ -109,26 +137,17 @@ mod tests { _ => panic!("Expected a current value"), } - // Check that normalized 0.0 is 12mA - let value = analog_input_getter.normalized_to_physical(0.0); + // 2047 raw ~ 12mA + let value = analog_input_getter.raw_to_physical(2047); match value { AnalogInputValue::Current(v) => { - assert_relative_eq!(v.get::(), 12.0, epsilon = f64::EPSILON); + assert_relative_eq!(v.get::(), 12.0, epsilon = 0.01); } _ => panic!("Expected a current value"), } - // Check that normalized 0.5 is 16mA - let value = analog_input_getter.normalized_to_physical(0.5); - match value { - AnalogInputValue::Current(v) => { - assert_relative_eq!(v.get::(), 16.0, epsilon = f64::EPSILON); - } - _ => panic!("Expected a current value"), - } - - // Check that normalized 1.0 is 20mA - let value = analog_input_getter.normalized_to_physical(1.0); + // 4095 raw = 20mA + let value = analog_input_getter.raw_to_physical(4095); match value { AnalogInputValue::Current(v) => { assert_relative_eq!(v.get::(), 20.0, epsilon = f64::EPSILON); diff --git a/ethercat-hal/src/io/analog_input_dummy.rs b/ethercat-hal/src/io/analog_input_dummy.rs index 16116918..9c5cd5c5 100644 --- a/ethercat-hal/src/io/analog_input_dummy.rs +++ b/ethercat-hal/src/io/analog_input_dummy.rs @@ -65,6 +65,8 @@ mod tests { let mut dummy = AnalogInputDummy::new(AnalogInputRange::Potential { min: ElectricPotential::new::(0.0), max: ElectricPotential::new::(10.0), + min_raw: 0, + max_raw: i16::MAX, }); let state = AnalogInputState { input: AnalogInputInput { normalized: 0.5 }, From 2c8f1e69894feb082009042d603087ad4ff3a4bc Mon Sep 17 00:00:00 2001 From: "93094049+kraemr@users.noreply.github.com" <93094049+kraemr@users.noreply.github.com> Date: Thu, 29 May 2025 18:12:57 +0200 Subject: [PATCH 3/7] refactored get_pressure --- .../extruder1/screw_speed_controller.rs | 40 ++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/server/src/machines/extruder1/screw_speed_controller.rs b/server/src/machines/extruder1/screw_speed_controller.rs index 76ecf601..c45451ef 100644 --- a/server/src/machines/extruder1/screw_speed_controller.rs +++ b/server/src/machines/extruder1/screw_speed_controller.rs @@ -1,4 +1,4 @@ -use std::time::Instant; +use std::{any, time::Instant}; use control_core::{ actors::{ @@ -8,10 +8,13 @@ use control_core::{ }, controllers::pid::PidController, converters::transmission_converter::TransmissionConverter, + helpers::interpolation::normalize, }; use uom::si::{ angular_velocity::revolution_per_minute, - f64::{AngularVelocity, Frequency, Pressure}, + electric_current::milliampere, + electric_potential::millivolt, + f64::{AngularVelocity, ElectricCurrent, Frequency, Pressure}, frequency::{cycle_per_minute, hertz}, pressure::bar, }; @@ -136,15 +139,34 @@ impl ScrewSpeedController { self.target_pressure } + pub fn get_sensor_current(&self) -> Result { + let phys: ethercat_hal::io::analog_input::physical::AnalogInputValue = self + .pressure_sensor + .get_physical() + .ok_or_else(|| anyhow::anyhow!("no value"))?; + + match phys { + ethercat_hal::io::analog_input::physical::AnalogInputValue::Potential(_) => { + Err(anyhow::anyhow!("Potential is not expected")) + } + ethercat_hal::io::analog_input::physical::AnalogInputValue::Current(quantity) => { + Ok(quantity) + } + } + } + pub fn get_pressure(&mut self) -> Pressure { - let normalized = self.pressure_sensor.get_normalized(); - let normalized = match normalized { - Some(normalized) => normalized, - None => 0.0, + let current_result = self.get_sensor_current(); + let current = match current_result { + Ok(current) => current.get::(), + Err(_) => todo!(), }; - // assuming full scale pressure of 350 bar, which is the max range of our sensors - let pressure: f64 = normalized as f64 * 350.0; - return Pressure::new::(pressure); + let normalized = normalize(current, 4.0, 20.0); + // Our pressure sensor has a range of Up to 350 Bar + + let actual_pressure = (normalized) * 350.0; + + return Pressure::new::(actual_pressure); } pub async fn update(&mut self, now: Instant) { From 5d79eaff5bfd5f124e235c8eaf68c15442d430a7 Mon Sep 17 00:00:00 2001 From: "93094049+kraemr@users.noreply.github.com" <93094049+kraemr@users.noreply.github.com> Date: Thu, 29 May 2025 21:49:44 +0200 Subject: [PATCH 4/7] tests should all compile now --- server/src/machines/winder2/tension_arm.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/server/src/machines/winder2/tension_arm.rs b/server/src/machines/winder2/tension_arm.rs index 0c85d08a..aeb3f571 100644 --- a/server/src/machines/winder2/tension_arm.rs +++ b/server/src/machines/winder2/tension_arm.rs @@ -84,7 +84,7 @@ mod tests { analog_input::{AnalogInputInput, physical::AnalogInputRange}, analog_input_dummy::AnalogInputDummy, }; - use std::time::Instant; + use std::{i16, time::Instant}; #[test] fn volts_to_angle() { @@ -92,6 +92,8 @@ mod tests { AnalogInputDummy::new(AnalogInputRange::Potential { min: ElectricPotential::new::(-10.0), max: ElectricPotential::new::(10.0), + min_raw: i16::MIN, + max_raw: i16::MAX, }) .analog_input(), )); @@ -123,6 +125,8 @@ mod tests { let mut analog_input_dummy = AnalogInputDummy::new(AnalogInputRange::Potential { min: ElectricPotential::new::(-10.0), max: ElectricPotential::new::(10.0), + min_raw: i16::MIN, + max_raw: i16::MAX, }); let analog_input_getter = AnalogInputGetter::new(analog_input_dummy.analog_input()); let mut tension_arm = TensionArm::new(analog_input_getter); @@ -152,6 +156,8 @@ mod tests { let mut analog_input_dummy = AnalogInputDummy::new(AnalogInputRange::Potential { min: ElectricPotential::new::(-10.0), max: ElectricPotential::new::(10.0), + min_raw: i16::MIN, + max_raw: i16::MAX, }); let analog_input = analog_input_dummy.analog_input(); let analog_input_getter = AnalogInputGetter::new(analog_input); From cd9b034ef2fed39ffceefb725ce2d924175ea9e9 Mon Sep 17 00:00:00 2001 From: "93094049+kraemr@users.noreply.github.com" <93094049+kraemr@users.noreply.github.com> Date: Thu, 29 May 2025 21:53:07 +0200 Subject: [PATCH 5/7] now tests should pass again --- server/src/machines/winder2/tension_arm.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/src/machines/winder2/tension_arm.rs b/server/src/machines/winder2/tension_arm.rs index aeb3f571..e618ce11 100644 --- a/server/src/machines/winder2/tension_arm.rs +++ b/server/src/machines/winder2/tension_arm.rs @@ -123,9 +123,9 @@ mod tests { #[test] fn get_volts() { let mut analog_input_dummy = AnalogInputDummy::new(AnalogInputRange::Potential { - min: ElectricPotential::new::(-10.0), + min: ElectricPotential::new::(0.0), max: ElectricPotential::new::(10.0), - min_raw: i16::MIN, + min_raw: 0, max_raw: i16::MAX, }); let analog_input_getter = AnalogInputGetter::new(analog_input_dummy.analog_input()); @@ -154,9 +154,9 @@ mod tests { #[test] fn test_tension_arm() { let mut analog_input_dummy = AnalogInputDummy::new(AnalogInputRange::Potential { - min: ElectricPotential::new::(-10.0), + min: ElectricPotential::new::(0.0), max: ElectricPotential::new::(10.0), - min_raw: i16::MIN, + min_raw: 0, max_raw: i16::MAX, }); let analog_input = analog_input_dummy.analog_input(); From 8f3894f68e4e7e4c2e00639eebde649455659369 Mon Sep 17 00:00:00 2001 From: "93094049+kraemr@users.noreply.github.com" <93094049+kraemr@users.noreply.github.com> Date: Thu, 29 May 2025 22:12:31 +0200 Subject: [PATCH 6/7] now tests should pass --- ethercat-hal/src/io/analog_input/physical.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/ethercat-hal/src/io/analog_input/physical.rs b/ethercat-hal/src/io/analog_input/physical.rs index 1725eb17..ff7082a1 100644 --- a/ethercat-hal/src/io/analog_input/physical.rs +++ b/ethercat-hal/src/io/analog_input/physical.rs @@ -37,14 +37,13 @@ impl AnalogInputRange { }; } - pub fn raw_to_normalized(&self, raw_value: i16) -> f32 { - let range = (self.get_max_raw() - self.get_min_raw()) as f32; - return (raw_value - self.get_min_raw()) as f32 / range; + pub fn raw_to_normalized(&self, raw_value: i16) -> f64 { + let range = (self.get_max_raw() as i32 - self.get_min_raw() as i32) as f64; + return (raw_value as i32 - self.get_min_raw() as i32) as f64 / range; } pub fn raw_to_physical(&self, raw_value: i16) -> AnalogInputValue { let normalized = self.raw_to_normalized(raw_value); - match self { AnalogInputRange::Potential { min, max, .. } => { let value = *min + (*max - *min).abs() * normalized as f64; @@ -92,7 +91,7 @@ mod tests { }; // 0 raw = -10V - let value = analog_input_getter.raw_to_physical(0); + let value = analog_input_getter.raw_to_physical(i16::MIN); match value { AnalogInputValue::Potential(v) => { assert_relative_eq!(v.get::(), -10.0, epsilon = f64::EPSILON); @@ -101,7 +100,7 @@ mod tests { } // 2047 raw ~ 0V - let value = analog_input_getter.raw_to_physical(2047); + let value = analog_input_getter.raw_to_physical(0); match value { AnalogInputValue::Potential(v) => { assert_relative_eq!(v.get::(), 0.0, epsilon = 0.01); @@ -110,7 +109,7 @@ mod tests { } // 4095 raw = 10V - let value = analog_input_getter.raw_to_physical(4095); + let value = analog_input_getter.raw_to_physical(i16::MAX); match value { AnalogInputValue::Potential(v) => { assert_relative_eq!(v.get::(), 10.0, epsilon = f64::EPSILON); @@ -138,7 +137,7 @@ mod tests { } // 2047 raw ~ 12mA - let value = analog_input_getter.raw_to_physical(2047); + let value = analog_input_getter.raw_to_physical(i16::MAX / 2); match value { AnalogInputValue::Current(v) => { assert_relative_eq!(v.get::(), 12.0, epsilon = 0.01); @@ -147,7 +146,7 @@ mod tests { } // 4095 raw = 20mA - let value = analog_input_getter.raw_to_physical(4095); + let value = analog_input_getter.raw_to_physical(i16::MAX); match value { AnalogInputValue::Current(v) => { assert_relative_eq!(v.get::(), 20.0, epsilon = f64::EPSILON); From eba54a4acbf4fc3f2eeb0f002d08b1656724a748 Mon Sep 17 00:00:00 2001 From: "93094049+kraemr@users.noreply.github.com" <93094049+kraemr@users.noreply.github.com> Date: Tue, 3 Jun 2025 15:45:33 +0200 Subject: [PATCH 7/7] fixed comments --- ethercat-hal/src/io/analog_input/physical.rs | 10 +++++----- server/src/machines/winder2/tension_arm.rs | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ethercat-hal/src/io/analog_input/physical.rs b/ethercat-hal/src/io/analog_input/physical.rs index ff7082a1..7bfb4ec8 100644 --- a/ethercat-hal/src/io/analog_input/physical.rs +++ b/ethercat-hal/src/io/analog_input/physical.rs @@ -90,7 +90,7 @@ mod tests { max_raw: i16::MAX, }; - // 0 raw = -10V + // -32768 raw = -10V let value = analog_input_getter.raw_to_physical(i16::MIN); match value { AnalogInputValue::Potential(v) => { @@ -99,7 +99,7 @@ mod tests { _ => panic!("Expected a potential value"), } - // 2047 raw ~ 0V + // 0 raw ~ 0V let value = analog_input_getter.raw_to_physical(0); match value { AnalogInputValue::Potential(v) => { @@ -108,7 +108,7 @@ mod tests { _ => panic!("Expected a potential value"), } - // 4095 raw = 10V + // 32767 raw = 10V let value = analog_input_getter.raw_to_physical(i16::MAX); match value { AnalogInputValue::Potential(v) => { @@ -136,7 +136,7 @@ mod tests { _ => panic!("Expected a current value"), } - // 2047 raw ~ 12mA + // 16383 raw ~ 12mA let value = analog_input_getter.raw_to_physical(i16::MAX / 2); match value { AnalogInputValue::Current(v) => { @@ -145,7 +145,7 @@ mod tests { _ => panic!("Expected a current value"), } - // 4095 raw = 20mA + // 32767 raw = 20mA let value = analog_input_getter.raw_to_physical(i16::MAX); match value { AnalogInputValue::Current(v) => { diff --git a/server/src/machines/winder2/tension_arm.rs b/server/src/machines/winder2/tension_arm.rs index e618ce11..db51207a 100644 --- a/server/src/machines/winder2/tension_arm.rs +++ b/server/src/machines/winder2/tension_arm.rs @@ -90,9 +90,9 @@ mod tests { fn volts_to_angle() { let tension_arm = TensionArm::new(AnalogInputGetter::new( AnalogInputDummy::new(AnalogInputRange::Potential { - min: ElectricPotential::new::(-10.0), + min: ElectricPotential::new::(0.0), max: ElectricPotential::new::(10.0), - min_raw: i16::MIN, + min_raw: 0, max_raw: i16::MAX, }) .analog_input(),