1use std::time::{Duration, SystemTime};
4
5use arci::{nalgebra, BaseVelocity};
6use serde::Deserialize;
7
8pub type Timestamp = chrono::DateTime<chrono::Utc>;
9
10pub fn from_str(lines: &str) -> Result<Vec<TracingLog>, arci::Error> {
11 let mut res = vec![];
12 for line in lines.lines() {
13 let value: serde_json::Value =
14 serde_json::from_str(line).map_err(|e| arci::Error::Other(e.into()))?;
15 if !matches!(value.get("target"), Some(target) if target == "openrr_tracing") {
17 continue;
18 }
19 let Some(fields) = value.get("fields") else {
20 continue;
21 };
22 match fields.get("method") {
23 Some(v) if v == "arci::Localization::current_pose" => {
24 let log: CurrentPoseLog =
25 serde_json::from_value(value).map_err(|e| arci::Error::Other(e.into()))?;
26 res.push(TracingLog::CurrentPose(log));
27 }
28 Some(v) if v == "arci::MotorDriveEffort::set_motor_effort" => {
29 let log: SetMotorEffortLog =
30 serde_json::from_value(value).map_err(|e| arci::Error::Other(e.into()))?;
31 res.push(TracingLog::SetMotorEffort(log));
32 }
33 Some(v) if v == "arci::MotorDriveEffort::get_motor_effort" => {
34 let log: GetMotorEffortLog =
35 serde_json::from_value(value).map_err(|e| arci::Error::Other(e.into()))?;
36 res.push(TracingLog::GetMotorEffort(log));
37 }
38 Some(v) if v == "arci::MotorDrivePosition::set_motor_position" => {
39 let log: SetMotorPositionLog =
40 serde_json::from_value(value).map_err(|e| arci::Error::Other(e.into()))?;
41 res.push(TracingLog::SetMotorPosition(log));
42 }
43 Some(v) if v == "arci::MotorDrivePosition::get_motor_position" => {
44 let log: GetMotorPositionLog =
45 serde_json::from_value(value).map_err(|e| arci::Error::Other(e.into()))?;
46 res.push(TracingLog::GetMotorPosition(log));
47 }
48 Some(v) if v == "arci::MotorDriveVelocity::set_motor_velocity" => {
49 let log: SetMotorVelocityLog =
50 serde_json::from_value(value).map_err(|e| arci::Error::Other(e.into()))?;
51 res.push(TracingLog::SetMotorVelocity(log));
52 }
53 Some(v) if v == "arci::MotorDriveVelocity::get_motor_velocity" => {
54 let log: GetMotorVelocityLog =
55 serde_json::from_value(value).map_err(|e| arci::Error::Other(e.into()))?;
56 res.push(TracingLog::GetMotorVelocity(log));
57 }
58 Some(v) if v == "arci::MoveBase::send_velocity" => {
59 let log: SendVelocityLog =
60 serde_json::from_value(value).map_err(|e| arci::Error::Other(e.into()))?;
61 res.push(TracingLog::SendVelocity(log));
62 }
63 Some(v) if v == "arci::MoveBase::current_velocity" => {
64 let log: CurrentVelocityLog =
65 serde_json::from_value(value).map_err(|e| arci::Error::Other(e.into()))?;
66 res.push(TracingLog::CurrentVelocity(log));
67 }
68 Some(v) if v == "arci::Navigation::send_goal_pose" => {
69 let log: SendGoalPoseLog =
70 serde_json::from_value(value).map_err(|e| arci::Error::Other(e.into()))?;
71 res.push(TracingLog::SendGoalPose(log));
72 }
73 Some(v) if v == "arci::Navigation::cancel" => {
74 let log: NavigationCancelLog =
75 serde_json::from_value(value).map_err(|e| arci::Error::Other(e.into()))?;
76 res.push(TracingLog::NavigationCancel(log));
77 }
78 Some(v) if v == "arci::Speaker::speak" => {
79 let log: SpeakLog =
80 serde_json::from_value(value).map_err(|e| arci::Error::Other(e.into()))?;
81 res.push(TracingLog::Speak(log));
82 }
83 Some(v) if v == "arci::TransformResolver::resolve_transformation" => {
84 let log: ResolveTransformationLog =
85 serde_json::from_value(value).map_err(|e| arci::Error::Other(e.into()))?;
86 res.push(TracingLog::ResolveTransformation(log));
87 }
88 _ => continue, }
90 }
91 Ok(res)
92}
93
94#[derive(Debug)]
95#[non_exhaustive]
96pub enum TracingLog {
97 CurrentPose(CurrentPoseLog),
99
100 SetMotorEffort(SetMotorEffortLog),
102 GetMotorEffort(GetMotorEffortLog),
104
105 SetMotorPosition(SetMotorPositionLog),
107 GetMotorPosition(GetMotorPositionLog),
109
110 SetMotorVelocity(SetMotorVelocityLog),
112 GetMotorVelocity(GetMotorVelocityLog),
114
115 SendVelocity(SendVelocityLog),
117 CurrentVelocity(CurrentVelocityLog),
119
120 SendGoalPose(SendGoalPoseLog),
122 NavigationCancel(NavigationCancelLog),
124
125 Speak(SpeakLog),
127
128 ResolveTransformation(ResolveTransformationLog),
130}
131
132#[derive(Deserialize)]
133struct RawTracingLog<Fields> {
134 timestamp: Timestamp,
135 fields: Fields,
136}
137
138#[derive(Debug)]
142#[non_exhaustive]
143pub struct CurrentPoseLog {
144 pub timestamp: Timestamp,
145 pub frame_id: String,
146 pub pose: arci::Isometry2<f64>,
147}
148
149impl<'de> Deserialize<'de> for CurrentPoseLog {
150 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
151 where
152 D: serde::Deserializer<'de>,
153 {
154 #[derive(Deserialize)]
155 struct Fields {
156 frame_id: String,
157 pose_rotation_re: f64,
158 pose_rotation_im: f64,
159 pose_translation_x: f64,
160 pose_translation_y: f64,
161 }
162 let v = RawTracingLog::<Fields>::deserialize(deserializer)?;
163 Ok(Self {
164 timestamp: v.timestamp,
165 frame_id: v.fields.frame_id,
166 pose: arci::Isometry2::from_parts(
167 nalgebra::Translation2::new(
168 v.fields.pose_translation_x,
169 v.fields.pose_translation_y,
170 ),
171 nalgebra::UnitComplex::from_complex(nalgebra::Complex {
172 re: v.fields.pose_rotation_re,
173 im: v.fields.pose_rotation_im,
174 }),
175 ),
176 })
177 }
178}
179
180#[derive(Debug)]
186#[non_exhaustive]
187pub struct SetMotorEffortLog {
188 pub timestamp: Timestamp,
189 pub effort: f64,
190}
191#[derive(Debug)]
192#[non_exhaustive]
193pub struct GetMotorEffortLog {
194 pub timestamp: Timestamp,
195 pub effort: f64,
196}
197
198#[derive(Deserialize)]
199struct MotorEffortLogFields {
200 effort: f64,
201}
202impl<'de> Deserialize<'de> for SetMotorEffortLog {
203 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
204 where
205 D: serde::Deserializer<'de>,
206 {
207 let v = RawTracingLog::<MotorEffortLogFields>::deserialize(deserializer)?;
208 Ok(Self {
209 timestamp: v.timestamp,
210 effort: v.fields.effort,
211 })
212 }
213}
214impl<'de> Deserialize<'de> for GetMotorEffortLog {
215 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
216 where
217 D: serde::Deserializer<'de>,
218 {
219 let v = RawTracingLog::<MotorEffortLogFields>::deserialize(deserializer)?;
220 Ok(Self {
221 timestamp: v.timestamp,
222 effort: v.fields.effort,
223 })
224 }
225}
226
227#[derive(Debug)]
233#[non_exhaustive]
234pub struct SetMotorPositionLog {
235 pub timestamp: Timestamp,
236 pub position: f64,
237}
238#[derive(Debug)]
239#[non_exhaustive]
240pub struct GetMotorPositionLog {
241 pub timestamp: Timestamp,
242 pub position: f64,
243}
244
245#[derive(Deserialize)]
246struct MotorPositionLogFields {
247 position: f64,
248}
249impl<'de> Deserialize<'de> for SetMotorPositionLog {
250 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
251 where
252 D: serde::Deserializer<'de>,
253 {
254 let v = RawTracingLog::<MotorPositionLogFields>::deserialize(deserializer)?;
255 Ok(Self {
256 timestamp: v.timestamp,
257 position: v.fields.position,
258 })
259 }
260}
261impl<'de> Deserialize<'de> for GetMotorPositionLog {
262 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
263 where
264 D: serde::Deserializer<'de>,
265 {
266 let v = RawTracingLog::<MotorPositionLogFields>::deserialize(deserializer)?;
267 Ok(Self {
268 timestamp: v.timestamp,
269 position: v.fields.position,
270 })
271 }
272}
273
274#[derive(Debug)]
280#[non_exhaustive]
281pub struct SetMotorVelocityLog {
282 pub timestamp: Timestamp,
283 pub velocity: f64,
284}
285#[derive(Debug)]
286#[non_exhaustive]
287pub struct GetMotorVelocityLog {
288 pub timestamp: Timestamp,
289 pub velocity: f64,
290}
291
292#[derive(Deserialize)]
293struct MotorVelocityLogFields {
294 velocity: f64,
295}
296impl<'de> Deserialize<'de> for SetMotorVelocityLog {
297 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
298 where
299 D: serde::Deserializer<'de>,
300 {
301 let v = RawTracingLog::<MotorVelocityLogFields>::deserialize(deserializer)?;
302 Ok(Self {
303 timestamp: v.timestamp,
304 velocity: v.fields.velocity,
305 })
306 }
307}
308impl<'de> Deserialize<'de> for GetMotorVelocityLog {
309 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
310 where
311 D: serde::Deserializer<'de>,
312 {
313 let v = RawTracingLog::<MotorVelocityLogFields>::deserialize(deserializer)?;
314 Ok(Self {
315 timestamp: v.timestamp,
316 velocity: v.fields.velocity,
317 })
318 }
319}
320
321#[derive(Debug)]
327#[non_exhaustive]
328pub struct SendVelocityLog {
329 pub timestamp: Timestamp,
330 pub velocity: BaseVelocity,
331}
332#[derive(Debug)]
333#[non_exhaustive]
334pub struct CurrentVelocityLog {
335 pub timestamp: Timestamp,
336 pub velocity: BaseVelocity,
337}
338
339#[derive(Deserialize)]
340struct VelocityLogFields {
341 velocity_x: f64,
342 velocity_y: f64,
343 velocity_theta: f64,
344}
345impl<'de> Deserialize<'de> for SendVelocityLog {
346 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
347 where
348 D: serde::Deserializer<'de>,
349 {
350 let v = RawTracingLog::<VelocityLogFields>::deserialize(deserializer)?;
351 Ok(Self {
352 timestamp: v.timestamp,
353 velocity: BaseVelocity {
354 x: v.fields.velocity_x,
355 y: v.fields.velocity_y,
356 theta: v.fields.velocity_theta,
357 },
358 })
359 }
360}
361impl<'de> Deserialize<'de> for CurrentVelocityLog {
362 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
363 where
364 D: serde::Deserializer<'de>,
365 {
366 let v = RawTracingLog::<VelocityLogFields>::deserialize(deserializer)?;
367 Ok(Self {
368 timestamp: v.timestamp,
369 velocity: BaseVelocity {
370 x: v.fields.velocity_x,
371 y: v.fields.velocity_y,
372 theta: v.fields.velocity_theta,
373 },
374 })
375 }
376}
377
378#[derive(Debug)]
382#[non_exhaustive]
383pub struct SendGoalPoseLog {
384 pub timestamp: Timestamp,
385 pub goal: arci::Isometry2<f64>,
386 pub frame_id: String,
387 pub timeout: Duration,
388}
389#[derive(Debug)]
390#[non_exhaustive]
391pub struct NavigationCancelLog {
392 pub timestamp: Timestamp,
393}
394
395impl<'de> Deserialize<'de> for SendGoalPoseLog {
396 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
397 where
398 D: serde::Deserializer<'de>,
399 {
400 #[derive(Deserialize)]
401 struct Fields {
402 goal_rotation_re: f64,
403 goal_rotation_im: f64,
404 goal_translation_x: f64,
405 goal_translation_y: f64,
406 frame_id: String,
407 timeout_secs: u64,
408 timeout_nanos: u32,
409 }
410 let v = RawTracingLog::<Fields>::deserialize(deserializer)?;
411 Ok(Self {
412 timestamp: v.timestamp,
413 goal: arci::Isometry2::from_parts(
414 nalgebra::Translation2::new(
415 v.fields.goal_translation_x,
416 v.fields.goal_translation_y,
417 ),
418 nalgebra::UnitComplex::from_complex(nalgebra::Complex {
419 re: v.fields.goal_rotation_re,
420 im: v.fields.goal_rotation_im,
421 }),
422 ),
423 frame_id: v.fields.frame_id,
424 timeout: Duration::new(v.fields.timeout_secs, v.fields.timeout_nanos),
425 })
426 }
427}
428impl<'de> Deserialize<'de> for NavigationCancelLog {
429 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
430 where
431 D: serde::Deserializer<'de>,
432 {
433 #[derive(Deserialize)]
434 struct Fields {}
435 let v = RawTracingLog::<Fields>::deserialize(deserializer)?;
436 Ok(Self {
437 timestamp: v.timestamp,
438 })
439 }
440}
441
442#[derive(Debug)]
446#[non_exhaustive]
447pub struct SpeakLog {
448 pub timestamp: Timestamp,
449 pub message: String,
450}
451
452impl<'de> Deserialize<'de> for SpeakLog {
453 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
454 where
455 D: serde::Deserializer<'de>,
456 {
457 #[derive(Deserialize)]
458 struct Fields {
459 message: String,
460 }
461 let v = RawTracingLog::<Fields>::deserialize(deserializer)?;
462 Ok(Self {
463 timestamp: v.timestamp,
464 message: v.fields.message,
465 })
466 }
467}
468
469#[derive(Debug)]
473#[non_exhaustive]
474pub struct ResolveTransformationLog {
475 pub timestamp: Timestamp,
476 pub from: String,
477 pub to: String,
478 pub time: SystemTime,
479}
480
481impl<'de> Deserialize<'de> for ResolveTransformationLog {
482 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
483 where
484 D: serde::Deserializer<'de>,
485 {
486 #[derive(Deserialize)]
487 struct Fields {
488 from: String,
489 to: String,
490 time_secs: u64,
491 time_nanos: u32,
492 }
493 let v = RawTracingLog::<Fields>::deserialize(deserializer)?;
494 Ok(Self {
495 timestamp: v.timestamp,
496 from: v.fields.from,
497 to: v.fields.to,
498 time: SystemTime::UNIX_EPOCH + Duration::new(v.fields.time_secs, v.fields.time_nanos),
499 })
500 }
501}