-
Notifications
You must be signed in to change notification settings - Fork 276
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Call UserCommand set_pose user without SceneBroadcaster triggering a full state update #1403
Comments
@srmainwaring did you try this PR #1392 ? |
Thanks @ahcorde, I missed that. Just cherry-picked #1392 into main for Metal and it completely solves the issue - so perfect! I ran a Will close this. |
@srmainwaring I want to simulate a conveyor belt and want to update the position of the items to get the items to move forward. I am using a phyton script which basically calls a terminal command.
However, as you mentioned calling the How exactly did you manage to update the pose at a high rate? |
@marc-wittwer |
@scybd Unfortunately not, I ended up using this approach: Toggle for code:
|
Desired behaviour
Would like to be able to call the service to set a model pose at a rate higher than the current limit (which is about 5Hz). For example, the user command to manually set the pose of a model
box
in the worldmodel_move
is:ign service -s /world/move_model/set_pose --reqtype ignition.msgs.Pose --reptype ignition.msgs.Boolean --timeout 300 --req 'name: "box", position: {x: 0, y: 0, z: 10}'
The service can be called repeatedly in a small C++ program by adapting the same code used to implement the user command in
ign-transport/src/cmd/ign.cc
L190-250. I'm using a python script and pybind11 bindings to the ignition transport library to do the same thing. Regardless of the mechanism, there appears to be an upper limit (between 5Hz and 10Hz) to the rate at which the pose of a model can be updated. Any higher and the GUI will spin, and no updates to the visual will occur. The Component Inspector will also stop displaying updates to the Pose and WorldPoseCmd components once this limit is reached.The problem appears to be that the
SceneBroadCaster
system requires a full state update here:https://github.com/ignitionrobotics/ign-gazebo/blob/310668726b81271b5597845ae528c1e3ffa0379a/src/systems/scene_broadcaster/SceneBroadcaster.cc#L332-L336
changeEvent
is true because the entity has a one time component changehttps://github.com/ignitionrobotics/ign-gazebo/blob/310668726b81271b5597845ae528c1e3ffa0379a/src/systems/scene_broadcaster/SceneBroadcaster.cc#L316-L317
An abridged version of the call stack from the user command is:
/world/<world>/set_pose
adds acomponents::WorldPoseCmd
to the target entity either by callingECM::CreateComponent
or by updating the pose on an existing component then calling ECM::SetChanged with a stateComponentState::OneTimeChange
oneTimeChangedComponents
held in the ECMPhysics
system maintains a list ofworldPoseCmdsToRemove
which it does so after applying the changed poses to the relevant entities. For non-static entities the ignition-physics FreeGroup has it's pose updated, for static entities anotherECM::SetChanged
call is made, this time forcomponents::Pose
.SceneBroadcaster
system then emits a message for the updated pose inSceneBroadcaster::PostUpdate
but also emits a full state update as described above.As the rate at which the
set_pose
service is called increases beyond a certain threshold the system cannot clear the serialisation buffer fast enough (and the GUI appears to no be able to deserialise fast enough) and the system stalls.It's clear that higher rates of pose updates can be achieved if the full state is not republished because the scene broadcaster already publishes pose updates from the physics engine at 60Hz.
Alternatives considered
Writing a system plugin that duplicates the functionality of the
UserComands
andPhysics
systems but avoids settingComponentState::OneTimeChange
each update.Implementation suggestion
I haven't spotted an easy solution. Initially I thought that we might be able to replace
ComponentState::OneTimeChange
inhttps://github.com/ignitionrobotics/ign-gazebo/blob/310668726b81271b5597845ae528c1e3ffa0379a/src/systems/user_commands/UserCommands.cc#L1352-L1356
with
ComponentState::PeriodicChange
, but this doesn't solve the problem because thePhysics
system is continually clearing out the currentWorldPoseCmd
s and callingECM::CreateComponent
implicitly registers aComponentState::OneTimeChange
.Additional context
We'd like to be able to use Ignition Gazebo as a viewer for 3D objects where the pose (and physics) is supplied by an external agent. The use case under consideration has ArduPilot SITL providing both flight control and flight dynamics using one of the test models. A user would like to visualise the model in 3D and attach a follow camera while using the SITL test case physics model. The vehicle pose can be obtained using pymavlink or dronekit, and the ignition-transport python bindings mentioned above make it straightforward to direct these to ignition.
The text was updated successfully, but these errors were encountered: