Ego Editor

Ego vehicle editing for scene manipulation.

The EgoEditor provides methods to edit the ego vehicle and all attached sensors as a unified rig. Access via scene.ego.

Example

>>> # Transform the ego rig
>>> scene.ego.shift(forward=5)
>>> scene.ego.rotate(yaw=15)
>>> # Perform maneuvers
>>> scene.ego.smooth_lane_change(start_idx=10, duration=30, left=3.5)
>>> scene.ego.stop(at_idx=50)
class mimic_scene_edition.editors.ego_editor.EgoEditor(scene, *, limited_mode=False, value_limits=None, editions=None)[source]

Bases: object

Editor for the ego vehicle and all attached sensors.

Provides methods to transform the ego vehicle and its sensor rig as a unified system. All sensor trajectories are updated to maintain their relative positions when the ego is transformed.

Parameters:
  • scene (Scene) – The scene containing the ego vehicle.

  • limited_mode (bool, optional) – If True, enable parameter value limit checking. Default is False.

  • value_limits (dict[str, tuple[float, float]] | None, optional) – Dictionary mapping parameter names to (min, max) bounds.

  • editions (list[EditionDict] | None, optional) – List to append edition records to.

Notes

EgoEditor instances should be obtained through SceneEditor.ego rather than instantiated directly.

All transformation methods return self to enable method chaining.

Examples

Basic transformations:

>>> scene.ego.shift(forward=5)  # Move forward 5m
>>> scene.ego.shift(left=2, up=0.5)  # Move left and up
>>> scene.ego.rotate(yaw=15)  # Turn 15° left

Maneuvers:

>>> scene.ego.smooth_lane_change(start_idx=10, duration=30, left=3.5)
>>> scene.ego.evasive_maneuver(start_idx=20, duration=40, left=2)

Stopping:

>>> scene.ego.stop(at_idx=50)  # Stop at frame 50
>>> scene.ego.stop(at_idx=50, duration=20)  # Stop for 20 frames
__init__(scene, *, limited_mode=False, value_limits=None, editions=None)[source]
resample(*, hz)[source]

Resample the ego rig trajectory to a target frame rate.

Resamples the ego vehicle and all sensor trajectories to produce poses at a uniform temporal spacing. Each camera frame keeps the image nearest to it in time.

Parameters:

hz (float) – Target frame rate in Hz (frames per second).

Returns:

Self for method chaining.

Return type:

EgoEditor

Examples

>>> scene.ego.resample(hz=20)  # Resample to 20 Hz
offset(*, offset_frame)[source]

Shift the timeline by a number of frames.

Performs a circular shift of all trajectories and associated image data, wrapping around at the boundaries.

Parameters:

offset_frame (int) – Number of frames to shift. Positive values shift forward.

Returns:

Self for method chaining.

Return type:

EgoEditor

Examples

>>> scene.ego.offset(offset_frame=5)  # Shift by 5 frames
stop(at_idx, *, duration=None, decel=10, profile='min_jerk')[source]

Stop the ego vehicle at a specific frame.

Brings the ego vehicle and all attached sensors to a stop, optionally with a smooth deceleration profile.

Parameters:
  • at_idx (int) – Frame index to stop at. If decel > 0, this is where the deceleration ends.

  • duration (int | None, optional) – Number of frames to stay stopped. If None, remain stopped until the end of the trajectory.

  • decel (int, optional) – Number of frames for gradual deceleration. Use 0 for instant stop. Default is 10.

  • profile ({"linear", "min_jerk"}, optional) –

    Deceleration profile:

    • "linear": Linear velocity reduction

    • "min_jerk": Smooth minimum-jerk profile (default)

Returns:

Self for method chaining.

Return type:

EgoEditor

Examples

>>> scene.ego.stop(at_idx=50)  # Stop at frame 50
>>> scene.ego.stop(at_idx=50, duration=20)  # Stop for 20 frames
>>> scene.ego.stop(at_idx=50, decel=15)  # Gradual 15-frame decel
stop_from(start_idx)[source]

