pub struct Registry<T = Timestamp>where
T: TimePoint,{
pub data: HashMap<String, Buffer<T>>,
/* private fields */
}Expand description
A registry for managing transforms between different frames. It can traverse the parent-child tree and calculate the final transform. It will interpolate between two entries if a time is requested that lies in between.
The Registry struct provides methods to add and retrieve transforms
between frames
§Examples
use transforms::{
geometry::{Quaternion, Transform, Vector3},
time::Timestamp,
Registry,
};
use core::time::Duration;
let mut registry = Registry::new(Duration::from_secs(60));
let t1 = Timestamp::now();
let mut registry = Registry::new();
let t1 = Timestamp::zero();
let t2 = t1.clone();
// Define a transform from frame "a" to frame "b"
let t_a_b_1 = Transform {
translation: Vector3 {
x: 1.0,
y: 0.0,
z: 0.0,
},
rotation: Quaternion {
w: 1.0,
x: 0.0,
y: 0.0,
z: 0.0,
},
timestamp: t1,
parent: "a".into(),
child: "b".into(),
};
// For validation
let t_a_b_2 = t_a_b_1.clone();
// Add the transform to the registry
registry.add_transform(t_a_b_1);
// Retrieve the transform from "a" to "b"
let result = registry.get_transform("a", "b", t2);
assert!(result.is_ok());
assert_eq!(result.unwrap(), t_a_b_2);Fields§
§data: HashMap<String, Buffer<T>>Implementations§
Source§impl<T> Registry<T>where
T: TimePoint,
impl<T> Registry<T>where
T: TimePoint,
Sourcepub fn new(max_age: Duration) -> Self
pub fn new(max_age: Duration) -> Self
Creates a new Registry with the specified max_age duration.
§Arguments
max_age- The duration for which transforms are considered valid.
§Returns
A new instance of Registry.
§Examples
use core::time::Duration;
use transforms::{time::Timestamp, Registry};
let mut registry = Registry::<Timestamp>::new(Duration::from_secs(60));Sourcepub fn add_transform(&mut self, t: Transform<T>)
pub fn add_transform(&mut self, t: Transform<T>)
Adds a transform to the registry.
§Arguments
t- The transform to add.
§Examples
use transforms::{geometry::Transform, time::Timestamp, Registry};
use core::time::Duration;
let mut registry = Registry::<Timestamp>::new(Duration::from_secs(60));
let mut registry = Registry::<Timestamp>::new();
let transform = Transform::identity();
registry.add_transform(transform);Sourcepub fn get_transform(
&self,
from: &str,
to: &str,
timestamp: T,
) -> Result<Transform<T>, TransformError>
pub fn get_transform( &self, from: &str, to: &str, timestamp: T, ) -> Result<Transform<T>, TransformError>
Retrieves a transform from the registry.
§Arguments
from- The source frame.to- The destination frame.timestamp- The timestamp for which the transform is requested.
§Errors
Returns a TransformError if the transform cannot be found.
§Examples
use transforms::{
geometry::{Quaternion, Transform, Vector3},
time::Timestamp,
Registry,
};
use core::time::Duration;
let mut registry = Registry::new(Duration::from_secs(60));
let t1 = Timestamp::now();
let mut registry = Registry::new();
let t1 = Timestamp::zero();
let t2 = t1.clone();
// Define a transform from frame "a" to frame "b"
let t_a_b_1 = Transform {
translation: Vector3 {
x: 1.0,
y: 0.0,
z: 0.0,
},
rotation: Quaternion {
w: 1.0,
x: 0.0,
y: 0.0,
z: 0.0,
},
timestamp: t1,
parent: "a".into(),
child: "b".into(),
};
// For validation
let t_a_b_2 = t_a_b_1.clone();
registry.add_transform(t_a_b_1);
let result = registry.get_transform("a", "b", t2);
assert!(result.is_ok());
assert_eq!(result.unwrap(), t_a_b_2);Sourcepub fn get_transform_for<U>(
&self,
value: &U,
target_frame: &str,
) -> Result<Transform<T>, TransformError>where
U: Localized<T>,
pub fn get_transform_for<U>(
&self,
value: &U,
target_frame: &str,
) -> Result<Transform<T>, TransformError>where
U: Localized<T>,
Retrieves a transform for a specific value into target_frame.
The source frame and timestamp are taken from the value.
If the value is already in target_frame, this returns an identity transform
with parent == child == target_frame and the value’s timestamp.
§Errors
Returns a TransformError if a transform cannot be resolved.
Sourcepub fn get_transform_at(
&self,
target_frame: &str,
target_time: T,
source_frame: &str,
source_time: T,
fixed_frame: &str,
) -> Result<Transform<T>, TransformError>
pub fn get_transform_at( &self, target_frame: &str, target_time: T, source_frame: &str, source_time: T, fixed_frame: &str, ) -> Result<Transform<T>, TransformError>
Retrieves a transform between two frames at different timestamps using a fixed frame.
This is the “time travel” API that allows you to get the transform from a source frame at one time to a target frame at a different time. This is useful for scenarios like tracking an object that was detected on a moving platform (e.g., a conveyor belt) and getting its current position in a static world frame.
The algorithm works by:
- Computing the transform from
source_frametofixed_frameatsource_time - Computing the transform from
fixed_frametotarget_frameattarget_time - Chaining these transforms together
§Arguments
target_frame- The destination frame for the transformtarget_time- The time at which to evaluate the target frame’s positionsource_frame- The source frame for the transformsource_time- The time at which to evaluate the source frame’s positionfixed_frame- A frame that does not change over time, used as an intermediate reference point (typically a world or map frame)
§Safety
The caller is responsible for ensuring that fixed_frame is actually stationary
between source_time and target_time. Passing a frame that moves between the
two timestamps will produce a mathematically meaningless result without any error.
Root frames (e.g., "world", "map") that have no parent are always safe choices.
§Errors
Returns a TransformError if any of the required transforms cannot be found
at the specified times.
§Examples
use transforms::{
geometry::{Quaternion, Transform, Vector3},
time::Timestamp,
Registry,
};
use core::time::Duration;
let mut registry = Registry::new(Duration::from_secs(60));
let t1 = Timestamp::now();
let t2 = (t1 + Duration::from_secs(1)).unwrap();
let mut registry = Registry::new();
let t1 = Timestamp::zero();
let t2 = Timestamp { t: 1_000_000_000 };
// Tree: fixed -> a -> b
// fixed -> a at t1: a is at x=1
registry.add_transform(Transform {
translation: Vector3 {
x: 1.0,
y: 0.0,
z: 0.0,
},
rotation: Quaternion {
w: 1.0,
x: 0.0,
y: 0.0,
z: 0.0,
},
timestamp: t1,
parent: "fixed".into(),
child: "a".into(),
});
// fixed -> a at t2: a has moved to x=2
registry.add_transform(Transform {
translation: Vector3 {
x: 2.0,
y: 0.0,
z: 0.0,
},
rotation: Quaternion {
w: 1.0,
x: 0.0,
y: 0.0,
z: 0.0,
},
timestamp: t2,
parent: "fixed".into(),
child: "a".into(),
});
// a -> b at t1: b is at y=1 relative to a
registry.add_transform(Transform {
translation: Vector3 {
x: 0.0,
y: 1.0,
z: 0.0,
},
rotation: Quaternion {
w: 1.0,
x: 0.0,
y: 0.0,
z: 0.0,
},
timestamp: t1,
parent: "a".into(),
child: "b".into(),
});
// Express b-at-t1 in a-at-t2, using "fixed" as the stationary reference
let result = registry.get_transform_at(
"a", // target_frame
t2, // target_time
"b", // source_frame
t1, // source_time
"fixed", // fixed_frame
);
assert!(result.is_ok());Sourcepub fn delete_transforms_before(&mut self, timestamp: T)
pub fn delete_transforms_before(&mut self, timestamp: T)
Removes transforms from every buffer based on the given threshold.
Iterates over all buffers and deletes all entries with a timestamp lower than the input argument.
§Fields
timestamp: the time to compare all entries in the buffer with.