Run, build, and verify FR3 Gazebo simulation end-to-end. Handles colcon build, launch commands, topic inspection, and output interpretation. Use whenever the user needs to start a simulation, test a code change in Gazebo, check sensor topics, or debug launch failures. Trigger phrases include 仿真, simulation, gazebo, 跑一下, launch, ign topic, 编译, build and run, 试试.
Owns the full build-launch-verify cycle for FR3 Gazebo simulation. Every time simulation is involved, this skill's rules apply.
Every simulation-related response MUST include:
colcon build yourself (never ask the user to build)No exceptions. If you skip any of these three, the user wastes a round-trip.
Always build before giving launch commands. Use absolute paths:
source <ros_distro_path>/setup.bash
source <your_workspace>/install/setup.bash
colcon build \
--build-base <your_workspace>/build \
--install-base <your_workspace>/install \
--base-paths <your_workspace>/src \
--packages-select <PACKAGE_NAMES>
After build, verify the installed files match the source:
Known trap: This workspace has duplicate directories:
src/franka_gazebo_bringup/ — the real colcon package (this is what gets built)src/franka_gazebo/franka_gazebo_bringup/ — git subdir, NOT a separate packageAlways edit files in src/franka_gazebo_bringup/ (or whatever package.xml belongs to). After build, always verify the installed file has your changes.
Default: give the user a single script that:
timeout auto-shutdownLog directory convention:
sim_logs/YYYYMMDD_HHMMSS/
├── launch.log # Full launch stdout+stderr
├── ign_topics.log # ign topic -l snapshot
├── ft_sensor.log # FT sensor data sample (if applicable)
├── ros2_topics.log # ros2 topic list snapshot
├── estimated_wrench.log # Controller wrench publisher (if applicable)
└── summary.txt # Auto-generated: duration, exit code, key grep results
Template for packaged run script:
Every script MUST start with a build step. The user should never need to build separately.
#!/bin/bash
# — Auto-generated simulation test —
# Run from anywhere. Logs saved to sim_logs/<timestamp>/
set -e
LOG_DIR=<your_workspace>/sim_logs/$(date +%Y%m%d_%H%M%S)
mkdir -p "$LOG_DIR"
echo "Logs → $LOG_DIR"
# Build first (always)
source <ros_distro_path>/setup.bash
source <your_workspace>/install/setup.bash
colcon build \
--build-base <your_workspace>/build \
--install-base <your_workspace>/install \
--base-paths <your_workspace>/src \
--packages-select <PACKAGE_NAMES> \
> "$LOG_DIR/build.log" 2>&1
source <your_workspace>/install/setup.bash # re-source after build
# Clean residual processes
pkill -f "ign gazebo" 2>/dev/null || true
pkill -f "controller_manager" 2>/dev/null || true
pkill -f "robot_state_publisher" 2>/dev/null || true
sleep 2
source <your_workspace>/install/setup.bash
# Start simulation with timeout (background)
timeout <DURATION>s \
ros2 launch <PACKAGE> <LAUNCH_FILE> <ARGS> \
> "$LOG_DIR/launch.log" 2>&1 &
SIM_PID=$!
# Wait for controller to activate (poll launch.log)
echo "Waiting for controller activation..."
for i in $(seq 1 60); do
if grep -q "Configured and activated" "$LOG_DIR/launch.log" 2>/dev/null; then
echo "Controller active after ${i}s"
break
fi
sleep 1
done
# Capture topic snapshots
ign topic -l > "$LOG_DIR/ign_topics.log" 2>&1 || true
ros2 topic list > "$LOG_DIR/ros2_topics.log" 2>&1 || true
# Capture topic data samples (run for a few seconds then kill)
# <ADD TOPIC-SPECIFIC CAPTURES HERE>
# Wait for simulation to finish (timeout auto-kills)
wait $SIM_PID 2>/dev/null || true
EXIT_CODE=$?
# Generate summary
{
echo "=== Simulation Run Summary ==="
echo "Time: $(date)"
echo "Duration: <DURATION>s (timeout)"
echo "Exit code: $EXIT_CODE"
echo ""
echo "=== Key Log Lines ==="
grep -E "Configured and activated|Contact detected|Failed to load|\\[Err\\]|ft_sensor" \
"$LOG_DIR/launch.log" 2>/dev/null || echo "(no key lines found)"
echo ""
echo "=== Ignition Topics ==="
cat "$LOG_DIR/ign_topics.log" 2>/dev/null || echo "(empty)"
echo ""
echo "=== ROS 2 Topics ==="
cat "$LOG_DIR/ros2_topics.log" 2>/dev/null || echo "(empty)"
} > "$LOG_DIR/summary.txt"
cat "$LOG_DIR/summary.txt"
echo ""
echo "Full logs: $LOG_DIR/"
When generating this script, always fill in <DURATION>, <PACKAGE>, <LAUNCH_FILE>, and add test-specific topic captures.
After the user says "跑完了", read sim_logs/ for the latest run's summary.txt and relevant logs.
Only use when the user explicitly wants interactive control. Always give full blocks:
# Terminal 1 — start simulation
source <your_workspace>/install/setup.bash
ros2 launch franka_gazebo_bringup gazebo_hybrid_circle_force.launch.py
For topic inspection:
# Terminal 2
source <your_workspace>/install/setup.bash
ros2 topic list | grep <PATTERN>
ros2 topic echo <FULL_TOPIC_NAME>
For Ignition-side topics:
ign topic -l | grep <PATTERN>
ign topic -e -t <FULL_TOPIC_PATH>
After giving commands, always tell the user:
Configured and activated hybrid_circle_force_controller"Failed to load system plugin"timed out, wait 10 more seconds, it's normal for large URDFs"[Err]"This workspace uses Ignition Gazebo Fortress (version 6). Critical naming differences:
| What | Fortress (us) | Garden+ |
|---|---|---|
| Namespace | ignition::gazebo::systems:: | gz::sim::systems:: |
| Plugin prefix | ignition-gazebo- | gz-sim- |
| CLI command | ign topic | gz topic |
| Plugin class example | ignition::gazebo::systems::ForceTorque | gz::sim::systems::ForceTorque |
Before writing any Gazebo plugin/sensor/system XML:
.so file: ls /usr/lib/x86_64-linux-gnu/ign-gazebo-6/plugins/strings <file>.so | grep "ignition::gazebo"For any Gazebo/ROS integration (plugins, sensors, bridges, URDF extensions):
franka_ros2 official repo — same branch first, then jazzyfranka_ros (ROS 1) — has mature Gazebo Classic implementationsros_gz examples — for bridge syntax and message type mappingsFor the standard force-control experiment:
cd <your_workspace>/src
source <your_workspace>/install/setup.bash
bash run_hybrid_circle_force_experiment.sh
This runs 1 sim (15s), collects data, generates report.md.
Before starting a new simulation, always clean residual processes:
# Kill leftover Gazebo / controller processes
pkill -f "ign gazebo" 2>/dev/null
pkill -f "controller_manager" 2>/dev/null
pkill -f "robot_state_publisher" 2>/dev/null
sleep 2
The terminate called ... Node needs to be associated with an executor crash on Ctrl+C is a known bug in IgnitionROS2ControlPlugin destructor. It is harmless — ignore it.
After generating a simulation run command or script, always copy it to the user's clipboard:
echo "<command>" | xclip -selection clipboard
Then tell the user: "已复制到剪切板,直接粘贴运行。"
This applies to both one-liner commands and script paths (e.g., bash <your_workspace>/run_ft_sensor_test.sh).
Before giving the user any simulation command:
colcon build myself?source included?xclip?