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]
Entity [8]
- Name: sun
- Parent: empty [1]
Entity [9]
- Name: box
- Parent: empty [1]
Entity [10]
- Name: box_link
- Parent: box [9]
Entity [11]
- Name: box_visual
- Parent: box_link [10]
Entity [12]
- Name: box_collision
- Parent: box_link [10]
but I'm not seeing this reflected in the GUI. Note the message appears identical when I do see the model in the GUI after calling the Ignition Transport message.
Am I going down the right path here? Should I just stick to poking Gazebo with Transport message and not worry about any of the Gazebo API?? When and how should the EntityComponentManager
and SdfEntityCreator
be used? If I want to programmatically control the simulation I'll most likely need a ignition::gazebo::Server
object - does that change how is best to interact with the simulation?
Asked by cmfuhrman on 2022-04-27 20:06:34 UTC
Comments
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.
Asked by cmfuhrman on 2022-04-27 20:09:07 UTC
Also see this (https://gazebosim.org/api/gazebo/6.7/python_interfaces.html) but I want a bit more fine-grained control than is currently official supported/available
Asked by cmfuhrman on 2022-04-27 20:16:33 UTC
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 inside a Gazebo plugin per the breadcrumbs system at https://github.com/ignitionrobotics/ign-gazebo/tree/ign-gazebo6/src/systems/breadcrumbs so I'm assuming anywhere outside a plugin should use Transport messagesAsked by cmfuhrman on 2022-04-28 10:11:19 UTC
This terminal call adds a urdf to your world.: https://github.com/robotology/gym-ignition/issues/44
Asked by marc-marc on 2022-06-02 07:24:06 UTC