19. ROS2
AGX Dynamics for Unreal has built in ROS2 support with no need for a separate ROS2 installation to work.
What is currently supported is message passing via the ROS2 Publisher
and ROS2 Subscriber
Components.
See Message passing for details about how these are used.
All messages types in the following packages are supported:
std_msgs
, sensor_msgs
, builtin_interfaces
, rosgraph_msgs
, geometry_msgs
and agx_msgs
.
There is also a mechanism for passing custom data types using the ROS2 Any Message Builder
and ROS2 Any Message Parser
Components, see Using Custom Types for details.
Specifying QOS
(Quality of Service) such as reliability, durability, history type and depth as well as domain ID is also supported, see QOS (Quality of Service).
ROS2 in AGX Dynamics for Unreal targets the version ROS2 Humble
and specifically the DDS implementation Fast-DDS
which is the default DDS implementation in ROS2 Humble
.
ROS2 generally does not guarantee compatibility between ROS2 versions and DDS vendors, but it should work in practice, especially when matching the DDS vendor types.
For details regarding troubleshooting, see Troubleshooting.
19.1. Message passing
Sending and receiving ROS2 messages in AGX Dynamics for Unreal is done via the ROS2 Publisher
and ROS2 Subscriber
Components.
19.1.1. Sending a ROS2 Message
To send a ROS2 message, simply add a new ROS2 Publisher
Component in a Blueprint.
Then call one of the Send
functions for the message type wanted.
Specify a topic and pass a message struct of the appropriate type.
Below is an example of sending a std_msgs::Float32
on topic mytopic
.
Note that a single ROS2 Publisher
Component can be used to send messages on multiple topics and message types.
This is possible because the Component uses a pool of publishers internally, one for each topic.
Using multiple ROS2 Publisher
Components is supported as well.
Passing messages of different types to the same topic is not supported.
If using C++, the same can be done by calling the appropriate Send function:
Pub->SendStdMsgsFloat32(Msg, "mytopic");
19.1.2. Receiving a ROS2 Message
To receive a ROS2 message, simply add a new ROS2 Subscriber
Component in a Blueprint.
Then call one of the Receive
functions for the message type wanted.
Specify a topic and remember to always check the return value.
true
is returned if a message was received, false
otherwise.
Below is an example of receiving a std_msgs::Float32
on topic mytopic
and printing the received data to the screen.
Note that a single ROS2 Subscriber
Component can be used to receive messages on multiple topics and message types.
This is possible because the Component uses a pool of subscribers internally, one for each topic.
Using multiple ROS2 Subscriber
Components is supported as well.
If using C++, the same can be done by calling the appropriate Receive function:
if (Sub->ReceiveStdMsgsFloat32(OutMsg, "mytopic"))
{
/* Use OutMsg */
}
19.2. Using Custom Types
Passing custom data types is possible by using the ROS2 Any Message Builder
and ROS2 Any Message Parser
Components.
These are helper classes that can serialize and deserialize custom data to and from a agx_msgs::Any
message.
These support some of the more common built in integer, floating point, boolean, and string types as well as sequences of these.
The agx_msgs::Any
message type as well as AnyMessageBuilder and AnyMessageParser are also avaiable open-source on GitHub so that these can be used on machines that does not have AGX Dynamics or AGX Dynamics for Unreal installed.
By serializing a custom data type to an agx_msgs::Any
message using a ROS2 Any Message Builder
, the agx_msgs::Any
message can then be sent via ROS2.
On the receiving side, the agx_msgs::Any
message is deserialized using a ROS2 Any Message Parser
to retrieve the custom data.
Below is an example of serializing and passing the equivalent of the following C++ struct:
struct MyStruct
{
float MyFloat;
std::vector<std::string> MyStrings;
};
Note that the Begin Message
function must be called before starting to build a new message using the ROS2 Any Message Builder
Component, as the image above shows.
To retrieve the custom data type, we receive the message and then use the ROS2 Any Message Parser
Component to read the data back:
Note that the Begin Parse
function must be called each time before starting to read (or “parse”) a new agx_msgs::Any
message.
Also note that the order of write and read when using the ROS2 Any Message Builder
and ROS2 Any Message Parser
Components must match on the sending and receiving side.
The layout of the custom data type must also be known by both sides and serialized according to its data members.
19.3. QOS (Quality of Service)
QOS or Quality of Service determines the lifetime behaviour of ROS2 messages.
QOS can be set for each ROS2 Publisher
and ROS2 Subscriber
Component in the Details Panel.
Setting the Reliability, Durability, History and History Depth is supported.
By default these will be set to the same values as in ROS2 Humble
.
Changing the QOS setting on an existing ROS2 Publisher
or ROS2 Subscriber
during Play is not supported.
19.4. Limitations
Since only integer types uint8
, int32
and int64
is currently supported by Blueprints, some of the built in message types exposed in AGX Dynamics for Unreal has been modified to use these in place of other non-supported integer types.
These are converted internally to the correct integer types, so as a User no special logic needs to be written to convert these values.
Passing messages of different types to the same topic is not supported.
Changing the QOS setting on an existing ROS2 Publisher
or ROS2 Subscriber
during Play is not supported.
Since the type uint64 is not supported in Blueprints, data loss may occur when receiving messages containing members of uint64 type. These will be cast to int64 automatically to work in Blueprints.
19.5. Troubleshooting
If messages are missed, or the first couple of messages are missed, it may be of use to check the QOS
settings used.
By default the QOS settings are the same as in ROS2 Humble
.
More details on these settings can be seen (here).
If no communication between a built in ROS2 Publisher
and ROS2 Subscriber
can be established it is possible that it is blocked by a firewall on the computer.
Check the firewall settings and unblock the process in case it has been blocked.
If no communication between a built in ROS2 Publisher
or ROS2 Subscriber
and an external ROS2 node running on a complete ROS2 installation can be established, ensure that the same version of ROS2 is used.
The built in ROS2 support in AGX Dynamics for Unreal targets ROS2 Humble
.
If this does not solve the problem, ensure that the DDS implementation Fast-DDS
is used in the ROS2 installation.
This can be forced by setting the environment variable RMW_IMPLEMENTATION=rmw_fastrtps_cpp
. See the (ROS2 documentation) for details.
Also check the firewall settings if necessary.
If the creation of a agxIO::ROS2::Publisher
or agxIO::ROS2::Subscriber
hangs forever it is possible a seemingly rare bug in Fast-DDS is the culprit.
This seems to happen when creating a DDS Participant (which is done automatically by AGX Dynamcis) on Windows on rare occations.
The underlying reason why this can happen is not known, but a manual workaround is to do the following:
1. Turn off any process using ROS2.
2. Manually remove all files in C:\ProgramData\eprosima\fastrtps_interprocess
(replace drive-letter if applicable).