Source code for mimic_data_api.scene

"""
Scene Module
============

This module defines the top-level data structures for representing a complete
driving scene, including the ego vehicle, its sensors, and all actors
(other objects) in the environment.

The ``Scene`` class serves as the root container for all scene data and is
the primary entry point for working with the Data API.

Classes
-------
Sensors
    Collection of all sensors mounted on the ego vehicle.
EgoVehicle
    The autonomous/recording vehicle with its trajectory and sensor suite.
Scene
    Complete scene representation including ego vehicle and all actors.

Architecture
------------
The scene data model follows a hierarchical structure::

    Scene
    ├── EgoVehicle
    │   ├── trajectory: WorldTrajectory
    │   └── sensors: Sensors
    │       ├── cameras: list[Camera]
    │       ├── lidars: list[Lidar] (optional)
    │       └── radars: list[Radar] (optional)
    └── actors: list[Actor]

Example
-------
Creating a complete scene::

    from mimic_data_api.scene import Scene, EgoVehicle, Sensors
    from mimic_data_api.camera import Camera
    from mimic_data_api.actor import Actor

    scene = Scene(
        ego_vehicle=EgoVehicle(
            trajectory=ego_trajectory,
            sensors=Sensors(
                cameras=[front_camera, rear_camera],
                lidars=[top_lidar],
                radars=[front_radar]
            )
        ),
        actors=[vehicle_1, pedestrian_1, cyclist_1]
    )
"""

from pydantic import BaseModel, Field
from mimic_data_api.camera import Camera
from mimic_data_api.actor import Actor
from mimic_data_api.lidar import Lidar
from mimic_data_api.radar import Radar
from mimic_data_api.trajectory_numpy import WorldTrajectory
from mimic_data_api.unstructured.pointclouds import ColorizedPointCloud


class BackgroundPointCloudPaths(BaseModel):
    lidar_accumulated_pcd_filepath: str | None = None
    lidar_accumulated_pcd: ColorizedPointCloud | None = None

    colmap_pcd_filepath: str | None = None
    colmap_pcd: ColorizedPointCloud | None = None

    background_init_pcd_filepath: str | None = None
    background_init_pcd: ColorizedPointCloud | None = None

    background_road_pcd_filepath: str | None = None
    background_road_pcd: ColorizedPointCloud | None = None

    background_non_road_pcd_filepath: str | None = None
    background_non_road_pcd: ColorizedPointCloud | None = None


[docs] class Sensors(BaseModel): """Collection of sensors mounted on the ego vehicle. This class aggregates all perception sensors attached to the ego vehicle, providing a unified interface for accessing camera, LiDAR, and radar data. Attributes ---------- cameras : list of Camera List of camera sensors. At least one camera is required. lidars : list of Lidar List of LiDAR sensors. At least one LiDAR is required. radars : list of Radar or None Optional list of radar sensors. ``None`` if no radars are present. Note ---- Every scene must contain at least one camera and one LiDAR. Radar sensors remain optional. Example ------- >>> sensors = Sensors( ... cameras=[front_cam, rear_cam, left_cam, right_cam], ... lidars=[top_lidar, front_lidar], ... radars=[front_radar, rear_radar] ... ) >>> print(f"Number of cameras: {len(sensors.cameras)}") Number of cameras: 4 """ cameras: list[Camera] = Field(min_length=1) lidars: list[Lidar] = Field(min_length=1) radars: list[Radar] | None = None
[docs] class EgoVehicle(BaseModel): """The autonomous or recording vehicle in the scene. Represents the vehicle carrying the sensor suite, including its trajectory through the scene and all mounted sensors. Attributes ---------- trajectory : WorldTrajectory Time-series of ego vehicle poses in world coordinates. Defines the vehicle's position and orientation over time. sensors : Sensors Collection of all sensors mounted on the ego vehicle. Note ---- The ego vehicle's trajectory defines the reference frame for sensor data alignment. All sensor extrinsics are defined relative to the vehicle body frame, and the trajectory transforms from body frame to world frame. Coordinate conventions: - **Vehicle Frame**: X-forward, Y-left, Z-up (FLU) - **World Frame**: Typically ENU (East-North-Up) or local tangent plane Example ------- >>> ego = EgoVehicle( ... trajectory=WorldTrajectory( ... timestamps=np.arange(0, 10, 0.1), ... object2world=poses # (100, 4, 4) array ... ), ... sensors=Sensors(cameras=[camera], lidars=[lidar]) ... ) """ trajectory: WorldTrajectory sensors: Sensors
[docs] class Scene(BaseModel): """Complete driving scene representation. The ``Scene`` class is the top-level container for all data in a driving scenario. It includes the ego vehicle (with sensors and trajectory) and all detected/annotated actors in the environment. This class serves as the primary interface for loading, saving, and manipulating scene data in the Data API. Attributes ---------- ego_vehicle : EgoVehicle The autonomous/recording vehicle with trajectory and sensors. actors : list of Actor List of all other objects (vehicles, pedestrians, cyclists, etc.) present in the scene. world_offset : list of float or None Constant (x, y, z) translation subtracted from every global ``object2world`` translation (e.g. world re-centering during preprocessing); add it back to recover the source world frame. ``None`` means no offset was applied. Note ---- The scene data structure is designed for: - **Serialization**: Easy JSON export/import for data exchange - **Simulation**: Providing ground truth for rendering and replay - **Analysis**: Querying and filtering scene elements - **Editing**: Adding, removing, or modifying scene components Example ------- Creating and serializing a scene:: >>> scene = Scene( ... ego_vehicle=ego, ... actors=[car_1, car_2, pedestrian_1] ... ) >>> # Serialize to JSON >>> json_data = scene.model_dump_json(indent=2) >>> # Load from JSON >>> loaded_scene = Scene.model_validate_json(json_data) Accessing scene components:: >>> # Get all camera data >>> cameras = scene.ego_vehicle.sensors.cameras >>> # Get all dynamic actors >>> dynamic_actors = [a for a in scene.actors if a.dynamic] >>> # Get ego trajectory timestamps >>> timestamps = scene.ego_vehicle.trajectory.timestamps """ ego_vehicle: EgoVehicle actors: list[Actor] world_offset: list[float] | None = None """(x, y, z) offset subtracted from global object2world translations; see class docstring.""" background_pcd_paths: BackgroundPointCloudPaths | None = None base_folderpath: str | None = Field( default=None, exclude=True, description=( "Path where the scene.json file is loaded from. " "Excluded from serialization; useful for resolving relative paths." ), )