robot_description_builder/joint/joint_data/
calibration_data.rs

1#[cfg(feature = "xml")]
2use quick_xml::{events::attributes::Attribute, name::QName};
3
4#[derive(Debug, PartialEq, Clone, Copy, Default)]
5// TODO: DOC
6pub struct CalibrationData {
7	pub rising: Option<f32>,
8	pub falling: Option<f32>,
9}
10
11impl CalibrationData {
12	/// A function to check if any of the fields are set.
13	///
14	/// It doesn't check if the some fields have the default value, since it can be format depended.
15	///
16	/// ## Example
17	///
18	/// ```
19	/// # use robot_description_builder::joint_data::CalibrationData;
20	/// assert!(CalibrationData {
21	///     rising: Some(1.),
22	///     falling: Some(2.)
23	/// }
24	/// .contains_some());
25	///
26	/// assert!(CalibrationData {
27	///     rising: Some(1.),
28	///     ..Default::default()
29	/// }
30	/// .contains_some());
31	///
32	/// assert!(CalibrationData {
33	///     falling: Some(2.),
34	///     ..Default::default()
35	/// }
36	/// .contains_some());
37	///
38	/// assert!(!CalibrationData::default().contains_some())
39	/// ```
40	pub fn contains_some(&self) -> bool {
41		self.rising.is_some() || self.falling.is_some()
42	}
43}
44
45#[cfg(feature = "urdf")]
46impl crate::to_rdf::to_urdf::ToURDF for CalibrationData {
47	fn to_urdf(
48		&self,
49		writer: &mut quick_xml::Writer<std::io::Cursor<Vec<u8>>>,
50		_urdf_config: &crate::to_rdf::to_urdf::URDFConfig,
51	) -> Result<(), quick_xml::Error> {
52		if self.contains_some() {
53			let mut element = writer.create_element("calibration");
54
55			if let Some(rising) = self.rising {
56				element = element.with_attribute(Attribute {
57					key: QName(b"rising"),
58					value: rising.to_string().as_bytes().into(),
59				});
60			}
61
62			if let Some(falling) = self.falling {
63				element = element.with_attribute(Attribute {
64					key: QName(b"falling"),
65					value: falling.to_string().as_bytes().into(),
66				});
67			}
68
69			element.write_empty()?;
70		}
71
72		Ok(())
73	}
74}
75
76#[cfg(test)]
77mod tests {
78	use crate::joint::joint_data::calibration_data::CalibrationData;
79	use test_log::test;
80
81	#[test]
82	fn contains_some() {
83		assert!(CalibrationData {
84			rising: Some(1.),
85			falling: Some(2.)
86		}
87		.contains_some());
88
89		assert!(CalibrationData {
90			rising: Some(1.),
91			..Default::default()
92		}
93		.contains_some());
94
95		assert!(CalibrationData {
96			falling: Some(2.),
97			..Default::default()
98		}
99		.contains_some());
100
101		assert!(!CalibrationData::default().contains_some())
102	}
103
104	#[cfg(feature = "urdf")]
105	mod to_urdf {
106		use std::io::Seek;
107
108		use super::{test, CalibrationData};
109		use crate::to_rdf::to_urdf::{ToURDF, URDFConfig};
110
111		fn test_to_urdf_calibration(
112			calibration_data: CalibrationData,
113			result: String,
114			urdf_config: &URDFConfig,
115		) {
116			let mut writer = quick_xml::Writer::new(std::io::Cursor::new(Vec::new()));
117			assert!(calibration_data.to_urdf(&mut writer, urdf_config).is_ok());
118
119			writer.get_mut().rewind().unwrap();
120
121			assert_eq!(
122				std::io::read_to_string(writer.into_inner()).unwrap(),
123				result
124			);
125		}
126
127		#[test]
128		fn empty() {
129			test_to_urdf_calibration(
130				CalibrationData::default(),
131				String::from(r#""#),
132				&URDFConfig::default(),
133			);
134		}
135
136		#[test]
137		fn rising() {
138			test_to_urdf_calibration(
139				CalibrationData {
140					rising: Some(1000.),
141					..Default::default()
142				},
143				String::from(r#"<calibration rising="1000"/>"#),
144				&URDFConfig::default(),
145			);
146
147			test_to_urdf_calibration(
148				CalibrationData {
149					rising: Some(0.02),
150					..Default::default()
151				},
152				String::from(r#"<calibration rising="0.02"/>"#),
153				&URDFConfig::default(),
154			);
155
156			test_to_urdf_calibration(
157				CalibrationData {
158					rising: Some(-9e-6),
159					..Default::default()
160				},
161				String::from(r#"<calibration rising="-0.000009"/>"#),
162				&URDFConfig::default(),
163			);
164		}
165
166		#[test]
167		fn falling() {
168			test_to_urdf_calibration(
169				CalibrationData {
170					falling: Some(-1000.),
171					..Default::default()
172				},
173				String::from(r#"<calibration falling="-1000"/>"#),
174				&URDFConfig::default(),
175			);
176
177			test_to_urdf_calibration(
178				CalibrationData {
179					falling: Some(-0.02),
180					..Default::default()
181				},
182				String::from(r#"<calibration falling="-0.02"/>"#),
183				&URDFConfig::default(),
184			);
185
186			test_to_urdf_calibration(
187				CalibrationData {
188					falling: Some(9e-6),
189					..Default::default()
190				},
191				String::from(r#"<calibration falling="0.000009"/>"#),
192				&URDFConfig::default(),
193			);
194		}
195
196		#[test]
197		fn rising_falling() {
198			test_to_urdf_calibration(
199				CalibrationData {
200					rising: Some(500.),
201					falling: Some(-1000.),
202				},
203				String::from(r#"<calibration rising="500" falling="-1000"/>"#),
204				&URDFConfig::default(),
205			);
206
207			test_to_urdf_calibration(
208				CalibrationData {
209					rising: Some(2e9),
210					falling: Some(-0.02),
211				},
212				String::from(r#"<calibration rising="2000000000" falling="-0.02"/>"#),
213				&URDFConfig::default(),
214			);
215
216			test_to_urdf_calibration(
217				CalibrationData {
218					rising: Some(-10000.0),
219					falling: Some(9e-6),
220				},
221				String::from(r#"<calibration rising="-10000" falling="0.000009"/>"#),
222				&URDFConfig::default(),
223			);
224		}
225	}
226}