From 57ea81598da094c6846011663f0073e03af4d1ba Mon Sep 17 00:00:00 2001 From: jbernavaprah Date: Thu, 11 Jun 2026 10:37:59 +0200 Subject: [PATCH] feat!: migrate component drivers to phoxal v0.5.0 typed bus Bump phoxal 0.4.0 -> 0.5.0. Drivers now use the fluent two-id component topics (component(id).(cap).()) with plain payloads + at_ns; no Stamped, TypedSchema, or profile_path helpers. bno085 imu/accel/gyro data; ddsm115 motor command (subscribe) + encoder data; vl53l1x range data. Verified: cargo check/build/test --workspace green. Co-Authored-By: Claude Opus 4.8 --- .DS_Store | Bin 0 -> 8196 bytes Cargo.lock | 5 +-- Cargo.toml | 2 +- bno085/src/runtime.rs | 75 +++++++++++++++++++---------------------- ddsm115/src/runtime.rs | 49 +++++++++++++-------------- vl53l1x/src/runtime.rs | 27 +++++++-------- 6 files changed, 75 insertions(+), 83 deletions(-) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..2ccc250d64d3d67aefdcb0b60483bb3d25afb211 GIT binary patch literal 8196 zcmeI1y>Ami5XIkul^DX8BOyf;=o;uiu|g#1j>wbHi0<+bzVANnc*~H z=yiQn#u;}fVN}cqddT{{=JIMb7**7ALkI`~As_^VfDrf>2=JY)M?Lc1x2rM>0U_{T z641|wgqMz~i@A;F(ZR{I0E{)>HiO^U2bi41#ni>zMw7}tZTFyDs&Xxcvguq;w45<@ zF}KmCL)mmFS6R6ZMVac%ON<;UwNYjvAOxxe65g7^ZLDGio00xKSRZ7qR;QnJm{%Xp z9DI2AbN_yMk3rTwQ8QYvoD&~+Ize@)aaG}axVZhKF+4B~O8fW};;O)pefUkGgCR1^<1Q9MH@800O|b5J z`Sy0<%M0tJq$!xhG@*~2Wyqz=&npbjF`HY;d|M=aOcQNX&;|UTow4aY>t!8 zlgSERqD@zA^z|H#I5+Voba?Hv z;T9--Z`Yr`E4Yl{(DD+c5XZ!>T-_QGBjjxVXX&?XZ7*~aU z$VcA)`Zpp&2%I*7v(~_z?*AXe&;L)`rqmY#Lf{V)P_@=_Yl#J1Z(S*+d+mhRGhTXV qU2daE;bhuzM$?Wn9{QABkyp?L4d&^lMwi;1bzduh7cS8 literal 0 HcmV?d00001 diff --git a/Cargo.lock b/Cargo.lock index 32d8163..34edf89 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1925,14 +1925,15 @@ dependencies = [ [[package]] name = "phoxal" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "069b276097c1231660a800e2fc27719cf4cc9d42e0f8928589d96da8db877847" +checksum = "28e98fd325a693585a7ba0db4dfbffa940b913217630bd412c3e82f077f77ce4" dependencies = [ "anyhow", "arc-swap", "async-trait", "clap", + "const_format", "derive-new", "derive_setters", "dotenvy", diff --git a/Cargo.toml b/Cargo.toml index 1dcc16b..acc9031 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ async-trait = "0.1.89" clap = { version = "4.6.1", features = ["derive"] } tokio = { version = "1", features = ["macros", "rt", "rt-multi-thread", "time", "signal", "sync", "fs"] } tracing = "0.1.44" -phoxal = { version = "0.4.0" } +phoxal = { version = "0.5.0" } [workspace.lints.rust] unused = "warn" diff --git a/bno085/src/runtime.rs b/bno085/src/runtime.rs index 7ae2dc1..adfd4d4 100644 --- a/bno085/src/runtime.rs +++ b/bno085/src/runtime.rs @@ -1,15 +1,14 @@ use std::time::Duration; use anyhow::{Result, bail}; -use phoxal::api::component::v1::capability::accelerometer::Sample as AccelerometerSample; -use phoxal::api::component::v1::capability::gyroscope::Sample as GyroscopeSample; -use phoxal::api::component::v1::capability::imu; -use phoxal::api::component::v1::capability::imu::Sample as ImuSample; -use phoxal::bus::pubsub::Stamped; +use phoxal::api::v1::component::capability::accelerometer::Sample as AccelerometerSample; +use phoxal::api::v1::component::capability::gyroscope::Sample as GyroscopeSample; +use phoxal::api::v1::component::capability::imu::Sample as ImuSample; +use phoxal::api::v1::topic; use phoxal::model::component::v1::CapabilityRef; use phoxal::model::component::v1::capability::Capability; use phoxal::runtime::clock::{Schedule, SchedulePolicy, Step}; -use phoxal::runtime::{EmptyArgs, Io, Publisher, RobotRuntimeArgs, Runtime, RuntimeInputs}; +use phoxal::runtime::{EmptyArgs, Io, RobotRuntimeArgs, Runtime, RuntimeInputs, TopicPublisher}; #[derive(Clone)] pub struct Config { @@ -137,9 +136,9 @@ pub struct Bno085Runtime { imu: Schedule, accelerometer: Schedule, gyroscope: Schedule, - imu_pub: Publisher>, - accelerometer_pub: Publisher>, - gyroscope_pub: Publisher>, + imu_pub: TopicPublisher, + accelerometer_pub: TopicPublisher, + gyroscope_pub: TopicPublisher, } #[async_trait::async_trait] @@ -160,25 +159,30 @@ impl Runtime for Bno085Runtime { async fn new(io: &mut Io, config: Self::Config) -> Result { let imu_pub = io - .publisher::>(&imu::path( - &config.imu.capability.component_id, - &config.imu.capability.capability_id, - )) + .publisher_topic( + topic::new() + .v1() + .component(&config.imu.capability.component_id) + .imu(&config.imu.capability.capability_id) + .data(), + ) .await?; let accelerometer_pub = io - .publisher::>( - &phoxal::api::component::v1::capability::default_profile_path( - &config.accelerometer.capability.component_id, - &config.accelerometer.capability.capability_id, - ), + .publisher_topic( + topic::new() + .v1() + .component(&config.accelerometer.capability.component_id) + .accelerometer(&config.accelerometer.capability.capability_id) + .data(), ) .await?; let gyroscope_pub = io - .publisher::>( - &phoxal::api::component::v1::capability::default_profile_path( - &config.gyroscope.capability.component_id, - &config.gyroscope.capability.capability_id, - ), + .publisher_topic( + topic::new() + .v1() + .component(&config.gyroscope.capability.component_id) + .gyroscope(&config.gyroscope.capability.capability_id) + .data(), ) .await?; @@ -200,31 +204,20 @@ impl Runtime for Bno085Runtime { } async fn step(&mut self, step: Step, _inputs: RuntimeInputs) -> Result<()> { + let at_ns = step.tick.time_ns(); if self.imu.due_steps(step.tick.time_ns()) > 0 { - self.imu_pub - .put(&Stamped::new( - step.tick.time_ns(), - ImuSample::new(self.backend.orientation().await?), - )) - .await?; + let sample = ImuSample::new(self.backend.orientation().await?); + self.imu_pub.put(at_ns, &sample).await?; } if self.accelerometer.due_steps(step.tick.time_ns()) > 0 { - self.accelerometer_pub - .put(&Stamped::new( - step.tick.time_ns(), - AccelerometerSample::new(self.backend.accelerometer().await?), - )) - .await?; + let sample = AccelerometerSample::new(self.backend.accelerometer().await?); + self.accelerometer_pub.put(at_ns, &sample).await?; } if self.gyroscope.due_steps(step.tick.time_ns()) > 0 { - self.gyroscope_pub - .put(&Stamped::new( - step.tick.time_ns(), - GyroscopeSample::new(self.backend.gyroscope().await?), - )) - .await?; + let sample = GyroscopeSample::new(self.backend.gyroscope().await?); + self.gyroscope_pub.put(at_ns, &sample).await?; } Ok(()) diff --git a/ddsm115/src/runtime.rs b/ddsm115/src/runtime.rs index 5e9271f..79d90a7 100644 --- a/ddsm115/src/runtime.rs +++ b/ddsm115/src/runtime.rs @@ -1,14 +1,13 @@ use std::time::Duration; use anyhow::{Result, bail}; -use phoxal::api::component::v1::capability::encoder::Sample; -use phoxal::api::component::v1::capability::motor::Command; -use phoxal::api::component::v1::capability::{encoder, motor}; -use phoxal::bus::pubsub::Stamped; +use phoxal::api::v1::component::capability::encoder::Sample; +use phoxal::api::v1::component::capability::motor::Command; +use phoxal::api::v1::topic; use phoxal::model::component::v1::CapabilityRef; use phoxal::model::component::v1::capability::{Capability, MotorCommand}; use phoxal::runtime::clock::{Schedule, SchedulePolicy, Step}; -use phoxal::runtime::{EmptyArgs, Io, Publisher, RobotRuntimeArgs, Runtime, RuntimeInputs}; +use phoxal::runtime::{EmptyArgs, Io, RobotRuntimeArgs, Runtime, RuntimeInputs, TopicPublisher}; use tracing::info; #[derive(Clone)] @@ -95,7 +94,7 @@ impl SampledEncoder { } pub enum Input { - Command(Stamped), + Command(Command), } #[derive(Debug)] @@ -151,7 +150,7 @@ pub struct Ddsm115Runtime { actuator_backend: StubActuatorBackend, encoder_backend: StubEncoderBackend, encoder_schedule: Option, - encoder_pub: Option>>, + encoder_pub: Option>, } impl Ddsm115Runtime { @@ -179,11 +178,12 @@ impl Runtime for Ddsm115Runtime { } async fn new(io: &mut Io, config: Self::Config) -> Result { - let command_topic = motor::command::path( - &config.actuator_id.component_id, - &config.actuator_id.capability_id, - ); - io.subscribe::, _>(&command_topic, Input::Command) + let command_topic = topic::new() + .v1() + .component(&config.actuator_id.component_id) + .motor(&config.actuator_id.capability_id) + .command(); + io.subscribe_topic(command_topic, |received| Input::Command(received.value)) .await?; let encoder_pub = declare_encoder_publisher(io, config.encoder.as_ref()).await?; @@ -206,11 +206,11 @@ impl Runtime for Ddsm115Runtime { for input in inputs { match input { Input::Command(command) => { - if !valid_command(&command.data) { + if !valid_command(&command) { tracing::warn!(actuator_id = %self.actuator_id, "ignored invalid motor command"); continue; } - self.apply_command(command.data).await; + self.apply_command(command).await; } } } @@ -223,12 +223,8 @@ impl Runtime for Ddsm115Runtime { } if let Some(publisher) = &self.encoder_pub { - publisher - .put(&Stamped::new( - step.tick.time_ns(), - Sample::new(self.encoder_backend.read().await?), - )) - .await?; + let sample = Sample::new(self.encoder_backend.read().await?); + publisher.put(step.tick.time_ns(), &sample).await?; } Ok(()) @@ -246,15 +242,18 @@ fn valid_command(command: &Command) -> bool { async fn declare_encoder_publisher( io: &mut Io, encoder: Option<&SampledEncoder>, -) -> Result>>> { +) -> Result>> { let Some(encoder) = encoder else { return Ok(None); }; Ok(Some( - io.publisher::>(&encoder::path( - &encoder.capability.component_id, - &encoder.capability.capability_id, - )) + io.publisher_topic( + topic::new() + .v1() + .component(&encoder.capability.component_id) + .encoder(&encoder.capability.capability_id) + .data(), + ) .await?, )) } diff --git a/vl53l1x/src/runtime.rs b/vl53l1x/src/runtime.rs index 22855e5..4068ac3 100644 --- a/vl53l1x/src/runtime.rs +++ b/vl53l1x/src/runtime.rs @@ -1,10 +1,10 @@ use anyhow::{Result, bail}; -use phoxal::api::component::v1::capability::range::{self, Sample}; -use phoxal::bus::pubsub::Stamped; +use phoxal::api::v1::component::capability::range::Sample; +use phoxal::api::v1::topic; use phoxal::model::component::v1::CapabilityRef; use phoxal::model::component::v1::capability::{Capability, Range as RangeConfig}; use phoxal::runtime::clock::{Schedule, SchedulePolicy, Step}; -use phoxal::runtime::{EmptyArgs, Io, Publisher, RobotRuntimeArgs, Runtime, RuntimeInputs}; +use phoxal::runtime::{EmptyArgs, Io, RobotRuntimeArgs, Runtime, RuntimeInputs, TopicPublisher}; #[derive(Clone)] pub struct Config { @@ -91,7 +91,7 @@ pub struct Vl53l1xRuntime { backend: StubBackend, default_distance_m: f32, schedule: Schedule, - range_pub: Publisher>, + range_pub: TopicPublisher, } #[async_trait::async_trait] @@ -112,10 +112,13 @@ impl Runtime for Vl53l1xRuntime { async fn new(io: &mut Io, config: Self::Config) -> Result { let range_pub = io - .publisher::>(&range::path( - &config.range.capability.component_id, - &config.range.capability.capability_id, - )) + .publisher_topic( + topic::new() + .v1() + .component(&config.range.capability.component_id) + .range(&config.range.capability.capability_id) + .data(), + ) .await?; Ok(Self { @@ -131,12 +134,8 @@ impl Runtime for Vl53l1xRuntime { return Ok(()); } - self.range_pub - .put(&Stamped::new( - step.tick.time_ns(), - Sample::new(self.backend.distance_m(self.default_distance_m).await?), - )) - .await?; + let sample = Sample::new(self.backend.distance_m(self.default_distance_m).await?); + self.range_pub.put(step.tick.time_ns(), &sample).await?; Ok(()) }