diff --git a/micro-rdk-macros/Cargo.toml b/micro-rdk-macros/Cargo.toml index 0b2909343..5b0f3d817 100644 --- a/micro-rdk-macros/Cargo.toml +++ b/micro-rdk-macros/Cargo.toml @@ -9,9 +9,15 @@ edition = "2021" proc-macro = true [dependencies] +proc-macro-crate = "2.0.0" +proc-macro2 = "1.0.67" quote = "1.0.33" syn = "1.0.109" +[dev-dependencies] +anyhow = { version = "1", features = ["backtrace"] } +micro-rdk = { path = "../", features = ["native"] } + [[test]] name = "do-command-tests" -path = "tests/test.rs" \ No newline at end of file +path = "tests/test.rs" diff --git a/micro-rdk-macros/src/lib.rs b/micro-rdk-macros/src/lib.rs index 9e934b16b..eceb2abac 100644 --- a/micro-rdk-macros/src/lib.rs +++ b/micro-rdk-macros/src/lib.rs @@ -1,13 +1,128 @@ +//! Collection of macros useful for implementing traits for various components. NOTE: THESE +//! MACROS WILL NOT WORK PROPERLY IF YOU RENAME THE MICRO-RDK DEPENDENCY USING THE PACKAGE +//! ATTRIBUTE IN CARGO.TOML. +//! +//! DoCommand - trivially implements the DoCommand trait (most component traits require this trait to be +//! satisfied to allow for driver-specific commands that fall outside of the component's API, but most +//! implementations have no real need for it) +//! +//! MovementSensorReadings - provides a default implementation of the Readings trait for implementers +//! of the MovementSensor trait. `get_generic_readings` will return a struct of key-value pairs for every +//! method that is declared supported by `get_properties` +//! +//! PowerSensorReadings - provides a default implementation of the Readings trait for implementers +//! of the PowerSensor trait. `get_generic_readings` will return a struct containing the voltage (in volts), +//! current (in amperes), power (in watts), and whether or not the power supply is AC. +//! +//! # Example using `MovementSensorReadings` +//! +//! ```ignore +//! use std::collections::HashMap; +//! use micro_rdk::common::{ +//! movement_sensor::{MovementSensor, MovementSensorSupportedMethods}, +//! status::Status, +//! }; +//! use micro_rdk::{DoCommand, MovementSensorReadings}; +//! +//! #[derive(DoCommand, MovementSensorReadings)] +//! pub struct MyMovementSensor {} +//! +//! impl MovementSensor for MyMovementSensor { +//! fn get_angular_velocity(&mut self) -> anyhow::Result { +//! anyhow::bail!("unimplemented") +//! } +//! fn get_compass_heading(&mut self) -> anyhow::Result { +//! Ok(25.0) +//! } +//! fn get_linear_acceleration( +//! &mut self, +//! ) -> anyhow::Result { +//! anyhow::bail!("unimplemented") +//! } +//! fn get_linear_velocity(&mut self) -> anyhow::Result { +//! anyhow::bail!("unimplemented") +//! } +//! fn get_position(&mut self) -> anyhow::Result { +//! anyhow::bail!("unimplemented") +//! } +//! fn get_properties(&self) -> MovementSensorSupportedMethods { +//! MovementSensorSupportedMethods { +//! position_supported: false, +//! linear_velocity_supported: false, +//! angular_velocity_supported: false, +//! linear_acceleration_supported: false, +//! compass_heading_supported: false, +//! } +//! } +//! } +//! +//! impl Status for MyMovementSensor { +//! fn get_status(&self) -> anyhow::Result> { +//! Ok(Some(micro_rdk::google::protobuf::Struct { +//! fields: HashMap::new(), +//! })) +//! } +//! } +//! ``` + use proc_macro::TokenStream; +use proc_macro2::Span; +use proc_macro_crate::{crate_name, FoundCrate}; use quote::quote; +use syn::Ident; + +fn get_micro_rdk_crate_ident() -> Ident { + let found_crate = crate_name("micro-rdk").expect("micro-rdk is present in `Cargo.toml`"); + match found_crate { + FoundCrate::Itself => Ident::new("crate", Span::call_site()), + FoundCrate::Name(name) => Ident::new(&name, Span::call_site()), + } +} #[proc_macro_derive(DoCommand)] pub fn impl_do_command_default(input: TokenStream) -> TokenStream { let ast: syn::DeriveInput = syn::parse(input).unwrap(); let name = &ast.ident; let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl(); + + let crate_ident = get_micro_rdk_crate_ident(); let gen = quote! { - impl #impl_generics DoCommand for #name #ty_generics #where_clause {} + impl #impl_generics #crate_ident::common::generic::DoCommand for #name #ty_generics #where_clause {} }; gen.into() } + +#[proc_macro_derive(MovementSensorReadings)] +pub fn impl_readings_for_movement_sensor(input: TokenStream) -> TokenStream { + let ast: syn::DeriveInput = syn::parse(input).unwrap(); + let name = &ast.ident; + let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl(); + + let crate_ident = get_micro_rdk_crate_ident(); + let gen = quote! { + impl #impl_generics #crate_ident::common::sensor::Readings for #name #ty_generics #where_clause { + fn get_generic_readings(&mut self) -> anyhow::Result<#crate_ident::common::sensor::GenericReadingsResult> { + #crate_ident::common::movement_sensor::get_movement_sensor_generic_readings(self) + } + } + }; + gen.into() +} + +#[proc_macro_derive(PowerSensorReadings)] +pub fn impl_readings_for_power_sensor(input: TokenStream) -> TokenStream { + let ast: syn::DeriveInput = syn::parse(input).unwrap(); + let name = &ast.ident; + let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl(); + + let crate_ident = get_micro_rdk_crate_ident(); + let gen = quote! { + impl #impl_generics #crate_ident::common::sensor::Readings for #name #ty_generics #where_clause { + fn get_generic_readings(&mut self) -> anyhow::Result<#crate_ident::common::sensor::GenericReadingsResult> { + #crate_ident::common::power_sensor::get_power_sensor_generic_readings(self) + } + } + }; + + gen.into() +} diff --git a/micro-rdk-macros/tests/test.rs b/micro-rdk-macros/tests/test.rs index 2d0045a94..8d0a532f5 100644 --- a/micro-rdk-macros/tests/test.rs +++ b/micro-rdk-macros/tests/test.rs @@ -1,27 +1,172 @@ -use micro_rdk_macros::DoCommand; +use micro_rdk::common::math_utils::Vector3; +use micro_rdk::common::movement_sensor::{ + GeoPosition, MovementSensor, MovementSensorSupportedMethods, +}; +use micro_rdk::common::power_sensor::{Current, PowerSensor, PowerSupplyType, Voltage}; +use micro_rdk::common::sensor::Readings; +use micro_rdk::common::status::Status; +use micro_rdk::google::protobuf::value::Kind; +use micro_rdk_macros::{DoCommand, MovementSensorReadings, PowerSensorReadings}; +use std::collections::HashMap; -pub trait DoCommand { - fn do_command(&self) -> u8 { - 1 +#[derive(DoCommand)] +struct TestDoCommandStruct {} + +#[derive(DoCommand, MovementSensorReadings)] +struct TestMovementSensor {} + +impl MovementSensor for TestMovementSensor { + fn get_position(&mut self) -> anyhow::Result { + Ok(GeoPosition { + lat: 1.0, + lon: 2.0, + alt: 3.0, + }) + } + + fn get_linear_acceleration(&mut self) -> anyhow::Result { + Ok(Vector3 { + x: 0.0, + y: 1.0, + z: 2.0, + }) + } + + fn get_properties(&self) -> MovementSensorSupportedMethods { + MovementSensorSupportedMethods { + position_supported: true, + linear_acceleration_supported: true, + linear_velocity_supported: false, + angular_velocity_supported: false, + compass_heading_supported: true, + } + } + + fn get_linear_velocity(&mut self) -> anyhow::Result { + anyhow::bail!("unimplemented: movement_sensor_get_linear_velocity") + } + + fn get_angular_velocity(&mut self) -> anyhow::Result { + anyhow::bail!("unimplemented: movement_sensor_get_angular_velocity") + } + + fn get_compass_heading(&mut self) -> anyhow::Result { + Ok(3.5) } } -pub trait TestTrait: DoCommand { - fn test_fn(&self) -> u8; +impl Status for TestMovementSensor { + fn get_status(&self) -> anyhow::Result> { + Ok(Some(micro_rdk::google::protobuf::Struct { + fields: HashMap::new(), + })) + } } -#[derive(DoCommand)] -pub struct TestStruct {} +#[derive(DoCommand, PowerSensorReadings)] +struct TestPowerSensor {} + +impl PowerSensor for TestPowerSensor { + fn get_voltage(&mut self) -> anyhow::Result { + Ok(Voltage { + volts: 5.0, + power_supply_type: PowerSupplyType::AC, + }) + } + + fn get_current(&mut self) -> anyhow::Result { + Ok(Current { + amperes: 6.0, + power_supply_type: PowerSupplyType::AC, + }) + } -impl TestTrait for TestStruct { - fn test_fn(&self) -> u8 { - 2 + fn get_power(&mut self) -> anyhow::Result { + Ok(7.0) + } +} + +impl Status for TestPowerSensor { + fn get_status(&self) -> anyhow::Result> { + Ok(Some(micro_rdk::google::protobuf::Struct { + fields: HashMap::new(), + })) } } #[test] fn do_command_derive() { - let a = TestStruct {}; - assert_eq!(a.do_command(), 1); - assert_eq!(a.test_fn(), 2); + use micro_rdk::common::generic::DoCommand; + let mut a = TestDoCommandStruct {}; + assert!(a.do_command(None).is_err()); +} + +#[test] +fn movement_sensor_readings_derive() { + let mut a = TestMovementSensor {}; + let res = a.get_generic_readings(); + assert!(res.is_ok()); + let res = res.unwrap(); + + // test position + let pos = res.get("position"); + assert!(pos.is_some()); + let pos = &pos.unwrap().kind; + assert!(pos.is_some()); + let pos = pos.as_ref().unwrap(); + if let Kind::StructValue(pos_struct) = pos { + let lat_val = pos_struct.fields.get("lat"); + assert!(lat_val.is_some()); + if let Some(Kind::NumberValue(lat)) = lat_val.unwrap().kind { + assert_eq!(lat, 1.0); + } else { + assert!(false) + } + } else { + assert!(false) + } + + // test acceleration + let acc = res.get("linear_acceleration"); + assert!(acc.is_some()); + let acc = &acc.unwrap().kind; + assert!(acc.is_some()); + let acc = acc.as_ref().unwrap(); + if let Kind::StructValue(acc_struct) = acc { + let y_val = acc_struct.fields.get("y"); + assert!(y_val.is_some()); + if let Some(Kind::NumberValue(y)) = y_val.unwrap().kind { + assert_eq!(y, 1.0); + } else { + assert!(false) + } + } else { + assert!(false) + } +} + +#[test] +fn power_sensor_readings_derive() { + let mut a = TestPowerSensor {}; + let res = a.get_generic_readings(); + assert!(res.is_ok()); + let res = res.unwrap(); + + let volts = res.get("volts"); + assert!(volts.is_some()); + let volts = &volts.unwrap().kind; + assert!(volts.is_some()); + let volts = volts.as_ref().unwrap(); + if let Kind::NumberValue(volts) = volts { + assert_eq!(*volts, 5.0) + } + + let is_ac = res.get("is_ac"); + assert!(is_ac.is_some()); + let is_ac = &is_ac.unwrap().kind; + assert!(is_ac.is_some()); + let is_ac = is_ac.as_ref().unwrap(); + if let Kind::BoolValue(is_ac) = is_ac { + assert!(is_ac) + } } diff --git a/src/common/adxl345.rs b/src/common/adxl345.rs index 9a13067f6..3bfe05cac 100755 --- a/src/common/adxl345.rs +++ b/src/common/adxl345.rs @@ -6,7 +6,6 @@ use crate::google; use super::board::Board; use super::config::ConfigType; -use super::generic::DoCommand; use super::i2c::I2CHandle; use super::movement_sensor::MovementSensorType; use super::registry::{get_board_from_dependencies, ComponentRegistry, Dependency}; @@ -31,7 +30,7 @@ pub(crate) fn register_models(registry: &mut ComponentRegistry) { const READING_START_REGISTER: u8 = 50; const STANDBY_MODE_REGISTER: u8 = 45; -#[derive(DoCommand)] +#[derive(DoCommand, MovementSensorReadings)] pub struct ADXL345 { i2c_handle: I2cHandleType, i2c_address: u8, diff --git a/src/common/gpio_motor.rs b/src/common/gpio_motor.rs index fc9db44fe..8016b6577 100644 --- a/src/common/gpio_motor.rs +++ b/src/common/gpio_motor.rs @@ -49,7 +49,6 @@ use super::config::ConfigType; use super::encoder::{ Encoder, EncoderPositionType, EncoderType, COMPONENT_NAME as EncoderCompName, }; -use super::generic::DoCommand; use super::math_utils::go_for_math; use super::motor::{ Motor, MotorPinType, MotorPinsConfig, MotorSupportedProperties, MotorType, diff --git a/src/common/gpio_servo.rs b/src/common/gpio_servo.rs index 5f7925867..2a930f602 100644 --- a/src/common/gpio_servo.rs +++ b/src/common/gpio_servo.rs @@ -28,7 +28,6 @@ use super::{ actuator::Actuator, board::{Board, BoardType}, config::{AttributeError, ConfigType}, - generic::DoCommand, registry::{get_board_from_dependencies, ComponentRegistry, Dependency}, servo::{Servo, ServoType}, status::Status, diff --git a/src/common/ina.rs b/src/common/ina.rs index fe7e9f45f..21f75343b 100644 --- a/src/common/ina.rs +++ b/src/common/ina.rs @@ -19,7 +19,6 @@ use std::sync::{Arc, Mutex}; use super::{ board::Board, config::ConfigType, - generic::DoCommand, i2c::I2cHandleType, power_sensor::{Current, PowerSensor, PowerSensorType, PowerSupplyType, Voltage}, registry::{get_board_from_dependencies, ComponentRegistry, Dependency}, @@ -119,7 +118,7 @@ impl fmt::Display for Model { } } -#[derive(DoCommand)] +#[derive(DoCommand, PowerSensorReadings)] struct Ina { model: Model, i2c_handle: H, diff --git a/src/common/math_utils.rs b/src/common/math_utils.rs index 109a18896..b4e45860d 100644 --- a/src/common/math_utils.rs +++ b/src/common/math_utils.rs @@ -1,7 +1,10 @@ #![allow(dead_code)] -use crate::proto::common; +use crate::{ + google::protobuf::{value::Kind, Struct, Value}, + proto::common, +}; use anyhow::bail; -use std::time::Duration; +use std::{collections::HashMap, time::Duration}; #[derive(Clone, Copy, Debug, Default)] pub struct Vector3 { @@ -29,6 +32,35 @@ impl From for common::v1::Vector3 { } } } + +impl From for Value { + fn from(value: Vector3) -> Self { + let fields = HashMap::from([ + ( + "x".to_string(), + Value { + kind: Some(Kind::NumberValue(value.x)), + }, + ), + ( + "y".to_string(), + Value { + kind: Some(Kind::NumberValue(value.y)), + }, + ), + ( + "z".to_string(), + Value { + kind: Some(Kind::NumberValue(value.z)), + }, + ), + ]); + Self { + kind: Some(Kind::StructValue(Struct { fields })), + } + } +} + // If revolutions is 0, the returned wait duration will be 0 representing that // the motor should run indefinitely. pub(crate) fn go_for_math( diff --git a/src/common/moisture_sensor.rs b/src/common/moisture_sensor.rs index f6d22977c..e7c6b5292 100644 --- a/src/common/moisture_sensor.rs +++ b/src/common/moisture_sensor.rs @@ -10,7 +10,7 @@ use std::cell::RefCell; use std::collections::HashMap; use std::rc::Rc; -use super::generic::DoCommand; +use super::sensor::Readings; #[derive(DoCommand)] pub struct MoistureSensor { @@ -23,8 +23,10 @@ impl MoistureSensor { } } -impl Sensor for MoistureSensor { - fn get_generic_readings(&self) -> anyhow::Result { +impl Sensor for MoistureSensor {} + +impl Readings for MoistureSensor { + fn get_generic_readings(&mut self) -> anyhow::Result { Ok(self .get_readings()? .into_iter() diff --git a/src/common/movement_sensor.rs b/src/common/movement_sensor.rs index f9c17cf68..0484828c1 100755 --- a/src/common/movement_sensor.rs +++ b/src/common/movement_sensor.rs @@ -3,8 +3,10 @@ use super::config::ConfigType; use super::generic::DoCommand; use super::math_utils::Vector3; use super::registry::{ComponentRegistry, Dependency}; +use super::sensor::{GenericReadingsResult, Readings}; use super::status::Status; use crate::google; +use crate::google::protobuf::{value::Kind, Struct, Value}; use crate::proto::common::v1::GeoPoint; use crate::proto::component::movement_sensor; @@ -54,6 +56,35 @@ pub struct GeoPosition { pub alt: f32, } +impl From for Value { + fn from(value: GeoPosition) -> Self { + let mut fields = HashMap::new(); + fields.insert( + "lat".to_string(), + Value { + kind: Some(google::protobuf::value::Kind::NumberValue(value.lat)), + }, + ); + fields.insert( + "lon".to_string(), + Value { + kind: Some(google::protobuf::value::Kind::NumberValue(value.lon)), + }, + ); + fields.insert( + "alt".to_string(), + Value { + kind: Some(google::protobuf::value::Kind::NumberValue(value.alt as f64)), + }, + ); + Value { + kind: Some(google::protobuf::value::Kind::StructValue(Struct { + fields, + })), + } + } +} + impl From for movement_sensor::v1::GetPositionResponse { fn from(pos: GeoPosition) -> movement_sensor::v1::GetPositionResponse { let pt = GeoPoint { @@ -69,7 +100,7 @@ impl From for movement_sensor::v1::GetPositionResponse { // A trait for implementing a movement sensor component driver. TODO: add // get_orientation and get_accuracy if/when they become supportable. -pub trait MovementSensor: Status + DoCommand { +pub trait MovementSensor: Status + Readings + DoCommand { fn get_position(&mut self) -> anyhow::Result; fn get_linear_velocity(&mut self) -> anyhow::Result; fn get_angular_velocity(&mut self) -> anyhow::Result; @@ -80,7 +111,44 @@ pub trait MovementSensor: Status + DoCommand { pub type MovementSensorType = Arc>; -#[derive(DoCommand)] +pub fn get_movement_sensor_generic_readings( + ms: &mut dyn MovementSensor, +) -> anyhow::Result { + let mut res = std::collections::HashMap::new(); + let supported_methods = ms.get_properties(); + if supported_methods.position_supported { + res.insert("position".to_string(), ms.get_position()?.into()); + } + if supported_methods.linear_velocity_supported { + res.insert( + "linear_velocity".to_string(), + ms.get_linear_velocity()?.into(), + ); + } + if supported_methods.linear_acceleration_supported { + res.insert( + "linear_acceleration".to_string(), + ms.get_linear_acceleration()?.into(), + ); + } + if supported_methods.angular_velocity_supported { + res.insert( + "angular_velocity".to_string(), + ms.get_angular_velocity()?.into(), + ); + } + if supported_methods.compass_heading_supported { + res.insert( + "compass_heading".to_string(), + Value { + kind: Some(Kind::NumberValue(ms.get_compass_heading()?)), + }, + ); + } + Ok(res) +} + +#[derive(DoCommand, MovementSensorReadings)] pub struct FakeMovementSensor { pos: GeoPosition, linear_acc: Vector3, diff --git a/src/common/mpu6050.rs b/src/common/mpu6050.rs index 2b39c53b0..b1c90e3ce 100755 --- a/src/common/mpu6050.rs +++ b/src/common/mpu6050.rs @@ -22,7 +22,6 @@ use crate::google; use super::board::Board; use super::config::ConfigType; -use super::generic::DoCommand; use super::i2c::I2CHandle; use super::movement_sensor::MovementSensorType; use super::registry::{get_board_from_dependencies, ComponentRegistry, Dependency}; @@ -48,7 +47,7 @@ const READING_START_REGISTER: u8 = 59; const STANDBY_MODE_REGISTER: u8 = 107; const MAX_I16: f64 = 32768.0; -#[derive(DoCommand)] +#[derive(DoCommand, MovementSensorReadings)] pub struct MPU6050 { i2c_handle: I2cHandleType, i2c_address: u8, diff --git a/src/common/power_sensor.rs b/src/common/power_sensor.rs index 8c362ae0e..16abcccf9 100644 --- a/src/common/power_sensor.rs +++ b/src/common/power_sensor.rs @@ -1,8 +1,15 @@ use std::sync::{Arc, Mutex}; -use crate::proto::component; +use crate::{ + google::protobuf::{value::Kind, Value}, + proto::component, +}; -use super::{generic::DoCommand, status::Status}; +use super::{ + generic::DoCommand, + sensor::{GenericReadingsResult, Readings}, + status::Status, +}; pub static COMPONENT_NAME: &str = "power_sensor"; @@ -48,7 +55,7 @@ impl From for component::power_sensor::v1::GetCurrentResponse { } } -pub trait PowerSensor: Status + DoCommand { +pub trait PowerSensor: Status + Readings + DoCommand { fn get_voltage(&mut self) -> anyhow::Result; fn get_current(&mut self) -> anyhow::Result; @@ -59,6 +66,45 @@ pub trait PowerSensor: Status + DoCommand { pub type PowerSensorType = Arc>; +pub fn get_power_sensor_generic_readings( + ps: &mut dyn PowerSensor, +) -> anyhow::Result { + let voltage = ps.get_voltage()?; + let current = ps.get_current()?; + let power = ps.get_power()?; + + let res = std::collections::HashMap::from([ + ( + "volts".to_string(), + Value { + kind: Some(Kind::NumberValue(voltage.volts)), + }, + ), + ( + "amps".to_string(), + Value { + kind: Some(Kind::NumberValue(current.amperes)), + }, + ), + ( + "is_ac".to_string(), + Value { + kind: Some(Kind::BoolValue(matches!( + voltage.power_supply_type, + PowerSupplyType::AC + ))), + }, + ), + ( + "watts".to_string(), + Value { + kind: Some(Kind::NumberValue(power)), + }, + ), + ]); + Ok(res) +} + impl