Freeze the ego and all sensors from start_idx onward.

Unlike stop(), no deceleration ramp is applied — the pose at start_idx is simply replicated for every subsequent frame and velocities are zeroed.

Parameters:

start_idx (int) – Frame index from which to freeze.

Returns:

Self for method chaining.

Return type:

EgoEditor

speed(multiplier)[source]

Change the apparent speed by retiming timestamps.

Adjusts trajectory timestamps to change perceived speed without modifying the spatial path. Affects the ego and all attached sensors.

Parameters:

multiplier (float) –

Speed scaling factor:

  • > 1: Faster (e.g., 1.5 = 50% faster)

  • < 1: Slower (e.g., 0.5 = 50% slower)

Returns:

Self for method chaining.

Return type:

EgoEditor

Examples

>>> scene.ego.speed(multiplier=1.5)  # 50% faster
>>> scene.ego.speed(multiplier=0.5)  # 50% slower
apply_T_sequence(T, *, start_idx=None, end_idx=None, referential='world', mode='auto', coverage='bin')[source]

Apply a sequence of 4x4 transformation matrices.

Applies SE(3) transformation matrices to the ego and all sensors in the specified frame range.

Parameters:
  • T (np.ndarray) – Transformation matrices with shape (4, 4) for a single transform, or (N, 4, 4) for per-frame transforms.

  • start_idx (int | None, optional) – First frame to transform (inclusive). None means 0.

  • end_idx (int | None, optional) – Last frame to transform (exclusive). None means end.

  • referential ({"world", "local"}, optional) –

    How to apply the transformation:

    • "world": Left-multiply. Sensors resampled to their times.

    • "local": Right-multiply on ego; conjugate onto sensors.

    Default is "world".

  • mode ({"auto", "conjugate", "interpolate"}, optional) – Mode for local referential. Default is "auto".

  • coverage ({"time", "bin"}, optional) – Coverage mode for world referential. Default is "bin".

Returns:

Self for method chaining.

Return type:

EgoEditor

Notes

World referential (left-multiply):

  • E2W’ = T_world @ E2W

  • S2W’ = T_world @ S2W (resampled to each sensor time)

Local referential (right-multiply):

  • E2W’ = E2W @ T_local

  • S2W’ = S2W @ (S2E^{-1} @ T_local @ S2E)

Examples

>>> T = np.eye(4)
>>> T[:3, 3] = [1, 0, 0]  # Translation
>>> scene.ego.apply_T_sequence(T, referential="world")
apply_T(T, **kwargs)[source]

Apply a single 4x4 transformation matrix.

Alias for apply_T_sequence() when passing a single transform.

Parameters:
  • T (np.ndarray) – 4x4 transformation matrix.

  • **kwargs – Additional arguments passed to apply_T_sequence().

Returns:

Self for method chaining.

Return type:

EgoEditor

transform(*, left=0.0, right=0.0, up=0.0, down=0.0, forward=0.0, backward=0.0, roll=0.0, pitch=0.0, yaw=0.0, start_idx=None, end_idx=None, referential='world')[source]

Apply both translation and rotation in a single operation.

Combines translation and rotation into a single SE(3) transformation applied to the ego rig.

Parameters:
  • left (float, optional) – Distance left (positive Y) in meters. Default is 0.

  • right (float, optional) – Distance right (negative Y) in meters. Default is 0.

  • up (float, optional) – Distance up (positive Z) in meters. Default is 0.

  • down (float, optional) – Distance down (negative Z) in meters. Default is 0.

  • forward (float, optional) – Distance forward (positive X) in meters. Default is 0.

  • backward (float, optional) – Distance backward (negative X) in meters. Default is 0.

  • roll (float, optional) – Rotation around X axis in degrees. Default is 0.

  • pitch (float, optional) – Rotation around Y axis in degrees. Default is 0.

  • yaw (float, optional) – Rotation around Z axis in degrees. Default is 0.

  • start_idx (int | None, optional) – First frame to transform (inclusive). None means all frames.

  • end_idx (int | None, optional) – Last frame to transform (exclusive). None means all frames.

  • referential ({"world", "local"}, optional) – Coordinate frame. Default is "world".

