1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use crate::;
/// A trait for types that are localized in a specific coordinate frame at a specific time.
///
/// This trait provides frame and timestamp introspection, enabling automatic transform
/// lookup via [`Registry::get_transform_for`](crate::core::Registry::get_transform_for).
///
/// Separate from [`Transformable`] so that types without frame/timestamp metadata
/// can still implement `Transformable` independently.
///
/// # Examples
///
/// ```
/// use transforms::{
/// geometry::{Point, Quaternion, Vector3},
/// time::Timestamp,
/// Localized,
/// };
///
/// let point = Point {
/// position: Vector3::new(1.0, 0.0, 0.0),
/// orientation: Quaternion::identity(),
/// timestamp: Timestamp::zero(),
/// frame: "camera".into(),
/// };
///
/// assert_eq!(point.frame(), "camera");
/// ```
/// A trait for types that can be transformed between different coordinate frames.
///
/// This trait provides functionality to apply spatial transformations to objects,
/// typically used in robotics and computer vision applications. The transformations
/// follow the common robotics convention where transforms are considered from child
/// to parent frame (e.g., from sensor frame to base frame, or from base frame to
/// map frame).
///
/// # Frame Convention
///
/// In robotics, it's common to transform data from sensor reference frames "up" to
/// base or map reference frames. For example:
/// - A camera's data might need to be transformed from the camera frame to the robot's base frame
/// - Lidar points might need to be transformed from the lidar frame to the map frame
///
/// This trait follows this convention, where transforms are applied from child frame
/// to parent frame. The child frame is typically the more specific/local frame (e.g.,
/// a sensor frame), while the parent frame is typically the more general/global frame
/// (e.g., map or world frame).
///
/// # Examples
///
/// ```
/// use transforms::{
/// geometry::{Point, Quaternion, Transform, Transformable, Vector3},
/// time::Timestamp,
/// };
///
/// let mut point = Point {
/// position: Vector3::new(1.0, 0.0, 0.0),
/// orientation: Quaternion::identity(),
/// timestamp: Timestamp::zero(),
/// frame: "camera".into(),
/// };
///
/// let transform = Transform {
/// translation: Vector3::new(0.0, 1.0, 0.0),
/// rotation: Quaternion::identity(),
/// timestamp: point.timestamp,
/// parent: "base".into(),
/// child: "camera".into(),
/// };
///
/// // Transform the point from camera frame to base frame
/// point
/// .transform(&transform)
/// .expect("Failed to transform point");
/// ```
///
/// # Errors
///
/// Returns `TransformError` if:
/// - The frames are incompatible (transform's child frame doesn't match the object's frame)
/// - The timestamps don't match
/// - Other transform-specific errors occur