|
Mujoco KDL Wrapper
0.1.0
MuJoCo + KDL bridge for robot kinematics and dynamics
|
All examples use the Kinova GEN3 7-DOF arm and Robotiq 2F-85 gripper from MuJoCo Menagerie. Requires -DFETCH_MENAGERIE=ON at configure time.
Build from the repo root:
Every example accepts --headless to skip the GLFW window and run a fixed number of physics steps, printing a brief result to stdout.
| Example | Scene | Main behavior |
|---|---|---|
ex_gravity_comp | arm only | hold home pose with KDL gravity compensation |
ex_pos_ctrl | arm only | position trajectory tracking |
ex_vel_ctrl | arm only | velocity-style convergence control |
ex_impedance | arm + gripper | joint impedance with gripper inertia |
ex_table_scene | table + free objects | table/object scene construction |
ex_pick | floor cube | scripted pick and lift |
ex_table_pick_place | table + blue cube | scripted tabletop pick, transfer, release, and retreat |
ex_table_pour | table + transparent receiver | scripted pour from small gripper-held bottle into a tabletop vessel |
ex_rnea_pick_place | table + blue cube | Cartesian target interpolation with IK + RNEA inverse dynamics |
ex_achd_table_slide | table contact | ACHD partial constraint comparison with wrist/table support |
ex_achd_pick_place | table + blue cube | ACHD Cartesian pick/place with 6D TCP regulation and half-arm support wrench |
ex_dual_arm | two arms + grippers | multi-robot scene with independent KDL chains |
ex_record | arm only | headless MP4 recording |
Scene: Kinova GEN3 arm (arm only, no gripper).
What it does:
Control law: CtrlMode::TORQUE — KDL gravity compensation.
Headless output: EE drift after 500 steps: X.XXX mm
Scene: Kinova GEN3 arm (arm only, no gripper).
What it does:
kMotionDuration = 2.0 s.Control law: CtrlMode::POSITION — MuJoCo's built-in position actuator.
The wrapper's update() writes jnt_pos_cmd to MuJoCo ctrl[] each step; the actuator handles the PD tracking internally.
Headless output: max joint error at end: X.XXXX rad (after motion + 1 s settle).
Scene: Kinova GEN3 arm + Robotiq 2F-85 gripper attached at bracelet_link.
What it does:
fmod(t, 6) < 3 ? 255 : 0).tool_body = "g_base" so gripper inertia is lumped into the last segment — gravity compensation is correct for the full arm+gripper mass.Control law: CtrlMode::TORQUE — PD + KDL gravity.
Headless output: EE drift after 200 steps: X.XXX mm
Scene: Kinova GEN3 + 2F-85 gripper, mounted on a table (z = 0.7 m surface) with five free objects: 3 boxes (red, green, blue) and 2 spheres (orange, purple).
What it does:
SceneSpec with an MJCF table asset and five primitive SceneObject entries using Shape::BOX and Shape::SPHERE.Control law: CtrlMode::TORQUE — KDL gravity compensation.
Headless output: EE drift after 500 steps: X.XXX mm
Scene: Kinova GEN3 + 2F-85 gripper + orange cube (4 cm, mass 0.1 kg) on the floor.
What it does:
HOME -> PREGRASP -> GRASP -> CLOSE -> LIFT -> HOLDKDL::ChainIkSolverPos_NR_JL with joint limits, seeded from each prior solution.q_enter) to the IK target over a nominal duration, transitioning when both elapsed time and joint error criteria are met (or on timeout).Control law: CtrlMode::TORQUE — joint impedance (PD + KDL gravity) throughout all states.
State table (durations in seconds):
| State | Duration | Timeout | Settle tol | Gripper |
|---|---|---|---|---|
| HOME | 1.0 | 2.5 | 0.08 rad | open |
| PREGRASP | 2.0 | 4.0 | 0.08 rad | open |
| GRASP | 2.0 | 4.0 | 0.06 rad | open |
| CLOSE | 1.5 | 2.5 | (none) | closed |
| LIFT | 3.0 | 5.0 | 0.08 rad | closed |
| HOLD | 10.0 (GUI) / 1.0 (headless) | same | (none) | closed |
Headless output: cube Z after pick: X.XXX m
Scene: Kinova GEN3 + 2F-85 gripper mounted on a table, with a blue cube on the tabletop.
What it does:
SceneObject and places the robot base on the tabletop surface.HOME -> PICK_ABOVE -> PICK -> CLOSE -> LIFT -> PLACE_ABOVE -> PLACE -> OPEN -> RETREAT -> HOLDControl law: CtrlMode::TORQUE — joint impedance (PD + KDL gravity), matching ex_pick.
Headless output: cube final position: [x, y, z] target=[x, y, z] xy_error=X.XXX gripper=open
Scene: Kinova GEN3 + 2F-85 gripper mounted on a table, with a transparent receiver vessel and small free spheres representing rice or pellets.
What it does:
ToolFrameSpec::tool_body.pour_center site frame.Control law: CtrlMode::TORQUE — joint impedance (PD + KDL gravity), matching the pick examples.
Headless output: balls in transparent receiver: N/36
The ACHD examples use ChainHdSolver_Vereshchagin_Fixed_Joint to convert Cartesian task accelerations into constrained joint accelerations. For MuJoCo torque control, the examples command the full inverse-dynamics torque computed from that ACHD qddot:
ex_achd_table_slide compares table-supported motion with linear-Z constrained vs unconstrained.ex_achd_pick_place runs a pick/place sequence. During the place-side phases it feeds an ACHD-only upward support wrench on half_arm_2_link to keep the elbow/half-arm from dropping while preserving the TCP task.Run headless:
Scene: Two Kinova GEN3 arms with 2F-85 grippers in a shared simulation. arm1 at x = -1.0 m, arm2 at x = +1.0 m with prefix r2_.
What it does:
SceneSpec with different positions and prefixes.Robot handles and KDL chains from the same compiled mjModel by passing matching base_link/bracelet_link names with the correct prefix ("" vs "r2_").jnt_trq_cmd is primed before the loop so the very first physics step already gets correct gravity compensation.Control law: CtrlMode::TORQUE — PD + KDL gravity for both arms independently.
Each arm calls update() and JntToGravity separately every step.
Headless output: EE Cartesian positions for both arms after 600 steps.
Scene: Kinova GEN3 arm (arm only).
What it does:
VideoRecorder (EGL offscreen rendering + ffmpeg pipe).kFps = 60 Hz regardless of the physics timestep (steps_per_frame = floor(1 / (fps * dt))).Control law: CtrlMode::TORQUE — KDL gravity compensation.
Usage:
Resolution presets map to 16:9 dimensions (R1080p = 1920x1080, etc.). Default is 1080p; output file defaults to sim.mp4.
Requires: BUILD_RECORDER=ON (default) and ffmpeg in PATH.