1use crate::FrameId;
2use chrono::{DateTime, Utc};
3use nalgebra::{Isometry3, Point3, Rotation3, Translation3, UnitQuaternion, Vector3};
4use std::fmt;
5
6#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
8pub struct TransformId {
9 pub parent_frame_id: FrameId,
10 pub child_frame_id: FrameId,
11}
12
13impl TransformId {
14 pub fn new(parent_frame_id: FrameId, child_frame_id: FrameId) -> Self {
15 assert_ne!(
16 parent_frame_id, child_frame_id,
17 "frame_id must be different from child_frame_id"
18 );
19 Self {
20 parent_frame_id,
21 child_frame_id,
22 }
23 }
24}
25
26impl fmt::Display for TransformId {
27 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
28 write!(
29 f,
30 "frame_id={} child_frame_id={}",
31 self.parent_frame_id, self.child_frame_id
32 )
33 }
34}
35
36impl From<(FrameId, FrameId)> for TransformId {
37 fn from((parent_frame_id, child_frame_id): (FrameId, FrameId)) -> Self {
38 Self::new(parent_frame_id, child_frame_id)
39 }
40}
41
42impl From<(&FrameId, &FrameId)> for TransformId {
43 fn from((parent_frame_id, child_frame_id): (&FrameId, &FrameId)) -> Self {
44 Self::new(parent_frame_id.clone(), child_frame_id.clone())
45 }
46}
47
48impl From<(&str, &str)> for TransformId {
49 fn from((parent, child): (&str, &str)) -> Self {
50 TransformId::new(FrameId::from(parent), FrameId::from(child))
51 }
52}
53
54#[derive(Debug, Clone, Copy, PartialEq)]
56pub struct TimedTransform {
57 pub timestamp: DateTime<Utc>,
58 pub transform: Transform,
59}
60
61impl TimedTransform {
62 pub fn new(timestamp: DateTime<Utc>, transform: Transform) -> Self {
63 Self {
64 timestamp,
65 transform,
66 }
67 }
68
69 pub fn from(timestamp: DateTime<Utc>, isometry: Isometry3<f64>) -> Self {
70 Self {
71 timestamp,
72 transform: Transform::from(isometry),
73 }
74 }
75}
76
77#[derive(Debug, Clone, Copy, PartialEq)]
79pub struct Transform {
80 pub translation: Vector3<f64>,
81 pub rotation: UnitQuaternion<f64>,
82}
83
84impl Transform {
85 pub fn new(translation: Vector3<f64>, rotation: UnitQuaternion<f64>) -> Self {
86 Self {
89 translation,
90 rotation,
91 }
92 }
93
94 pub fn from(isometry: Isometry3<f64>) -> Self {
95 Self {
96 translation: isometry.translation.vector,
97 rotation: isometry.rotation,
98 }
99 }
100
101 pub fn translation(&self) -> Translation3<f64> {
102 Translation3::from(self.translation)
103 }
104
105 pub fn rotation(&self) -> Rotation3<f64> {
106 Rotation3::from(self.rotation)
107 }
108
109 pub fn isometry(&self) -> Isometry3<f64> {
110 let translation = self.translation();
111 Isometry3::from_parts(translation, self.rotation)
112 }
113
114 pub fn transform_point(&self, pt: &Point3<f64>) -> Point3<f64> {
115 let rotated_point = self.rotation().transform_point(pt);
116 let _translated_point = self.translation().transform_point(pt);
117 rotated_point
118 }
119}