1use num_traits::Zero;
2use serde::Deserialize;
3use std::str::FromStr;
4
5macro_rules! value_node {
6 ( $name:ident, $t:ty ) => {
7 #[derive(Debug, Deserialize, Default, Clone)]
8 pub struct $name {
9 #[serde(rename = "$value")]
10 pub value: $t,
11 }
12 };
13}
14
15value_node!(Mass, f64);
16value_node!(Ixx, f64);
17value_node!(Ixy, f64);
18value_node!(Ixz, f64);
19value_node!(Iyy, f64);
20value_node!(Iyz, f64);
21value_node!(Izz, f64);
22value_node!(Radius, f64);
23value_node!(Length, f64);
24value_node!(Name, String);
25value_node!(Uri, String);
26value_node!(Damping, f64);
27value_node!(Friction, f64);
28value_node!(Lower, f64);
29value_node!(Upper, f64);
30value_node!(UseParentModelFrame, bool);
31value_node!(Parent, String);
32value_node!(Child, String);
33
34pub fn string_to_array<T, const N: usize>(s: &str) -> Option<[T; N]>
35where
36 T: Zero + FromStr + Copy,
37{
38 let vec = s
39 .split(' ')
40 .filter_map(|x| x.parse::<T>().ok())
41 .collect::<Vec<_>>();
42 if vec.len() != N {
43 return None;
44 }
45 let mut arr = [T::zero(); N];
46 arr.copy_from_slice(&vec);
47 Some(arr)
48}
49
50mod sdf_fvec6 {
51 use serde::{self, Deserialize, Deserializer};
52 pub fn deserialize<'a, D>(deserializer: D) -> Result<[f64; 6], D::Error>
53 where
54 D: Deserializer<'a>,
55 {
56 let s = String::deserialize(deserializer)?;
57 let some_arr = crate::string_to_array::<f64, 6>(&s);
58 if let Some(arr) = some_arr {
59 Ok(arr)
60 } else {
61 return Err(serde::de::Error::custom(format!(
62 "failed to parse float array in {}",
63 s
64 )));
65 }
66 }
67}
68
69mod sdf_fvec3 {
70 use serde::{self, Deserialize, Deserializer};
71 pub fn deserialize<'a, D>(deserializer: D) -> Result<[f64; 3], D::Error>
72 where
73 D: Deserializer<'a>,
74 {
75 let s = String::deserialize(deserializer)?;
76 let some_arr = crate::string_to_array::<f64, 3>(&s);
77 if let Some(arr) = some_arr {
78 Ok(arr)
79 } else {
80 return Err(serde::de::Error::custom(format!(
81 "failed to parse float array in {}",
82 s
83 )));
84 }
85 }
86}
87
88mod sdf_ivec3 {
89 use serde::{self, Deserialize, Deserializer};
90 pub fn deserialize<'a, D>(deserializer: D) -> Result<[u32; 3], D::Error>
91 where
92 D: Deserializer<'a>,
93 {
94 let s = String::deserialize(deserializer)?;
95 let some_arr = crate::string_to_array::<u32, 3>(&s);
96 if let Some(arr) = some_arr {
97 Ok(arr)
98 } else {
99 return Err(serde::de::Error::custom(format!(
100 "failed to parse u32 array in {}",
101 s
102 )));
103 }
104 }
105}
106
107#[derive(Debug, Deserialize, Clone)]
108pub struct Pose {
109 #[serde(rename = "$value", with = "sdf_fvec6")]
110 pub value: [f64; 6],
111}
112
113impl Default for Pose {
114 fn default() -> Pose {
115 Pose { value: [0f64; 6] }
116 }
117}
118
119#[derive(Debug, Deserialize, Clone)]
120pub struct Size {
121 #[serde(rename = "$value", with = "sdf_fvec3")]
122 pub value: [f64; 3],
123}
124
125#[derive(Debug, Deserialize, Clone)]
126pub struct Xyz {
127 #[serde(rename = "$value", with = "sdf_ivec3")]
128 pub value: [u32; 3],
129}
130
131#[derive(Debug, Deserialize, Clone)]
132pub struct Inertia {
133 pub ixx: Ixx,
134 pub ixy: Ixy,
135 pub ixz: Ixz,
136 pub iyy: Iyy,
137 pub iyz: Iyz,
138 pub izz: Izz,
139}
140
141#[derive(Debug, Deserialize, Clone)]
142pub struct Inertial {
143 pub pose: Pose,
144 pub inertia: Inertia,
145 pub mass: Mass,
146}
147
148#[derive(Debug, Deserialize, Clone)]
149#[serde(rename_all = "lowercase")]
150pub enum Geometry {
151 Box { size: Size },
152 Cylinder { radius: Radius, length: Length },
153}
154
155impl Default for Geometry {
156 fn default() -> Geometry {
157 Geometry::Box {
158 size: Size {
159 value: [0.0f64, 0.0, 0.0],
160 },
161 }
162 }
163}
164
165#[derive(Debug, Deserialize, Default, Clone)]
166pub struct Collision {
167 pub name: String,
168 pub pose: Pose,
169 pub geometry: Geometry,
170}
171
172#[derive(Debug, Deserialize, Default, Clone)]
173pub struct Script {
174 pub uri: Uri,
175 pub name: Name,
176}
177
178#[derive(Debug, Deserialize, Default, Clone)]
179pub struct Material {
180 pub script: Script,
181}
182
183#[derive(Debug, Deserialize, Default, Clone)]
184pub struct Visual {
185 pub name: String,
186 pub pose: Pose,
187 pub geometry: Geometry,
188 pub material: Material,
189}
190
191#[derive(Debug, Deserialize, Clone)]
192pub struct Link {
193 #[serde(default)]
194 pub pose: Pose,
195 pub inertial: Option<Inertial>,
196 #[serde(rename = "collision", default)]
197 pub collisions: Vec<Collision>,
198 #[serde(rename = "visual", default)]
199 pub visuals: Vec<Visual>,
200}
201
202#[derive(Debug, Deserialize, Clone)]
203pub struct Dynamics {
204 pub damping: Damping,
205 pub friction: Friction,
206}
207
208#[derive(Debug, Deserialize, Clone)]
209pub struct Limit {
210 pub lower: Lower,
211 pub upper: Upper,
212}
213
214#[derive(Debug, Deserialize, Clone)]
215pub struct Axis {
216 pub dynamics: Dynamics,
217 pub limit: Option<Limit>,
218 pub xyz: Xyz,
219 pub use_parent_model_frame: UseParentModelFrame,
220}
221
222#[derive(Debug, Deserialize, Clone)]
223pub struct Joint {
224 pub name: String,
225 #[serde(rename = "type")]
226 pub joint_type: String,
227 pub parent: Parent,
228 pub child: Child,
229 pub axis: Axis,
230}
231
232#[derive(Debug, Deserialize, Clone)]
233pub struct Model {
234 pub name: String,
235 #[serde(rename = "link", default)]
236 pub links: Vec<Link>,
237 #[serde(rename = "joint", default)]
238 pub joints: Vec<Joint>,
239}