Data Types
All data classes inherit from Data, which provides a frame_id attribute.
Time-ordered data extends SequentialData, adding timestamps and hertz analysis.
Spatial pose data extends PathData, adding positions, orientations, and a coordinate frame.
Enumerations
- class robotdataprocess.CoordinateFrame(value)
Enum for different coordinate frames used in robotics.
- FLU
X forward, Y left, Z up := RHS
- NED
X forward (north), Y right (east), Z down := RHS
- ENU
X right (east), Y forward (north), Z up := RHS
- NONE
No defined coordinate frame.
- class robotdataprocess.ROSMsgLibType(value)
Enum for different ROS message library types.
- ROSBAGS
Use ROS messages from the rosbags library (Pure Python library).
- RCLPY
Use ROS messages from the rclpy library (ROS2 Python client library).
- ROSPY
Use ROS messages from the rospy library (ROS1 Python client library).
- NONE
No ROS message library (for testing purposes only).
SequentialData
- class robotdataprocess.SequentialData(frame_id: str, timestamps: ndarray | list)
Bases:
DataData class for sequential (time-ordered) data. Provides timestamps, hertz analysis, and methods that should be overwritten by children.
- compute_hertz_stats(trim_outliers: bool = True) tuple[List, List, int]
Compute hertz statistics from timestamps.
- Parameters:
trim_outliers – If True and there are more than 5 samples, remove first and last 5 values.
- Returns:
hertz_diffs: List of time differences between consecutive timestamps
hertz_values: List of hertz values (1/diff) for non-zero differences
num_zero_diffs: Number of consecutive timestamp pairs with zero difference
- Return type:
Tuple of (hertz_diffs, hertz_values, num_zero_diffs) where
- Raises:
ValueError – If there are fewer than 2 data samples.
- crop_data(start: Decimal, end: Decimal)
Will crop the data so only values within [start, end] inclusive are kept.
- Parameters:
start – The earliest timestamp to keep.
end – The latest timestamp to keep.
- Raises:
NotImplementedError – Always; must be overridden by subclasses.
- get_ros_msg(libtype: ROSMsgLibType, i: int)
Will create and return a ROS message object.
- Parameters:
libtype – Which ROS message library to use.
i – Index of the data sample to convert.
- Returns:
A ROS message populated with the data at index
i.- Raises:
NotImplementedError – Always; must be overridden by subclasses.
- static get_ros_msg_type(libtype: ROSMsgLibType)
Will return the msgtype for the ROS message for this Data object.
- Parameters:
libtype – Which ROS message library to use.
- Returns:
The ROS message type class.
- Raises:
NotImplementedError – Always; must be overridden by subclasses.
- hertz_analysis(show_plots: bool = True) tuple[List, List]
Plot histograms with the sequential data hertz rates and time differences.
- Parameters:
show_plots – If True, display matplotlib plots. Set to False for testing.
- Returns:
Tuple of (hertz_diffs, hertz_values) for testing purposes.
- len() int
Returns the number of items in this data class.
- Returns:
The number of timestamped entries.
- Return type:
int
- round_timestamps(decimals: int)
Rounds all timestamps to the specified number of decimal places.
- Parameters:
decimals – Number of decimal places to round to.
PathData
- class robotdataprocess.PathData(frame_id: str, timestamps: ndarray | List, positions: ndarray | List, orientations: ndarray | List, frame: CoordinateFrame)
Bases:
SequentialDataTrajectory data with timestamped 3D positions and orientations.
Extends SequentialData with spatial pose information. Serves as the base class for OdometryData and provides methods for frame conversion, trajectory alignment, error evaluation (APE/RPE via evo), and 2D/3D visualization.
- positions
(N, 3) array of x, y, z positions in meters.
- Type:
numpy.ndarray
- orientations
(N, 4) array of quaternions in (x, y, z, w) order.
- Type:
numpy.ndarray
- frame
The coordinate frame convention of this data.
- static align_and_calculate_traj_errors(gt_path: PathData, est_path: PathData, max_diff: float, visualize: bool = False, axes_length: float | list[float] = 10.0, axes_interval: int | list[int] = 1000) Tuple[dict, PathData, PathData]
Utilizing the evo library, calculates a variety of trajectory error metrics and returns them in a dictionary. Also returns aligned PathData objects.
- Parameters:
max_diff – maximum absolute time difference allowed between associated timestamps
visualize – If true, will show a 3D plot of the aligned trajectories.
axes_length – Same as in visualize() method.
axes_interval – Same as in visualize() method.
- apply_transformation_left_side(H: ndarray)
Applies a rigid-body transformation to the entire path. In terms of transformation matrices, this multiplies this path on the left side.
- Parameters:
H – The 4x4 transformation matrix
- apply_transformation_right_side(H: ndarray)
Applies a rigid-body transformation to the entire path. In terms of transformation matrices, this multiplies this path on the right side (row-vector convention).
- Parameters:
H – The 4x4 transformation matrix
- static concatenate_PathData(path_data_objs: list[PathData]) PathData
Combines multiple PathData objects into a single PathData object. In doing so, will shift the timestamps of each subsequent PathData so that their data starts one second after the previous PathData ends. Also assumes the frame_id and frame of the first PathData object for final PathData object.
Mimics the behavior found in ROMAN’s (https://github.com/lunarlab-gatech/roman) evaluation scripts.
- Parameters:
path_data_objs – List of PathData objects to concatenate.
- Returns:
A single PathData with all trajectories joined end-to-end.
- Return type:
- Raises:
ValueError – If the list is empty or has only one element.
- crop_data(start: Decimal, end: Decimal | None = None)
Will crop the data so only values within [start, end] inclusive are kept.
- Parameters:
start – The earliest timestamp to keep.
end – The latest timestamp to keep. If None, keeps all data from
startonward.
- classmethod from_csv(csv_path: Path | str, frame_id: str, frame: CoordinateFrame, header_included: bool, column_to_data: List[int] | None = None, separator: str | None = None, filter: Tuple[str, str] | None = None, ts_in_ns: bool = False, reorder_data: bool = False)
Creates a class structure from a csv file.
- Parameters:
csv_path (Path | str) – Path to the CSV file.
frame_id (str) – The frame that this path is relative to.
frame (CoordinateFrame) – The coordinate system convention of this data.
header_included (bool) – If this csv file has a header, so we can remove it.
column_to_data (list[int]) – Tells the algorithms which columns in the csv contain which of the following data: [‘timestamp’, ‘x’, ‘y’, ‘z’, ‘qw’, ‘qx’, ‘qy’, ‘qz’]. Thus, index 0 of column_to_data should be the column that timestamp data is found in the csv file. Set to None to use [0,1,2,3,4,5,6,7].
separator (str | None) – The separator used in the csv file. If None, will use a comma by default.
filter – A tuple of (column_name, value), where only rows with column_name == value will be kept. If csv file has no headers, then column_name should be the index of the column as a string.
ts_in_ns (bool) – If True, assumes timestamps are in nanoseconds and converts to seconds. Otherwise, assumes timestamps are already in seconds.
reorder_data (bool) – If True, reorders the data to be in order of timestamps. If False, assumes data is already ordered by timestamp.
- Returns:
Instance of this class.
- Return type:
- classmethod from_evo(pose_trajectory_3d: PoseTrajectory3D, frame_id: str, frame: CoordinateFrame) PathData
Creates a PathData object from an evo PoseTrajectory3D object.
- Parameters:
pose_trajectory_3d – An evo PoseTrajectory3D with positions, orientations, and timestamps.
frame_id – The frame ID to assign.
frame – The coordinate frame of this data.
- Returns:
Instance of this class.
- Return type:
- classmethod from_ros2_bag(bag_path: Path | str, odom_topic: str, frame: CoordinateFrame) PathData
Creates a class structure from a ROS2 bag file with a Path topic.
- Parameters:
bag_path (Union[Path, str]) – Path to the ROS2 bag file.
odom_topic (str) – Topic of the Path messages.
frame – The coordinate frame of this data.
- Returns:
Instance of this class.
- Return type:
- classmethod from_tum(file_path: Path | str, frame_id: str, frame: CoordinateFrame) PathData
Creates a PathData class from a TUM RGB-D dataset trajectory format text file.
Each row must contain 8 space-separated values:
timestamp x y z q_x q_y q_z q_w
where
timestampis in seconds and the orientation quaternion is in(x, y, z, w)order.- Parameters:
file_path (Path | str) – Path to the TUM trajectory file.
frame_id (str) – The frame where this path is relative to.
frame (CoordinateFrame) – The coordinate system convention of this data.
- Returns:
Instance of this class.
- Return type:
- classmethod from_txt(file_path: Path | str, frame_id: str, frame: CoordinateFrame, header_included: bool, column_to_data: List[int] | None = None)
Creates a PathData class from a text file.
- Parameters:
file_path (Path | str) – Path to the file containing the path data.
frame_id (str) – The frame where this path is relative to.
frame (CoordinateFrame) – The coordinate system convention of this data.
header_included (bool) – If this text file has a header, so we can remove it.
column_to_data (list[int]) – Tells the algorithms which columns in the text file contain which of the following data: [‘timestamp’, ‘x’, ‘y’, ‘z’, ‘qw’, ‘qx’, ‘qy’, ‘qz’]. Thus, index 0 of column_to_data should be the column that timestamp data is found in the text file. Set to None to use [0,1,2,3,4,5,6,7].
- Returns:
Instance of this class.
- Return type:
- interpolate_to_hz(target_hz: float)
Linearly interpolates position and SLERPs orientation so that path data is output at the desired frequency.
- Parameters:
target_hz (float) – Desired output frequency in Hertz (e.g. 6.0)
- static make_start_and_end_times_match(est: list[PathData], gt: list[PathData]) Tuple[list[PathData], list[PathData]]
For pairs of lists of PathData objects, extract each pair by index and ensure that the first and last timestamps match by extending the data as necessary at the start and end with duplicate values. Used for evaluation purposes.
Mimics the behavior found in ROMAN’s (https://github.com/lunarlab-gatech/roman) evaluation scripts.
- Parameters:
est – List of PathData objects that represent estimated paths.
gt – List of PathData objects that represent ground truth paths.
- static seperate_PathData(original_PathDatas: list[PathData], merged_PathData: PathData) list[PathData]
Inverse of concatenate_PathData(); needs the original objects to know the timestamps that each trajectory is found on.
- Parameters:
original_PathDatas – The original PathData objects used during concatenation, needed to determine timestamp boundaries.
merged_PathData – The single merged PathData to split apart.
- Returns:
One PathData per original trajectory, cropped from the merged data.
- Return type:
list[PathData]
- shift_position(x_shift: float, y_shift: float, z_shift: float)
Shifts the positions of the path.
- Parameters:
x_shift (float) – Shift in x-axis.
y_shift (float) – Shift in y_axis.
z_shift (float) – Shift in z_axis.
- shift_to_start_at_identity()
Alter the positions and orientations based so that the first pose starts at Identity.
- to_OdometryData(new_frame_id: str, new_child_frame_id: str)
Returns an OdometryData object for this class.
- Parameters:
new_frame_id – The new frame ID to assign to the OdometryData object.
new_child_frame_id – The new child frame ID to assign to the OdometryData object.
- to_coordinate_frame(target_frame: CoordinateFrame, transform_type: TransformType = TransformType.CHANGE_OF_BASIS)
Converts positions and orientations into the target coordinate frame.
- Parameters:
target_frame – The desired coordinate frame.
transform_type – How to apply the frame change.
CHANGE_OF_BASISapplies a similarity transform to orientations (R * q * R^-1) and rotates positions (default, original behaviour).ROTATIONleft-multiplies the frame change rotation onto both positions and orientations without the inverse on orientations.
- to_csv(csv_path: Path | str, write_header: bool = True)
Writes the path data to a .csv file. Note that data will be saved in the following order: timestamp, pos.x, pos.y, pos.z, ori.w, ori.x, ori.y, ori.z. Timestamp is in seconds.
- Parameters:
csv_path (Path | str) – Path to the output csv file.
write_header (bool) – If false, skip the header row.
- Raises:
ValueError – If the output file already exists.
- to_evo() PoseTrajectory3D
Returns an evo PoseTrajectory3D object for this class.
- Returns:
Trajectory with positions, orientations (wxyz), and timestamps.
- Return type:
PoseTrajectory3D
- to_tum(file_path: Path | str)
Writes the path data to a TUM RGB-D dataset trajectory format text file.
Each row contains 8 space-separated values:
timestamp x y z q_x q_y q_z q_w
where
timestampis in seconds and the orientation quaternion is in(x, y, z, w)order.- Parameters:
file_path (Path | str) – Path to the output text file.
- Raises:
ValueError – If the output file already exists.
- to_txt_file(file_path: Path | str, data_to_column: List[int] | None = None)
Writes the path data to a space-separated text file. This is the inverse of
from_txt().data_to_columnspecifies the output column index for each of the 8 data fields (in this fixed order): timestamp, x, y, z, qw, qx, qy, qz. For example, the default[0, 1, 2, 3, 4, 5, 6, 7]produces:timestamp x y z qw qx qy qz
Set to None to use the default
[0, 1, 2, 3, 4, 5, 6, 7].- Parameters:
file_path (Path | str) – Path to the output text file.
data_to_column (list[int] | None) – Maps each data field to its output column index. Must be a permutation of
[0, 1, 2, 3, 4, 5, 6, 7].
- Raises:
ValueError – If the output file already exists.
- static visualize_2D(dataList: List[PathData], isGTList: List[bool], colorList: List[str], nameList: List[str], save_path: str | None = None, no_background: bool = False, line_width: float = 1.0, show_grid: bool = False, legend: bool = True, no_border: bool = False, disable_x_label: bool = False, disable_y_label: bool = False, google_maps_scale_bar: bool = False, google_maps_scale_bar_loc: str = 'bottom-right', gt_color_lightness_range_val: int = 3, background_image_path: str | None = None, background_image_x_edge: float | None = None, ax: Axes | None = None, background_image_extent_offsets: Tuple[float, float] | None = None)
Plot all PathData objects on a 2D XY plane.
- Parameters:
dataList – All PathData objects to plot.
isGTList – Whether or not each PathData object is GT.
colorList – Colors to assign to each PathData object (as hex strings starting with #).
nameList – Robot names corresponding to each PathData object.
save_path – If provided, figure will be saved to the location. Otherwise, show the figure. This does nothing if ax is not None.
no_background – If true, plot with a transparent background.
line_width – Width of trajectory lines in the plot.
show_grid – Whether to draw a grid on the plot.
legend – If true, include a legend.
no_border – If true, remove the x & y axes.
disable_x_label – Remove the x label.
disable_y_label – Remove the y label.
google_maps_scale_bar – Whether to add a Google Maps-like scale bar onto the plot.
google_maps_scale_bar_loc – Location for the scale bar.
background_image_path – Path to an image to plot in the background; It is assumed that the center of the image corresponds to x=0 & y=0 in the PataData frames.
background_image_x_edge – The distance in meters from center of image to the x edge.
background_image_extent_offets – XY locations where the image center should be located.
ax – If passed, plot is drawn onto these axes instead of on a new figure.
- visualize_3D(otherList: List[PathData], titles: List[str], axes_length: float | List[float] = 10.0, axes_interval: int | List[int] = 1000)
Visualizes this PathData (and all others included in otherList) on a single plot.
- Parameters:
otherList (List[PathData]) – All other PathData objects whose path should also be visualized on this plot.
titles (List[str]) – Titles for each PathData object, starting with self.
OdometryData
- class robotdataprocess.OdometryData(frame_id: str, child_frame_id: str, timestamps: ndarray | list, positions: ndarray | list, orientations: ndarray | list, frame: CoordinateFrame)
Bases:
PathDataOdometry data extending PathData with a child frame ID and ROS message caching.
Supports loading from ROS2 bags, CSV files, and TXT files, and exporting to CSV or ROS messages (Odometry, Path, and maplab OdometryWithImuBiases).
- child_frame_id
The frame whose pose is described by this odometry (e.g.
"base_link").- Type:
str
- poses
Cached rosbags PoseStamped messages (rebuilt after any mutation).
- Type:
list
- poses_rclpy
Cached rclpy/rospy PoseStamped messages (rebuilt after any mutation).
- Type:
list
- classmethod from_csv(csv_path: Path | str, frame_id: str, child_frame_id: str, frame: CoordinateFrame, header_included: bool, column_to_data: List[int] | None = None, separator: str | None = None, filter: Tuple[str, str] | None = None, ts_in_ns: bool = False, reorder_data: bool = False)
Creates a class structure from a csv file.
- Parameters:
csv_path (Path | str) – Path to the CSV file.
frame_id (str) – The frame that this odometry is relative to.
child_frame_id (str) – The frame whose pose is represented by this odometry.
frame (CoordinateFrame) – The coordinate system convention of this data.
header_included (bool) – If this csv file has a header, so we can remove it.
column_to_data (list[int]) – Tells the algorithms which columns in the csv contain which of the following data: [‘timestamp’, ‘x’, ‘y’, ‘z’, ‘qw’, ‘qx’, ‘qy’, ‘qz’]. Thus, index 0 of column_to_data should be the column that timestamp data is found in the csv file. Set to None to use [0,1,2,3,4,5,6,7].
separator (str | None) – The separator used in the csv file. If None, will use a comma by default.
filter – A tuple of (column_name, value), where only rows with column_name == value will be kept. If csv file has no headers, then column_name should be the index of the column as a string.
ts_in_ns (bool) – If True, assumes timestamps are in nanoseconds and converts to seconds. Otherwise, assumes timestamps are already in seconds.
reorder_data (bool) – If True, reorders the data to be in order of timestamps. If False, assumes data is already ordered by timestamp.
- Returns:
Instance of this class.
- Return type:
- classmethod from_ros2_bag(bag_path: Path | str, odom_topic: str, frame: CoordinateFrame)
Creates a class structure from a ROS2 bag file with an Odometry topic.
- Parameters:
bag_path (Path | str) – Path to the ROS2 bag file.
odom_topic (str) – Topic of the Odometry messages.
- Returns:
Instance of this class.
- Return type:
- classmethod from_tum(file_path: Path | str, frame_id: str, child_frame_id: str, frame: CoordinateFrame)
Creates an OdometryData class from a TUM RGB-D dataset trajectory format text file.
Each row must contain 8 space-separated values:
timestamp x y z q_x q_y q_z q_w
where
timestampis in seconds and the orientation quaternion is in(x, y, z, w)order.- Parameters:
file_path (Path | str) – Path to the TUM trajectory file.
frame_id (str) – The frame where this odometry is relative to.
child_frame_id (str) – The frame whose pose is represented by this odometry.
frame (CoordinateFrame) – The coordinate system convention of this data.
- Returns:
Instance of this class.
- Return type:
- classmethod from_txt(file_path: Path | str, frame_id: str, child_frame_id: str, frame: CoordinateFrame, header_included: bool, column_to_data: List[int] | None = None)
Creates an OdometryData class from a text file.
- Parameters:
file_path (Path | str) – Path to the file containing the odometry data.
frame_id (str) – The frame where this odometry is relative to.
child_frame_id (str) – The frame whose pose is represented by this odometry.
frame (CoordinateFrame) – The coordinate system convention of this data.
header_included (bool) – If this text file has a header, so we can remove it.
column_to_data (list[int]) – Tells the algorithms which columns in the text file contain which of the following data: [‘timestamp’, ‘x’, ‘y’, ‘z’, ‘qw’, ‘qx’, ‘qy’, ‘qz’]. Thus, index 0 of column_to_data should be the column that timestamp data is found in the text file. Set to None to use [0,1,2,3,4,5,6,7].
- Returns:
Instance of this class.
- Return type:
- get_ros_msg(lib_type: ROSMsgLibType, i: int, msg_type: str = 'Odometry')
Gets an Odometry ROS message corresponding to the data at index i.
- Parameters:
lib_type – Which ROS message library to use.
i – The index of the odometry data to convert.
msg_type – The message type name (
"Odometry","Path","TFMessage", or"maplab_msg/OdometryWithImuBiases").
- Raises:
IndexError – If
iis outside the data bounds.ValueError – If
msg_typeis not supported for the givenlib_type.
- static get_ros_msg_type(lib_type: ROSMsgLibType, msg_type: str = 'Odometry') Any
Return the ROS message type class for odometry-related messages.
- Parameters:
lib_type – Which ROS message library to use.
msg_type – The message type name. Supported values are
"Odometry","Path","TFMessage", and"maplab_msg/OdometryWithImuBiases"(ROSPY only).
- Returns:
The ROS message type class.
- Raises:
ValueError – If
msg_typeis not supported for the givenlib_type.NotImplementedError – If
lib_typeis not supported.
ImuData
- class robotdataprocess.ImuData(frame_id: str, frame: CoordinateFrame, timestamps: ndarray | list, lin_acc: ndarray | list, ang_vel: ndarray | list, orientations: ndarray[Any, dtype[ScalarType]] | None)
Bases:
SequentialDataIMU sensor data with linear acceleration, angular velocity, and optional orientation.
Supports loading from ROS2 bags and TXT files (TartanAir format). Can be integrated via Euler’s method to produce a PathData trajectory, or published as
sensor_msgs/ImuROS messages.- lin_acc
(N, 3) array of linear accelerations in m/s^2.
- Type:
numpy.ndarray[Any, numpy.dtype[numpy._typing._generic_alias.ScalarType]]
- ang_vel
(N, 3) array of angular velocities in rad/s.
- Type:
numpy.ndarray[Any, numpy.dtype[numpy._typing._generic_alias.ScalarType]]
- orientations
(N, 4) array of quaternions (x, y, z, w), or None if unavailable.
- Type:
numpy.ndarray[Any, numpy.dtype[numpy._typing._generic_alias.ScalarType]] | None
- frame
The coordinate frame convention of this data.
- crop_data(start: Decimal, end: Decimal | None = None)
Will crop the data so only values within [start, end] inclusive are kept.
- Parameters:
start – The earliest timestamp to keep.
end – The latest timestamp to keep. If None, keeps all data from
startonward.
- classmethod from_ros2_bag(bag_path: Path | str, imu_topic: str, frame_id: str)
Creates a class structure from a ROS2 bag file with an Imu topic.
- Parameters:
bag_path (Path | str) – Path to the ROS2 bag file.
imu_topic (str) – Topic of the Imu messages.
frame_id (str) – The frame where this IMU data was collected.
- Returns:
Instance of this class.
- Return type:
- classmethod from_txt(file_path: Path | str, frame_id: str, frame: CoordinateFrame, nine_axis: bool = False)
Creates a class structure from the TartanAir dataset format, which includes various .txt files with IMU data. It expects (in order) the timestamp, the linear acceleration, and the angular velocity seperated by spaces. Will also expect orientation (xyzw) at the end if nine_axis is set to True.
- Parameters:
file_path (Path | str) – Path to the file containing the IMU data.
frame_id (str) – The frame where this IMU data was collected.
frame (CoordinateFrame) – The coordinate system convention of this data.
nine_axis (bool) – If true, will also load orientations from txt file.
- Returns:
Instance of this class.
- Return type:
- get_ros_msg(lib_type: ROSMsgLibType, i: int)
Gets an Imu ROS message corresponding to the data at index i.
- Parameters:
lib_type – Which ROS message library to use.
i – The index of the IMU data to convert.
- Raises:
ValueError – If
iis outside the data bounds.NotImplementedError – If
lib_typeis not supported.
- static get_ros_msg_type(lib_type: ROSMsgLibType) Any
Return the ROS message type class for an Imu message.
- Parameters:
lib_type – Which ROS message library to use.
- Returns:
The ROS message type class for
sensor_msgs/Imu.- Raises:
NotImplementedError – If
lib_typeis not supported.
- to_PathData(initial_pos: ndarray[Any, dtype[ScalarType]], initial_vel: ndarray[Any, dtype[ScalarType]], initial_ori: ndarray[Any, dtype[ScalarType]], use_ang_vel: bool) PathData
Converts this IMUData class into OdometeryData by integrating the IMU data using Euler’s method.
- Parameters:
initial_pos – The initial position as a numpy array.
initial_vel – The initial velocity as a numpy array.
initial_ori – The initial orientation as a numpy array (quaternion x, y, z, w), only used if use_ang_vel is True.
use_ang_vel – If True, will use angular velocity data to calculate orientation. If False, will use orientation data directly from the IMUData class.
- Returns:
The resulting PathData class.
- Return type:
- visualize(ts_start: float, ts_end: float)
Plot the linear acceleration, angular velocity, and orientation data.
- Parameters:
ts_start – Start timestamp of the window to plot.
ts_end – End timestamp of the window to plot.
LiDARData
- class robotdataprocess.data_types.LiDARData.LiDARData(frame_id: str, timestamps: ndarray | list, point_clouds: List[ndarray], channels: List[ndarray] | None, frame: CoordinateFrame)
Bases:
SequentialDataLiDAR Data class that contains LiDAR-specific attributes and methods. Inherits from the generic Data class.
NOTE: Assumes points at [0,0,0] are invalid and will set them to NaNs when necessary. Thus, all other points are assumed to be valid.
- calculate_point_channels(num_channels: int, v_min_angle: float, v_max_angle: float) None
Calculate channel numbers for each point.
NOTE: This assumes that lasers are evenly spaced within the angular range and that the first laser fires at v_min_angle and the last laser fires at v_max_angle. NOTE: Invalid points (NaNs) get a channel of 65535.
- Parameters:
num_channels – Number of laser channels (e.g. 16 for VLP-16).
v_min_angle – Minimum vertical angle in degrees.
v_max_angle – Maximum vertical angle in degrees.
- crop_data(start: Decimal, end: Decimal | None = None)
Will crop the data so only values within [start, end] inclusive are kept.
- Parameters:
start – The earliest timestamp to keep.
end – The latest timestamp to keep. If None, keeps all data from
startonward.
- estimate_FOV(n_frames: int = 10) Tuple[float, float]
Estimate the vertical field of view of the LiDAR sensor from the point cloud data.
Samples up to
n_framesevenly-spaced frames, computes the elevation angle of every valid point in each frame, and returns the observed vertical FOV as a(v_min_deg, v_max_deg)tuple. Elevation is measured from the horizontal plane: positive angles are above horizontal, negative angles are below. The data must be in the FLU coordinate frame; callto_FLU_frame()first if needed.The 1st and 99th percentiles are used rather than strict min/max to guard against stray points near the sensor or at extreme ranges.
- Parameters:
n_frames – Maximum number of frames to sample. Frames are drawn evenly across the full dataset. Defaults to 10.
- Returns:
(v_min_deg, v_max_deg)— the estimated vertical FOV in degrees, consistent with thelidar_v_fovconvention used elsewhere in this library.- Raises:
RuntimeError – If the data is not in the FLU coordinate frame.
RuntimeError – If no valid points are found across the sampled frames.
- classmethod from_npy_files(npy_folder_path: Path | str, frame_id: str, frame: CoordinateFrame) LiDARData
Load LiDAR data from a series of .npy files in a specified folder, where file names correspond to timestamps. Each point is expected to contain either [x, y, z] or [x, y, z, channel].
- Parameters:
npy_folder_path – Path to the folder.
frame_id – The frame ID for the LiDAR data.
frame – The coordinate frame of the LiDAR data.
- Returns:
An instance of LiDARData populated with the loaded data.
- Return type:
- classmethod from_ros2_bag(bag_path: Path | str, lidar_topic: str, frame: CoordinateFrame)
Creates a class structure from a ROS2 bag file with a PointCloud2 topic. The frame_id is loaded directly from the message header in the bag.
- Parameters:
bag_path (Path | str) – Path to the ROS2 bag file.
lidar_topic (str) – Topic of the PointCloud2 messages.
frame – The coordinate frame of the LiDAR data.
- Returns:
Instance of this class.
- Return type:
- get_point_cloud_at_index(index: int)
Gets the point cloud at index T and ensures all necessary transformations are applied. This is a safe copy of the memmapped array, meaning it can be transformed and changed.
- Parameters:
index – The index of the point cloud to retrieve (0-based within the possibly-cropped dataset).
- Returns:
Tuple of
(points, channels)wherepointsis an (N, 3) float32 array andchannelsis an (N,) uint16 array or None.
- get_ros_msg(lib_type: ROSMsgLibType, i: int)
Gets a PointCloud2 message corresponding to the point cloud at index i.
- Parameters:
lib_type (ROSMsgLibType) – The type of ROS message to return (e.g., ROSBAGS, RCLPY).
i (int) – The index of the point cloud to convert.
- Raises:
ValueError – If i is outside the data bounds.
NOTE: Currently publishes an unordered point cloud. NOTE: Assumes all points are collected at same time (likely false in the real-world). NOTE: Assumes channels data is provided. NOTE: Assumes intensity of 255 for all points.
- static get_ros_msg_type(lib_type: ROSMsgLibType) Any
Return the ROS message type class for a PointCloud2 message.
- Parameters:
lib_type – Which ROS message library to use.
- Returns:
The ROS message type class for
sensor_msgs/PointCloud2.- Raises:
NotImplementedError – If
lib_typeis not supported.
- make_dense()
Removes invalid points (infinity and NaNs) to make the point cloud dense.
- to_FLU_frame()
Adds a transformation so that point clouds returned by get_point_cloud_at_index are rotated into the FLU coordinate frame.
- to_npy_files(npy_folder_path: Path | str) None
Save LiDAR data to a series of .npy files in a specified folder, where file names correspond to timestamps. Each file contains an (N, 3) array if channels are None, or (N, 4) array if channels exist (4th column is the channel).
- Parameters:
npy_folder_path – Path to the output folder. Created if it doesn’t exist.
- visualize(interval_ms: int = 100, plot_lims: Tuple[float, float] = (-50.0, 50.0), testing: bool = False)
Visualizes the raw LiDAR data over time using Matplotlib FuncAnimation.
- Parameters:
interval_ms – The time between plotted frames.
plot_lims – The axes limits of the 3D plot.
testing – Only used for test cases, disables blocking in plt.show()
LoopClosureData
- class robotdataprocess.LoopClosureData(timestamps_a: ndarray | list, timestamps_b: ndarray | list, names: List[Tuple[str, str]], translations: ndarray | list, orientations: ndarray | list, detected_inliers: ndarray | list | None = None)
Bases:
DataData class for inter-robot loop closure measurements. Each loop closure represents a relative pose between two robots at specific timestamps.
- calculate_errors(name_to_path: dict) dict
Calculate translation and rotation errors for each loop closure by comparing the estimated relative transform against ground truth computed from PathData trajectories.
The estimated loop closure provides the pose of the second robot (names[1]) with respect to the first robot (names[0]), or H_A->B. The GT relative transform is computed as (T_W->A)^{-1} * T_W->B, where A is names[0] and B is names[1].
- Parameters:
name_to_path – Dict mapping robot names to their ground truth PathData.
- Returns:
“translation_errors”: (N,) float64 array of translation magnitude errors in meters. “rotation_errors”: (N,) float64 array of rotation angle errors in degrees.
- Return type:
Dict with
- classmethod from_g2o(g2o_path: Path | str, time_path: Path | str, names_override: dict | None = None) LoopClosureData
Creates a LoopClosureData instance from a g2o file containing EDGE_SE3:QUAT entries, using a timestamp file to map keyframe indices to real timestamps.
GTSAM symbol keys are decoded as (character << 56 | index). The character is converted to a robot id (‘a’ -> 0, ‘b’ -> 1, etc.) and used together with the index to look up the timestamp from the time file.
The g2o quaternion order is (qx, qy, qz, qw), which matches the xyzw convention used by this class.
- Parameters:
g2o_path – Path to the .g2o file.
time_path – Path to the timestamp file. Each line has: robot_id keyframe_id timestamp_ns [ignored…]
names_override – Optional dict mapping decoded character keys to desired robot names (e.g.
{"a": "aerial-07", "b": "ground-03"}). Keys not present in the dict are kept as their decoded character.
- Returns:
LoopClosureData instance.
- classmethod from_json(json_path: Path | str, names_override: dict | None = None) LoopClosureData
Creates a LoopClosureData instance from a JSON file containing loop closure alignment data.
- Parameters:
json_path – Path to the JSON file.
names_override – Optional dict mapping names found in the JSON to desired replacement names (e.g.
{"0": "aerial-07", "1": "ground-03"}). Names not present in the dict are kept as-is.
- Returns:
LoopClosureData instance.
- label_inliers_via_other_LoopClosureData(other: LoopClosureData) None
Label loop closures as inliers if they are also detected in another LoopClosureData instance. The
otherobject is assumed to be a subset ofself— every loop closure inothermust have a matching entry inself. A ValueError is raised if any loop closure inothercannot be matched.This modifies the detected_inliers attribute in place.
Matches are checked by name pairs, timestamps, translations, and orientations. Quaternion sign ambiguity is handled: q and -q are treated as equivalent.
Note: Swapped name pairs ((A,B) vs (B,A)) are NOT matched. Both LoopClosureData instances must use the same robot1-to-robot2 convention for loop closures to be identified as inliers.
- Parameters:
other – Another LoopClosureData instance that is a subset of self; unaffected by this method.
- Raises:
ValueError – If any loop closure in
otheris not found inself, violating the subset assumption.
- round_timestamps(decimals: int)
Rounds all timestamps to the specified number of decimal places.
- Parameters:
decimals – Number of decimal places to round to.
- static visualize_error_scatter(errors: List[dict], labels: List[str], inlier_masks: List[ndarray] | None = None, show_plots: bool = True, save_path: str | None = None, max_translation_frac: float = 1.0, max_rotation_frac: float = 1.0, trans_err_in_target: float = 1.0, rot_err_in_target: float = 5.0, title: str | None = None)
Scatter plot of loop closure errors (log-log scale): each point is one loop closure. Inliers and outliers are shown with different markers.
- Parameters:
errors – List of error dicts, each containing
"translation_errors"and"rotation_errors"arrays.labels – Display name for each error dict.
inlier_masks – Optional list of boolean arrays marking inlier loop closures. If None, all points are treated as outliers.
show_plots – If True, display the plot interactively.
save_path – If provided, save the figure to this path instead of showing.
max_translation_frac – Fraction of max translation error for axis limit.
max_rotation_frac – Fraction of max rotation error for axis limit.
trans_err_in_target – Translation error threshold for the highlighted region.
rot_err_in_target – Rotation error threshold for the highlighted region.
title – Optional plot title.
- Returns:
matplotlib Figure object.
- Raises:
ValueError – If list lengths do not match or fraction values are out of range.
RuntimeError – If both
show_plotsandsave_pathare set.
- static visualize_success_rate(errors: List[dict], labels: List[str], num_thresholds: int = 100, show_plots: bool = True, max_translation_frac: float = 1.0, max_rotation_frac: float = 1.0)
Plot loop closure success as a function of error threshold. Produces six plots: translation success rate, rotation success rate, translation count, rotation count, combined success rate, and combined count.
- Parameters:
errors – List of error dicts, each containing
"translation_errors"and"rotation_errors"arrays.labels – Display name for each error dict.
num_thresholds – Number of evenly-spaced threshold values to evaluate.
show_plots – If True, display the plots interactively.
max_translation_frac – Fraction of the maximum translation error to use as the upper threshold bound.
max_rotation_frac – Fraction of the maximum rotation error to use as the upper threshold bound.
- Returns:
Tuple of six matplotlib Figure objects (translation %, rotation %, translation count, rotation count, combined %, combined count).
- Raises:
ValueError – If list lengths do not match or fraction values are out of range.
ImageData
- class robotdataprocess.data_types.ImageData.ImageData.ImageData(frame_id: str, timestamps: ndarray | list, height: int, width: int, encoding: ImageEncoding, images: ndarray | Any)
Bases:
SequentialDataGeneric ImageData class that should be overwritten by children
- class ImageEncoding(value)
Bases:
EnumAn enumeration.
- crop_data(start: Decimal, end: Decimal | None = None)
Will crop the data so only values within [start, end] inclusive are kept.
- Parameters:
start – The earliest timestamp to keep.
end – The latest timestamp to keep. If None, keeps all data from
startonward.
- classmethod from_image_files(image_folder_path: Path | str, frame_id: str) ImageData
Creates a class structure from a folder with .png files.
- Parameters:
image_folder_path – Path to the folder containing image files.
frame_id – The frame ID to assign.
- Returns:
Instance of this class.
- Return type:
- get_ros_msg(lib_type: ROSMsgLibType, i: int)
Gets an Image ROS2 Humble message corresponding to the image represented by index i.
- Parameters:
lib_type (ROSMsgLibType) – The type of ROS message to return (e.g., ROSBAGS, RCLPY).
i (int) – The index of the image message to convert.
- Raises:
ValueError – If i is outside the data bounds.
- static get_ros_msg_type(lib_type: ROSMsgLibType) Any
Return the __msgtype__ for an Image msg.
- Parameters:
lib_type – The ROS message library to use.
- Returns:
The Image message type for the specified library.
- Raises:
NotImplementedError – If
lib_typeis not supported.
- to_image_files(output_folder_path: Path | str)
Saves each image in this ImageData instance to the specified folder, using the timestamps as filenames in .png format (lossless compression).
- Parameters:
output_folder_path (Path | str) – The folder to save images into.
- to_npy(output_folder_path: Path | str)
Saves each image in this ImageData into three files:
imgs.npy (with image data)
times.npy (with timestamps)
attributes.txt
- Parameters:
output_folder_path (Path | str) – The folder to save the .npy file at.
ImageDataInMemory
- class robotdataprocess.ImageDataInMemory(frame_id: str, timestamps: ndarray | list, height: int, width: int, encoding: ImageEncoding, images: ndarray)
Bases:
ImageDataImage data stored entirely in RAM (or as a memory-mapped numpy array).
Supports loading from ROS2 bags,
.npyfiles, and.pngfolders. Provides in-memory downscaling and export to PNG or.npyformat.- downscale_by_factor(scale: int)
Scales down all images by the provided factor.
- Parameters:
scale (int) – The downscaling factor. Must evenly divide both height and width.
- classmethod from_image_files(image_folder_path: Path | str, frame_id: str)
Creates a class structure from a folder with .png files, using the file names as the timestamps. This is the format that the HERCULES v1.4 dataset provides for image data.
- Parameters:
image_folder_path (Path | str) – Path to the folder with the images.
frame_id (str) – The frame where this image data was collected.
- Returns:
Instance of this class.
- Return type:
- classmethod from_npy(folder_path: Path | str)
Creates a class structure from .npy and .txt files (the ones written by from_ros2_bag()).
- Parameters:
folder_path (Path | str) – Path to the folder with: - imgs.npy - times.npy - attributes.txt
- Returns:
Instance of this class.
- Return type:
- classmethod from_npy_files(npy_folder_path: Path | str, frame_id: str)
Creates a class structure from .npy files, where each individual image is stored in an .npy file with the timestamp as the name
- Parameters:
npy_folder_path (Path | str) – Path to the folder with the npy images.
frame_id (str) – The frame where this image data was collected.
- Returns:
Instance of this class.
- Return type:
- classmethod from_ros2_bag(bag_path: Path | str, img_topic: str, save_folder: Path | str)
Creates a class structure from a ROS2 bag file with an Image topic. Will Also save all the data into .npy and .txt files as this is required if image data doesn’t fit into the RAM.
- Parameters:
bag_path (Path | str) – Path to the ROS2 bag file.
img_topic (str) – Topic of the Image messages.
save_folder (Path | str) – Path to save class data into.
- Returns:
Instance of this class.
- Return type:
ImageDataOnDisk
- class robotdataprocess.ImageDataOnDisk(frame_id: str, timestamps: ndarray | list, height: int, width: int, encoding: ImageEncoding, image_paths: List[Path], transformations: List[Callable] | None = None)
Bases:
ImageDataImage data loaded lazily from disk, reading each image only when accessed. Uses a
LazyImageArraythat loads PNG or.npyfiles on demand, keeping memory usage low for large image sequences. Supports loading from.pngand.npyfolders where filenames encode timestamps.- crop_images_to_LiDAR_FOV(lidar_v_fov: Tuple[float, float], camera_data: Any) None
Crop the top and bottom of every image so that the camera’s vertical FOV matches the given LiDAR vertical FOV.
The LiDAR vertical FOV is specified in degrees, measured from the horizontal plane: positive angles are above horizontal, negative angles are below. The crop is applied lazily via the transformation pipeline, so no images are read from disk until accessed.
The crop row boundaries are computed from the camera intrinsic matrix
K(specificallyfyandcy). For a pixel rowvin the original image, the elevation angle istheta = -arctan((v - cy) / fy), so the row that maps to a given angle isv = cy - fy * tan(theta).- Parameters:
lidar_v_fov –
(min_deg, max_deg)tuple giving the LiDAR’s vertical angular range in degrees. Positive is above horizontal, negative is below.min_deg < max_degis required.camera_data – A
CameraDatainstance whose intrinsics are used to compute the crop boundaries. Itsheight,K, andPfields are updated to reflect the new image dimensions.
- Raises:
ValueError – If
min_deg >= max_deg.ValueError – If the LiDAR FOV does not intersect the image’s vertical extent, or if the computed crop has zero height.
- classmethod from_image_files(image_folder_path: Path | str, frame_id: str) ImageDataOnDisk
Creates a class structure from a folder with .png files, using the file names as the timestamps.
- Parameters:
image_folder_path (Path | str) – Path to the folder with the images.
frame_id (str) – The frame where this image data was collected.
- Returns:
Instance of this class.
- Return type:
- classmethod from_npy_files(npy_folder_path: Path | str, frame_id: str)
Creates a class structure from .npy files, where each individual image is stored in an .npy file with the timestamp as the name
- Parameters:
npy_folder_path (Path | str) – Path to the folder with the npy images.
frame_id (str) – The frame where this image data was collected.
- Returns:
Instance of this class.
- Return type:
- to_encoding(encoding: ImageEncoding)
Swap the encoding of the image data. Currently only supports RGB8 -> BGR8.
- Parameters:
encoding – The target encoding to convert to.
- Raises:
NotImplementedError – If the conversion between the current and target encoding is not supported.