diff --git a/en/SUMMARY.md b/en/SUMMARY.md index ea0ad4fdac8d..039d8f9b6ca8 100644 --- a/en/SUMMARY.md +++ b/en/SUMMARY.md @@ -808,6 +808,7 @@ - [PX4 ROS 2 Interface Library](ros2/px4_ros2_interface_lib.md) - [Control Interface](ros2/px4_ros2_control_interface.md) - [Navigation Interface](ros2/px4_ros2_navigation_interface.md) + - [ROS 2 Message Translation Node](ros2/px4_ros2_msg_translation_node.md) - [ROS 1 (Deprecated)](ros/ros1.md) - [ROS/MAVROS Installation Guide](ros/mavros_installation.md) - [ROS/MAVROS Offboard Example (C++)](ros/mavros_offboard_cpp.md) diff --git a/en/_sidebar.md b/en/_sidebar.md index 001b27d44194..279112e3a3c4 100644 --- a/en/_sidebar.md +++ b/en/_sidebar.md @@ -797,6 +797,7 @@ - [PX4 ROS 2 Interface Library](/ros2/px4_ros2_interface_lib.md) - [Control Interface](/ros2/px4_ros2_control_interface.md) - [Navigation Interface](/ros2/px4_ros2_navigation_interface.md) + - [ROS 2 Message Translation Node](/ros2/px4_ros2_msg_translation_node.md) - [ROS 1 (Deprecated)](/ros/ros1.md) - [ROS/MAVROS Installation Guide](/ros/mavros_installation.md) - [ROS/MAVROS Offboard Example (C++)](/ros/mavros_offboard_cpp.md) diff --git a/en/ros2/index.md b/en/ros2/index.md index fc35b40ffd26..64b8ae76fd03 100644 --- a/en/ros2/index.md +++ b/en/ros2/index.md @@ -37,6 +37,7 @@ The main topics in this section are: - [ROS 2 Multi Vehicle Simulation](../ros2/multi_vehicle.md): Instructions for connecting to multipole PX4 simulations via single ROS 2 agent. - [PX4 ROS 2 Interface Library](../ros2/px4_ros2_interface_lib.md): A C++ library that simplies interacting with PX4 from ROS 2. Can be used to create and register flight modes wrtten using ROS2 and send position estimates from ROS2 applications such as a VIO system. +- [ROS 2 Message Translation Node](../ros2/px4_ros2_msg_translation_node.md): A ROS 2 message translation node that enables communcation between PX4 and ROS 2 applications that were compiled with different sets of messages versions. ## Further Information diff --git a/en/ros2/px4_ros2_msg_translation_node.md b/en/ros2/px4_ros2_msg_translation_node.md new file mode 100644 index 000000000000..709b201ec6a7 --- /dev/null +++ b/en/ros2/px4_ros2_msg_translation_node.md @@ -0,0 +1,110 @@ +# PX4 ROS 2 Message Translation Node + + + +The message translation node allows to run applications that are compiled with one set of message versions against a PX4 with another set of message versions, without having to change either the application or the PX4 side. + +Specifically for this to work, topic publication/subscription/service names contain a message version in the form of `_v`. + +The translation node knows about all existing message versions, and dynamically monitors the publications, subscriptions and services, and then creates translations as needed. + +## Installation and First Test + +Create a ROS 2 workspace in which to build the message translation node and its dependencies. + +```bash +mkdir -p /path/to/ros_ws/src +``` + +Run the following helper script, it will copy the message definitions and translation node to your ROS workspace directory. + +```bash +cd /path/to/ros_ws +/path/to/PX4-Autopilot/Tools/copy_to_ros_ws.sh . +``` + +Build and source the workspace. + +```bash +colcon build +source /path/to/ros_ws/install/setup.bash +``` + +Finally, run the translation node. You should see an output similar to: + +```bash +ros2 run translation_node translation_node_bin +[INFO] [1734525720.729530513] [translation_node]: Registered pub/sub topics and versions: +[INFO] [1734525720.729594413] [translation_node]: Registered services and versions: +``` + +## Updating a Message + +When changing a message, a new version needs to be added. + +The steps include: + +- Copy the versioned message file (`.msg`/`.srv`) to `px4_msgs_old/msg/` (or `px4_msgs_old/srv/`) and add the current version to the file name. + For example `msg/versioned/VehicleAttitude.msg` becomes `px4_msgs_old/msg/VehicleAttitudeV3.msg`. + Update the existing translations that use the current topic version to the now old version. + For example `px4_msgs::msg::VehicleAttitude` becomes `px4_msgs_old::msg::VehicleAttitudeV3`. +- Increment `MESSAGE_VERSION` and update the message fields as desired. +- Add a version translation by adding a new translation header. Examples: (TODO: update GitHub urls) + - [`translations/example_translation_direct_v1.h`](https://github.com/PX4/PX4-Autopilot/blob/message_versioning_and_translation/msg/translation_node/translations/example_translation_direct_v1.h) + - [`translations/example_translation_multi_v2.h`](https://github.com/PX4/PX4-Autopilot/blob/message_versioning_and_translation/msg/translation_node/translations/example_translation_multi_v2.h) + - [`translations/example_translation_service_v1.h`](https://github.com/PX4/PX4-Autopilot/blob/message_versioning_and_translation/msg/translation_node/translations/example_translation_service_v1.h) +- Include the added header in [`translations/all_translations.h`](https://github.com/PX4/PX4-Autopilot/blob/message_versioning_and_translation/msg/translation_node/translations/all_translations.h). + +For the second last step and for topics, there are two options: + +1. Direct translations: these translate a single topic between two different versions. + This is the simpler case and should be preferred if possible. +2. Generic case: this allows a translation between N input topics and M output topics. + This can be used for merging or splitting a message. + Or for example when moving a field from one message to another, a single translation should be added with the two older message versions as input and the two newer versions as output. + This way there is no information lost when translating forward or backward. + +::: info +If a nested message definition changes, all messages including that message also require a version update. +This is primarily important for services. +::: + +## Usage in ROS + +The message version can be added generically to a topic like this: + +```c++ +topic_name + "_v" + std::to_string(T::MESSAGE_VERSION) +``` + +Where `T` is the message type, e.g. `px4_msgs::msg::VehicleAttitude`. + +The DDS client in PX4 automatically adds the version suffix if a message contains the field `uint32 MESSAGE_VERSION = x`. + +::: info Version 0 of a topic means that no `_v` suffix should be added. +::: + +## Implementation Details + +The translation node dynamically monitors the topics and services. +It then instantiates the countersides of the publications and subscribers as required. +For example if there is an external publisher for version 1 of a topic and subscriber for version 2. + +Internally, it maintains a graph of all known topic and version tuples (which are the graph nodes). +The graph is connected by the message translations. +As arbitrary message translations can be registered, the graph can have cycles and multiple paths from one node to another. +Therefore on a topic update, the graph is traversed using a shortest path algorithm. +When moving from one node to the next, the message translation method is called with the current topic data. +If a node contains an instantiated publisher (because it previously detected an external subscriber), the data is published. +Thus, multiple subscribers of any version of the topic can be updated with the correct version of the data. + +For translations with multiple input topics, the translation continues once all input messages are available. + +## Limitations + +- The current implementation depends on a service API that is not yet available in ROS Humble, and therefore does not support services when built for ROS Humble. +- Services only support a linear history, i.e. no message splitting or merging +- Having both publishers and subscribers for two different versions of a topic is currently not handled by the translation node and would trigger infinite circular publications. + This could be extended if required. + +Original document with requirements: https://docs.google.com/document/d/18_RxV1eEjt4haaa5QkFZAlIAJNv9w5HED2aUEiG7PVQ/edit?usp=sharing \ No newline at end of file