Trajectory Module¶
The trajectory module provides data structures for representing time-series pose data in world coordinates.
WorldTrajectory¶
- class mimic_data_api.trajectory_numpy.WorldTrajectory(*, timestamps, object2world, angular_velocity=None, linear_velocity=None)[source]¶
Bases:
BaseModelTime-series trajectory of an object in world coordinates.
This class represents a sequence of poses (position and orientation) for an object over time, stored as 4x4 homogeneous transformation matrices. Optionally includes angular and linear velocity information.
The transformation matrices follow the convention where the matrix transforms points from the object’s local coordinate frame to the world coordinate frame:
\[p_{world} = T_{object \rightarrow world} \cdot p_{object}\]- timestamps¶
1D array of N timestamps in seconds. Must be strictly increasing (monotonic, no duplicates) and match the number of transformation matrices.
- Type:
NDArray[Shape[”* x”], float]
- object2world¶
Array of shape (N, 4, 4) containing homogeneous transformation matrices. Each matrix transforms points from object coordinates to world coordinates.
- Type:
NDArray[Shape[”* x, 4 y, 4 z”], float]
- angular_velocity¶
Optional array of shape (N, 3) containing angular velocity vectors in world coordinates, measured in rad/s. Order is (roll, pitch, yaw) rate.
- Type:
NDArray[Shape[”* x, 3 y”], float] or None
- linear_velocity¶
Optional array of shape (N, 3) containing linear velocity vectors in world coordinates, measured in m/s. Order is (vx, vy, vz).
- Type:
NDArray[Shape[”* x, 3 y”], float] or None
- Raises:
ValueError – If timestamps and transforms have different lengths, or if velocity arrays (when provided) don’t match the timestamp count.
Note
This class uses
validate_assignment=True, meaning validation runs on attribute assignment, not just initialization.Example
Creating a trajectory with velocity information:
import numpy as np from mimic_data_api.trajectory_numpy import WorldTrajectory n_frames = 100 trajectory = WorldTrajectory( timestamps=np.linspace(0, 10, n_frames), object2world=np.stack([np.eye(4)] * n_frames), linear_velocity=np.zeros((n_frames, 3)), angular_velocity=np.zeros((n_frames, 3)) )
Accessing pose at a specific time index:
pose_at_t5 = trajectory.object2world[5] # 4x4 matrix position = pose_at_t5[:3, 3] # Translation vector rotation = pose_at_t5[:3, :3] # Rotation matrix
Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
Usage Example
import numpy as np from mimic_data_api import WorldTrajectory # Create a 100-frame trajectory trajectory = WorldTrajectory( timestamps=np.linspace(0, 10, 100), object2world=np.stack([np.eye(4)] * 100), linear_velocity=np.zeros((100, 3)), angular_velocity=np.zeros((100, 3)) ) # Access pose at frame 50 pose = trajectory.object2world[50] position = pose[:3, 3] # Translation rotation = pose[:3, :3] # Rotation matrix
- len_validation()[source]¶
Validate that all arrays have consistent lengths.
- Returns:
The validated trajectory instance.
- Return type:
- Raises:
ValueError – If array lengths are inconsistent, or if
timestampsis not strictly increasing (monotonic, no duplicates).
- __eq__(other)[source]¶
Check equality with another WorldTrajectory.
Two trajectories are considered equal if they have the same timestamps, transforms, and velocity arrays (using approximate comparison for floats).
- model_config: ClassVar[ConfigDict] = {'validate_assignment': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
Sensor World Poses¶
The ego vehicle trajectory stores vehicle-to-world poses. For a mounted
sensor, trajectory.object2world stores sensor-to-world poses, not the raw
ego vehicle poses. Compose each sensor pose as:
The sensor’s extrinsics field is T_sensor_to_vehicle. This contract
applies to cameras, LiDARs, and radars. Sensor data files themselves remain
in the sensor-local coordinate frame.
Extrinsic Calibration¶
- mimic_data_api.extrinsic.SensorExtrinsic¶
Type alias for a 4x4 sensor extrinsic calibration matrix.
This matrix transforms points from the sensor coordinate frame to the vehicle body coordinate frame:
\[p_{vehicle} = T_{sensor \rightarrow vehicle} \cdot p_{sensor}\]- Type:
NDArray[Shape[“4 x, 4 y”], float]
import numpy as np from mimic_data_api.extrinsic import SensorExtrinsic # Identity transform (sensor aligned with vehicle) extrinsic: SensorExtrinsic = np.eye(4) # LiDAR mounted 1.5m above vehicle origin extrinsic = np.array([ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 1.5], [0, 0, 0, 1] ])