Skip to content

ROS2 Gazebo project

Demo: Launch gazebo and spawn robot

  • ROS2 gazebo project build using minimal 4 packages
  • robot_application: project logic
  • robot_bringup: launch and config
  • robot_description: urdf and models
  • robot_gazebo: gazebo world and plugins
  • Run gazebo using executable
  • Spawn robot using robot_description
launch:
  - arg:
      name: "bridge_config_file"
      default: "$(find-pkg-share robot_bringup)/config/bridge.yaml"

  - arg:
      name: "world_name"
      default: "robot.world"


    #gazebo simulation
  - executable:
      cmd: gz sim -v 4 -r $(var world_name)
      output: screen
      env:
        - name: GZ_SIM_RESOURCE_PATH
          value: "$(env GZ_SIM_RESOURCE_PATH):$(find-pkg-share robot_gazebo)/worlds"

    #ros-gz bridge
  - node:
      pkg: "ros_gz_bridge"
      exec: "parameter_bridge"
      output: screen
      args:
          "--ros-args -p config_file:=$(var bridge_config_file)"

  - node:
      pkg: robot_state_publisher
      exec: robot_state_publisher
      name: robot_state_publisher
      output: screen
      param:
        - name: robot_description
          value: "$(command 'xacro $(find-pkg-share robot_description)/urdf/robot.xacro')"

  - node:
      pkg: ros_gz_sim
      exec: create
      output: screen
      args:
          "-entity my_robot -topic robot_description"
bridge.yaml
1
2
3
4
5
- ros_topic_name: "/clock"
  gz_topic_name: "/clock"
  ros_type_name: "rosgraph_msgs/msg/Clock"
  gz_type_name: "gz.msgs.Clock"
  direction: GZ_TO_ROS

Resources

├── loc_bringup
│   ├── CMakeLists.txt
│   ├── launch
│   │   └── gazebo.launch.py
│   └── package.xml
└── loc_gazebo
    ├── CMakeLists.txt
    ├── hooks
    │   ├── loc_gazebo.dsv.in
    │   └── loc_gazebo.sh.in
    ├── package.xml
    └── worlds
        └── world.sdf

gazebo package

loc_gazebo.dsv
prepend-non-duplicate;GZ_SIM_RESOURCE_PATH;share;@CMAKE_INSTALL_PREFIX@/share/loc_gazebo/worlds
loc_gazebo.sh
ament_prepend_unique_value GZ_SIM_RESOURCE_PATH "$AMENT_CURRENT_PREFIX/share/@PROJECT_NAME@/worlds"
CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
project(loc_gazebo)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
install(
  DIRECTORY
    worlds/
  DESTINATION share/${PROJECT_NAME}/worlds
)

ament_environment_hooks("${CMAKE_CURRENT_SOURCE_DIR}/hooks/${PROJECT_NAME}.dsv.in")
ament_environment_hooks("${CMAKE_CURRENT_SOURCE_DIR}/hooks/${PROJECT_NAME}.sh.in")

ament_package()

Bringup package

gazebo.launch.py
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch.actions import IncludeLaunchDescription, TimerAction
from launch.launch_description_sources import PythonLaunchDescriptionSource

WORLD_NAME="world.sdf"
ROS_GZ_PKG = "ros_gz_sim"

def generate_launch_description():
    ld = LaunchDescription()


    gz_args = " ".join([
        "-r",
        "-v1",
        WORLD_NAME
    ])

    gazebo = IncludeLaunchDescription(
                PythonLaunchDescriptionSource([os.path.join(
                    get_package_share_directory(ROS_GZ_PKG), 'launch', 'gz_sim.launch.py')]),
                    launch_arguments={
                        'gz_args': gz_args,
                        "on_exit_shutdown": "true"}.items()
             )

    ld.add_action(gazebo)

    return ld