How to administrate (spawning and deleting) models synchronously and deterministically for testrun automation?
Hi,
i've got some questions regarding the simulation loop inside of Gazebo:
(Q1) We want to use multiple plugins, with have different times for loading up (since we are instantiating different amount of models). We want to wait until all plugins are ready. Is there any function, which is executed before any callback connected to OnWorldUpdateBegin(), which can be blocked or take arbitrary times before being finished?
(Q2) If we want to spawn a set of models at the beginning of every single scenario, is there a possibility to get a direct response or feedback about the success/failure of its "birth"? This is insofar important, since we need to spawn our models in order to provide reproducibility of the distinct scenarios?
(Q3) Init(), Reset() and Load(): If we want to realize testrun automation within Gazebo, we have the necessity of adding and removing models for scenario variation between successive testruns. In order to be able to create or remove models between those runs, we might get in conflict with the different threads accessing those models. This, for example, is the case with Reset() and OnUpdate(), which has been registered to the WorldUpdateBegin() event, e.g.. So, we might need to disconnect the callback for example right BEFORE the deletion of the model in in the Reset() method to avoid any threading issues, right?
(Q4) My next question then continues the right usage of those functions: How are Load() and Init() (or Reset()) are in general thought to be used? Which data structures should be instantiated in which function (gazebo transport node, …)?
I think it might get clearer, if i outline and detail our application and sketch it in the context of question (Q1) and (Q2):
We are using Gazebo as a co-simulation master for controlling two connected simulations and combining the specific agents in one, common environment model for a co-simulation plattform: Two dedicated plugins, both of type WorldPlugin, establish their connection to a microscopic vehicle and a pedestrian crowd simulation. Both plugins build up the connection in their specific Load() function, receive the number of expected vehicles and pedestrians from both simulations and then requests Gazebo to instantiate the number of necessary models via InsertModelAsSDF() on the world ptrs of the plugins. Since the Load() function shall be non-blocking, a OnUpdate() function, which has been previously connected to the OnWorldUpdateBegin() event of the simulation loop, then checks at the very beginning if the available amount of models corresponds to the number of recently requested models. If so, the plugins and the simulation models are synchronized. This approach has two big disadvantages:
- We completely miss reproducability, since it is not predictable in which stimulation step Gazebo is synchronized with one of the coupled simulations, especially considering the synchronization with both simulations.
- This also prevents us from implementing a simple Reset(). We are able to reset the connected simulations, but... we (1) have to remove our EventConnection on OnWorldUpdateBegin()-Event, (2) remove the agents safely by deleting the models, then finally also re-instantiate the event in the Reset() function for the next scenario, causing a lot of duplicated code and potential errors.
Also, we have a similar issue, when we want to use the gazebo transport system with publisher and subscriber before the simulation shall start with it's first step, such as .g. for the exchange of information, which is static over the runtime of a concrete Scenario and only needs to be exchanged once. It looks like that the publisher/subscriber principle of the plugins are inappropriate being used before the initial simulation step.
My third question (Q3) is also related to the issue mentioned above, that in order to reset a plugin, which administrates a set of models, it also needs to handle the instantiation and deletion of events very carefully in order to avoid race conditions: Such as removing a model in Reset(), while the OnUpdate() tries to move the model itself in the meantime.
Are there any experiences on such application of Gazebo?
With best regards and thanks in advance!
Asked by Illuminatur on 2018-12-09 18:58:16 UTC
Answers
Your first question is difficult to understand. Are you looking for a function to block simulation update at a particular time? Are you experiencing a situation where gazebo hangs? Are you trying to block simulation based on an event?
One approach is to send out a "birth" message on your own topic. You can also monitor the
/pose/info
topic, which will contain pose info on your model after the model is spawned.Since I can reproduce your test scenario the best answer I can give is maybe. What have you tried, where did it fail, and what steps can I follow to reproduce your problem?
After construction of an entity, you should call Load to configure the entity. Init should follow Load. You will likely get unexpected results if you call Reset followed by Init. While there was intention to eventually support this use-case, we have never implemented the Init --> Reset --> Init pattern.
Asked by nkoenig on 2018-12-11 17:42:54 UTC
Comments
Hi, i just added my explanations to the original post. Are there any ideas how we could solve our issue?
Asked by Illuminatur on 2018-12-12 14:34:00 UTC
Hi,
since some time has passed, i wanted to ask, if there are some new insights?
Any help is really appreciated.
Regards and thanks a lot.
Asked by Illuminatur on 2019-01-29 23:37:09 UTC
Comments