|
| 1 | +# Gazebo Classic to Gazebo Sim Migration Guide |
| 2 | + |
| 3 | +This document describes the migration from Gazebo Classic to Gazebo Sim (formerly Ignition Gazebo) for the hunter_robot package. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +The hunter_gazebo package now supports both Gazebo Classic and Gazebo Sim, allowing users to choose their preferred simulation environment. |
| 8 | + |
| 9 | +## What Changed |
| 10 | + |
| 11 | +### 1. Package Dependencies (hunter_gazebo/package.xml) |
| 12 | + |
| 13 | +Added new dependencies for Gazebo Sim while keeping Gazebo Classic dependencies: |
| 14 | + |
| 15 | +```xml |
| 16 | +<exec_depend>ros_gz_sim</exec_depend> |
| 17 | +<exec_depend>ros_gz_bridge</exec_depend> |
| 18 | +<exec_depend>gz_ros2_control</exec_depend> |
| 19 | +``` |
| 20 | + |
| 21 | +### 2. Launch Files |
| 22 | + |
| 23 | +- **launch_sim.launch.py** (unchanged): For Gazebo Classic |
| 24 | +- **launch_gz_sim.launch.py** (new): For Gazebo Sim |
| 25 | + |
| 26 | +Key differences in the Gazebo Sim launch file: |
| 27 | +- Uses `ros_gz_sim/gz_sim.launch.py` instead of `gazebo_ros/gazebo.launch.py` |
| 28 | +- Uses `ros_gz_sim/create` instead of `gazebo_ros/spawn_entity.py` |
| 29 | +- Adds clock bridge: `/clock@rosgraph_msgs/msg/Clock[gz.msgs.Clock` |
| 30 | +- Uses `controller_manager/spawner` nodes instead of `ExecuteProcess` with ros2 CLI |
| 31 | + |
| 32 | +### 3. URDF/Xacro (hunter_description/description/ros2_control.xacro) |
| 33 | + |
| 34 | +Added Gazebo Sim plugin while keeping the Gazebo Classic plugin: |
| 35 | + |
| 36 | +```xml |
| 37 | +<!-- Gazebo Classic plugin --> |
| 38 | +<gazebo> |
| 39 | + <plugin filename="libgazebo_ros2_control.so" name="gazebo_ros2_control"> |
| 40 | + <parameters>$(find-pkg-share hunter_description)/config/ackermann_like_controller.yaml</parameters> |
| 41 | + </plugin> |
| 42 | +</gazebo> |
| 43 | + |
| 44 | +<!-- Gazebo Sim (Ignition/Gz) plugin --> |
| 45 | +<gazebo> |
| 46 | + <plugin filename="libgz_ros2_control-system.so" name="gz_ros2_control::GazeboSimROS2ControlPlugin"> |
| 47 | + <parameters>$(find-pkg-share hunter_description)/config/ackermann_like_controller.yaml</parameters> |
| 48 | + </plugin> |
| 49 | +</gazebo> |
| 50 | +``` |
| 51 | + |
| 52 | +Also updated the parameter path syntax from `$(find ...)` (ROS1 style) to `$(find-pkg-share ...)` (ROS2 style). |
| 53 | + |
| 54 | +## Usage |
| 55 | + |
| 56 | +### Gazebo Sim (Recommended) |
| 57 | + |
| 58 | +```bash |
| 59 | +ros2 launch hunter_gazebo launch_gz_sim.launch.py |
| 60 | +``` |
| 61 | + |
| 62 | +### Gazebo Classic (Legacy) |
| 63 | + |
| 64 | +```bash |
| 65 | +ros2 launch hunter_gazebo launch_sim.launch.py |
| 66 | +``` |
| 67 | + |
| 68 | +### Teleop Control (works with both) |
| 69 | + |
| 70 | +```bash |
| 71 | +ros2 run teleop_twist_keyboard teleop_twist_keyboard --ros-args --remap cmd_vel:=/ackermann_like_controller/cmd_vel |
| 72 | +``` |
| 73 | + |
| 74 | +## Technical Details |
| 75 | + |
| 76 | +### Controller Loading |
| 77 | + |
| 78 | +**Gazebo Classic approach** (ExecuteProcess): |
| 79 | +```python |
| 80 | +load_joint_state_broadcaster = ExecuteProcess( |
| 81 | + cmd=['ros2', 'control', 'load_controller', '--set-state', 'active', |
| 82 | + 'joint_state_broadcaster'], |
| 83 | + output='screen' |
| 84 | +) |
| 85 | +``` |
| 86 | + |
| 87 | +**Gazebo Sim approach** (spawner node): |
| 88 | +```python |
| 89 | +load_joint_state_broadcaster = Node( |
| 90 | + package='controller_manager', |
| 91 | + executable='spawner', |
| 92 | + arguments=['joint_state_broadcaster'], |
| 93 | + output='screen' |
| 94 | +) |
| 95 | +``` |
| 96 | + |
| 97 | +### Clock Synchronization |
| 98 | + |
| 99 | +Gazebo Sim requires explicit clock bridging: |
| 100 | +```python |
| 101 | +bridge = Node( |
| 102 | + package='ros_gz_bridge', |
| 103 | + executable='parameter_bridge', |
| 104 | + arguments=['/clock@rosgraph_msgs/msg/Clock[gz.msgs.Clock'], |
| 105 | + output='screen' |
| 106 | +) |
| 107 | +``` |
| 108 | + |
| 109 | +## Backward Compatibility |
| 110 | + |
| 111 | +All changes maintain backward compatibility: |
| 112 | +- Original Gazebo Classic launch file remains unchanged |
| 113 | +- Both Gazebo plugins are present in the URDF |
| 114 | +- Original dependencies are kept alongside new ones |
| 115 | + |
| 116 | +## Testing |
| 117 | + |
| 118 | +To test the migration: |
| 119 | + |
| 120 | +1. **Build the package**: |
| 121 | + ```bash |
| 122 | + colcon build --packages-select hunter_gazebo hunter_description |
| 123 | + source install/setup.bash |
| 124 | + ``` |
| 125 | + |
| 126 | +2. **Test Gazebo Sim**: |
| 127 | + ```bash |
| 128 | + ros2 launch hunter_gazebo launch_gz_sim.launch.py |
| 129 | + ``` |
| 130 | + |
| 131 | +3. **Test Gazebo Classic** (ensure backward compatibility): |
| 132 | + ```bash |
| 133 | + ros2 launch hunter_gazebo launch_sim.launch.py |
| 134 | + ``` |
| 135 | + |
| 136 | +4. **Verify controllers**: |
| 137 | + ```bash |
| 138 | + ros2 control list_controllers |
| 139 | + ``` |
| 140 | + |
| 141 | + Expected output: |
| 142 | + - `joint_state_broadcaster[joint_state_broadcaster/JointStateBroadcaster] active` |
| 143 | + - `ackermann_like_controller[tricycle_controller/TricycleController] active` |
| 144 | + |
| 145 | +5. **Test robot control**: |
| 146 | + ```bash |
| 147 | + ros2 run teleop_twist_keyboard teleop_twist_keyboard --ros-args --remap cmd_vel:=/ackermann_like_controller/cmd_vel |
| 148 | + ``` |
| 149 | + |
| 150 | +## References |
| 151 | + |
| 152 | +- [LCAS Migration Guide](https://github.com/LCAS/aoc_distro/wiki/Migration-to-new-Gazebo) |
| 153 | +- [ros_gz_sim Documentation](https://github.com/gazebosim/ros_gz) |
| 154 | +- [gz_ros2_control Documentation](https://github.com/ros-controls/gz_ros2_control) |
| 155 | +- [RBT1001 Reference Implementation](https://github.com/LCAS/RBT1001) |
0 commit comments