-
Notifications
You must be signed in to change notification settings - Fork 773
ROS 2 Migration: Spawn and delete
In ROS 1, services for spawning and deleting models and lights into simulation were provided by the gazebo_ros_api_plugin
. In ROS 2, this feature is provided by the gazebo_ros_factory
plugin.
Read more about the migration of gazebo_ros_api_plugin
at ROS 2 Migration: gazebo_ros_api_plugin.
-
All spawn and delete service topics and messages have been renamed to better reflect the functionality, by including the word "entity", which encompasses both models and lights in Gazebo.
-
There are no longer two separate services to spawn SDF and URDF files. Both are handled by the same service.
-
In ROS 1, the
model_name
field was required in theSpawnModel
service. In ROS 2, thename
field is optional:- If set, the service will fail to spawn an entity if there's already an entity with this name
- If not set, the service won't check whether the name is already used. In case it is, Gazebo will automatically append numbers to the entity name.
-
In ROS 1, there were two separate services for deleting models and lights, which called the same Gazebo service under the hood. In ROS 2, deleting both models and lights can be done with the same service.
ROS 1 | ROS 2 | |
---|---|---|
Service names | spawn_sdf_model |
spawn_entity |
spawn_urdf_model |
spawn_entity |
|
delete_model |
delete_entity |
|
delete_light |
delete_entity |
|
Service types | gazebo_msgs/SpawnModel |
gazebo_msgs/SpawnEntity |
gazebo_msgs/DeleteModel |
gazebo_msgs/DeleteEntity |
|
gazebo_msgs/DeleteLight |
gazebo_msgs/DeleteEntity |
|
Fields | model_name |
name (optional) |
light_name |
name (optional) |
|
model_xml |
xml |
|
robot_namespace (optional) |
robot_namespace (optional) |
|
initial_pose (optional) |
initial_pose (optional) |
|
reference_frame (optional) |
reference_frame (optional) |
First, run Gazebo with the plugin:
gazebo --verbose -s libgazebo_ros_factory.so
Now call the spawn service from the command line, for example, to spawn a static SDF model:
ros2 service call /spawn_entity 'gazebo_msgs/SpawnEntity' '{name: "sdf_ball", xml: "<?xml version=\"1.0\" ?><sdf version=\"1.5\"><model name=\"will_be_ignored\"><static>true</static><link name=\"link\"><visual name=\"visual\"><geometry><sphere><radius>1.0</radius></sphere></geometry></visual></link></model></sdf>"}'
To spawn an SDF light, try for example:
ros2 service call /spawn_entity 'gazebo_msgs/SpawnEntity' '{name: "bulb", xml: "<?xml version=\"1.0\" ?><sdf version=\"1.5\"><light name=\"will_be_ignored\" type=\"directional\"></light></sdf>"}'
Now try this URDF robot:
ros2 service call /spawn_entity 'gazebo_msgs/SpawnEntity' '{name: "urdf_ball", xml: "<?xml version=\"1.0\" ?><robot name=\"will_be_ignored\"><link name=\"link\"><visual><geometry><sphere radius=\"1.0\"/></geometry></visual><inertial><mass value=\"1\"/><inertia ixx=\"1\" ixy=\"0.0\" ixz=\"0.0\" iyy=\"1\" iyz=\"0.0\" izz=\"1\"/></inertial></link></robot>"}'
Notice that since the name
field was set in all examples above, the entity's name in the XML description (will_be_ignored
) is always ignored.
Let's try to spawn another model without setting the name
field. Run the following command a few times:
ros2 service call /spawn_entity 'gazebo_msgs/SpawnEntity' '{xml: "<?xml version=\"1.0\" ?><sdf version=\"1.5\"><model name=\"another_model\"><static>true</static><link name=\"link\"><visual name=\"visual\"><geometry><sphere><radius>1.0</radius></sphere></geometry></visual></link></model></sdf>"}'
You'll see that the first model spawned is called another_model
, and subsequent ones are called another_model_0
, another_model_1
, etc.
Just like in ROS 1, in ROS 2 the service provides the option of adding / changing the ROS namespace for all gazebo_ros
-powered plugins in the entity being spawned.
However, note that while the convention in ROS 1 was to have a <robotNamespace>
tag under <plugin>
, in ROS 2, a <ros><namespace>
tag is added instead.
This change shouldn't affect developers who are calling the service, but it may affect plugin developers who are relying on the <robotNamespace>
tag in their own plugins. When porting your plugins to ROS 2, be sure to let gazebo_ros::Node
handle the namespace for you and remove code that expects <robotNamespace>
.
You can delete the ground plane model, for example, as follows:
ros2 service call /delete_entity 'gazebo_msgs/DeleteEntity' '{name: "ground_plane"}'
You can delete the sun light, for example, as follows:
ros2 service call /delete_entity 'gazebo_msgs/DeleteEntity' '{name: "sun"}'
- The ROS 1 version of the spawn service relied on a lot of custom code which used TinyXml to parse SDF and URDF files and update their values before sending a Gazebo factory message. The ROS 2 version is significantly shorter because it leverages the SDFormat library's parser to load both SDF and URDF files and manipulate their values.
In ROS1, gazebo_ros
provided a node spawn_model
to spawn a model in Gazebo. In ROS2, similar functionalities are offered by spawn_entity.py
. Model
has been renamed to Entity
as SpawnModel
service has been renamed to SpawnEntity
-
urdf
orsdf
arguments are no longer required. - Functionalities of
set_model_configuration
andDeleteEntity
on shutdown are not supported currently. -
unpause
requires thegazebo_ros_init
plugin to be loaded. -
param
is not supported. Please userobot_state_publisher
as the "source of truth" for the description, it will publish arobot_description
topic with the robot description. Use-topic
in launch arguments to get the robot_description. See this xacro example
ROS 1 | ROS 2 |
---|---|
urdf |
❌ |
sdf |
❌ |
model |
entity |
joints |
not supported currently |
bond |
not supported currently |
param |
not supported currently |
wait |
won't work until model_states is ported |
All other arguments remain the same. Only the default value of gazebo_namespace
has been changed from gazebo
to empty.
rosrun gazebo_ros spawn_model -model mymodel -urdf -x 0 -y 0 -z 0 -file /path/to/model/file
ros2 run gazebo_ros spawn_entity.py -entity myentity -x 0 -y 0 -z 0 -file /path/to/entity/file
cat /path/to/entity/file | ros2 run gazebo_ros spawn_entity.py -entity new_model -x 0 -y 0 -z 0 -stdin
ros2 run gazebo_ros spawn_entity.py -entity TheArm -x 10 -y 10 -z 10 -R 0.1 -P 0.2 -Y 0.3 -database simple_arm
First start the spawn node. It will wait until there are messages on the topic:
ros2 run gazebo_ros spawn_entity.py -entity a_ball -topic /robot_description
Publish a message with the robot description:
ros2 topic pub -1 --qos-durability transient_local /robot_description 'std_msgs/String' '{data: "<?xml version=\"1.0\" ?><robot name=\"will_be_ignored\"><link name=\"link\"><visual><geometry><sphere radius=\"1.0\"/></geometry></visual><inertial><mass value=\"1\"/><inertia ixx=\"1\" ixy=\"0.0\" ixz=\"0.0\" iyy=\"1\" iyz=\"0.0\" izz=\"1\"/></inertial></link></robot>"}'