Returns:

Self for method chaining.

Return type:

EgoEditor

Examples

>>> scene.ego.transform(forward=5, left=1, yaw=10)
shift(*, forward=0.0, backward=0.0, left=0.0, right=0.0, up=0.0, down=0.0, start_idx=None, end_idx=None, referential='local')[source]

Translate the ego rig using semantic direction components.

Applies a translation to the ego vehicle and all attached sensors.

Parameters:
  • forward (float, optional) – Distance forward (positive X) in meters. Default is 0.

  • backward (float, optional) – Distance backward (negative X) in meters. Default is 0.

  • left (float, optional) – Distance left (positive Y) in meters. Default is 0.

  • right (float, optional) – Distance right (negative Y) in meters. Default is 0.

  • up (float, optional) – Distance up (positive Z) in meters. Default is 0.

  • down (float, optional) – Distance down (negative Z) in meters. Default is 0.

  • start_idx (int | None, optional) – First frame to shift (inclusive). None means all frames.

  • end_idx (int | None, optional) – Last frame to shift (exclusive). None means all frames.

  • referential ({"local", "world"}, optional) –

    Coordinate frame:

    • "local": Components in ego axes (default)

    • "world": Components in world axes

Returns:

Self for method chaining.

Return type:

EgoEditor

Examples

>>> scene.ego.shift(forward=5)  # Move forward 5m
>>> scene.ego.shift(left=2, up=0.5)  # Move left and up
>>> scene.ego.shift(forward=3, start_idx=10)  # From frame 10 onwards

See also

translate

Alias for shift.

transform

Combined translation and rotation.

translate(**kwargs)[source]

Translate the ego rig.

Alias for shift().

Parameters:

**kwargs – Arguments passed to shift().

Returns:

Self for method chaining.

Return type:

EgoEditor

rotate(*, roll=0.0, pitch=0.0, yaw=0.0, start_idx=None, end_idx=None, referential='local')[source]

Rotate the ego rig using Euler angles.

Applies a rotation to the ego vehicle and all attached sensors.

Parameters:
  • roll (float, optional) – Rotation around X (forward) axis in degrees. Default is 0.

  • pitch (float, optional) – Rotation around Y (left) axis in degrees. Default is 0.

  • yaw (float, optional) – Rotation around Z (up) axis in degrees. Default is 0.

  • start_idx (int | None, optional) – First frame to rotate (inclusive). None means all frames.

  • end_idx (int | None, optional) – Last frame to rotate (exclusive). None means all frames.

  • referential ({"local", "world"}, optional) – Coordinate frame. Default is "local".

Returns:

Self for method chaining.

Return type:

EgoEditor

Examples

>>> scene.ego.rotate(yaw=15)  # Turn 15° left
>>> scene.ego.rotate(roll=5, pitch=-2)  # Combined rotation
yaw_deg(deg, **kw)[source]

Rotate the ego rig around the Z (up) axis.

Shortcut for rotate(yaw=deg).

Parameters:
  • deg (float) – Yaw angle in degrees.

  • **kw – Additional arguments passed to rotate().

Returns:

Self for method chaining.

Return type:

EgoEditor

pitch_deg(deg, **kw)[source]

Rotate the ego rig around the Y (left) axis.

Shortcut for rotate(pitch=deg).

Parameters:
  • deg (float) – Pitch angle in degrees.

  • **kw – Additional arguments passed to rotate().

Returns:

Self for method chaining.

Return type:

EgoEditor

roll_deg(deg, **kw)[source]

Rotate the ego rig around the X (forward) axis.

Shortcut for rotate(roll=deg).

Parameters:
  • deg (float) – Roll angle in degrees.

  • **kw – Additional arguments passed to rotate().

