-
Notifications
You must be signed in to change notification settings - Fork 773
ROS 2 Migration: Gazebo ROS Paths
If your package is exporting resources like models and plugins that need to be found by
Gazebo, you need to install them and export the install paths. Gazebo will look
on those paths to resolve URI schemas like model://
and package://
.
On ROS 1, there were 2 ways to export your packages paths so that they're picked up by gazebo_ros
:
- Using
<export><gazebo_ros....></export>
- Loading the
gazebo_ros_paths
plugin
This pages describes how to migrate both of these for ROS 2.
- The functionality is offered by
gazebo_ros_paths.py
ingazebo_ros
. - It is no longer a plugin but a python script which is used by
gzserver.launch.py
andgzclient.launch.py
while launchgzserver
andgzclient
respectively. - The plugin no longer sources gazebo's
setup.sh
. - This is convenient when using
gazebo_ros
's launch files, but the environment variables won't be set when you source yoursetup
file.
-
Install resources like models, plugins, worlds and other media files. You can do the following on your
CMakeLists.txt
for example:install(DIRECTORY models DESTINATION share/${PROJECT_NAME}/ ) install(DIRECTORY worlds DESTINATION share/${PROJECT_NAME}/ ) install(DIRECTORY media DESTINATION share/${PROJECT_NAME}/ ) install(TARGETS myPlugin DESTINATION lib )
-
Inside your
package.xml
, export the install paths above:<export> <gazebo_ros gazebo_plugin_path="lib"/> <gazebo_ros gazebo_model_path="${prefix}/models"/> <gazebo_ros gazebo_media_path="${prefix}/worlds:${prefix}/media"/> </export>
The variables correspond to the following environment variables:
-
gazebo_plugin_path
:GAZEBO_PLUGIN_PATH
-
gazebo_model_path
:GAZEBO_MODEL_PATH
-
gazebo_media_path
:GAZEBO_RESOURCE_PATH
This will not set the environment variables directly, but will make the values available to
gazebo_ros
. -
-
Include
gazebo.launch.py
in your launch file, and that will set the environment variables correctly. For example:from ament_index_python.packages import get_package_share_directory from launch import LaunchDescription from launch.actions import IncludeLaunchDescription from launch.launch_description_sources import PythonLaunchDescriptionSource def generate_launch_description(): pkg_gazebo_ros = get_package_share_directory('gazebo_ros') return LaunchDescription([ IncludeLaunchDescription( PythonLaunchDescriptionSource( os.path.join(pkg_gazebo_ros, 'launch', 'gazebo.launch.py'), ) ) ])
You can also use the
GazeboRosPaths
script directly, as done here.
- Env hooks directly set variables needed by Gazebo when your package's setup file is sourced.
-
Install resources the same way as above.
-
Create an
env-hooks
directory with files to be sourced. For example,project_name.sh.in
:# $AMENT_CURRENT_PREFIX is replaced with /opt/ros/<distro>/share/ on clean builds, that's why using $COLCON_CURRENT_PREFIX instead. ament_prepend_unique_value GAZEBO_MODEL_PATH "$COLCON_CURRENT_PREFIX/share/@PROJECT_NAME@/models" ament_prepend_unique_value GAZEBO_RESOURCE_PATH "$COLCON_CURRENT_PREFIX/share/@PROJECT_NAME@/worlds" ament_prepend_unique_value GAZEBO_RESOURCE_PATH "$COLCON_CURRENT_PREFIX/share/@PROJECT_NAME@/media" ament_prepend_unique_value GAZEBO_PLUGIN_PATH "$COLCON_CURRENT_PREFIX/lib"
Since ROS 2 Eloquent, you can also use
.dsv
files. Aproject_name.dsv.in
template would look like this:prepend-non-duplicate;GAZEBO_MODEL_PATH;share/@PROJECT_NAME@/models prepend-non-duplicate;GAZEBO_RESOURCE_PATH;share/@PROJECT_NAME@/worlds prepend-non-duplicate;GAZEBO_RESOURCE_PATH;share/@PROJECT_NAME@/media prepend-non-duplicate;GAZEBO_PLUGIN_PATH;share/@PROJECT_NAME@/plugins
-
In your
CMakeLists.txt
file, generate the templates with:ament_environment_hooks("${CMAKE_CURRENT_SOURCE_DIR}/env-hooks/${PROJECT_NAME}.sh.in") ament_environment_hooks("${CMAKE_CURRENT_SOURCE_DIR}/env-hooks/${PROJECT_NAME}.dsv.in")
Now when your source setup.sh
, the variables will be properly set.
A quick example to explain the easiest way to use env-hooks.
Imagine this is your package, you will need the following structure:
robot_description_package/
-env-hooks/
--robot_description_package.dsv.in
-models
--my_robot_model/
---meshes/
----my_mesh.stl
---my_robot.urdf
---model.config
CMakeLists.txt
package.xml
Your robot_description_package.dsv.in
file will look like this:
prepend-non-duplicate;GAZEBO_MODEL_PATH;share/robot_description_package/models
In myrobot.urdf
you will use the following line to address your mesh (Note that you start your path file directly after the path as dictated in your dsv file):
<visual>
<geometry>
<mesh filename="model://my_robot_model/meshes/my_mesh.stl"/>
</geometry>
</visual>
In 'model.config' you define some basic stuff about your robot, a simple file would look something like this (of course you don't need to add an author):
<?xml version="1.0"?>
<model>
<name>myRobot</name>
<version>2.0</version>
<sdf version="1.6">my_robot.urdf</sdf>
<author>
<name>yourname</name>
<email>[email protected]</email>
</author>
<description>
your description
</description>
</model>
In your CMakeLists.txt
you will need to add the following lines:
install(
DIRECTORY models
DESTINATION share/${PROJECT_NAME}
)
ament_environment_hooks("${CMAKE_CURRENT_SOURCE_DIR}/env-hooks/robot_description_package.dsv.in")
And then you should be ready to go! If you want more models, it will look something like this:
robot_description_package/
-env-hooks/
--robot_description_package.dsv.in
-models
--my_robot_model/
---meshes/
----my_mesh.stl
---my_robot.urdf
---model.config
--my_second_model/
---meshes/
----my_second_mesh.stl
---my_second_robot.urdf
---model.config
CMakeLists.txt
package.xml
And all you will need to do is write the model.config
for your second robot, and that's it.