When to Use
- A
scene_*_g2_{op,sp}is running (via thelaunch-sceneskill) and the user wants planning + RViz on top. - User wants to switch the active IK plugin or A/B the GenieBioIK "human priors" (torso-straight, chassis-pin, head LookAt).
- User wants to drive the arm directly via
/joint_command(e.g.wok_flip_cmds.py) without ros2_control fighting the publisher.
Do not use for:
- Robots other than Genie G2 — the SRDF, coupled-joint constraints, and ros2_controllers manifest are G2-only. Other robots run on the engine but don't have a packaged MoveIt config.
- Launching the simulator itself →
launch-sceneskill. - Building the workspace →
build-workspaceskill.
Critical Patterns
armandgripperare independent. Defaults arearm:=crsB gripper:=swiftpicker. The launch wires both into the URDF filename and the SRDF xacro mappings, so any(arm, gripper)combo that has a corresponding URDF undergenie_sim_robot_model/urdf/works.- Match MoveIt's
(arm, gripper)to the scene's robot variant.scene_pnp_g2_op→gripper:=omnipicker,scene_wbc_g2_sp→gripper:=swiftpicker. Mismatched values produce a URDF MoveIt can plan against but a robot the engine refuses to drive. - Pick the IK plugin via
use_human_priors, not by editing yaml.use_human_priors:=true(default) loadsconfig/kinematics.yaml(GenieBioIK with priors);use_human_priors:=falseloadsconfig/kinematics_vanilla.yaml(upstream BioIK, every prior weight zeroed). Both files share the plugin selection / IK links / timeouts so the only A/B variable is the goal stack. use_ros2_control:=falsefor/joint_commanddriving. When an external publisher (teleop, wok-flip script) writes/joint_command, the ros2_control node would republish at the CM update rate and fight it — set this flag to leavemove_groupalone (the/compute_ik,/compute_fkservices) so there's a single source on the topic.
The matrix
Scene (from launch-scene) | Recommended wbc.launch.py args |
|---|---|
scene_pnp_g2_op | arm:=crsB gripper:=omnipicker |
scene_wbc_g2_sp | arm:=crsB gripper:=swiftpicker (defaults) |
scene_flat_g2_sp / _chef / _shirt | defaults (crsB + swiftpicker) |
| IK plugin / mode | Args |
|---|---|
| GenieBioIK with human priors (default) | use_human_priors:=true |
| Upstream BioIK (priors zeroed, for A/B) | use_human_priors:=false |
move_group only — /compute_ik services, no controllers | use_ros2_control:=false |
Workflow
Step 1 — Confirm the scene is up
launch-scene skill should already be running in another shell.
Verify:
bashros2 topic list | grep -E "joint_states|tf|clock" ros2 topic hz /clock # sim-time pacing should be live
Step 2 — Pick arm + gripper
Ask via AskUserQuestion if not given. Default to the scene's
gripper (see matrix above).
Step 3 — Launch MoveIt
bashsource devel/setup.bash # Default (Genie G2 + crsB + swiftpicker + human priors + ros2_control): ros2 launch genie_sim_moveit wbc.launch.py # crs arm + omnipicker: ros2 launch genie_sim_moveit wbc.launch.py arm:=crs gripper:=omnipicker # A/B vanilla BioIK (priors disabled): ros2 launch genie_sim_moveit wbc.launch.py use_human_priors:=false # Direct /joint_command (e.g. external teleop / wok_flip_cmds.py): ros2 launch genie_sim_moveit wbc.launch.py use_ros2_control:=false
Step 4 — Plan in RViz
The launch starts move_group, robot_state_publisher, and
rviz2 with the MoveIt-Plan-Execute panel. Drag the interactive
marker on the IK link, hit Plan, then Execute.
Step 5 — (optional) Drive the chassis as a single chain
simple_body_controller claims the same body-joint position
interfaces as simple_waist_controller + simple_torso_controller,
so it's configured but not auto-spawned. To drive the body as one
chain:
bashros2 control switch_controllers \ --activate simple_body_controller \ --deactivate simple_waist_controller simple_torso_controller
Commands (copy-paste summary for the user)
bash# Inside the container, after sourcing the overlay: source devel/setup.bash # Most common: match a pnp scene ros2 launch genie_sim_moveit wbc.launch.py arm:=crsB gripper:=omnipicker # A/B the human priors ros2 launch genie_sim_moveit wbc.launch.py use_human_priors:=false # move_group only (for external /joint_command publishers) ros2 launch genie_sim_moveit wbc.launch.py use_ros2_control:=false
Notes
- The MoveIt URDF joint limits are widened by ±0.01 rad / ±0.001 m
at launch time to absorb MuJoCo soft-limit drift —
CheckStartStateBoundsreads URDF limits directly, so the per-pipelinestart_state_max_bounds_errordoesn't help. Helper lives ingenie_sim_robot_model.urdf_utils.pad_urdf_joint_limits. - Default workspace half-extent for OMPL planar-joint bounds is set
to 200 m via
ompl.default_workspace_bounds— without this,FixWorkspaceBoundsclampsplanar_joint/trans_{x,y}to a narrow box that excludes the actual map → base_link pose. fix_start_state:=truelets jazzy'sCheckStartStateBoundsadapter actively renormalise joint values that drift past<limit>by sub-mrad under contact load (default upstream is false).- The MoveIt config is distro-agnostic (Humble + Jazzy). Distro
drift is absorbed by
moveit_compat.hppingenie_sim_moveit_plugins/, never by#ifdefin the config package.
Resources
- Launch file: source/geniesim_ros/src/ros_ws/src/genie_sim_moveit/launch/wbc.launch.py
- Per-gripper SRDF fragments: source/geniesim_ros/src/ros_ws/src/genie_sim_moveit/config/srdf_grippers/
- IK plugins: source/geniesim_ros/src/ros_ws/src/genie_sim_moveit_plugins/
- MoveIt config overview: source/geniesim_ros/src/ros_ws/src/genie_sim_moveit/AGENTS.md

