Getting Started¶
This guide will help you get started with the MIMIC Scene Edition API.
Installation¶
You write scene edits against the client SDK, qvyon-mimic-sdk (imported as
mimic_sdk). Your script records an op-list; MIMIC replays it and renders the
result. Nothing executes locally, so the SDK needs no GPU, no scene data and no
checkout of this repository — only the standard library.
The standalone package¶
The SDK ships as one zip holding the wheel, ten worked examples, this documentation and a VS Code project:
qvyon-mimic-sdk-standalone-<version>.zip
├── wheel/qvyon_mimic_sdk-<version>-py3-none-any.whl
├── examples/s01_ego_lane_offset.py …
├── docs/index.html
├── pyproject.toml
└── .vscode/
Unzip it and run an example. uv fetches a Python
interpreter, installs the wheel from wheel/ and runs the script — that is the
whole setup:
uv run examples/s01_ego_lane_offset.py
In VS Code, open the folder, run uv sync once, then press F5. The debug list
holds every example by name, and justMyCode is off, so a breakpoint inside
scene.ego.shift(...) hits.
To install the wheel into an environment you already have (any Python ≥ 3.10):
pip install wheel/qvyon_mimic_sdk-<version>-py3-none-any.whl
What a script looks like¶
from mimic_sdk.scene_edition import MimicSceneEditor
client = MimicSceneEditor.login() # resolves the local store
scene = client.open_scene(sequence_id="lane_occlusion")
with scene.generate_variant("truck_at_45") as variant:
variant.ego.shift(left=1.0)
truck = variant.insert_static_actor(
actor_id="actor_10021", at_idx=60, yaw=45.0
)
variant.actor(truck).shift(forward=3.0)
print(client.document_path())
client.submit_variant("truck_at_45") # one variant, ops inline
Every method call appends an op; leaving the block cleanly saves the variant to
~/.mimic/variants/<sequence_id>/<script_id>.variant.json. A block that raises
writes nothing, and each variant is a fork of the baseline rather than a
continuation of the previous one.
Building the package¶
Maintainers regenerate the zip from the current op catalog with:
moon run mimic-scene-edition:package-sdk # or: tools/package_standalone_sdk.sh
# → build/dist/qvyon-mimic-sdk-standalone-<version>.zip
Working on this library¶
mimic-scene-edition itself is the server-side library that executes op-lists. It
pins Python 3.10 (requires-python = ">=3.10,<3.11") because of its native
dependencies, which is exactly why the client SDK is a separate, pure-stdlib package.
From a clone of the repository:
uv sync # add --all-groups for dev + docs extras
uv pip install -e .
uv run pytest -v
The recorder/decoder fidelity report doubles as the CI gate for the op-list lane and
is also installed as the mimic-oplist-verify command:
uv run python -m mimic_scene_edition.oplist.verify
uv run python -m mimic_scene_edition.oplist.verify s01 s10 # narrow to a few
Basic Concepts¶
Coordinate Frames¶
The API uses two coordinate frames:
Local (Vehicle) Frame: - X: Forward - Y: Left - Z: Up
World Frame: - Fixed global coordinates - Scene-dependent orientation
Most methods accept a referential parameter to specify which frame to use.
Fluent Interface¶
All editor methods return self, enabling method chaining:
scene.ego.shift(forward=5).rotate(yaw=15).stop(at_idx=50)
This is equivalent to:
scene.ego.shift(forward=5)
scene.ego.rotate(yaw=15)
scene.ego.stop(at_idx=50)
Value Limits¶
When limited_mode=True, transformation parameters are constrained to
prevent extreme edits. This is useful for generating realistic variations.
See Limits for the default allowed ranges per parameter.
Editor Hierarchy¶
SceneEditor (scene)
├── ego → EgoEditor
│ └── Manages ego trajectory and sensor rig
├── actor(id) → ActorEditor
│ └── Manages individual actor trajectories
├── camera(ref) → SensorEditor
├── lidar(ref) → SensorEditor
└── radar(ref) → SensorEditor
Common Operations¶
Ego Vehicle¶
# Move ego forward
scene.ego.shift(forward=5)
# Rotate ego
scene.ego.rotate(yaw=15)
# Stop ego at frame 50
scene.ego.stop(at_idx=50)
# Change speed
scene.ego.speed(multiplier=0.8)
# Lane change maneuver
scene.ego.smooth_lane_change(
start_idx=20,
duration=40,
left=3.5
)
Actors¶
# Get actor editor
actor = scene.actor(4)
# Displace along path
actor.displace(forward=20)
# Shift laterally (change lanes)
actor.shift(left=3.5)
# Rotate
actor.rotate(yaw=90)
# Stop actor
actor.stop(at_idx=30)
# Change speed
actor.speed(multiplier=1.5)
Sensors¶
# Access by name
cam = scene.camera("FRONT")
# Shift sensor position
cam.shift(up=0.05, forward=0.1)
# Rotate sensor
cam.rotate(pitch=-2)
# Scale resolution
cam.scale_camera_resolution(scale=0.5)
# Set intrinsics
cam.set_camera_intrinsics(fx=1000, fy=1000, cx=960, cy=540)
Inserting Actors¶
# Insert actor on ego trajectory
new_id = scene.insert_actor_on_ego_trajectory(
4, # source actor ID
forward=30,
left=3.5
)
# Insert static actor
new_id = scene.insert_static_actor(
4,
at_idx=0,
forward=20,
yaw=90
)
# Create crossing pedestrian
new_id = scene.crossing(
pedestrian_id,
start=20,
end=60,
forward=15,
direction="right_to_left"
)
AutoSplat Runtime Toggles¶
Mute or restore the AutoSplat per-frame appearance residual (brake lights,
blinkers, and other dynamic overlays). These methods only take visible effect
inside the render pipeline; in a pure offline editor the call is recorded in
editions but is otherwise a no-op.
# Mute the appearance residual for the whole scene
scene.object_appearance(False)
# Re-enable it for a single actor
scene.actor(28).object_appearance(True)
Debugging¶
All modifications are tracked:
# Get list of all edits
mods = scene.get_modifications()
for mod in mods:
print(f"{mod['method']}: {mod['description']}")
Reset to original state:
scene.reset()