Ignition Fortress: Gazebo: Dynamically Spawn and Remove Entity via SDF
Best practice for spawning and deleting entities during runtime?
What is the best way to dynamically spawn and delete entities in Ignition Gazebo (Ignition Fortress)?
Background
I'm trying to programmatically control Gazebo to create an AI gym such as gym-ignition but using ROS2 and adding sensor support. I plan to write Python wrappers around C++ code to control Gazebo. Suggestions here welcomed! I've used "Gazebo Classic" in the past as an undergrad but barely scratched the surface and pretty much just used worlds others had created. Picking it back up after a few years.
Problem
I want to spawn a model in an existing world. I have seen the example using Ignition Transport and the example using the EntityCreationManager
and have been able to transmit the spawn message and I see my model appear. However I found the SdfEntityCreator
and it seems like that is a better way to spawn and remove entities since the documentation states this "Provides convenient functions to spawn entities and load their plugins from SDF elements, to remove them, and to change their hierarchy". There does seem to be a transport topic I could sent to remove an entity by ID but is it better to use an SdfEntityCreator
object??
The below is my flow:
- I start gazebo via
ign gazebo --render-engine ogre empty.sdf
- I run a compiled executable
- This instantiates an
EntityComponentManager
(ECM), anEventManager
, and anSdfEntityCreator
object - I populate the ECM with state data from the transport message
"/world/empty/state"
- I read the model's SDF file via the
sdf::Root::Load(std::string)
method - I offset the entity IDs by however many entities currently exist in the simulation
- I then call
SdfEntityCreator::CreateEntities
and passsdf.Model()
wheresdf
is ansdf::Root
object - I then set this mode's parent to be the world entity
- This instantiates an
Before and after trying to spawn this model I loop over each entity in the simulation via the ECM's Each
helper function (taken from the above-linked example) and print each entity and their parent. When I spawn the entity using the transport message I see the model appear in the GUI. When I try to spawn the entity using the ECM an SdfEntityCreator
I see the same information printed for entities, entity ID's, and parents as when I use the transport message but I do not see the model in the GUI.
My program's output is below:
Initially there are 8 entities in the Gazebo simulation
Entity [1]
- Name: empty
- Parent:
Entity [4]
- Name: ground_plane
- Parent: empty [1]
Entity [5]
- Name: link
- Parent: ground_plane [4]
Entity [6]
- Name: visual
- Parent: link [5]
Entity [7]
- Name: collision
- Parent: link [5]
Entity [8]
- Name: sun
- Parent: empty [1]
Now there are 12 entities in the Gazebo simulation
Entity [1]
- Name: empty
- Parent:
Entity [4]
- Name: ground_plane
- Parent: empty [1]
Entity [5]
- Name: link
- Parent: ground_plane [4]
Entity [6]
- Name: visual
- Parent: link [5]
Entity [7]
- Name: collision
- Parent: link [5 ...
Note the choice of render engine is only because I'm in a VM and ogre works when ogre2 doesn't. I did not spend much time trying to make ogre2 work since I'm just using VM for initial development.
Also see this (https://gazebosim.org/api/gazebo/6.7/...) but I want a bit more fine-grained control than is currently official supported/available
Okay so I think I'm getting close to the answer here. I'll update the question to a wiki post when I get things working.
It seems that things like the
SdfEntityCreator
and theEntityComponentManager
are for use insidea Gazebo plugin per the breadcrumbs system at https://github.com/ignitionrobotics/i... so I'm assuming anywhere outside a plugin should use Transport messagesThis terminal call adds a urdf to your world.: https://github.com/robotology/gym-ign...