|
| 1 | +\page posecomponent Case Study: Using the Pose Component |
| 2 | + |
| 3 | +We will show how to use the gz::sim::components::Pose component in a system. |
| 4 | + |
| 5 | +An example usage of the component can be found in the |
| 6 | +gz::sim::systems::OdometryPublisher system |
| 7 | +([source code](https://github.com/gazebosim/gz-sim/tree/gz-sim8/src/systems/odometry_publisher)), |
| 8 | +which reads the pose component of a model through the Model entity, uses the |
| 9 | +pose for some calculations, and then publishes the result as a message. |
| 10 | + |
| 11 | +More usage can be found in the |
| 12 | +[integration test](https://github.com/gazebosim/gz-sim/blob/gz-sim8/test/integration/odometry_publisher.cc) |
| 13 | +for the system, with test worlds `odometry*.sdf` |
| 14 | +[here](https://github.com/gazebosim/gz-sim/tree/main/test/worlds). |
| 15 | + |
| 16 | +### Objects of interest |
| 17 | + |
| 18 | +- gz::sim::components::Pose: A component containing pose information |
| 19 | +- gz::math::Pose3d: The actual data underlying a pose component |
| 20 | +- gz::sim::systems::OdometryPublisher: A system that reads the pose component |
| 21 | + of a model |
| 22 | +- gz::sim::Model: The type underlying a model entity (gz::sim::Entity) |
| 23 | + |
| 24 | +### Find the model entity |
| 25 | + |
| 26 | +First, we will need access to an entity, the \ref gz::sim::Model entity in this |
| 27 | +case. |
| 28 | +`OdometryPublisher` happens to be a system meant to be specified under `<model>` |
| 29 | +in the SDF, so at the time `Configure()` is called, it has access to a model |
| 30 | +entity from which we can extract a \ref gz::sim::Model: |
| 31 | + |
| 32 | +\snippet src/systems/odometry_publisher/OdometryPublisher.cc modelDeclaration |
| 33 | +\snippet src/systems/odometry_publisher/OdometryPublisher.cc Configure |
| 34 | + |
| 35 | +### Read the pose component |
| 36 | + |
| 37 | +Once we have the handle to an entity, we can access components associated with |
| 38 | +it. |
| 39 | +A component may have been created at the time the world is loaded, or you may |
| 40 | +create a component at runtime if it does not exist yet. |
| 41 | + |
| 42 | +In this case, we use the model entity found above to access its pose component, |
| 43 | +which is created by default on every model entity. |
| 44 | + |
| 45 | +In `PostUpdate()`, which happens after physics has updated, we can get the |
| 46 | +world pose of a model through gz::sim::worldPose, by passing in the model |
| 47 | +entity and the entity component manager. |
| 48 | + |
| 49 | +\snippet src/systems/odometry_publisher/OdometryPublisher.cc worldPose |
| 50 | + |
| 51 | +It returns the raw data to us in the gz::math::Pose3d type, which is also the |
| 52 | +data type underlying a pose component. |
| 53 | +We can perform calculations on the gz::math::Pose3d type, not the |
| 54 | +gz::sim::components::Pose type, which is just a wrapper. |
| 55 | + |
| 56 | +### Use the pose component |
| 57 | + |
| 58 | +Now we can use the pose data as we like. |
| 59 | + |
| 60 | +Here, we manipulate the pose and package the result into a gz::msgs::Odometry |
| 61 | +message to be published: |
| 62 | + |
| 63 | +\snippet src/systems/odometry_publisher/OdometryPublisher.cc declarePoseMsg |
| 64 | + |
| 65 | +\snippet src/systems/odometry_publisher/OdometryPublisher.cc setPoseMsg |
| 66 | + |
| 67 | +See the source code for setting other fields of the message, such as twist and |
| 68 | +the header. |
| 69 | + |
| 70 | +The message is then published: |
| 71 | + |
| 72 | +\snippet src/systems/odometry_publisher/OdometryPublisher.cc publishMsg |
| 73 | + |
| 74 | +where `odomPub` is defined in `Configure()`: |
| 75 | + |
| 76 | +\snippet src/systems/odometry_publisher/OdometryPublisher.cc definePub |
| 77 | + |
| 78 | +Outside the scope of this tutorial, the odometry publisher system also |
| 79 | +calculates the covariance and publishes a pose vector on a TF topic. |
| 80 | +See the source code to learn more. |
0 commit comments