Skip to main content

phoxal_model/simulation/
capability.rs

1//! Canonical simulation facts normalized from a versioned `simulation.yaml`.
2
3#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq)]
4#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)]
5pub enum Capability {
6    Motor(Motor),
7    Encoder(Encoder),
8    Accelerometer(Accelerometer),
9    Gyroscope(Gyroscope),
10    Magnetometer(Magnetometer),
11    Imu(Imu),
12    Gnss(Gnss),
13    Camera(Camera),
14    Depth(Depth),
15    Range(Range),
16    Lidar(Lidar),
17    Mmwave(Mmwave),
18    Microphone(Microphone),
19    Speaker,
20    Battery,
21    Led,
22    EmergencyStop,
23}
24
25impl Capability {
26    #[must_use]
27    pub const fn kind_name(&self) -> &'static str {
28        match self {
29            Self::Motor(_) => "motor",
30            Self::Encoder(_) => "encoder",
31            Self::Accelerometer(_) => "accelerometer",
32            Self::Gyroscope(_) => "gyroscope",
33            Self::Magnetometer(_) => "magnetometer",
34            Self::Imu(_) => "imu",
35            Self::Gnss(_) => "gnss",
36            Self::Camera(_) => "camera",
37            Self::Depth(_) => "depth",
38            Self::Range(_) => "range",
39            Self::Lidar(_) => "lidar",
40            Self::Mmwave(_) => "mmwave",
41            Self::Microphone(_) => "microphone",
42            Self::Speaker => "speaker",
43            Self::Battery => "battery",
44            Self::Led => "led",
45            Self::EmergencyStop => "emergency_stop",
46        }
47    }
48}
49
50#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Eq, Default)]
51#[serde(rename_all = "snake_case")]
52pub enum ActuatorType {
53    #[default]
54    Velocity,
55    Position,
56    Torque,
57}
58
59#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
60#[serde(rename_all = "snake_case")]
61pub enum CameraProjection {
62    Planar,
63    Cylindrical,
64    Spherical,
65}
66
67#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Default)]
68#[serde(deny_unknown_fields)]
69pub struct Motor {
70    pub actuator_type: ActuatorType,
71    pub acceleration_radps2: Option<f64>,
72    pub control_pid: Option<Vec<f64>>,
73    pub sampling_period_torque_hz: Option<f64>,
74}
75
76#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Default)]
77#[serde(deny_unknown_fields)]
78pub struct Encoder {
79    pub sampling_period_hz: f64,
80    pub resolution: Option<f64>,
81    pub noise: Option<f64>,
82}
83
84#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Default)]
85#[serde(deny_unknown_fields)]
86pub struct Accelerometer {
87    pub sampling_period_hz: f64,
88    pub resolution: Option<f64>,
89    pub lookup_table: Option<Vec<Vec<f64>>>,
90}
91
92#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Default)]
93#[serde(deny_unknown_fields)]
94pub struct Gyroscope {
95    pub sampling_period_hz: f64,
96    pub resolution: Option<f64>,
97    pub lookup_table: Option<Vec<Vec<f64>>>,
98}
99
100#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Default)]
101#[serde(deny_unknown_fields)]
102pub struct Magnetometer {
103    pub sampling_period_hz: f64,
104    pub resolution: Option<f64>,
105    pub lookup_table: Option<Vec<Vec<f64>>>,
106}
107
108#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Default)]
109#[serde(deny_unknown_fields)]
110pub struct Imu {
111    pub sampling_period_hz: f64,
112    pub resolution: Option<f64>,
113    pub noise: Option<f64>,
114}
115
116#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Default)]
117#[serde(deny_unknown_fields)]
118pub struct Gnss {
119    pub sampling_period_hz: f64,
120    pub resolution: Option<f64>,
121    pub accuracy: Option<f64>,
122    pub noise_correlation: Option<f64>,
123    pub speed_resolution: Option<f64>,
124    pub speed_noise: Option<f64>,
125}
126
127#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Default)]
128#[serde(deny_unknown_fields)]
129pub struct Camera {
130    pub sampling_period_hz: f64,
131    pub projection: Option<CameraProjection>,
132    pub near: Option<f64>,
133    pub far: Option<f64>,
134    pub exposure: Option<f64>,
135    pub anti_aliasing: Option<bool>,
136    pub ambient_occlusion_radius: Option<f64>,
137    pub bloom_threshold: Option<f64>,
138    pub noise: Option<f64>,
139    pub motion_blur: Option<f64>,
140    pub noise_mask_url: Option<String>,
141}
142
143#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Default)]
144#[serde(deny_unknown_fields)]
145pub struct Depth {
146    pub sampling_period_hz: f64,
147    pub noise: Option<f64>,
148    pub resolution: Option<f64>,
149    pub motion_blur: Option<f64>,
150}
151
152#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Default)]
153#[serde(deny_unknown_fields)]
154pub struct Range {
155    pub sampling_period_hz: f64,
156    pub noise: Option<f64>,
157    pub resolution: Option<f64>,
158}
159
160#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Default)]
161#[serde(deny_unknown_fields)]
162pub struct Lidar {
163    pub sampling_period_hz: f64,
164    pub noise: Option<f64>,
165    pub resolution: Option<f64>,
166}
167
168#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Default)]
169#[serde(deny_unknown_fields)]
170pub struct Mmwave {
171    pub sampling_period_hz: f64,
172    pub noise: Option<f64>,
173    pub resolution: Option<f64>,
174    pub lookup_table: Option<Vec<Vec<f64>>>,
175}
176
177#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Default)]
178#[serde(deny_unknown_fields)]
179pub struct Microphone {
180    pub sampling_period_hz: f64,
181    pub aperture: Option<f64>,
182}