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) -> Registry<T>
pub fn new(max_age: Duration) -> Registry<T>
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.
Auto Trait Implementations§
impl<T> Freeze for Registry<T>
impl<T> RefUnwindSafe for Registry<T>where
T: RefUnwindSafe,
impl<T> Send for Registry<T>where
T: Send,
impl<T> Sync for Registry<T>where
T: Sync,
impl<T> Unpin for Registry<T>where
T: Unpin,
impl<T> UnsafeUnpin for Registry<T>
impl<T> UnwindSafe for Registry<T>where
T: RefUnwindSafe + UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.