owb_core/utils/controllers/
mod.rs1pub mod i2c;
11pub mod leds;
12
13use core::cell::RefCell;
14use serde::{Deserialize, Serialize};
15
16pub use i2c::I2C_CHANNEL;
17pub use leds::LED_CHANNEL;
18
19#[derive(Debug, Serialize, Deserialize)]
20#[serde(tag = "ct", rename_all = "snake_case")] pub enum SystemCommand {
22 I(i2c::I2CCommand),
23 L(leds::LEDCommand),
24}
25
26pub struct SystemController<I2C: 'static> {
27 pub sensors: Option<i2c::I2CDevices<'static, I2C>>,
28 pub robot_dimensions: (f32, f32), }
30impl<I2C> SystemController<I2C>
31where
32 I2C: embedded_hal::i2c::I2c + 'static,
33{
34 pub fn new(
39 i2c_bus: &'static RefCell<I2C>,
40 wheel_radius: Option<f32>,
41 robot_radius: Option<f32>,
42 ) -> Self {
43 let wr = wheel_radius.unwrap_or(0.148f32);
44 let rr = robot_radius.unwrap_or(0.195f32);
45
46 let mut i2c_dev = i2c::I2CDevices::new(i2c_bus, wr, rr);
47
48 let sensors = match i2c_dev.init_devices() {
49 Ok(()) => {
50 let _ = i2c_dev.configure_pwm();
51 i2c_dev.init_imu_data();
52 Some(i2c_dev)
53 }
54 Err(e) => {
55 tracing::warn!("I2C init failed, scanning instead: {:?}", e);
56 i2c_dev.scan_bus();
57 None
58 }
59 };
60
61 SystemController {
62 sensors,
63 robot_dimensions: (wr, rr),
64 }
65 }
66
67 pub async fn i2c_ch(&mut self) -> ! {
72 loop {
73 let i2c_channel = i2c::I2C_CHANNEL.receiver().receive().await;
74 tracing::info!("Received I2C Command: {:?}", i2c_channel);
75 if let Some(devs) = self.sensors.as_mut() {
76 match devs.execute_command(i2c_channel) {
77 Ok(Some((accel, gyro, temp))) => {
78 tracing::info!(?accel, ?gyro, ?temp, "IMU Data Read");
79 }
80 Ok(None) => tracing::info!("I2C command executed successfully"),
81 Err(_) => tracing::error!("I2C command failed"),
82 }
83 } else {
84 tracing::warn!(
85 "I2C command received but devices not initialized: {:?}",
86 i2c_channel
87 );
88 }
89 }
90 }
91}