Skip to content
This repository was archived by the owner on Jul 2, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
75 changes: 34 additions & 41 deletions bno085/src/runtime.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -137,9 +136,9 @@ pub struct Bno085Runtime {
imu: Schedule,
accelerometer: Schedule,
gyroscope: Schedule,
imu_pub: Publisher<Stamped<ImuSample>>,
accelerometer_pub: Publisher<Stamped<AccelerometerSample>>,
gyroscope_pub: Publisher<Stamped<GyroscopeSample>>,
imu_pub: TopicPublisher<ImuSample>,
accelerometer_pub: TopicPublisher<AccelerometerSample>,
gyroscope_pub: TopicPublisher<GyroscopeSample>,
}

#[async_trait::async_trait]
Expand All @@ -160,25 +159,30 @@ impl Runtime for Bno085Runtime {

async fn new(io: &mut Io<Self::Input>, config: Self::Config) -> Result<Self> {
let imu_pub = io
.publisher::<Stamped<ImuSample>>(&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::<Stamped<AccelerometerSample>>(
&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::<Stamped<GyroscopeSample>>(
&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?;

Expand All @@ -200,31 +204,20 @@ impl Runtime for Bno085Runtime {
}

async fn step(&mut self, step: Step, _inputs: RuntimeInputs<Self::Input>) -> 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(())
Expand Down
49 changes: 24 additions & 25 deletions ddsm115/src/runtime.rs
Original file line number Diff line number Diff line change
@@ -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)]
Expand Down Expand Up @@ -95,7 +94,7 @@ impl SampledEncoder {
}

pub enum Input {
Command(Stamped<Command>),
Command(Command),
}

#[derive(Debug)]
Expand Down Expand Up @@ -151,7 +150,7 @@ pub struct Ddsm115Runtime {
actuator_backend: StubActuatorBackend,
encoder_backend: StubEncoderBackend,
encoder_schedule: Option<Schedule>,
encoder_pub: Option<Publisher<Stamped<Sample>>>,
encoder_pub: Option<TopicPublisher<Sample>>,
}

impl Ddsm115Runtime {
Expand Down Expand Up @@ -179,11 +178,12 @@ impl Runtime for Ddsm115Runtime {
}

async fn new(io: &mut Io<Self::Input>, config: Self::Config) -> Result<Self> {
let command_topic = motor::command::path(
&config.actuator_id.component_id,
&config.actuator_id.capability_id,
);
io.subscribe::<Stamped<Command>, _>(&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?;
Expand All @@ -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;
}
}
}
Expand All @@ -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(())
Expand All @@ -246,15 +242,18 @@ fn valid_command(command: &Command) -> bool {
async fn declare_encoder_publisher(
io: &mut Io<Input>,
encoder: Option<&SampledEncoder>,
) -> Result<Option<Publisher<Stamped<Sample>>>> {
) -> Result<Option<TopicPublisher<Sample>>> {
let Some(encoder) = encoder else {
return Ok(None);
};
Ok(Some(
io.publisher::<Stamped<Sample>>(&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?,
))
}
27 changes: 13 additions & 14 deletions vl53l1x/src/runtime.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -91,7 +91,7 @@ pub struct Vl53l1xRuntime {
backend: StubBackend,
default_distance_m: f32,
schedule: Schedule,
range_pub: Publisher<Stamped<Sample>>,
range_pub: TopicPublisher<Sample>,
}

#[async_trait::async_trait]
Expand All @@ -112,10 +112,13 @@ impl Runtime for Vl53l1xRuntime {

async fn new(io: &mut Io<Self::Input>, config: Self::Config) -> Result<Self> {
let range_pub = io
.publisher::<Stamped<Sample>>(&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 {
Expand All @@ -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(())
}
Expand Down
Loading