Open yschulz opened 1 year ago
I can confirm this:
gz sim world.sdf
),/world/test_world/create
service.I am able to reproduce this as well. I think the issue is that Contact uses EachNew
in the PreUpdate
, which is fine when entities are created by SimulationRunner
because the entity creation happens before any of the *Update
calls. But when a model is spawned through the create
service, it uses the UserCommands
system which creates entities in the PreUpdate
phase, so the new entities will not be included in the EachNew
call. In fact, the documentation for EachNew
states that it should not be used in the PreUpdate
for this reason.
I see three solutions, with increasing complexity:
Contact::PreUpdate
to Contact::Update
in the Contact
system. This will ensure that new entities created by UserCommands
will be captured by EachNew
in the Contact
system. We usually reserve the Update
calls to the Physics
system, but I don't see any harm in doing this since the Contact
system would mostly be initializing internal state during this call. If the Physics
system happens to run before the Contact
system, we would miss contacts from the first iteration immediately after the model is spawned.Contact::Update
, use a combination of Contact::PostUpdate
and Contact::PreUpdate
. The PostUpdate
would be used to initialize internal state and the PreUpdate
would be used to create ContactSensorData
components on the collision entities identified in the PostUpdate
.*Update
calls. This would avoid any ordering issues like this for all systems, not just Contact
, but would be a lot more work.I could fix 1 or 2, especially since 1523 did the same as 2, I believe. I cannot answer though if we are ok with 1 ¯_(ツ)_/¯
Thanks for taking a look though!
@azeey I was just implementing your 2nd suggested version when I ran into runtime issues and started testing back and forth with the new and previous version. I suddenly wasn't able to reproduce the issue anymore. It turns out, if you put the plugin tag in the sdf for the UserCommand
before the one of Contact
, the issue disappears.
This would suggest that it doesn't matter when the entities are created in the sequence. What's important is that the UserCommand
system is loaded before the Contact
system. That also sounds strange to me, but also like a separate issue to the call to EachNew
inside PreUpdate
.
The UserCommand
system is what listens to /world/test_world/create
and spawns the model, so it's not that it doesn't matter when the entities are created in the sequence. When you put the plugin tag for UserCommand
before Contact
, it means UserCommand::PreUpdate
will be called before Contact::PreUpdate
, so the entities will have been created before Contact::PreUpdate
is called.
Environment
Description
gz topic -l
regardless of spawning a model through the world file or through create serviceSteps to reproduce
I was using an xacro/urdf description, but converted manually to sdf for testing Combined test world:
To avoid clutter, I leave it at that. Just separate model and world and spawn via
gz service -s /world/test_world/create --reqtype gz.msgs.EntityFactory --reptype gz.msgs.Boolean --timeout 200 --req 'sdf_filename: "[path_to_model_sdf]" '