From 57f6674159045dab0d510c21ac4419c1c7bce961 Mon Sep 17 00:00:00 2001 From: GuillaumeLaine Date: Fri, 31 Jan 2025 09:45:33 +0100 Subject: [PATCH 1/6] uorb: add section on nested messages --- en/middleware/uorb.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/en/middleware/uorb.md b/en/middleware/uorb.md index 93a43ca716af..6f5a2eec5edb 100644 --- a/en/middleware/uorb.md +++ b/en/middleware/uorb.md @@ -18,7 +18,7 @@ To add a new topic, you need to create a new **.msg** file in the `msg/` directo From this, the needed C/C++ code is automatically generated. Have a look at the existing `msg` files for supported types. -A message can also be used nested in other messages. +A message can also be used [nested in other messages](#nested-messages). To each generated C/C++ struct, a field `uint64_t timestamp` will be added. This is used for the logger, so make sure to fill it in when publishing the message. @@ -141,6 +141,11 @@ Make sure not to mix `orb_advertise_multi` and `orb_advertise` for the same topi The full API is documented in [platforms/common/uORB/uORBManager.hpp](https://github.com/PX4/PX4-Autopilot/blob/main/platforms/common/uORB/uORBManager.hpp). +## Nested Messages + +In PX4, messages can be nested within other messages to create complex data structures. This allows for more organized and modular message definitions. + +To nest a message, simply include the nested message type in the parent message definition. For example, [`PositionSetpoint.msg`](../msg_docs/PositionSetpoint.md) is used as a nested message in the [`PositionSetpointTriplet.msg`](../msg_docs/PositionSetpointTriplet.md) topic message definition. ## Message/Field Deprecation {#deprecation} From 73287d537afbc415ed14e8b773421b7aead48eed Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 5 Feb 2025 19:41:39 +1100 Subject: [PATCH 2/6] Major restructure intro --- en/middleware/uorb.md | 71 +++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 16 deletions(-) diff --git a/en/middleware/uorb.md b/en/middleware/uorb.md index 6f5a2eec5edb..4094487c7fcd 100644 --- a/en/middleware/uorb.md +++ b/en/middleware/uorb.md @@ -15,27 +15,73 @@ New uORB topics can be added either within the main PX4/PX4-Autopilot repository For information on adding out-of-tree uORB message definitions, please see [this section](../advanced/out_of_tree_modules.md#out-of-tree-uorb-message-definitions). To add a new topic, you need to create a new **.msg** file in the `msg/` directory and add the file name to the `msg/CMakeLists.txt` list. -From this, the needed C/C++ code is automatically generated. +The section [Message Definitions](#message-definitions) below describes the message format. -Have a look at the existing `msg` files for supported types. -A message can also be used [nested in other messages](#nested-messages). +From the message definitions, the needed C/C++ code is automatically generated. To each generated C/C++ struct, a field `uint64_t timestamp` will be added. This is used for the logger, so make sure to fill it in when publishing the message. -To use the topic in the code, include the header: +To use the topic in the code, first include the generated header, which will be named using the snake-cased version of the (CamelCase) message definition file name. +For example, for a message named `VelocityLimits` you would include `velocity_limits.h` as shown: ```cpp -#include +#include ``` -By adding a line like the following in the `.msg` file, a single message definition can be used for multiple independent topics: +In code your refer to the topic using its id, which by default is also the snake_cased version of the message file name: `ORB_ID(velocity_limits)`. +If needed you can have multiple topics defined from the same message, as described below in [Multi-Topic Messages](#multi-topic-messages). -```cpp -# TOPICS mission offboard_mission onboard_mission +## Message Definitions + +The message definition should start with a descriptive _comment_ (a comment starts with the `#` symbol and goes to the end of the line). +The message will then define one or more fields, which are defined with a _type_, such as `bool`, `uint8`, and `float32`, followed by a _name_. +By convention, each field is followed by a descriptive _comment_, which is any text from the `#` symbol to the end of the line. + +For example the [VelocityLimits](../msg_docs/VelocityLimits.md) message definition shown below has a descriptive comment, followed by a number of fields, which each have a comment. + +``` +# Velocity and yaw rate limits for a multicopter position slow mode only + +uint64 timestamp # time since system start (microseconds) + +# absolute speeds, NAN means use default limit +float32 horizontal_velocity # [m/s] +float32 vertical_velocity # [m/s] +float32 yaw_rate # [rad/s] +``` + +By default this message definition will be compiled to a single topic with an id `velocity_limits`, a direct conversion from the CamelCase name to a snake-case version. + +This is the simplest form of a message. +See the existing [`msg`](../msg_docs/index.md) files for other examples of how messages are defined. + +### Multi-Topic Messages + +Sometimes it is useful to use the same message definition for multiple topics. +This can be specified at the end of the message using a line prefixed with `# TOPICS `, followed by space-separated topic ids. +For example, the [ActuatorOutputs](../msg_docs/ActuatorOutputs.md) message definition is used to define the topic IDs as shown: + +``` +# TOPICS actuator_outputs actuator_outputs_sim actuator_outputs_debug ``` -Then in the code, use them as topic id: `ORB_ID(offboard_mission)`. +### Nested Messages + +Message definitions can be nested within other messages to create complex data structures. + +To nest a message, simply include the nested message type in the parent message definition. For example, [`PositionSetpoint.msg`](../msg_docs/PositionSetpoint.md) is used as a nested message in the [`PositionSetpointTriplet.msg`](../msg_docs/PositionSetpointTriplet.md) topic message definition. + +``` +# Global position setpoint triplet in WGS84 coordinates. +# This are the three next waypoints (or just the next two or one). + +uint64 timestamp # time since system start (microseconds) + +PositionSetpoint previous +PositionSetpoint current +PositionSetpoint next +``` ## Publishing @@ -141,13 +187,6 @@ Make sure not to mix `orb_advertise_multi` and `orb_advertise` for the same topi The full API is documented in [platforms/common/uORB/uORBManager.hpp](https://github.com/PX4/PX4-Autopilot/blob/main/platforms/common/uORB/uORBManager.hpp). -## Nested Messages - -In PX4, messages can be nested within other messages to create complex data structures. This allows for more organized and modular message definitions. - -To nest a message, simply include the nested message type in the parent message definition. For example, [`PositionSetpoint.msg`](../msg_docs/PositionSetpoint.md) is used as a nested message in the [`PositionSetpointTriplet.msg`](../msg_docs/PositionSetpointTriplet.md) topic message definition. - - ## Message/Field Deprecation {#deprecation} As there are external tools using uORB messages from log files, such as [Flight Review](https://github.com/PX4/flight_review), certain aspects need to be considered when updating existing messages: From 7663cd79e755373b4daf0686a4e8b4807c432cb9 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 6 Feb 2025 10:00:42 +1100 Subject: [PATCH 3/6] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Guillaume Lainé <44861207+GuillaumeLaine@users.noreply.github.com> --- en/middleware/uorb.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/en/middleware/uorb.md b/en/middleware/uorb.md index 4094487c7fcd..f51564e0505c 100644 --- a/en/middleware/uorb.md +++ b/en/middleware/uorb.md @@ -22,7 +22,7 @@ From the message definitions, the needed C/C++ code is automatically generated. To each generated C/C++ struct, a field `uint64_t timestamp` will be added. This is used for the logger, so make sure to fill it in when publishing the message. -To use the topic in the code, first include the generated header, which will be named using the snake-cased version of the (CamelCase) message definition file name. +To use the topic in the code, first include the generated header, which will be named using the snake_cased version of the (CamelCase) message definition file name. For example, for a message named `VelocityLimits` you would include `velocity_limits.h` as shown: ```cpp @@ -51,7 +51,7 @@ float32 vertical_velocity # [m/s] float32 yaw_rate # [rad/s] ``` -By default this message definition will be compiled to a single topic with an id `velocity_limits`, a direct conversion from the CamelCase name to a snake-case version. +By default this message definition will be compiled to a single topic with an id `velocity_limits`, a direct conversion from the CamelCase name to a snake_case version. This is the simplest form of a message. See the existing [`msg`](../msg_docs/index.md) files for other examples of how messages are defined. @@ -60,7 +60,7 @@ See the existing [`msg`](../msg_docs/index.md) files for other examples of how m Sometimes it is useful to use the same message definition for multiple topics. This can be specified at the end of the message using a line prefixed with `# TOPICS `, followed by space-separated topic ids. -For example, the [ActuatorOutputs](../msg_docs/ActuatorOutputs.md) message definition is used to define the topic IDs as shown: +For example, the [ActuatorOutputs](../msg_docs/ActuatorOutputs.md) message definition is used to define the topic ids as shown: ``` # TOPICS actuator_outputs actuator_outputs_sim actuator_outputs_debug From 4ef1985778ebfc6a7520b1ced1125a6ec0e25345 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 6 Feb 2025 10:55:28 +1100 Subject: [PATCH 4/6] More corrections following review. Add links to Junwoo tutorial --- en/middleware/uorb.md | 54 ++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/en/middleware/uorb.md b/en/middleware/uorb.md index f51564e0505c..68bc5f42abd5 100644 --- a/en/middleware/uorb.md +++ b/en/middleware/uorb.md @@ -4,17 +4,24 @@ The uORB is an asynchronous `publish()` / `subscribe()` messaging API used for inter-thread/inter-process communication. -Look at the [tutorial](../modules/hello_sky.md) to learn how to use it in C++. +uORB is implemented in the [`uorb` module](../modules/modules_communication.md#uorb). +It is started automatically (with `uorb start`) early in the PX4 boot sequence, as many applications depend on it. +Unit tests can be started with `uorb_tests`. -uORB is automatically started early on bootup as many applications depend on it. -It is started with `uorb start`. Unit tests can be started with `uorb_tests`. +This document explains how to add uORB message definitions and their corresponding topic(s), how to use reference a topic in code, and how to view topics as they change in PX4. +The [First Application Tutorial (Hello Sky)](../modules/hello_sky.md) provides more comprehensive instructions for how to use topics in C++. -## Adding a new topic +## Adding a New Topic -New uORB topics can be added either within the main PX4/PX4-Autopilot repository, or can be added in an out-of-tree message definitions. -For information on adding out-of-tree uORB message definitions, please see [this section](../advanced/out_of_tree_modules.md#out-of-tree-uorb-message-definitions). +New uORB topics can be added either within the main PX4/PX4-Autopilot repository, or can be added in an [out-of-tree message definition](../advanced/out_of_tree_modules.md#out-of-tree-uorb-message-definitions). + +To add new topics, you need to create a new **.msg** "message definition file" in the `msg/` directory, and add the file name to the `msg/CMakeLists.txt` list. +The new file name should follow the CamelCase convention. + +A message definition file can define one or more _topics_, which all have the same fields and structure. +By default a definition maps to a single topic that is named using a snake_case version of the message definition file name (for example, `TopicName.msg` would define a topic `topic_name`). +You can also specify multiple topics to be created by the message definition, which is useful when you need several topics that have the same fields and structure (see [Multi-Topic Messages](#multi-topic-messages) below). -To add a new topic, you need to create a new **.msg** file in the `msg/` directory and add the file name to the `msg/CMakeLists.txt` list. The section [Message Definitions](#message-definitions) below describes the message format. From the message definitions, the needed C/C++ code is automatically generated. @@ -22,25 +29,24 @@ From the message definitions, the needed C/C++ code is automatically generated. To each generated C/C++ struct, a field `uint64_t timestamp` will be added. This is used for the logger, so make sure to fill it in when publishing the message. -To use the topic in the code, first include the generated header, which will be named using the snake_cased version of the (CamelCase) message definition file name. +To use the topic in the code, first include the generated header, which will be named using the snake_case version of the (CamelCase) message definition file name. For example, for a message named `VelocityLimits` you would include `velocity_limits.h` as shown: ```cpp #include ``` -In code your refer to the topic using its id, which by default is also the snake_cased version of the message file name: `ORB_ID(velocity_limits)`. -If needed you can have multiple topics defined from the same message, as described below in [Multi-Topic Messages](#multi-topic-messages). +In code you refer to the topic using its id, which in this example would be: `ORB_ID(velocity_limits)`. ## Message Definitions -The message definition should start with a descriptive _comment_ (a comment starts with the `#` symbol and goes to the end of the line). +The message definition should start with a descriptive _comment_ that outlines its purpose (a comment starts with the `#` symbol and goes to the end of the line). The message will then define one or more fields, which are defined with a _type_, such as `bool`, `uint8`, and `float32`, followed by a _name_. By convention, each field is followed by a descriptive _comment_, which is any text from the `#` symbol to the end of the line. For example the [VelocityLimits](../msg_docs/VelocityLimits.md) message definition shown below has a descriptive comment, followed by a number of fields, which each have a comment. -``` +```text # Velocity and yaw rate limits for a multicopter position slow mode only uint64 timestamp # time since system start (microseconds) @@ -62,7 +68,7 @@ Sometimes it is useful to use the same message definition for multiple topics. This can be specified at the end of the message using a line prefixed with `# TOPICS `, followed by space-separated topic ids. For example, the [ActuatorOutputs](../msg_docs/ActuatorOutputs.md) message definition is used to define the topic ids as shown: -``` +```text # TOPICS actuator_outputs actuator_outputs_sim actuator_outputs_debug ``` @@ -72,7 +78,7 @@ Message definitions can be nested within other messages to create complex data s To nest a message, simply include the nested message type in the parent message definition. For example, [`PositionSetpoint.msg`](../msg_docs/PositionSetpoint.md) is used as a nested message in the [`PositionSetpointTriplet.msg`](../msg_docs/PositionSetpointTriplet.md) topic message definition. -``` +```text # Global position setpoint triplet in WGS84 coordinates. # This are the three next waypoints (or just the next two or one). @@ -178,12 +184,17 @@ For more information see: [Plotting uORB Topic Data in Real Time using PlotJuggl ## Multi-instance -uORB provides a mechanism to publish multiple independent instances of the same topic through `orb_advertise_multi`. -It will return an instance index to the publisher. +uORB provides a mechanism to publish multiple independent instances of the _same_ topic. +This is useful, for example, if the system has several sensors of the same type. + +::: info +This differs from [Multi-Topic Messages](#multi-topic-messages), where we create different topics that happen to have the same structure. +::: + +A publisher can call `orb_advertise_multi` to create a new topic instance and get its instance index. A subscriber will then have to choose to which instance to subscribe to using `orb_subscribe_multi` (`orb_subscribe` subscribes to the first instance). -Having multiple instances is useful for example if the system has several sensors of the same type. -Make sure not to mix `orb_advertise_multi` and `orb_advertise` for the same topic. +Make sure not to mix `orb_advertise_multi` and `orb_advertise` for the same topic! The full API is documented in [platforms/common/uORB/uORBManager.hpp](https://github.com/PX4/PX4-Autopilot/blob/main/platforms/common/uORB/uORBManager.hpp). @@ -199,3 +210,10 @@ As there are external tools using uORB messages from log files, such as [Flight For example `uint8 quat_reset_counter` would become `# DEPRECATED: uint8 quat_reset_counter`. This is to ensure that removed fields (or messages) are not re-added in future. - In case of a semantic change (e.g. the unit changes from degrees to radians), the field must be renamed as well and the previous one marked as deprecated as above. + +## See Also + +- _PX4 uORB Explained_ Blog series + - [Part 1](https://px4.io/px4-uorb-explained-part-1/) + - [Part 2](https://px4.io/px4-uorb-explained-part-2/) + - [Part 3 (The deep stuff)](https://px4.io/px4-uorb-explained-part-3-the-deep-stuff/) From 6b59e36b06b5954d8b2daea8ba0e6c6c7d1a2b91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillaume=20Lain=C3=A9?= <44861207+GuillaumeLaine@users.noreply.github.com> Date: Thu, 6 Feb 2025 07:38:24 +0100 Subject: [PATCH 5/6] apply review suggestion Co-authored-by: Hamish Willee --- en/middleware/uorb.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/en/middleware/uorb.md b/en/middleware/uorb.md index 68bc5f42abd5..542f6bb91bc3 100644 --- a/en/middleware/uorb.md +++ b/en/middleware/uorb.md @@ -26,8 +26,8 @@ The section [Message Definitions](#message-definitions) below describes the mess From the message definitions, the needed C/C++ code is automatically generated. -To each generated C/C++ struct, a field `uint64_t timestamp` will be added. -This is used for the logger, so make sure to fill it in when publishing the message. +All message definitions **must** include the `uint64_t timestamp` field as shown, and this should be filled in when publishing the associated topic(s). +This field is needed in order for the logger to be able to record UORB topics. To use the topic in the code, first include the generated header, which will be named using the snake_case version of the (CamelCase) message definition file name. For example, for a message named `VelocityLimits` you would include `velocity_limits.h` as shown: From df6c61502557144e296502be6bd58b5f598e0626 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Fri, 7 Feb 2025 09:06:50 +1100 Subject: [PATCH 6/6] listener command --- en/middleware/uorb.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/en/middleware/uorb.md b/en/middleware/uorb.md index 542f6bb91bc3..0ee24f31b7d0 100644 --- a/en/middleware/uorb.md +++ b/en/middleware/uorb.md @@ -26,9 +26,6 @@ The section [Message Definitions](#message-definitions) below describes the mess From the message definitions, the needed C/C++ code is automatically generated. -All message definitions **must** include the `uint64_t timestamp` field as shown, and this should be filled in when publishing the associated topic(s). -This field is needed in order for the logger to be able to record UORB topics. - To use the topic in the code, first include the generated header, which will be named using the snake_case version of the (CamelCase) message definition file name. For example, for a message named `VelocityLimits` you would include `velocity_limits.h` as shown: @@ -44,6 +41,11 @@ The message definition should start with a descriptive _comment_ that outlines i The message will then define one or more fields, which are defined with a _type_, such as `bool`, `uint8`, and `float32`, followed by a _name_. By convention, each field is followed by a descriptive _comment_, which is any text from the `#` symbol to the end of the line. +::: warning +All message definitions **must** include the `uint64_t timestamp` field, and this should be filled in when publishing the associated topic(s). +This field is needed in order for the logger to be able to record UORB topics. +::: + For example the [VelocityLimits](../msg_docs/VelocityLimits.md) message definition shown below has a descriptive comment, followed by a number of fields, which each have a comment. ```text @@ -97,7 +99,8 @@ However, the topic needs to be advertised and published outside of an interrupt ## Listing Topics and Listening in ::: info -The `listener` command is only available on Pixracer (FMUv4) and Linux / OS X. +The `listener` command available on most boards after FMUv4. +You can check for a particular board by searching for the `CONFIG_SYSTEMCMDS_TOPIC_LISTENER` key in the [kconfig](../hardware/porting_guide_config.md) board configuration (for example, see the FMUv6 [default.px4board](https://github.com/PX4/PX4-Autopilot/blob/release/1.15/boards/px4/fmu-v6x/default.px4board#L100) file). ::: To list all topics, list the file handles: