Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Message versioning and ROS 2 message translation #3465

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

GuillaumeLaine
Copy link
Contributor

@GuillaumeLaine GuillaumeLaine commented Nov 20, 2024

This documents the newly versioned subset of PX4 messages, and the ROS 2 translation node that enables seamless communication between PX4 and ROS 2 applications that may be using different message definition versions.

Related Work

To Do

  • Complete TODOs in the markdown of this PR

en/ros2/user_guide.md Outdated Show resolved Hide resolved
@GuillaumeLaine GuillaumeLaine force-pushed the message-versioning branch 3 times, most recently from 41873cf to 825115e Compare December 18, 2024 13:01
@GuillaumeLaine GuillaumeLaine changed the title WIP: message versioning Message versioning and ROS 2 message translation Dec 18, 2024
@GuillaumeLaine GuillaumeLaine force-pushed the message-versioning branch 4 times, most recently from 3c869fb to 2a3af80 Compare December 18, 2024 13:57
@GuillaumeLaine GuillaumeLaine marked this pull request as ready for review December 18, 2024 13:57
@GuillaumeLaine
Copy link
Contributor Author

@hamishwillee I think the PR is in a review ready state. I left a few TODOs in the markdown to resolve before merging. Mostly things that I need to go back to once the last related PR is merged

en/releases/main.md Outdated Show resolved Hide resolved
en/releases/main.md Outdated Show resolved Hide resolved
en/ros2/user_guide.md Outdated Show resolved Hide resolved
@@ -34,6 +34,9 @@ The generator uses the uORB message definitions in the source tree: [PX4-Autopil
ROS 2 applications need to be built in a workspace that has the _same_ message definitions that were used to create the uXRCE-DDS client module in the PX4 Firmware.
You can include these by cloning the interface package [PX4/px4_msgs](https://github.com/PX4/px4_msgs) into your ROS 2 workspace (branches in the repo correspond to the messages for different PX4 releases).

Starting from PX4 x.x.x in which [message versioning](../middleware/uorb.md#message-versioning) was introduced (TODO: specify PX4 version), ROS2 applications may use a different version of message definitions than those used to build PX4.
This requires the [ROS 2 Message Translation Node](../ros2/px4_ros2_msg_translation_node.md) to be running to ensure that messages can be converted and exchanged correctly.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thinking here is that we're going to want users to get used to this, and to almost do it by default - right?

If so I think you're going to need to add instructions to install and use the versioned messages in this guide - probably in a section of https://docs.px4.io/main/en/ros2/user_guide.html#build-ros-2-workspace

Note that when I say "install and use", I really mean "install and run" - you would link to your instructions in the translation node doc for how to update versions and so on. There would be some duplication in that doc.

en/middleware/uorb.md Outdated Show resolved Hide resolved
en/middleware/uorb.md Outdated Show resolved Hide resolved
en/middleware/uorb.md Outdated Show resolved Hide resolved
en/middleware/uorb.md Outdated Show resolved Hide resolved
Comment on lines +148 to +150
Message versioning was introduced to address the challenges of maintaining compatibility across systems where different versions of message definitions may be in use, such as between PX4 and external systems like ROS 2 applications.

This versioning mechanism supports the [ROS 2 Message Translation Node](../ros2/px4_ros2_msg_translation_node.md), which enables seamless communication between PX4 and ROS 2 applications; when different versions of message definitions are in use, the ROS 2 translation node ensures that messages can be converted and exchanged correctly.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a little messy and perhaps can be simplified. In particular

  • ROS2 Message Translation node supports versioning, not the versioning supporting the translation node.

Perhaps something like:

Suggested change
Message versioning was introduced to address the challenges of maintaining compatibility across systems where different versions of message definitions may be in use, such as between PX4 and external systems like ROS 2 applications.
This versioning mechanism supports the [ROS 2 Message Translation Node](../ros2/px4_ros2_msg_translation_node.md), which enables seamless communication between PX4 and ROS 2 applications; when different versions of message definitions are in use, the ROS 2 translation node ensures that messages can be converted and exchanged correctly.
Message versioning has been in introduced in PX4 v1.16 to make it easier to maintain compatibility between PX4 and ROS 2 versions.
This versioning mechanism uses the [ROS 2 Message Translation Node](../ros2/px4_ros2_msg_translation_node.md) to convert between different versions of messages, allowing seamless communication between PX4 and ROS 2 applications; when different versions of message definitions are in use.

Perhaps add a diagram showing where the magic happens?

It would also be good "somewhere here" to mention any forward thinking about the ROS 2 native translation system that they have been talking about for a couple of years. Perhaps as a note at the end.

en/releases/main.md Outdated Show resolved Hide resolved

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 `<topic_name>_v<version>`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what this means. Specifically, at this point if I look at https://github.com/PX4/PX4-Autopilot/blob/main/msg/versioned/VehicleLandDetected.msg it does not have this format - I suspect this is all ROS2 stuff.

I don't think you need to include this line here. I would include information about how this works lower down, maybe in the implementation section. Not needed here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, this only refers to the ROS 2 topic name. For example, this means that if PX4 uses a VehicleLandDetected message that is versioned with MESSAGE_VERSION = 2, then the uxrce dds bridge will now publish a ROS2 topic named /fmu/out/vehicle_land_detected_v2 (instead of /fmu/out/vehicle_land_detected)

I'll clarify and move this to the implementation section as suggested 👍

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

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is worth saying when you should do this. I presume for every workspace?

So something like: "For every workspace you create, it is recommended to install and run the node:", followed by the steps.


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.
Copy link
Collaborator

@hamishwillee hamishwillee Dec 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy the versioned message file (.msg/.srv)`

  • what is .srv here?
  • what is px4_msgs_old? How do they get that folder/repo?
  • "and add the" to "and append the current version information"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. .srv are the service definitions files (e.g. VehicleCommand.srv), as opposed to the .msg message definition files. It is indeed confusing because the px4_msgs ROS2 package actually contains both the .msg and .srv definitions, and we use the term "message" loosely to designate specifically a message file, as well as either a message or service file. To clarify, I will change to:
Suggested change
- 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.
- Copy the versioned `.msg` message file (or versioned `.srv` service file) to `px4_msgs_old/msg/` (or `px4_msgs_old/srv/`) and append the current version information to the file name.
  1. px4_msgs_old is the ROS2 package that stores the versioned history of PX4 messages (and services), used by the translation node package. That folder is added to the PX4 repo in the final open PR, here. Currently it is empty, but in practice if px4_msgs has a message MyMessage.msg which is at MESSAGE_VERSION = 3, then px4_msgs_old will contain two definitions MyMessageV1.msg and MyMessageV2.msg. I will try to clarify

If a nested message definition changes, all messages including that message also require a version update.
This is primarily important for services.
:::

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do I do if I have custom messages I want to version?


- 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.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update the existing translations that use the current topic version to the now old version.

  1. What's a translation? Needs a definition.
  2. Am I replacing or adding a new one of these "whatever they are". I guess I'm asking if I make 3 versions of my message do I have three files? Or one that is updated three times?

- 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`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example doesn't help answer my questions above - in what file would it be?

Comment on lines +68 to +69
If a nested message definition changes, all messages including that message also require a version update.
This is primarily important for services.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know anything about nested message definitions. What are they?

Either way, perhaps a warning or tip?

Comment on lines +52 to +65
- 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.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't looked at the example, but it seems to me that this might require some worked examples of each type. If the headers are specific to each type, perhaps move them under the following sections?

The message version can be added generically to a topic like this:

```c++
topic_name + "_v" + std::to_string(T::MESSAGE_VERSION)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is something you have to do for all topics?

I think I might make this a bit more "real" by having a several line real-world example afterwards.


## 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.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So what versions will it work for?

## 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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean services as in something different than message/topics? Perhaps this is what you mean by .svr above? Is there information on what those mean anywhere?

Either way, so are you saying that services require a linear history, but you can split or merge messages as you like?


- 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.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So a ROS application must compile against just one version of a topic? What if there are two ROS applications running on the network compiled against different versions - is this the problem case?

Copy link
Collaborator

@hamishwillee hamishwillee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GuillaumeLaine

OK, lots of comments here. They don't reflect that this is pretty good structure. Just I'm using myself as the straw man, and I don't know much ROS 2.

When you've had a look at the comments and tried address them, can you loop in Beat and Benja to have a look? I ask because I probably will be on holiday when you do this. Back around week of Jan 20th.

Copy link

No flaws found

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants