Skip to content

Commit

Permalink
code review: sample hook implementation
Browse files Browse the repository at this point in the history
Signed-off-by: Jan Hanca <[email protected]>
  • Loading branch information
jhanca-robotecai committed Dec 27, 2023
1 parent a397b45 commit 2cbb293
Showing 1 changed file with 38 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ weight: 100

## Introduction

Robots described in either [SDFormat](http://sdformat.org/), [URDF](http://wiki.ros.org/urdf), or [XACRO](http://wiki.ros.org/xacro) format, can be imported into your O3DE simulation project using the Robot Importer. The tool converts links and joints into O3DE entities and components alongside the parameters defined in the input robot description file. You can find more details about Robot Importer in the [documentation](/docs/user-guide/interactivity/robotics/importing-robot/).
Robots described in either [SDFormat](http://sdformat.org/), [URDF](http://wiki.ros.org/urdf), or [XACRO](http://wiki.ros.org/xacro) format, can be imported into your O3DE simulation project using the Robot Importer. The tool creates O3DE entities and components that model a robot. You can find more details about Robot Importer in the [documentation](/docs/user-guide/interactivity/robotics/importing-robot/).

Similarly, the robots' [sensors](http://sdformat.org/spec?ver=1.10&elem=sensor) are imported from the description files into O3DE using ROS 2 sensor components available in [ROS 2 Gem](/docs/user-guide/gems/reference/robotics/ros2/). Note, that the sensor's description can be stored directly in SDFormat files or using `<gazebo>` tag in URDF and XACRO files.

Expand All @@ -23,9 +23,8 @@ Four basic sensors' _hooks_ are predefined in Robot Importer. These can be summa

| _Hook_ name | Supported SDFormat sensors | Supported SDFormat plugins | O3DE sensor component |
| ------------------ | -------------------------- | ----------------------------- | --------------------------- |
| _CameraSensorHook_ | `camera_sensor`, | `libgazebo_ros_camera` | `ROS2CameraSensorComponent` |
| _CameraSensorHook_ | `camera_sensor` | `libgazebo_ros_camera` | `ROS2CameraSensorComponent` |
| | `depth_camera` | `libgazebo_ros_depth_camera` | |
| | `multicamera` | `libgazebo_ros_multicamera` | |
| | `rgbd_camera` | `libgazebo_ros_openni_kinect` | |
| _GNSSSensorHook_ | `gps`, `navsat` | `libgazebo_ros_gps_sensor` | `ROS2GNSSSensor` |
| _ImuSensorHook_ | `imu` | `libgazebo_ros_imu_sensor` | `ROS2ImuSensorComponent` |
Expand All @@ -44,20 +43,50 @@ First, you need to declare `ROS2::SDFormat::SensorImporterHook` structure that c
* set of the supported parameters in the input robot description (used for import verbose only)
* registered callback function that is invoked by Robot Importer when _hook's_ definition matches the input data

The registered callback function creates a number of O3DE components that are necessary to simulate a particular sensor. Additionally, it parses the robot description file to read certain processing parameters.
The registered callback function creates a number of O3DE components that are necessary to simulate a particular sensor. Additionally, it parses the robot description file to read certain processing parameters and lists the supported sensors and plugins. Your sample implementation for `sdf::SensorType::NAVSAT` that implements `libgazebo_myps_sensor.so` in O3DE can look as follows:

```cpp
ROS2::SDFormat::SensorImporterHook ROS2SensorHooks::MyGNSSSensor()
{
ROS2::SDFormat::SensorImporterHook importerHook;
importerHook.m_sensorTypes = AZStd::unordered_set<sdf::SensorType>{ sdf::SensorType::NAVSAT };
importerHook.m_supportedSensorParams = AZStd::unordered_set<AZStd::string>{ ">update_rate", ">my_parameter" };
importerHook.m_pluginNames = AZStd::unordered_set<AZStd::string>{ "libgazebo_mygps_sensor.so" };
importerHook.m_sdfSensorToComponentCallback = [](AZ::Entity& entity, const sdf::Sensor& sdfSensor)
-> ROS2::SDFormat::SensorImporterHook::ConvertSensorOutcome
{
if (!sdfSensor.NavSatSensor())
{
return AZ::Failure(AZStd::string("Failed to read parsed SDFormat data of %s NavSat sensor", sdfSensor.Name().c_str()));
}
const float myUpdateRate = sdfSensor.UpdateRate();
const float myParameter = sdfSensor.Element()->Get<float>("my_parameter", 1.0f).first;
if (Utils::CreateComponent<MyO3DEEditorComponent>(entity, myUpdateRate, myParameter))
{
return AZ::Success();
}
else
{
return AZ::Failure(AZStd::string("Failed to create NavSat MyO3DEEditorComponent."));
}
};

return importerHook;
}
```

Your second task is to implement your desired simulation behavior in an O3DE component, which would be created by the Robot Importer. Finally, you need to define and register your _hook_ via the _SerializeContext_ reflection system using `SensorImporterHooks` attribute tag. This allows the Robot Importer to find and add your _hook_ to the mapping. The registration can be done in any O3DE editor component and multiple _hooks_ can be registered at once. For simplicity, you might want to add the registration directly to your O3DE component. A sample code implementing the registration scheme can be as follows:
```cpp
void YourO3DEEditorComponent::Reflect(AZ::ReflectContext* context)
void MyO3DEEditorComponent::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
const ROS2::SDFormat::SensorImporterHook& yourImporterHook = YourMethodToCreateHook();
const ROS2::SDFormat::SensorImporterHook& anotherImporterHook = YourAnotherMethodToCreateHook();
serializeContext->Class<YourO3DEEditorComponent, BaseClassOfYourO3DEEditorComponent>()
const ROS2::SDFormat::SensorImporterHook& myImporterHook = CreateMyHook();
const ROS2::SDFormat::SensorImporterHook& anotherImporterHook = CreateAnotherHook();
serializeContext->Class<MyO3DEEditorComponent, BaseClassOfMyO3DEEditorComponent>()
->Attribute(
"SensorImporterHooks",
ROS2::SDFormat::SensorImporterHooksStorage{ AZStd::move(yourImporterHook), AZStd::move(anotherImporterHook) });
ROS2::SDFormat::SensorImporterHooksStorage{ AZStd::move(myImporterHook), AZStd::move(anotherImporterHook) });
}
// more reflection code goes here
}
Expand Down

0 comments on commit 2cbb293

Please sign in to comment.