IN THIS ARTICLE
ROS 2 Concepts and Structure
This topic describes the underlying concepts and structure of the ROS 2 Gem in Open 3D Engine (O3DE). You will learn about how ROS 2 and O3DE communicate, and how ROS 2 components interface with each other to perform various functions in a robotics simulation.
ROS 2 Concepts
For a quick introduction to ROS 2 concepts, please refer to ROS 2 Concepts documentation .
Structure and Communication
The Gem creates a ROS 2 node which is directly a part of the ROS 2 ecosystem. As such, your simulation will not use any bridges to communicate and is subject to configuration through settings such as Environment Variables. It is truly a part of the ecosystem.
Note that the simulation node is handled through ROS2SystemComponent - a singleton. However, you are free to create and use your own nodes if you need more than one.
Typically, you will be creating publishers and subscriptions in order to communicate with the ROS 2 ecosystem using common topics. This is done through rclcpp API . Example:
auto ros2Node = ROS2Interface::Get()->GetNode();
AZStd::string fullTopic = ROS2Names::GetNamespacedName(GetNamespace(), m_MyTopic);
m_myPublisher = ros2Node->create_publisher<sensor_msgs::msg::PointCloud2>(fullTopic.data(), QoS());
Note that QoS class is a simple wrapper to
rclcpp::QoS .
Components overview
- Central Singleton
ROS2SystemComponent
- Core abstractions
ROS2FrameComponentROS2SensorComponent
- Sensors
ROS2CameraSensorComponentROS2GNSSSensorComponentROS2IMUSensorComponentROS2LidarSensorComponentROS2OdometrySensorComponent
- Robot control
AckermannControlComponentRigidBodyTwistControlComponentSkidSteeringControlComponent
- Spawner
ROS2SpawnerComponentROS2SpawnPointComponent
- Vehicle dynamics
AckermannVehicleModelComponentSkidSteeringModelComponentWheelControllerComponent
- Robot Import (URDF) system component
ROS2RobotImporterSystemComponent
See the class diagram to understand how components are connected.
Frames
ROS2FrameComponent is a representation of an interesting physical part of the robot. It handles the spatio-temporal relationship between this part and other frames of reference. It also encapsulates namespaces, which help to distinguish between different robots and different parts of the robot, such as in the case of multiple identical sensors on one robot.
All Sensors and the Robot Control components require ROS2FrameComponent.
Sensors
Sensors acquire data from the simulated environment and publish it to ROS 2 domain. Sensor components derive from ROS2SensorComponent.
- Each sensor has a configuration, including one or more Publishers.
- Sensors publish at a given rate (frequency).
- Some sensors can be visualized.
If your sensor is not supported by the provided sensor components, you will most likely need to create a new component deriving from ROS2SensorComponent.
When developing a new sensor, it is useful to look at how sensors that are already provided within the ROS2 Gem are implemented.
Consider adding your new sensor as a separate Gem. A good example of such sensor Gem is the
RGL Gem .
Robot Control
The Gem comes with ROS2RobotControlComponent, which you can use to move your robot through:
- Twist messages
- AckermannDrive
The component subscribes to these command messages on a configured topic. The topic is cmd_vel by default, in a namespace as dictated by ROS2Frame.
To make use of received command messages, use either AckermannControlComponent, RigidBodyTwistControlComponent, or SkidSteeringControlComponent, depending on the steering type.
You can also implement your own control component or use Lua scripting to handle these commands.
Unless scripting is used, control components should translate ROS 2 commands to events on VehicleInputControlBus.
These events will be handled by a
VehicleModelComponent if it is present.
You can use tools such as
rqt_robot_steering to move your robot with Twist messages.
RobotControl is suitable to use with
ROS 2 navigation stack .
It is possible to implement your own control mechanisms with this component.
Vehicle Model
VehicleModelComponent serves the purpose of converting inputs such as target velocity, steering or acceleration to physical forces on parts of a vehicle (robot). VehicleModel has a VehicleConfiguration which is used to define axles, parametrize and assign wheels. The model requires a WheelControllerComponent present in each wheel entity. It also uses an implementation of DriveModel, which converts vehicle inputs to forces acting on steering elements and wheels.
Vehicle Dynamics
See the Vehicle Dynamics section.
Spawner
ROS2SpawnerComponent handles spawning entities during a simulation.
Before the simulation, you must set up as the component’s available spawnables and define the named spawn points in the component’s properties via the O3DE Editor.
This can be done by adding ROS2SpawnPointComponent to a child entity of an entity with ROS2SpawnerComponent.
During the simulation you can access the names of available spawnables and request spawning by using ROS 2 services.
The names of services are /get_available_spawnable_names and /spawn_entity respectivly.
GetWorldProperties.srv and SpawnEntity.srv types are used to handle these features.
In order to request the defined spawn point names, you can use the /get_spawn_points_names service with the GetWorldProperties.srv type.
Detailed information about specific spawn point, such as pose, can be accessed using the /get_spawn_point_info service with the GetModelState.srv type.
All used services types are defined in the gazebo_msgs package.
- Spawning: To spawn, you must pass in the spawnable name into
request.nameand the position of entity intorequest.initial_pose.- Example call:
ros2 service call /spawn_entity gazebo_msgs/srv/SpawnEntity '{name: 'robot', initial_pose: {position:{ x: 4, y: 4, z: 0.2}, orientation: {x: 0.0, y: 0.0, z: 0.0, w:.0}}} - Spawning in defined spawn point: Pass in a spawnable into
request.nameand the name of the spawn point intorequest.xml.- Example call:
ros2 service call /spawn_entity gazebo_msgs/srv/SpawnEntity '{name: 'robot', xml: 'spawn_spot'}'
- Example call:
- Available spawnable names access: Send the names of available spawnables into
response.model_names.- Example call:
ros2 service call /get_available_spawnable_names gazebo_msgs/srv/GetWorldProperties
- Example call:
- Defined spawn points’ names access: Send the names of defined points into
response.model_names- Example call:
ros2 service call /get_spawn_points_names gazebo_msgs/srv/GetWorldProperties
- Example call:
- Detailed spawn point info access: Pass in the spawn point name into
request.model_nameand the defined pose intoresponse.pose.- Example call:
ros2 service call /get_spawn_point_info gazebo_msgs/srv/GetModelState '{model_name: 'spawn_spot'}'
- Example call:
Related topics
| Topic | Description |
|---|---|
| ROS 2 Gem class diagram | Class diagram for the ROS 2 Gem. |