pub const SCHEMA_NAME: &str = "phoxal-api-drive/v1";
pub const SCHEMA_VERSION: u32 = 1;
use crate::bus::zenoh::TypedSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct Target {
pub linear_x_mps: f64,
pub angular_z_radps: f64,
}
impl TypedSchema for Target {
const SCHEMA_NAME: &'static str = "runtime/drive/target";
const SCHEMA_VERSION: u32 = 1;
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct State {
pub target: Target,
pub limited_target: Target,
pub actuator_authority: ActuatorAuthority,
pub stop_reason: Option<StopReason>,
}
impl TypedSchema for State {
const SCHEMA_NAME: &'static str = "runtime/drive/state";
const SCHEMA_VERSION: u32 = 1;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ActuatorAuthority {
Active,
Stopped,
Degraded,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum StopReason {
CommandTimedOut,
SafetyStop,
EmergencyStop,
NoTarget,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ActuatorCommands {
pub commands: Vec<ActuatorCommand>,
}
impl TypedSchema for ActuatorCommands {
const SCHEMA_NAME: &'static str = "runtime/drive/debug/actuator_commands";
const SCHEMA_VERSION: u32 = 1;
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ActuatorCommand {
pub component_id: String,
pub capability_id: String,
pub value: f64,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Saturation {
pub requested: Target,
pub limited: Target,
pub reasons: Vec<String>,
}
impl TypedSchema for Saturation {
const SCHEMA_NAME: &'static str = "runtime/drive/debug/saturation";
const SCHEMA_VERSION: u32 = 1;
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Watchdog {
pub target_fresh: bool,
pub reason: Option<String>,
}
impl TypedSchema for Watchdog {
const SCHEMA_NAME: &'static str = "runtime/drive/debug/watchdog";
const SCHEMA_VERSION: u32 = 1;
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Kinematics {
pub profile: String,
pub actuator_commands: Vec<ActuatorCommand>,
}
impl TypedSchema for Kinematics {
const SCHEMA_NAME: &'static str = "runtime/drive/debug/kinematics";
const SCHEMA_VERSION: u32 = 1;
}
crate::bus::topic_leaf! {
pubsub target {
path: "runtime/drive/target",
payload: Target
}
}
crate::bus::topic_leaf! {
pubsub state {
path: "runtime/drive/state",
payload: State
}
}
pub mod debug {
use super::*;
crate::bus::topic_leaf! {
pubsub actuator_commands {
path: "runtime/drive/debug/actuator_commands",
payload: ActuatorCommands
}
}
crate::bus::topic_leaf! {
pubsub saturation {
path: "runtime/drive/debug/saturation",
payload: Saturation
}
}
crate::bus::topic_leaf! {
pubsub watchdog {
path: "runtime/drive/debug/watchdog",
payload: Watchdog
}
}
crate::bus::topic_leaf! {
pubsub kinematics {
path: "runtime/drive/debug/kinematics",
payload: Kinematics
}
}
}
#[cfg(test)]
mod tests {
use crate::bus::zenoh::TypedSchema;
use super::{
ActuatorCommands, Kinematics, SCHEMA_NAME, SCHEMA_VERSION, Saturation, State, Target,
Watchdog,
};
#[test]
fn schema_contracts_do_not_drift() {
assert_eq!(SCHEMA_NAME, "phoxal-api-drive/v1");
assert_eq!(SCHEMA_VERSION, 1);
assert_eq!(Target::SCHEMA_NAME, "runtime/drive/target");
assert_eq!(Target::SCHEMA_VERSION, 1);
assert_eq!(State::SCHEMA_NAME, "runtime/drive/state");
assert_eq!(State::SCHEMA_VERSION, 1);
assert_eq!(
ActuatorCommands::SCHEMA_NAME,
"runtime/drive/debug/actuator_commands"
);
assert_eq!(ActuatorCommands::SCHEMA_VERSION, 1);
assert_eq!(Saturation::SCHEMA_NAME, "runtime/drive/debug/saturation");
assert_eq!(Saturation::SCHEMA_VERSION, 1);
assert_eq!(Watchdog::SCHEMA_NAME, "runtime/drive/debug/watchdog");
assert_eq!(Watchdog::SCHEMA_VERSION, 1);
assert_eq!(Kinematics::SCHEMA_NAME, "runtime/drive/debug/kinematics");
assert_eq!(Kinematics::SCHEMA_VERSION, 1);
}
#[test]
fn topic_paths_are_stable() {
assert_eq!(super::target::path(), "runtime/drive/target");
assert_eq!(super::state::path(), "runtime/drive/state");
assert_eq!(
super::debug::actuator_commands::path(),
"runtime/drive/debug/actuator_commands"
);
assert_eq!(
super::debug::saturation::path(),
"runtime/drive/debug/saturation"
);
assert_eq!(
super::debug::watchdog::path(),
"runtime/drive/debug/watchdog"
);
assert_eq!(
super::debug::kinematics::path(),
"runtime/drive/debug/kinematics"
);
}
}
#[cfg(test)]
mod v1_version_tests {
use super::{SCHEMA_NAME, SCHEMA_VERSION};
#[test]
fn api_contract_version_is_stable() {
assert_eq!(SCHEMA_NAME, "phoxal-api-drive/v1");
assert_eq!(SCHEMA_VERSION, 1);
}
}