Bring up and test the Moleworks Terra ROS2 + IsaacLab stack in the correct Docker containers and tmux windows; use when starting/restarting isaac-terra + ros-terra, setting CycloneDDS/ROS_DOMAIN_ID, and validating /mole/state, /clock, TF, and basic node health.
Install
npx skillscat add idate96/codex-skills/moleworks-terra-stack Install via the SkillsCat registry.
SKILL.md
Moleworks Terra Stack (IsaacLab + ROS2)
Non-negotiables
- Always run IsaacLab scripts via
/workspace/isaaclab/isaaclab.sh -p. - Always open a new tmux window for IsaacLab or ROS commands; capture the pane output after each command.
- When launching long commands via
tmux send-keys, run them asbash -lc '...; exec bash -i'so the pane stays open on early failures. - Always set the same
ROS_DOMAIN_IDon both sides (example:24). - Only force the DDS implementation if needed:
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp(optional; otherwise use the distro default)export CYCLONEDDS_URI=...(optional; only if you need a custom CycloneDDS config)
- For TF/topics checks, use long timeouts (10-15s).
- Most general ROS launch entry points live under
mole_bringup/launch(e.g.,terra.launch.py,robot.launch.py,nav2.launch.py).
Bring up Isaac container (isaac-terra window)
To allow agents in the ROS container to restart Isaac, start Isaac as a restartable service (not docker compose run --rm).
- Host:
tmux new-window -n isaac-terra- Host: start the dev container as a service:
cd ~/moleworks/moleworks_ext/docker
docker compose --env-file .env.moleworks_ext-dev \
-f docker-compose.yaml -f docker-compose.override.yaml \
up -d isaac-lab-ext-dev- (Optional) Tail logs:
docker logs -f isaac-lab-moleworks_ext-devBring up ROS container (ros-terra window)
If you need agents inside ROS to control Isaac, you MUST mount the host Docker socket into the ROS container.
- Host:
tmux new-window -n ros-terra- Host: launch the ROS container with the docker socket:
cd ~/moleworks/ros2_ws/src/moleworks_ros/docker
./docker_launch.sh moleworks_ros:latest mole.Dockerfile --docker-sock- Inside ROS container (match DDS + domain):
export ROS_DOMAIN_ID=24
source /opt/ros/jazzy/setup.bash
source "$HOME/moleworks/ros2_ws/install/setup.bash"- Capture output:
tmux capture-pane -p -S -200Start sim from ROS (sim-terra window)
This runs IsaacLab Terra inside the Isaac container, triggered from the ROS container via /var/run/docker.sock.
- Host:
tmux new-window -n sim-terra- Inside ROS container:
export ROS_DOMAIN_ID=24
mole_sim_ctl terra- Capture output:
tmux capture-pane -p -S -200Health checks (ros-check window)
Run these inside the ROS container (new ros-check window recommended):
tmux new-window -n ros-check# 1) Topic exists + message arrives
ros2 topic list | rg /mole/state
# Sim publishes /mole/state; on Jazzy you typically need best-effort QoS:
timeout 60 ros2 topic echo /mole/state --once --qos-reliability best_effort
# 2) Sim time is publishing
timeout 60 ros2 topic echo /clock --once
# 3) TF sanity (use a real frame pair if known)
# Example only; adjust frames to your setup
# timeout 15 bash -c 'ros2 run tf2_ros tf2_echo map base_link 2>&1' | head -20Always capture output:
tmux capture-pane -p -S -200Restart workflow
- Restart Isaac dev container from inside ROS container:
mole_sim_ctl restart- then re-run
mole_sim_ctl terra - then re-run
mole_state
Troubleshooting quick hits
- No /mole/state: verify both sides have the same
ROS_DOMAIN_IDandRMW_IMPLEMENTATION=rmw_cyclonedds_cpp, and Isaac is still running. - CycloneDDS/serdata errors: if you've been connected to a robot via FastDDS discovery server, try
unset FASTRTPS_DEFAULT_PROFILES_FILE ROS_DISCOVERY_SERVERon both sides. - "Failed to find a free participant index": set
CYCLONEDDS_URIto a CycloneDDS config in each container (examples: Isaac:$HOME/moleworks/moleworks_ext/.ros/cyclonedds.xml, ROS:$HOME/moleworks/ros2_ws/src/moleworks_ros/.ros/cyclonedds.xml). - No messages but topic exists: likely QoS mismatch; use
--qos-reliability best_effortwhen echoing/mole/state. - TF lookup fails: use long timeouts and confirm frames exist; TF can take a few seconds to appear.