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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
//! A blazingly fast and efficient coordinate transform library for robotics and computer vision applications.
//!
//! This library provides functionality for managing coordinate transformations between different frames
//! of reference. It supports both synchronous and asynchronous operations through feature flags, making
//! it suitable for both real-time and event-driven applications.
//!
//! If you enable the <code>async</code> feature flag then the registry provides the ability to await for transforms
//! asynchronously. View async specific documentation: <code>cargo doc --open --features async</code>
//!
//! # Architecture
//!
//! The library is organized around three main components:
//!
//! - **Registry**: The main interface for managing transforms
//! - **Buffer**: Internal storage for transforms between specific frames
//! - **Transform**: The core data structure representing spatial transformations
//!
//! # Features
//!
//! - **Transform Interpolation**: Smooth interpolation between transforms at different timestamps
//! - **Transform Chaining**: Automatic computation of transforms between indirectly connected frames
//! - **Thread-safe Operations**: Safe concurrent access to the transform registry
//! - **Time-based Buffer Management**: Automatic cleanup of old transforms
//!
//! # Non-Goals
//!
//! This library intentionally limits its scope to rigid body transformations (translation and rotation)
//! commonly used in robotics and computer vision. The following transformations are explicitly not
//! supported and will not be considered for future implementation:
//!
//! - Scaling transformations
//! - Skew transformations
//! - Perspective transformations
//! - Non-rigid transformations
//! - Affine transformations beyond rigid body motion
//!
//! This decision helps maintain the library's focus on its core purpose: providing fast and efficient
//! rigid body transformations for robotics applications. For more general transformation needs,
//! consider using a computer graphics or linear algebra library instead.
//!
//! # Examples
//!
//! ## Synchronous Usage
//!
//! ```rust
//! # #[cfg(not(feature = "async"))]
//! # async fn example() {
//! use std::time::Duration;
//! use transforms::{
//! geometry::{Quaternion, Transform, Vector3},
//! time::Timestamp,
//! Registry,
//! };
//!
//! let mut registry = Registry::new(Duration::from_secs(60));
//! let timestamp = Timestamp::now();
//!
//! // Create a transform from frame "base" to frame "sensor"
//! let transform = Transform {
//! translation: Vector3::new(1.0, 0.0, 0.0),
//! rotation: Quaternion::identity(),
//! timestamp,
//! parent: "base".into(),
//! child: "sensor".into(),
//! };
//!
//! // Add the transform to the registry
//! registry.add_transform(transform).unwrap();
//!
//! // Retrieve the transform
//! let result = registry.get_transform("base", "sensor", timestamp).unwrap();
//! # }
//! ```
//!
//! ## Asynchronous Usage
//!
//! ```rust
//! # #[cfg(feature = "async")]
//! # async fn example() {
//! use std::time::Duration;
//! use transforms::{
//! geometry::{Quaternion, Transform, Vector3},
//! time::Timestamp,
//! Registry,
//! };
//!
//! let registry = Registry::new(Duration::from_secs(60));
//! let timestamp = Timestamp::now();
//!
//! let transform = Transform {
//! translation: Vector3::new(1.0, 0.0, 0.0),
//! rotation: Quaternion::identity(),
//! timestamp,
//! parent: "base".into(),
//! child: "sensor".into(),
//! };
//!
//! registry.add_transform(transform).await.unwrap();
//!
//! // Wait for transform to become available
//! let result = registry
//! .await_transform("base", "sensor", timestamp)
//! .await
//! .unwrap();
//! # }
//! ```
//!
//! # Transform and Data Transformation
//!
//! The library provides a `Transform` type that represents spatial transformations between different
//! coordinate frames. Transforms follow the common robotics convention where transformations are
//! considered from child to parent frame (e.g., from sensor frame to base frame, or from base frame
//! to map frame).
//!
//! To make your data transformable between different coordinate frames, implement the `Transformable`
//! trait. This allows you to easily transform your data using the transforms stored in the registry.
//!
//! ```rust
//! use transforms::{
//! geometry::{Point, Quaternion, Transform, Vector3},
//! time::Timestamp,
//! Transformable,
//! };
//!
//! // Create a point in the camera frame
//! let mut point = Point {
//! position: Vector3::new(1.0, 0.0, 0.0),
//! orientation: Quaternion::identity(),
//! timestamp: Timestamp::now(),
//! frame: "camera".into(),
//! };
//!
//! // Define transform from camera to base frame
//! 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).unwrap();
//! assert_eq!(point.position.x, 1.0);
//! assert_eq!(point.position.y, 1.0);
//! ```
//!
//! The transform convention follows the common robotics practice where data typically needs to be
//! transformed from specific sensor reference frames "up" to more general frames like the robot's
//! base frame or a global map frame.
//!
//! # Feature Flags
//!
//! - `async`: Enables async support using tokio (disabled by default)
//!
//! # Relationship with ROS2's tf2
//!
//! This library draws inspiration from ROS2's tf2 (Transform Framework 2), a widely-used
//! transform library in the robotics community. While this crate aims to solve the same
//! fundamental problem of transformation tracking, it does so in its own way.
//!
//! ## Similarities with tf2
//!
//! - Maintains relationships between coordinate frames in a tree structure
//! - Buffers transforms over time
//! - Supports transform lookups between arbitrary frames
//! - Handles interpolation between transforms
//!
//! ## Key Differences
//!
//! This library:
//! - Is a pure Rust implementation, not a wrapper around tf2
//! - Makes no attempt to perfectly match the ROS2/tf2 API
//! - Focuses on providing an ergonomic Rust-first experience
//! - Is independent of ROS2's middleware and communication system
//!
//! While the core concepts and functionality align with tf2, this library prioritizes
//! optimal usage for rust software over maintaining API compatibility with ROS2's tf2. Users
//! familiar with tf2 will find the concepts familiar, but the implementation details
//! and API design follow Rust idioms and best practices as best as it can.
//!
//! # Performance Considerations
//!
//! - Transform lookups are optimized for O(log n) time complexity
//! - Automatic cleanup of old transforms prevents unbounded memory growth
//! - Lock-free data structures are used where possible in the async implementation
//!
//! # Safety
//!
//! This crate uses `#![forbid(unsafe_code)]` to ensure memory safety through pure Rust implementations.
extern crate alloc;
pub use Registry;
pub use ;