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 6 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 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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think this needs to be done for every PX4/ROS workspace. I think it's sufficient to have one workspace to build and run the translation node, and separate workspaces containing their respective apps. The translation node and those apps will then build separately, but they can still be run in parallel.

That said I don't think it's wrong to have the translation as part of multiple larger workspaces, I'm just not sure we should prescribe a specific workflow to the developer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added a few sentences maybe it helps clarify


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 link
Contributor Author

Choose a reason for hiding this comment

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

Good points, I've elaborated on this.

I guess I'm asking if I make 3 versions of my message do I have three files?

Exactly, 3 new versions of a message means adding three new translation files: each translation file bridging one version to the next

- 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?

Copy link
Contributor Author

@GuillaumeLaine GuillaumeLaine Jan 8, 2025

Choose a reason for hiding this comment

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

Nested messages are message definitions that include fields referencing other message types instead of using only the classic data types. For instance PositionSetpointTriplet.

Thanks I've added the example and made the paragraph into a warning

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right, I've gone and added a worked example also to make the steps clearer


## 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?

Copy link
Contributor Author

@GuillaumeLaine GuillaumeLaine Jan 8, 2025

Choose a reason for hiding this comment

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

Correct, ROS distinguishes between services and topics like so: https://docs.ros.org/en/foxy/How-To-Guides/Topics-Services-Actions.html. In PX4, we have the srv/ services folder vs the msg/ topics folder.

Messages define the data format used to communicate over either topics or via services. The confusing part is that .srv files define service messages, and .msg files define topic messages (the file extension introduces confusion and make them seem more generic)

And finally yes, currently services require a linear history to translate while topics (.msg) can be split and merged

Thanks for the comment, I realized I was also confused by this too. I'll do my best to make this clear in the docs


- 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.

@mrpollo
Copy link
Contributor

mrpollo commented Jan 6, 2025

Maybe worth adding to the 1.16 release wip page? @hamishwillee

Copy link

github-actions bot commented Jan 8, 2025

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.

4 participants