mj — MuJoCo free-flyer sim wrapper
Purpose
FFSimwraps MuJoCo for the free-flying chaser: it builds the scene (target mesh + chaser robot,
optional starfield/mocap marker), drives kinematic display or force-driven playback, counts
non-capsule collisions, and writes offline MP4s. An offline-only, visualization/diagnostic tool —
the live control loop never imports it.
Role in the system
- Visualization / collision-check layer, not part of the live control chain (no GNC module imports it).
- Consumes robot (
GiordanoRobotfor kinematics) and parameter_loader (load_parametersfor cfg). - Pulls the target mesh path and reach config from
cfg.camera_guidance.targeting(built from mesh geometry). - Uses infra for
next_filename(MP4 naming) andRecursiveNamespace(robot-variant cfg override). render_log_videoreplays a saved run’s loggedqkinematically — pairs with the runner/orchestrator log pipeline.
Inputs / Outputs
- In: a Pinocchio config
q_pin(xyzw quat) or full statex = [q; v]; optional controlu(applied asqfrc_applied); aStatesrecord (x,u); or a saved NPZ log path. - Out:
mj_data(forward-evaluated), integer collision counts, and an MP4 written tovideos/(path inself.last_video_path).
Key methods / functions
FFSim.create_scene— build theMjSpec(mesh, chaser, lights, stars, mocap) —utils/mj.py:47FFSim.display_config— set qpos andmj_forward(kinematics only, no dynamics) —utils/mj.py:152FFSim.sim_config— set state, apply clippeduasqfrc_applied,mj_forward—utils/mj.py:162FFSim.collision_count— non-capsule contact-pair count at a config —utils/mj.py:193FFSim.configure_camera— auto-frame the chaser+target shot —utils/mj.py:239FFSim.display_traj— live viewer or offline MP4 of a trajectory; returns total collisions —utils/mj.py:291render_log_video— replay a saved log’sqkinematically to an MP4 (robot variant inferred from row width) —utils/mj.py:419pin_to_mj_qpos/mj_to_pin_qpos— quaternion-order conversion (xyzw ↔ wxyz) —utils/mj.py:442/:451count_contacts_no_capsules— module collision predicate (drops_capsulegeoms + self-contacts) —utils/mj.py:486
Pseudocode (offline playback)
FFSim(cfg, q_pin) → create_scene → compile → MjData # gravity-free free-flyer
for each step q (and optional u):
sim_config(q, u) if u else display_config(q) # dynamics vs kinematics-only
n_fr = count_contacts_no_capsules(model, data) # ignore *_capsule + self pairs
frame = add_text(renderer.render(), f"collisions: {n_fr}")
write_video(next_filename(stem, "videos", ".mp4"), frames)
Related
robot · parameter_loader · infra · mesh · plotter3d · runner · terminology