Returns:

Self for method chaining.

Return type:

EgoEditor

spin(*, period=10, axis='z', start_idx=None, end_idx=None)[source]

Apply continuous rotation (spinning) to the ego rig.

Makes the ego vehicle rotate continuously around the specified axis. Useful for testing or special effects.

Parameters:
  • period (int, optional) – Frames per full revolution. Default is 10.

  • axis ({"x", "y", "z"}, optional) – Rotation axis. Default is "z" (vertical).

  • start_idx (int | None, optional) – First frame to apply spin (inclusive). None means 0.

  • end_idx (int | None, optional) – Last frame to apply spin (exclusive). None means end.

Returns:

Self for method chaining.

Return type:

EgoEditor

Raises:

ValueError – If period is not positive or indices are invalid.

Examples

>>> scene.ego.spin(period=20, axis="z")  # One revolution per 20 frames
smooth_lane_change(*, start_idx, duration, left=0.0, right=0.0, profile='min_jerk', kind='smooth', param='index', constant_speed=True, yaw_window=9, yaw_poly=2)[source]

Perform a smooth lane change maneuver.

Generates a smooth lateral displacement to simulate a lane change, with proper heading adjustments.

Parameters:
  • start_idx (int) – Frame index to start the maneuver.

  • duration (int) – Number of frames for the maneuver.

  • left (float, optional) – Lateral distance left in meters. Default is 0.

  • right (float, optional) – Lateral distance right in meters. Default is 0.

  • profile ({"min_jerk", "bezier"}, optional) –

    Curve profile:

    • "min_jerk": Minimum-jerk trajectory (default)

    • "bezier": Bezier curve

  • kind ({"smooth", "evasive"}, optional) –

    Maneuver type:

    • "smooth": Step to new lane position (default)

    • "evasive": Return to original lane after swerve

  • param ({"index", "arc"}, optional) – Parameterization method. Default is "index".

  • constant_speed (bool, optional) – Maintain constant speed during maneuver. Default is True.

  • yaw_window (int | None, optional) – Window size for yaw smoothing. Default is 9.

  • yaw_poly (int, optional) – Polynomial order for yaw smoothing. Default is 2.

Returns:

Self for method chaining.

Return type:

EgoEditor

Examples

>>> # Change to left lane
>>> scene.ego.smooth_lane_change(start_idx=10, duration=30, left=3.5)
>>> # Temporary evasive swerve
>>> scene.ego.smooth_lane_change(
...     start_idx=10, duration=30, left=2, kind="evasive"
... )
evasive_maneuver(*, start_idx, duration, left=0.0, right=0.0)[source]

Perform an evasive maneuver that returns to the original lane.

Generates a swerve maneuver where the ego moves laterally and then returns to its original lane position.

Parameters:
  • start_idx (int) – Frame index to start the maneuver.

  • duration (int) – Number of frames for the complete maneuver.

  • left (float, optional) – Maximum lateral distance left in meters. Default is 0.

  • right (float, optional) – Maximum lateral distance right in meters. Default is 0.

Returns:

Self for method chaining.

Return type:

EgoEditor

Examples

>>> scene.ego.evasive_maneuver(start_idx=20, duration=40, left=2)

See also

smooth_lane_change

General lane change with options.

normalize_camera_conventions(*, to='vehicle', verify=True)[source]

Convert all camera extrinsics to a consistent convention.

Normalizes all cameras to use the same coordinate convention, ensuring consistent behavior across the sensor rig.

Parameters:
  • to ({"vehicle", "opencv"}, optional) – Target coordinate convention. Default is "vehicle".

  • verify (bool, optional) – If True (default), verify each camera’s current convention before converting.

Returns:

Self for method chaining.

Return type:

EgoEditor

Notes

Coordinate conventions:

  • Vehicle: X-forward, Y-left, Z-up

  • OpenCV: X-right, Y-down, Z-forward

Examples

>>> scene.ego.normalize_camera_conventions(to="vehicle")