PowerSensor for Mutex

where P: ?Sized + PowerSensor, diff --git a/src/common/registry.rs b/src/common/registry.rs index 5ffafd51d..fcf5f8e24 100755 --- a/src/common/registry.rs +++ b/src/common/registry.rs @@ -435,7 +435,8 @@ mod tests { registry::{ComponentRegistry, Dependency, RegistryError}, robot::LocalRobot, sensor::{ - GenericReadingsResult, Sensor, SensorResult, SensorT, SensorType, TypedReadingsResult, + GenericReadingsResult, Readings, Sensor, SensorResult, SensorT, SensorType, + TypedReadingsResult, }, status::Status, }; @@ -462,8 +463,10 @@ mod tests { } } - impl Sensor for TestSensor { - fn get_generic_readings(&self) -> anyhow::Result { + impl Sensor for TestSensor {} + + impl Readings for TestSensor { + fn get_generic_readings(&mut self) -> anyhow::Result { Ok(self .get_readings()? .into_iter() diff --git a/src/common/robot.rs b/src/common/robot.rs index a006ee9b6..08a943d46 100755 --- a/src/common/robot.rs +++ b/src/common/robot.rs @@ -780,7 +780,7 @@ mod tests { use crate::common::movement_sensor::MovementSensor; use crate::common::registry::ComponentRegistry; use crate::common::robot::{LocalRobot, ResourceMap}; - use crate::common::sensor::Sensor; + use crate::common::sensor::Readings; use crate::google; use crate::google::protobuf::Struct; use crate::proto::app::v1::ComponentConfig; diff --git a/src/common/sensor.rs b/src/common/sensor.rs index b7fd850eb..63a1235a6 100755 --- a/src/common/sensor.rs +++ b/src/common/sensor.rs @@ -26,10 +26,12 @@ pub type GenericReadingsResult = pub type TypedReadingsResult = ::std::collections::HashMap; -pub trait Sensor: Status + DoCommand { - fn get_generic_readings(&self) -> anyhow::Result; +pub trait Readings { + fn get_generic_readings(&mut self) -> anyhow::Result; } +pub trait Sensor: Readings + Status + DoCommand {} + pub type SensorType = Arc>; pub trait SensorT: Sensor { @@ -74,8 +76,10 @@ impl Default for FakeSensor { } } -impl Sensor for FakeSensor { - fn get_generic_readings(&self) -> anyhow::Result { +impl Sensor for FakeSensor {} + +impl Readings for FakeSensor { + fn get_generic_readings(&mut self) -> anyhow::Result { Ok(self .get_readings()? .into_iter() @@ -92,11 +96,24 @@ impl SensorT for FakeSensor { } } -impl Sensor for Mutex +impl Sensor for Mutex where A: ?Sized + Sensor {} + +impl Sensor for Arc> where A: ?Sized + Sensor {} + +impl Readings for Mutex +where + A: ?Sized + Readings, +{ + fn get_generic_readings(&mut self) -> anyhow::Result { + self.get_mut().unwrap().get_generic_readings() + } +} + +impl Readings for Arc> where - A: ?Sized + Sensor, + A: ?Sized + Readings, { - fn get_generic_readings(&self) -> anyhow::Result { + fn get_generic_readings(&mut self) -> anyhow::Result { self.lock().unwrap().get_generic_readings() } } diff --git a/src/esp32/base.rs b/src/esp32/base.rs index 0ac24cda3..35131ef7e 100755 --- a/src/esp32/base.rs +++ b/src/esp32/base.rs @@ -2,7 +2,6 @@ use crate::common::actuator::Actuator; use crate::common::base::{Base, BaseType, COMPONENT_NAME as BaseCompName}; use crate::common::config::ConfigType; -use crate::common::generic::DoCommand; use crate::common::motor::{Motor, MotorType, COMPONENT_NAME as MotorCompName}; use crate::common::registry::{ComponentRegistry, Dependency, ResourceKey}; use crate::common::robot::Resource; diff --git a/src/esp32/board.rs b/src/esp32/board.rs index d807eae67..ca09d1565 100755 --- a/src/esp32/board.rs +++ b/src/esp32/board.rs @@ -15,7 +15,6 @@ use crate::{ board::{Board, BoardType}, config::ConfigType, digital_interrupt::DigitalInterruptConfig, - generic::DoCommand, i2c::I2cHandleType, registry::ComponentRegistry, status::Status, diff --git a/src/esp32/encoder.rs b/src/esp32/encoder.rs index 68527d2a1..7998b60e6 100644 --- a/src/esp32/encoder.rs +++ b/src/esp32/encoder.rs @@ -23,7 +23,6 @@ use crate::common::config::ConfigType; use crate::common::encoder::{ Encoder, EncoderPosition, EncoderPositionType, EncoderSupportedRepresentations, EncoderType, }; -use crate::common::generic::DoCommand; use crate::common::registry::{ComponentRegistry, Dependency}; use crate::common::status::Status; use crate::google; diff --git a/src/esp32/single_encoded_motor.rs b/src/esp32/single_encoded_motor.rs index 59a7c9b78..b469e8f23 100644 --- a/src/esp32/single_encoded_motor.rs +++ b/src/esp32/single_encoded_motor.rs @@ -4,7 +4,6 @@ use crate::common::actuator::Actuator; use crate::common::encoder::{ Direction, Encoder, EncoderPositionType, EncoderSupportedRepresentations, SingleEncoder, }; -use crate::common::generic::DoCommand; use crate::common::motor::{Motor, MotorSupportedProperties, MotorType}; use crate::common::status::Status; use crate::google; diff --git a/src/esp32/single_encoder.rs b/src/esp32/single_encoder.rs index 969944848..ce71da5fb 100644 --- a/src/esp32/single_encoder.rs +++ b/src/esp32/single_encoder.rs @@ -8,7 +8,6 @@ use crate::common::encoder::{ Direction, Encoder, EncoderPosition, EncoderPositionType, EncoderSupportedRepresentations, EncoderType, SingleEncoder, }; -use crate::common::generic::DoCommand; use crate::common::registry::{ComponentRegistry, Dependency}; use crate::google; diff --git a/src/lib.rs b/src/lib.rs index 90adf6502..133e04a27 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,8 @@ pub mod native; pub extern crate micro_rdk_macros; pub use micro_rdk_macros::DoCommand; +pub use micro_rdk_macros::MovementSensorReadings; +pub use micro_rdk_macros::PowerSensorReadings; /// gRPC protobuf utilities, auto-generated pub mod google {