mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-03 15:28:53 +08:00
Move PX4 Guide source into /docs (#24490)
* Add vitepress tree * Update existing workflows so they dont trigger on changes in the docs path * Add nojekyll, package.json, LICENCE etc * Add crowdin docs upload/download scripts * Add docs flaw checker workflows * Used docs prefix for docs workflows * Crowdin obvious fixes * ci: docs move to self hosted runner runs on a beefy server for faster builds Signed-off-by: Ramon Roche <mrpollo@gmail.com> * ci: don't run build action for docs or ci changes Signed-off-by: Ramon Roche <mrpollo@gmail.com> * ci: update runners Signed-off-by: Ramon Roche <mrpollo@gmail.com> * Add docs/en * Add docs assets and scripts * Fix up editlinks to point to PX4 sources * Download just the translations that are supported * Add translation sources for zh, uk, ko * Update latest tranlsation and uorb graphs * update vitepress to latest --------- Signed-off-by: Ramon Roche <mrpollo@gmail.com> Co-authored-by: Ramon Roche <mrpollo@gmail.com>
This commit is contained in:
co-authored by
Ramon Roche
parent
8e6d2ebe4a
commit
88d623bedb
@@ -0,0 +1,152 @@
|
||||
# 驱动开发
|
||||
|
||||
PX4 device drivers are based on the [Device](https://github.com/PX4/PX4-Autopilot/tree/main/src/lib/drivers/device) framework.
|
||||
|
||||
## 创建驱动程序
|
||||
|
||||
PX4 almost exclusively consumes data from [uORB](../middleware/uorb.md). 常见外设类型的驱动程序必须发布正确的 uORB 消息(例如: 陀螺仪、加速度计、压力传感器等)。
|
||||
|
||||
The best approach for creating a new driver is to start with a similar driver as a template (see [src/drivers](https://github.com/PX4/PX4-Autopilot/tree/main/src/drivers)).
|
||||
|
||||
:::info
|
||||
More detailed information about working with specific I/O buses and sensors may be available in [Sensor and Actuator Buses](../sensor_bus/index.md) section.
|
||||
:::
|
||||
|
||||
:::info
|
||||
Publishing the correct uORB topics is the only pattern that drivers _must_ follow.
|
||||
:::
|
||||
|
||||
## 核心架构
|
||||
|
||||
PX4 is a [reactive system](../concept/architecture.md) and uses [uORB](../middleware/uorb.md) publish/subscribe to transport messages. File handles are not required or used for the core operation of the system. Two main APIs are used:
|
||||
|
||||
- Publish / subscribe 系统具有文件、网络或共享内存后端,具体取决于系统 PX4 运行。
|
||||
- The global device registry, which can be used to enumerate devices and get/set their configuration. This can be as simple as a linked list or map to the file system. 这可以像链接列表或映射到文件系统一样简单。
|
||||
|
||||
## 设备ID
|
||||
|
||||
For the example of three magnetometers on a system, use the flight log (.px4log) to dump the parameters. The three parameters encode the sensor IDs and <code>MAG_PRIME</code> identifies which magnetometer is selected as the primary sensor. Each MAGx_ID is a 24bit number and should be padded left with zeros for manual decoding. 这三个参数解码传感器的 ID, 并且 <code>MAG_PRIME</code> 区分那个磁力计作为主传感器。
|
||||
|
||||
The order of sensors (e.g. if there is a `/dev/mag0` and an alternate `/dev/mag1`) does not determine priority - the priority is instead stored as part of the published uORB topic.
|
||||
|
||||
### 解码示例
|
||||
|
||||
This is the internal HMC5983 connected via SPI, bus 1, slave select slot 5. It will show up in the log file as <code>IMU1.MagX</code>. The three parameters encode the sensor IDs and `MAG_PRIME` identifies which magnetometer is selected as the primary sensor. Each MAGx_ID is a 24bit number and should be padded left with zeros for manual decoding.
|
||||
|
||||
```
|
||||
CAL_MAG0_ID = 73225.0
|
||||
CAL_MAG1_ID = 66826.0
|
||||
CAL_MAG2_ID = 263178.0
|
||||
CAL_MAG_PRIME = 73225.0
|
||||
```
|
||||
|
||||
This is the external HMC5983 connected via I2C, bus 1 at address `0x1E`: It will show up in the log file as `IMU.MagX`.
|
||||
|
||||
```
|
||||
# device ID 73225 in 24-bit binary:
|
||||
00000001 00011110 00001 001
|
||||
|
||||
# decodes to:
|
||||
HMC5883 0x1E bus 1 I2C
|
||||
```
|
||||
|
||||
根据此格式,设备 ID 是一个24bit 数字。 It will show up in the log file as `IMU1.MagX`.
|
||||
|
||||
```
|
||||
# device ID 66826 in 24-bit binary:
|
||||
00000001 00000101 00001 010
|
||||
|
||||
# decodes to:
|
||||
HMC5883 dev 5 bus 1 SPI
|
||||
```
|
||||
|
||||
And this is the internal MPU9250 magnetometer connected via SPI, bus 1, slave select slot 4. It will show up in the log file as `IMU2.MagX`.
|
||||
|
||||
```
|
||||
# device ID 263178 in 24-bit binary:
|
||||
00000100 00000100 00001 010
|
||||
|
||||
#decodes to:
|
||||
MPU9250 dev 4 bus 1 SPI
|
||||
```
|
||||
|
||||
### 设备 ID 编码
|
||||
|
||||
The device ID is a 24bit number according to this format. Note that the first fields are the least significant bits in the decoding example above.
|
||||
|
||||
```C
|
||||
struct DeviceStructure {
|
||||
enum DeviceBusType bus_type : 3;
|
||||
uint8_t bus: 5; // which instance of the bus type
|
||||
uint8_t address; // address on the bus (eg. I2C address)
|
||||
uint8_t devtype; // device class specific device type
|
||||
};
|
||||
```
|
||||
|
||||
The `bus_type` is decoded according to:
|
||||
|
||||
```C
|
||||
enum DeviceBusType {
|
||||
DeviceBusType_UNKNOWN = 0,
|
||||
DeviceBusType_I2C = 1,
|
||||
DeviceBusType_SPI = 2,
|
||||
DeviceBusType_UAVCAN = 3,
|
||||
};
|
||||
```
|
||||
|
||||
and `devtype` is decoded according to:
|
||||
|
||||
```C
|
||||
#define DRV_MAG_DEVTYPE_HMC5883 0x01
|
||||
#define DRV_MAG_DEVTYPE_LSM303D 0x02
|
||||
#define DRV_MAG_DEVTYPE_ACCELSIM 0x03
|
||||
#define DRV_MAG_DEVTYPE_MPU9250 0x04
|
||||
#define DRV_ACC_DEVTYPE_LSM303D 0x11
|
||||
#define DRV_ACC_DEVTYPE_BMA180 0x12
|
||||
#define DRV_ACC_DEVTYPE_MPU6000 0x13
|
||||
#define DRV_ACC_DEVTYPE_ACCELSIM 0x14
|
||||
#define DRV_ACC_DEVTYPE_GYROSIM 0x15
|
||||
#define DRV_ACC_DEVTYPE_MPU9250 0x16
|
||||
#define DRV_GYR_DEVTYPE_MPU6000 0x21
|
||||
#define DRV_GYR_DEVTYPE_L3GD20 0x22
|
||||
#define DRV_GYR_DEVTYPE_GYROSIM 0x23
|
||||
#define DRV_GYR_DEVTYPE_MPU9250 0x24
|
||||
#define DRV_RNG_DEVTYPE_MB12XX 0x31
|
||||
#define DRV_RNG_DEVTYPE_LL40LS 0x32
|
||||
```
|
||||
|
||||
## 调试
|
||||
|
||||
For general debugging topics see: [Debugging/Logging](../debug/index.md).
|
||||
|
||||
### 使用操纵杆
|
||||
|
||||
Drivers (and other modules) output minimally verbose logs strings by default (e.g. for `PX4_DEBUG`, `PX4_WARN`, `PX4_ERR`, etc.).
|
||||
|
||||
Log verbosity is defined at build time using the `RELEASE_BUILD` (default), `DEBUG_BUILD` (verbose) or `TRACE_BUILD` (extremely verbose) macros.
|
||||
|
||||
Change the logging level using `COMPILE_FLAGS` in the driver `px4_add_module` function (**CMakeLists.txt**).
|
||||
The code fragment below shows the required change to enable DEBUG_BUILD level debugging for a single module or driver.
|
||||
|
||||
```
|
||||
px4_add_module(
|
||||
MODULE templates__module
|
||||
MAIN module
|
||||
```
|
||||
|
||||
```
|
||||
COMPILE_FLAGS
|
||||
-DDEBUG_BUILD
|
||||
```
|
||||
|
||||
```
|
||||
SRCS
|
||||
module.cpp
|
||||
DEPENDS
|
||||
modules__uORB
|
||||
)
|
||||
```
|
||||
|
||||
:::tip
|
||||
Verbose logging can also be enabled on a per-file basis, by adding `#define DEBUG_BUILD` at the very top of a .cpp file (before any includes).
|
||||
:::
|
||||
@@ -0,0 +1,7 @@
|
||||
# 中间件
|
||||
|
||||
This section contains topics about PX4 middleware, including PX4 internal communication mechanisms ([uORB](../middleware/uorb.md)), and between PX4 and offboard systems like companion computers and GCS (e.g. [MAVLink](../middleware/mavlink.md), [uXRCE-DDS](../middleware/uxrce_dds.md)).
|
||||
|
||||
:::tip
|
||||
For a detailed overview of the platform architecture see the [Architectural Overview](../concept/architecture.md).
|
||||
:::
|
||||
@@ -0,0 +1,526 @@
|
||||
# MAVLink通讯
|
||||
|
||||
[MAVLink](https://mavlink.io/en/) is a very lightweight messaging protocol that has been designed for the drone ecosystem.
|
||||
|
||||
PX4 uses _MAVLink_ to communicate with ground stations and MAVLink SDKs, such as _QGroundControl_ and [MAVSDK](https://mavsdk.mavlink.io/), and as the integration mechanism for connecting to drone components outside of the flight controller: companion computers, MAVLink enabled cameras, and so on.
|
||||
|
||||
This topic provides a brief overview of fundamental MAVLink concepts, such as messages, commands, and microservices.
|
||||
It also provides tutorial instructions for how you can add PX4 support for:
|
||||
|
||||
- Streaming MAVLink messages
|
||||
- Handling incoming MAVLink messages and writing to a uORB topic.
|
||||
|
||||
:::info
|
||||
The topic does not cover _command_ handling and sending, or how to implement your own microservices.
|
||||
:::
|
||||
|
||||
## MAVLink Overview
|
||||
|
||||
MAVLink is a lightweight protocol that was designed for efficiently sending messages over unreliable low-bandwidth radio links.
|
||||
|
||||
_Messages_ are simplest and most "fundamental" definition in MAVLink, consisting of a name (e.g. [ATTITUDE](https://mavlink.io/en/messages/common.html#ATTITUDE)), id, and fields containing relevant data.
|
||||
They are deliberately lightweight, with a constrained size, and no semantics for resending and acknowledgement.
|
||||
Stand-alone messages are commonly used for streaming telemetry or status information, and for sending commands where no acknowledgement is required - such as setpoint commands sent at high rate.
|
||||
|
||||
The [Command Protocol](https://mavlink.io/en/services/command.html) is a higher level protocol for sending commands that may need acknowledgement.
|
||||
Specific commands are defined as values of the [MAV_CMD](https://mavlink.io/en/messages/common.html#mav_commands) enumeration, such as the takeoff command [MAV_CMD_NAV_TAKEOFF](https://mavlink.io/en/messages/common.html#MAV_CMD_NAV_TAKEOFF), and include up to 7 numeric "param" values.
|
||||
The protocol sends a command by packaging the parameter values in a `COMMAND_INT` or `COMMAND_LONG` message, and waits for an acknowledgement with a result in a `COMMAND_ACK`.
|
||||
The command is resent automatically if no acknowledgment is received.
|
||||
Note that [MAV_CMD](https://mavlink.io/en/messages/common.html#mav_commands) definitions are also used to define mission actions, and that not all definitions are supported for use in commands/missions on PX4.
|
||||
|
||||
[Microservices](https://mavlink.io/en/services/) are other higher level protocols built on top of MAVLink messages.
|
||||
They are used to communicate information that cannot be sent in a single message, and to deliver features such as reliable communication.
|
||||
The command protocol described above is one such service.
|
||||
Others include the [File Transfer Protocol](https://mavlink.io/en/services/ftp.html), [Camera Protocol](https://mavlink.io/en/services/camera.html) and [Mission Protocol](https://mavlink.io/en/services/mission.html).
|
||||
|
||||
MAVLink messages, commands and enumerations are defined in [XML definition files](https://mavlink.io/en/guide/define_xml_element.html).
|
||||
The MAVLink toolchain includes code generators that create programming-language-specific libraries from these definitions for sending and receiving messages.
|
||||
Note that most generated libraries do not create code to implement microservices.
|
||||
|
||||
The MAVLink project standardizes a number of messages, commands, enumerations, and microservices, for exchanging data using the following definition files (note that higher level files _include_ the definitions of the files below them):
|
||||
|
||||
- [development.xml](https://mavlink.io/en/messages/development.html) — Definitions that are proposed to be part of the standard.
|
||||
The definitions move to `common.xml` if accepted following testing.
|
||||
- [common.xml](https://mavlink.io/en/messages/common.html) — A "library" of definitions meeting many common UAV use cases.
|
||||
These are supported by many flight stacks, ground stations, and MAVLink peripherals.
|
||||
Flight stacks that use these definitions are more likely to interoperate.
|
||||
- [standard.xml](https://mavlink.io/en/messages/standard.html) — Definitions that are actually standard.
|
||||
They are present on the vast majority of flight stacks and implemented in the same way.
|
||||
- [minimal.xml](https://mavlink.io/en/messages/minimal.html) — Definitions required by a minimal MAVLink implementation.
|
||||
|
||||
The project also hosts [dialect XML definitions](https://mavlink.io/en/messages/#dialects), which contain MAVLink definitions that are specific to a flight stack or other stakeholder.
|
||||
|
||||
The protocol relies on each end of the communication having a shared definition of what messages are being sent.
|
||||
What this means is that in order to communicate both ends of the communication must use libraries generated from the same XML definition.
|
||||
|
||||
<!--
|
||||
The messages are sent over-the-wire in the "payload" of a [MAVLink packet](https://mavlink.io/en/guide/serialization.html#mavlink2_packet_format).
|
||||
In order to reduce the amount of information that must be sent, the packet does not include the message metadata, such as what fields are in the message and so on.
|
||||
Instead, the fields are serialized in a predefined order based on data size and XML definition order, and MAVLink relies on each end of the communication having a shared definition of what messages are being sent.
|
||||
The shared identity of the message is conveyed by the message id, along with a CRC ("`CRC_EXTRA`") that uniquely identifies the message based on its name and id, and the field names and types.
|
||||
The receiving end of the communication will discard any packet for which the message id and the `CRC_EXTRA` do not match.
|
||||
-->
|
||||
|
||||
## PX4 and MAVLink
|
||||
|
||||
PX4 releases build `common.xml` MAVLink definitions by default, for the greatest compatibility with MAVLink ground stations, libraries, and external components such as MAVLink cameras.
|
||||
In the `main` branch, these are included from `development.xml` on SITL, and `common.xml` for other boards.
|
||||
|
||||
:::info
|
||||
To be part of a PX4 release, any MAVLink definitions that you use must be in `common.xml` (or included files such as `standard.xml` and `minimal.xml`).
|
||||
During development you can use definitions in `development.xml`.
|
||||
You will need to work with the [MAVLink team](https://mavlink.io/en/contributing/contributing.html) to define and contribute these definitions.
|
||||
:::
|
||||
|
||||
PX4 includes the [mavlink/mavlink](https://github.com/mavlink/mavlink) repo as a submodule under [/src/modules/mavlink](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/mavlink).
|
||||
This contains XML definition files in [/mavlink/messages/1.0/](https://github.com/mavlink/mavlink/blob/master/message_definitions/v1.0/).
|
||||
|
||||
The build toolchain generates the MAVLink 2 C header files at build time.
|
||||
The XML file for which headers files are generated may be defined in the [PX4 kconfig board configuration](../hardware/porting_guide_config.md#px4-board-configuration-kconfig) on a per-board basis, using the variable `CONFIG_MAVLINK_DIALECT`:
|
||||
|
||||
- For SITL `CONFIG_MAVLINK_DIALECT` is set to `development` in [boards/px4/sitl/default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/sitl/default.px4board#L36).
|
||||
You can change this to any other definition file, but the file must include `common.xml`.
|
||||
- For other boards `CONFIG_MAVLINK_DIALECT` is not set by default, and PX4 builds the definitions in `common.xml` (these are build into the [mavlink module](../modules/modules_communication.md#mavlink) by default — search for `menuconfig MAVLINK_DIALECT` in [src/modules/mavlink/Kconfig](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mavlink/Kconfig#L10)).
|
||||
|
||||
The files are generated into the build directory: `/build/<build target>/mavlink/`.
|
||||
|
||||
## Custom MAVLink Messages
|
||||
|
||||
A custom MAVLink message is one that isn't in the default definitions included into PX4.
|
||||
|
||||
:::info
|
||||
If you use a custom definition you will need maintain the definition in PX4, your ground station, and any other SDKs that communicate with it.
|
||||
Generally you should use (or add to) the standard definitions if at all possible to reduce the maintenance burden.
|
||||
:::
|
||||
|
||||
Custom definitions can be added in a new dialect file in the same directory as the standard XML definitions.
|
||||
For example, create `PX4-Autopilot/src/modules/mavlink/mavlink/message_definitions/v1.0/custom_messages.xml`, and set `CONFIG_MAVLINK_DIALECT` to build the new file for SITL.
|
||||
This dialect file should include `development.xml` so that all the standard definitions are also included.
|
||||
|
||||
For initial prototyping, or if you intend your message to be "standard", you can also add your messages to `common.xml` (or `development.xml`).
|
||||
This simplifies building, because you don't need to modify the dialect that is built.
|
||||
|
||||
The MAVLink developer guide explains how to define new messages in [How to Define MAVLink Messages & Enums](https://mavlink.io/en/guide/define_xml_element.html).
|
||||
|
||||
You can check that your new messages are built by inspecting the headers generated in the build directory (`/build/<build target>/mavlink/`).
|
||||
If your messages are not built they may be incorrectly formatted, or use clashing ids.
|
||||
Inspect the build log for information.
|
||||
|
||||
Once the message is being built you can stream, receive, or otherwise use it, as described in the following sections.
|
||||
|
||||
:::info
|
||||
The [MAVLink Developer guide](https://mavlink.io/en/getting_started/) has more information about using the MAVLink toolchain.
|
||||
:::
|
||||
|
||||
## Streaming MAVLink Messages
|
||||
|
||||
MAVLink messages are streamed using a streaming class, derived from `MavlinkStream`, that has been added to the PX4 stream list.
|
||||
The class has framework methods that you implement so PX4 can get information it needs from the generated MAVLink message definition.
|
||||
It also has a `send()` method that is called each time the message needs to be sent — you override this to copy information from a uORB subscription to the MAVLink message object that is to be sent.
|
||||
|
||||
This tutorial demonstrates how to stream a uORB message as a MAVLink message, and applies to both standard and custom messages.
|
||||
|
||||
### 操作前提
|
||||
|
||||
Generally you will already have a [uORB](../middleware/uorb.md) message that contains information you'd like to stream and a definition of a MAVLink message that you'd like to stream it with.
|
||||
|
||||
For this example we're going to assume that you want to stream the (existing) [BatteryStatus](../msg_docs/BatteryStatus.md) uORB message to a new MAVLink battery status message, which we will name `BATTERY_STATUS_DEMO`.
|
||||
|
||||
Copy this `BATTERY_STATUS_DEMO` message into the message section of `development.xml` in your PX4 source code, which will be located at: `\src\modules\mavlink\mavlink\message_definitions\v1.0\development.xml`.
|
||||
|
||||
```xml
|
||||
<message id="11514" name="BATTERY_STATUS_DEMO">
|
||||
<description>Simple demo battery.</description>
|
||||
<field type="uint8_t" name="id" instance="true">Battery ID</field>
|
||||
<field type="int16_t" name="temperature" units="cdegC" invalid="INT16_MAX">Temperature of the whole battery pack (not internal electronics). INT16_MAX field not provided.</field>
|
||||
<field type="uint8_t" name="percent_remaining" units="%" invalid="UINT8_MAX">Remaining battery energy. Values: [0-100], UINT8_MAX: field not provided.</field>
|
||||
</message>
|
||||
```
|
||||
|
||||
:::info
|
||||
Note that this is a cut-down version of the not-yet-implemented [BATTERY_STATUS_V2](https://mavlink.io/en/messages/development.html#BATTERY_STATUS_V2) message with randomly chosen unused id of `11514`.
|
||||
Here we've put the message in `development.xml`, which is fine for testing and if the message is intended to eventually be part of the standard message set, but you might also put a [custom message](#custom-mavlink-messages) in its own dialect file.
|
||||
:::
|
||||
|
||||
Build PX4 for SITL and confirm that the associated message is generated in `/build/px4_sitl_default/mavlink/development/mavlink_msg_battery_status_demo.h`.
|
||||
|
||||
Because `BatteryStatus` already exists you will not need to do anything to create or build it.
|
||||
|
||||
### Define the Streaming Class
|
||||
|
||||
First create a file named `BATTERY_STATUS_DEMO.hpp` for your streaming class (named after the message to stream) inside the [/src/modules/mavlink/streams](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/mavlink/streams) directory.
|
||||
|
||||
Add the headers for the uORB message(s) to the top of the file (the required MAVLink headers should already be available):
|
||||
|
||||
```cpp
|
||||
#include <uORB/topics/battery_status.h>
|
||||
```
|
||||
|
||||
:::info
|
||||
The uORB topic's snake-case header file is generated from the CamelCase uORB filename at build time.
|
||||
:::
|
||||
|
||||
Then copy the streaming class definition below into the file:
|
||||
|
||||
```cpp
|
||||
class MavlinkStreamBatteryStatusDemo : public MavlinkStream
|
||||
{
|
||||
public:
|
||||
static MavlinkStream *new_instance(Mavlink *mavlink)
|
||||
{
|
||||
return new MavlinkStreamBatteryStatusDemo(mavlink);
|
||||
}
|
||||
const char *get_name() const
|
||||
{
|
||||
return MavlinkStreamBatteryStatusDemo::get_name_static();
|
||||
}
|
||||
static const char *get_name_static()
|
||||
{
|
||||
return "BATTERY_STATUS_DEMO";
|
||||
}
|
||||
static uint16_t get_id_static()
|
||||
{
|
||||
return MAVLINK_MSG_ID_BATTERY_STATUS_DEMO;
|
||||
}
|
||||
uint16_t get_id()
|
||||
{
|
||||
return get_id_static();
|
||||
}
|
||||
unsigned get_size()
|
||||
{
|
||||
return MAVLINK_MSG_ID_BATTERY_STATUS_DEMO_LEN + MAVLINK_NUM_NON_PAYLOAD_BYTES;
|
||||
}
|
||||
|
||||
private:
|
||||
//Subscription to array of uORB battery status instances
|
||||
uORB::SubscriptionMultiArray<battery_status_s, battery_status_s::MAX_INSTANCES> _battery_status_subs{ORB_ID::battery_status};
|
||||
// SubscriptionMultiArray subscription is needed because battery has multiple instances.
|
||||
// uORB::Subscription is used to subscribe to a single-instance topic
|
||||
|
||||
/* do not allow top copying this class */
|
||||
MavlinkStreamBatteryStatusDemo(MavlinkStreamBatteryStatusDemo &);
|
||||
MavlinkStreamBatteryStatusDemo& operator = (const MavlinkStreamBatteryStatusDemo &);
|
||||
|
||||
protected:
|
||||
explicit MavlinkStreamBatteryStatusDemo(Mavlink *mavlink) : MavlinkStream(mavlink)
|
||||
{}
|
||||
|
||||
bool send() override
|
||||
{
|
||||
bool updated = false;
|
||||
|
||||
// Loop through _battery_status_subs (subscription to array of BatteryStatus instances)
|
||||
for (auto &battery_sub : _battery_status_subs) {
|
||||
// battery_status_s is a struct that can hold the battery object topic
|
||||
battery_status_s battery_status;
|
||||
|
||||
// Update battery_status and publish only if the status has changed
|
||||
if (battery_sub.update(&battery_status)) {
|
||||
// mavlink_battery_status_demo_t is the MAVLink message object
|
||||
mavlink_battery_status_demo_t bat_msg{};
|
||||
|
||||
bat_msg.id = battery_status.id - 1;
|
||||
bat_msg.percent_remaining = (battery_status.connected) ? roundf(battery_status.remaining * 100.f) : -1;
|
||||
|
||||
// check if temperature valid
|
||||
if (battery_status.connected && PX4_ISFINITE(battery_status.temperature)) {
|
||||
bat_msg.temperature = battery_status.temperature * 100.f;
|
||||
} else {
|
||||
bat_msg.temperature = INT16_MAX;
|
||||
}
|
||||
|
||||
//Send the message
|
||||
mavlink_msg_battery_status_demo_send_struct(_mavlink->get_channel(), &bat_msg);
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
};
|
||||
```
|
||||
|
||||
Most streaming classes are very similar (see examples in [/src/modules/mavlink/streams](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/mavlink/streams)):
|
||||
|
||||
- The streaming class derives from [`MavlinkStream`](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mavlink/mavlink_stream.h) and is named using the pattern `MavlinkStream<CamelCaseMessageName>`.
|
||||
|
||||
- The `public` definitions are "near-boilerplate", allowing PX4 to get an instance of the class (`new_instance()`), and then to use it to fetch the name, id, and size of the message from the MAVLink headers (`get_name()`, `get_name_static()`, `get_id_static()`, `get_id()`, `get_size()`).
|
||||
For your own streaming classes these can just be copied and modified to match the values for your MAVLink message.
|
||||
|
||||
- The `private` definitions subscribe to the uORB topics that need to be published.
|
||||
In this case the uORB topic has multiple instances: one for each battery.
|
||||
We use `uORB::SubscriptionMultiArray` to get an array of battery status subscriptions.
|
||||
|
||||
Here we also define constructors to prevent the definition being copied.
|
||||
|
||||
- The `protected` section is where the important work takes place!
|
||||
|
||||
Here we override the `send()` method, copying values from the subscribed uORB topic(s) into appropriate fields in the MAVLink message, and then send the message.
|
||||
|
||||
In this particular example we have an array of uORB instances `_battery_status_subs` (because we have multiple batteries).
|
||||
We iterate the array and use `update()` on each subscription to check if the associated battery instance has changed (and update a structure with the current data).
|
||||
This allows us to send the MAVLink message _only_ if the associated battery uORB topic has changed:
|
||||
|
||||
```cpp
|
||||
// Struct to hold current topic data.
|
||||
battery_status_s battery_status;
|
||||
|
||||
// update() populates battery_status and returns true if the status has changed
|
||||
if (battery_sub.update(&battery_status)) {
|
||||
// Use battery_status to populate message and send
|
||||
}
|
||||
```
|
||||
|
||||
If wanted to send a MAVLink message whether or not the data changed, we could instead use `copy()` as shown:
|
||||
|
||||
```cpp
|
||||
battery_status_s battery_status;
|
||||
battery_sub.copy(&battery_status);
|
||||
```
|
||||
|
||||
::: info
|
||||
For a single-instance topic like [VehicleStatus](../msg_docs/VehicleStatus.md) we would subscribe like this:
|
||||
|
||||
```cpp
|
||||
// Create subscription _vehicle_status_sub
|
||||
uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)};
|
||||
```
|
||||
|
||||
And we could use the resulting subscription in the same way with update or copy.
|
||||
|
||||
```cpp
|
||||
vehicle_status_s vehicle_status{}; // vehicle_status_s is the definition of the uORB topic
|
||||
if (_vehicle_status_sub.update(&vehicle_status)) {
|
||||
// Use the vehicle_status as it has been updated.
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
:::
|
||||
|
||||
Next we include our new class in [mavlink_messages.cpp](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mavlink/mavlink_messages.cpp#L2193).
|
||||
Add the line below to the part of the file where all the other streams are included:
|
||||
|
||||
```cpp
|
||||
#include "streams/BATTERY_STATUS_DEMO.hpp"
|
||||
```
|
||||
|
||||
Finally append the stream class to the `streams_list` at the bottom of
|
||||
[mavlink_messages.cpp](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mavlink/mavlink_messages.cpp)
|
||||
|
||||
```C
|
||||
StreamListItem *streams_list[] = {
|
||||
...
|
||||
#if defined(BATTERY_STATUS_DEMO_HPP)
|
||||
create_stream_list_item<MavlinkStreamBatteryStatusDemo>(),
|
||||
#endif // BATTERY_STATUS_DEMO_HPP
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
The class is now available for streaming, but won't be streamed by default.
|
||||
We cover that in the next sections.
|
||||
|
||||
### Streaming by Default
|
||||
|
||||
The easiest way to stream your messages by default (as part of a build) is to add them to [mavlink_main.cpp](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mavlink/mavlink_main.cpp) in the appropriate message group.
|
||||
|
||||
If you search in the file you'll find groups of messages defined in a switch statement:
|
||||
|
||||
- `MAVLINK_MODE_NORMAL`: Streamed to a GCS.
|
||||
- `MAVLINK_MODE_ONBOARD`: Streamed to a companion computer on a fast link, such as Ethernet
|
||||
- `MAVLINK_MODE_ONBOARD_LOW_BANDWIDTH`: Streamed to a companion computer for re-routing to a reduced-traffic link, such as a GCS.
|
||||
- `MAVLINK_MODE_GIMBAL`: Streamed to a gimbal
|
||||
- `MAVLINK_MODE_EXTVISION`: Streamed to an external vision system
|
||||
- `MAVLINK_MODE_EXTVISIONMIN`: Streamed to an external vision system on a slower link
|
||||
- `MAVLINK_MODE_OSD`: Streamed to an OSD, such as an FPV headset.
|
||||
- `MAVLINK_MODE_CUSTOM`: Stream nothing by default. Used when configuring streaming using MAVLink.
|
||||
- `MAVLINK_MODE_MAGIC`: Same as `MAVLINK_MODE_CUSTOM`
|
||||
- `MAVLINK_MODE_CONFIG`: Streaming over USB with higher rates than `MAVLINK_MODE_NORMAL`.
|
||||
- `MAVLINK_MODE_MINIMAL`: Stream a minimal set of messages. Normally used for poor telemetry links.
|
||||
- `MAVLINK_MODE_IRIDIUM`: Streamed to an iridium satellite phone
|
||||
|
||||
Normally you'll be testing on a GCS, so you could just add the message to the `MAVLINK_MODE_NORMAL` case using the `configure_stream_local()` method.
|
||||
For example, to stream CA_TRAJECTORY at 5 Hz:
|
||||
|
||||
```cpp
|
||||
case MAVLINK_MODE_CONFIG: // USB
|
||||
// Note: streams requiring low latency come first
|
||||
...
|
||||
configure_stream_local("BATTERY_STATUS_DEMO", 5.0f);
|
||||
...
|
||||
```
|
||||
|
||||
It is also possible to add a stream by calling the [mavlink](../modules/modules_communication.md#mavlink) module with the `stream` argument in a [startup script](../concept/system_startup.md).
|
||||
For example, you might add the following line to [/ROMFS/px4fmu_common/init.d-posix/px4-rc.mavlink](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d-posix/px4-rc.mavlink) in order to stream `BATTERY_STATUS_DEMO` at 50Hz on UDP port `14556` (`-r` configures the streaming rate and `-u` identifies the MAVLink channel on UDP port 14556).
|
||||
|
||||
```sh
|
||||
mavlink stream -r 50 -s BATTERY_STATUS_DEMO -u 14556
|
||||
```
|
||||
|
||||
### Streaming on Request
|
||||
|
||||
Some messages are only needed once, when particular hardware is connected, or under other circumstances.
|
||||
In order to avoid clogging communications links with messages that aren't needed you may not stream all messages by default, even at low rate.
|
||||
|
||||
If you needed, a GCS or other MAVLink API can request that particular messages are streamed at a particular rate using [MAV_CMD_SET_MESSAGE_INTERVAL](https://mavlink.io/en/messages/common.html#MAV_CMD_SET_MESSAGE_INTERVAL).
|
||||
A particular message can be requested just once using [MAV_CMD_REQUEST_MESSAGE](https://mavlink.io/en/messages/common.html#MAV_CMD_REQUEST_MESSAGE).
|
||||
|
||||
## Receiving MAVLink Messages
|
||||
|
||||
This section explains how to receive a message over MAVLink and publish it to uORB.
|
||||
|
||||
It assumes that we are receiving the `BATTERY_STATUS_DEMO` message and we want to update the (existing) [BatteryStatus uORB message](../msg_docs/BatteryStatus.md) with the contained information.
|
||||
This is the kind of implementation that you would provide to support a MAVLink battery integration with PX4.
|
||||
|
||||
Add the headers for the uORB topic to publish to in [mavlink_receiver.h](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mavlink/mavlink_receiver.h#L77):
|
||||
|
||||
```cpp
|
||||
#include <uORB/topics/battery_status.h>
|
||||
```
|
||||
|
||||
Add a function signature for a function that handles the incoming MAVLink message in the `MavlinkReceiver` class in
|
||||
[mavlink_receiver.h](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mavlink/mavlink_receiver.h#L126)
|
||||
|
||||
```cpp
|
||||
void handle_message_battery_status_demo(mavlink_message_t *msg);
|
||||
```
|
||||
|
||||
Normally you would add a uORB publisher for the uORB topic to publish in the `MavlinkReceiver` class in
|
||||
[mavlink_receiver.h](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mavlink/mavlink_receiver.h#L296).
|
||||
In this case the [BatteryStatus](../msg_docs/BatteryStatus.md) uORB topic already exists:
|
||||
|
||||
```cpp
|
||||
uORB::Publication<battery_status_s> _battery_pub{ORB_ID(battery_status)};
|
||||
```
|
||||
|
||||
This creates a publication to a single uORB topic instance, which by default will be the _first_ instance.
|
||||
|
||||
:::info
|
||||
This implementation won't work on multi-battery systems, because several batteries might be publishing data to the first instance of the topic, and there is no way to differentiate them.
|
||||
To support multiple batteries we'd need to use `PublicationMulti` and map the MAVLink message instance IDs to specific uORB topic instances.
|
||||
:::
|
||||
|
||||
Implement the `handle_message_battery_status_demo` function in [mavlink_receiver.cpp](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mavlink/mavlink_receiver.cpp).
|
||||
|
||||
```cpp
|
||||
void
|
||||
MavlinkReceiver::handle_message_battery_status_demo(mavlink_message_t *msg)
|
||||
{
|
||||
if ((msg->sysid != mavlink_system.sysid) || (msg->compid == mavlink_system.compid)) {
|
||||
// ignore battery status coming from other systems or from the autopilot itself
|
||||
return;
|
||||
}
|
||||
|
||||
// external battery measurements
|
||||
mavlink_battery_status_t battery_mavlink;
|
||||
mavlink_msg_battery_status_decode(msg, &battery_mavlink);
|
||||
|
||||
battery_status_s battery_status{};
|
||||
battery_status.timestamp = hrt_absolute_time();
|
||||
|
||||
battery_status.remaining = (float)battery_mavlink.battery_remaining / 100.0f;
|
||||
battery_status.temperature = (float)battery_mavlink.temperature;
|
||||
battery_status.connected = true;
|
||||
|
||||
_battery_pub.publish(battery_status);
|
||||
}
|
||||
```
|
||||
|
||||
:::info
|
||||
Above we only write to the battery fields that are defined in the topic.
|
||||
In practice you'd update all fields with either valid or invalid values: this has been cut back for brevity.
|
||||
:::
|
||||
|
||||
and finally make sure it is called in [MavlinkReceiver::handle_message()](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/mavlink/mavlink_receiver.cpp#L228)
|
||||
|
||||
```cpp
|
||||
MavlinkReceiver::handle_message(mavlink_message_t *msg)
|
||||
{
|
||||
switch (msg->msgid) {
|
||||
...
|
||||
case MAVLINK_MSG_ID_BATTERY_STATUS_DEMO:
|
||||
handle_message_battery_status_demo(msg);
|
||||
break;
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 另一种自定义MAVlink消息的办法
|
||||
|
||||
Sometimes there is the need for a custom MAVLink message with content that is not fully defined.
|
||||
|
||||
For example when using MAVLink to interface PX4 with an embedded device, the messages that are exchanged between the autopilot and the device may go through several iterations before they are stabilized.
|
||||
In this case, it can be time-consuming and error-prone to regenerate the MAVLink headers, and make sure both devices use the same version of the protocol.
|
||||
|
||||
An alternative - and temporary - solution is to re-purpose debug messages.
|
||||
Instead of creating a custom MAVLink message `CA_TRAJECTORY`, you can send a message `DEBUG_VECT` with the string key `CA_TRAJ` and data in the `x`, `y` and `z` fields.
|
||||
See [this tutorial](../debug/debug_values.md) for an example usage of debug messages.
|
||||
|
||||
:::info
|
||||
This solution is not efficient as it sends character string over the network and involves comparison of strings.
|
||||
It should be used for development only!
|
||||
:::
|
||||
|
||||
## 测试
|
||||
|
||||
As a first step, and while debugging, commonly you'll just want to confirm that any messages you've created are being sent/received as you expect.
|
||||
|
||||
You should should first use the `uorb top [<message_name>]` command to verify in real-time that your message is published and the rate (see [uORB Messaging](../middleware/uorb.md#uorb-top-command)).
|
||||
This approach can also be used to test incoming messages that publish a uORB topic (for other messages you might use `printf` in your code and test in SITL).
|
||||
|
||||
There are several approaches you can use to view MAVLink traffic:
|
||||
|
||||
- Create a [Wireshark MAVLink plugin](https://mavlink.io/en/guide/wireshark.html) for your dialect.
|
||||
This allows you to inspect MAVLink traffic on an IP interface - for example between _QGroundControl_ or MAVSDK and your real or simulated version of PX4.
|
||||
|
||||
:::tip
|
||||
It is much easier to generate a wireshark plugin and inspect traffic in Wireshark, than to rebuild QGroundControl with your dialect and use MAVLink Inspector.
|
||||
|
||||
:::
|
||||
|
||||
- [Log uORB topics](../dev_log/logging.md) associate with your MAVLink message.
|
||||
|
||||
- View received messages in the QGroundControl [MAVLink Inspector](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/mavlink_inspector.html).
|
||||
You will need to rebuild QGroundControl with the custom message definitions, [as described below](#updating-qgroundcontrol)
|
||||
|
||||
### Set Streaming Rate using a Shell
|
||||
|
||||
For testing, it is sometimes useful to increase the streaming rate of individual topics at runtime (e.g. for inspection in QGC).
|
||||
This can be achieved using by calling the [mavlink](../modules/modules_communication.md#mavlink) module through the [QGC MAVLink console](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/mavlink_console.html) (or some other shell):
|
||||
|
||||
```sh
|
||||
mavlink stream -u <port number> -s <mavlink topic name> -r <rate>
|
||||
```
|
||||
|
||||
You can get the port number with `mavlink status` which will output (amongst others) `transport protocol: UDP (<port number>)`.
|
||||
An example would be:
|
||||
|
||||
```sh
|
||||
mavlink stream -u 14556 -s CA_TRAJECTORY -r 300
|
||||
```
|
||||
|
||||
## Updating Ground Stations
|
||||
|
||||
Ultimately you'll want to use your new MAVLink interface by providing the corresponding ground station or MAVSDK implementation.
|
||||
|
||||
The important thing to remember here is that MAVLink requires that you use a version of the library that is built to the same definition (XML file).
|
||||
So if you have created a custom message in PX4 you won't be able to use it unless you build QGC or MAVSDK with that same definition.
|
||||
|
||||
### Updating QGroundControl
|
||||
|
||||
You will need to [Build QGroundControl](https://docs.qgroundcontrol.com/master/en/qgc-dev-guide/getting_started/index.html) including a pre-built C library that contains your custom messages.
|
||||
|
||||
QGC uses a pre-built C library that must be located at [/qgroundcontrol/libs/mavlink/include/mavlink](https://github.com/mavlink/qgroundcontrol/tree/master/libs/mavlink/include/mavlink) in the QGC source.
|
||||
|
||||
By default this is pre-included as a submodule from <https://github.com/mavlink/c_library_v2> but you can [generate your own MAVLink Libraries](https://mavlink.io/en/getting_started/generate_libraries.html).
|
||||
|
||||
QGC uses the all.xml dialect by default, which includes **common.xml**.
|
||||
You can include your messages in either file or in your own dialect.
|
||||
However if you use your own dialect then it should include ArduPilotMega.xml (or it will miss all the existing messages), and you will need to change the dialect used by setting it in [`MAVLINK_CONF`](https://github.com/mavlink/qgroundcontrol/blob/master/QGCExternalLibs.pri#L52) when running _qmake_.
|
||||
|
||||
### Updating MAVSDK
|
||||
|
||||
See the MAVSDK docs for information about how to work with [MAVLink headers and dialects](https://mavsdk.mavlink.io/main/en/cpp/guide/build.html).
|
||||
@@ -0,0 +1,6 @@
|
||||
# RTPS/ROS2 接口:PX4-FastRTPS桥接
|
||||
|
||||
<Badge type="info" text="Discontinued" />
|
||||
|
||||
[uXRCE-DDS (PX4-ROS 2/DDS Bridge)](../middleware/uxrce_dds.md) has replaced the _Fast-RTPS Bridge_.
|
||||
If you're working in PX4 v1.13 or earlier see: [Fast-RTPS Bridge](https://docs.px4.io/v1.13/en/middleware/micrortps.html#rtps-dds-interface-px4-fast-rtps-dds-bridge)
|
||||
@@ -0,0 +1,267 @@
|
||||
# uORB 消息
|
||||
|
||||
## 简介
|
||||
|
||||
The uORB is an asynchronous `publish()` / `subscribe()` messaging API used for inter-thread/inter-process communication.
|
||||
|
||||
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`.
|
||||
|
||||
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
|
||||
|
||||
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" named following the CamelCase convention.
|
||||
The file should be added to the [msg/](https://github.com/PX4/PX4-Autopilot/tree/main/msg/) directory (or [msg/versioned](https://github.com/PX4/PX4-Autopilot/tree/main/msg/versioned) if it needs to be versioned) and then listed in the `msg/CMakeLists.txt` file.
|
||||
|
||||
:::tip
|
||||
Messages need to be versioned if they are exposed to ROS 2 and needs to remain compatible across multiple ROS and PX4 versions.
|
||||
See [Message Versioning](#message-versioning) for more information.
|
||||
:::
|
||||
|
||||
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).
|
||||
|
||||
The section [Message Definitions](#message-definitions) below describes the message format.
|
||||
|
||||
From the message definitions, the needed C/C++ code is automatically generated.
|
||||
|
||||
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 <uORB/topics/velocity_limits.h>
|
||||
```
|
||||
|
||||
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_ 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.
|
||||
|
||||
:::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.
|
||||
:::
|
||||
|
||||
:::info
|
||||
All _versioned_ messages definitions must include the `uint32 MESSAGE_VERSION` field.
|
||||
For more information, refer to the [Message Versioning](#message-versioning) section.
|
||||
:::
|
||||
|
||||
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)
|
||||
|
||||
# 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:
|
||||
|
||||
```text
|
||||
# TOPICS actuator_outputs actuator_outputs_sim actuator_outputs_debug
|
||||
```
|
||||
|
||||
### 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.
|
||||
|
||||
```text
|
||||
# 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
|
||||
```
|
||||
|
||||
### 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:
|
||||
|
||||
- 如果有充分理由进行更新,更改外部工具所依赖的现有字段或信息通常是可以接受的。
|
||||
In particular for breaking changes to _Flight Review_, _Flight Review_ must be updated before code is merged to `master`.
|
||||
- 为了使外部工具能够可靠地区分两个消息版本,必须遵循以下步骤:
|
||||
- Removed or renamed messages must be added to the `deprecated_msgs` list in [msg/CMakeLists.txt](https://github.com/PX4/PX4-Autopilot/blob/c5a6a60903455c3600f47e3c45ecaa48614559c8/msg/CMakeLists.txt#L189) and the **.msg** file needs to be deleted.
|
||||
- Removed or renamed fields must be commented and marked as deprecated.
|
||||
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.
|
||||
|
||||
## Message Versioning
|
||||
|
||||
<Badge type="tip" text="main (planned for: PX4 v1.16+)" />
|
||||
|
||||
Optional message versioning was introduced in the `main` branch (planned for PX4 v1.16+) to make it easier to maintain compatibility between PX4 and ROS 2 versions compiled against different message definitions.
|
||||
Versioned messages are designed to remain more stable over time compared to their non-versioned counterparts, as they are intended to be used across multiple releases of PX4 and external systems, ensuring greater compatibility over longer periods.
|
||||
|
||||
Versioned messages include an additional field `uint32 MESSAGE_VERSION = x`, where `x` corresponds to the current version of the message.
|
||||
|
||||
Versioned and non-versioned messages are separated in the file system:
|
||||
|
||||
- Non-versioned topic message files and [server service](../ros2/user_guide.md#px4-ros-2-service-servers) message files remain in the [`msg/`](https://github.com/PX4/PX4-Autopilot/tree/main/msg) and [`srv/`](https://github.com/PX4/PX4-Autopilot/tree/main/srv) directories, respectively.
|
||||
- The current (highest) version of message files are located in the `versioned` subfolders ([`msg/versioned`](https://github.com/PX4/PX4-Autopilot/tree/main/msg/versioned) and [`srv/versioned`](https://github.com/PX4/PX4-Autopilot/tree/main/srv/versioned)).
|
||||
- Older versions of messages are stored in nested `msg/px4_msgs_old/` subfolders ([`msg/px4_msgs_old/msg/`](https://github.com/PX4/PX4-Autopilot/tree/main/msg/px4_msgs_old/msg) and [`msg/px4_msgs_old/srv/`](https://github.com/PX4/PX4-Autopilot/tree/main/msg/px4_msgs_old/srv)).
|
||||
The files are also renamed with a suffix to indicate their version number.
|
||||
|
||||
:::tip
|
||||
The file structure is outlined in more detail in [File structure (ROS 2 Message Translation Node)](../ros2/px4_ros2_msg_translation_node.md#file-structure).
|
||||
:::
|
||||
|
||||
The [ROS 2 Message Translation Node](../ros2/px4_ros2_msg_translation_node.md) uses the above message definitions to seamlessly convert messages sent between PX4 and ROS 2 applications that have been compiled against different message versions.
|
||||
|
||||
Updating a versioned message involves more steps compared to updating a non-versioned one.
|
||||
For more information see [Updating a Versioned Message](../ros2/px4_ros2_msg_translation_node.md#updating-a-versioned-message).
|
||||
|
||||
For the full list of versioned and non-versioned messages see: [uORB Message Reference](../msg_docs/index.md).
|
||||
|
||||
For more on PX4 and ROS 2 communication, see [PX4-ROS 2 Bridge](../ros/ros2_comm.md).
|
||||
|
||||
:::info
|
||||
ROS 2 plans to natively support message versioning in the future, but this is not implememented yet.
|
||||
See the related ROS Enhancement Proposal ([REP 2011](https://github.com/ros-infrastructure/rep/pull/358)).
|
||||
See also this [Foxglove post](https://foxglove.dev/blog/sending-ros2-message-types-over-the-wire) on message hashing and type fetching.
|
||||
:::
|
||||
|
||||
## 发布
|
||||
|
||||
Publishing a topic can be done from anywhere in the system, including interrupt context (functions called by the `hrt_call` API).
|
||||
However, the topic needs to be advertised and published outside of an interrupt context (at least once) before it can be published in an interrupt context.
|
||||
|
||||
### 多实例
|
||||
|
||||
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).
|
||||
|
||||
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).
|
||||
|
||||
## 主题列表和监听(Listener)
|
||||
|
||||
:::info
|
||||
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).
|
||||
:::
|
||||
|
||||
列出所有主题,列出文件句柄:
|
||||
|
||||
```sh
|
||||
ls /obj
|
||||
```
|
||||
|
||||
要监听一个主题内容中五条信息,运行监听器:
|
||||
|
||||
```sh
|
||||
listener sensor_accel 5
|
||||
```
|
||||
|
||||
输出是n次主题正文:
|
||||
|
||||
```sh
|
||||
TOPIC: sensor_accel #3
|
||||
timestamp: 84978861
|
||||
integral_dt: 4044
|
||||
error_count: 0
|
||||
x: -1
|
||||
y: 2
|
||||
z: 100
|
||||
x_integral: -0
|
||||
y_integral: 0
|
||||
z_integral: 0
|
||||
temperature: 46
|
||||
range_m_s2: 78
|
||||
scaling: 0
|
||||
|
||||
TOPIC: sensor_accel #4
|
||||
timestamp: 85010833
|
||||
integral_dt: 3980
|
||||
error_count: 0
|
||||
x: -1
|
||||
y: 2
|
||||
z: 100
|
||||
x_integral: -0
|
||||
y_integral: 0
|
||||
z_integral: 0
|
||||
temperature: 46
|
||||
range_m_s2: 78
|
||||
scaling: 0
|
||||
```
|
||||
|
||||
:::tip
|
||||
On NuttX-based systems (Pixhawk, Pixracer, etc) the `listener` command can be called from within the _QGroundControl_ MAVLink Console to inspect the values of sensors and other topics.
|
||||
这是一个非常实用的调试工具,应为它可以在QGC通过无线连接的时候使用(例如,当机体在飞行中)。
|
||||
For more information see: [Sensor/Topic Debugging](../debug/sensor_uorb_topic_debugging.md).
|
||||
:::
|
||||
|
||||
### uorb top 命令
|
||||
|
||||
The command `uorb top` shows the publishing frequency of each topic in real-time:
|
||||
|
||||
```sh
|
||||
update: 1s, num topics: 77
|
||||
TOPIC NAME INST #SUB #MSG #LOST #QSIZE
|
||||
actuator_armed 0 6 4 0 1
|
||||
actuator_controls_0 0 7 242 1044 1
|
||||
battery_status 0 6 500 2694 1
|
||||
commander_state 0 1 98 89 1
|
||||
control_state 0 4 242 433 1
|
||||
ekf2_innovations 0 1 242 223 1
|
||||
ekf2_timestamps 0 1 242 23 1
|
||||
estimator_status 0 3 242 488 1
|
||||
mc_att_ctrl_status 0 0 242 0 1
|
||||
sensor_accel 0 1 242 0 1
|
||||
sensor_accel 1 1 249 43 1
|
||||
sensor_baro 0 1 42 0 1
|
||||
sensor_combined 0 6 242 636 1
|
||||
```
|
||||
|
||||
列分别是:主题名字,多实例索引值,订阅者数量,发布频率(Hz),每秒丢失的信息数(对所有订阅者)和队列大小。
|
||||
|
||||
## Plotting Changes in Topics
|
||||
|
||||
Topic changes can be plotted in realtime using PlotJuggler and the PX4 ROS 2 integration (note that this actually plots ROS topics that correspond to uORB topics, but the effect is the same).
|
||||
|
||||
For more information see: [Plotting uORB Topic Data in Real Time using PlotJuggler](../debug/plotting_realtime_uorb_data.md).
|
||||
|
||||
<video src="../../assets/debug/realtime_debugging/realtime_debugging.mp4" width="720" controls></video>
|
||||
|
||||
## 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/)
|
||||
@@ -0,0 +1,30 @@
|
||||
# uORB Publication/Subscription Graph
|
||||
|
||||
This page provides a uORB publication/subscription graph that shows the communication between modules.
|
||||
It is based on information that is extracted directly from the source code.
|
||||
Usage instructions are provided [below](#graph-properties).
|
||||
|
||||
<iframe :src="withBase('/middleware/index.html')" frameborder="0" width="1300" height="1450px" style="text-align: center; margin-left: 0px; margin-right: 0px;"></iframe>
|
||||
|
||||
<script setup>
|
||||
import { withBase } from 'vitepress';
|
||||
</script>
|
||||
|
||||
## Graph Properties
|
||||
|
||||
The graph has the following properties:
|
||||
|
||||
- Modules are shown in gray with rounded corners while topics are displayed as coloured rectangular boxes.
|
||||
- Associated modules and topics are connected by lines.
|
||||
Dashed lines indicate that the module publishes the topic, solid lines indicate that the module subscribes to the topic, while dot-dashed lines indicate that the module both publishes and subscribes to the topic.
|
||||
- Some modules and topics are excluded:
|
||||
- Topics that are subscribed/published by many modules: `parameter_update`, `mavlink_log` and `log_message`.
|
||||
- The set of logged topics.
|
||||
- Topics that have no subscriber or no publisher.
|
||||
- Modules in **src/examples**.
|
||||
- Hovering over a module/topic highlights all its connections.
|
||||
- Double-clicking on a topic opens its message definition.
|
||||
- Make sure your browser window is wide enough to display the full graph (the sidebar menu can be hidden with the icon in the top-left corner).
|
||||
You can also zoom the image.
|
||||
- The _Preset_ selection list allows you to refine the list of modules that are shown.
|
||||
- The _Search_ box can be used to find particular modules/topics (topics that are not selected by the search are greyed-out).
|
||||
@@ -0,0 +1,655 @@
|
||||
# uXRCE-DDS (PX4-ROS 2/DDS Bridge)
|
||||
|
||||
<Badge type="tip" text="PX4 v1.14" />
|
||||
|
||||
:::info
|
||||
uXRCE-DDS replaces the [Fast-RTPS Bridge](https://docs.px4.io/v1.13/en/middleware/micrortps.html#rtps-dds-interface-px4-fast-rtps-dds-bridge) used in PX4 v1.13.
|
||||
If you were using the Fast-RTPS Bridge, please follow the [migration guidelines](#fast-rtps-to-uxrce-dds-migration-guidelines).
|
||||
:::
|
||||
|
||||
PX4 uses uXRCE-DDS middleware to allow [uORB messages](../middleware/uorb.md) to be published and subscribed on a companion computer as though they were [ROS 2](../ros2/user_guide.md) topics.
|
||||
This provides a fast and reliable integration between PX4 and ROS 2, and makes it much easier for ROS 2 applications to get vehicle information and send commands.
|
||||
|
||||
PX4 uses an XRCE-DDS implementation that leverages [eProsima Micro XRCE-DDS](https://micro-xrce-dds.docs.eprosima.com/en/stable/introduction.html).
|
||||
|
||||
The following guide describes the architecture and various options for setting up the client and agent.
|
||||
代理端(Agent)充当客户端的代理,使其能够在DDS全局数据空间中发布和订阅话题。
|
||||
|
||||
## 软件架构
|
||||
|
||||
The uXRCE-DDS middleware consists of a client running on PX4 and an agent running on the companion computer, with bi-directional data exchange between them over a serial or UDP link.
|
||||
The agent acts as a proxy for the client, enabling it to publish and subscribe to topics in the global DDS data space.
|
||||
|
||||

|
||||
|
||||
In order for PX4 uORB topics to be shared on the DDS network you will need _uXRCE-DDS client_ running on PX4, connected to the _micro XRCE-DDS agent_ running on the companion.
|
||||
|
||||
The PX4 [uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client) publishes to/from a defined set of uORB topics to the global DDS data space.
|
||||
|
||||
The [eProsima micro XRCE-DDS _agent_](https://github.com/eProsima/Micro-XRCE-DDS-Agent) runs on the companion computer and acts as a proxy for the client in the DDS/ROS 2 network.
|
||||
|
||||
The agent itself has no dependency on client-side code and can be built and/or installed independent of PX4 or ROS.
|
||||
|
||||
Code that wants to subscribe/publish to PX4 does have a dependency on client-side code; it requires uORB message definitions that match those used to create the PX4 uXRCE-DDS client so that it can interpret the messages.
|
||||
|
||||
## 代码生成
|
||||
|
||||
The PX4 [uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client) is generated at build time and included in PX4 firmare by default.
|
||||
The agent has no dependency on client code.
|
||||
It can be built standalone or in a ROS 2 workspace, or installed as a snap package on Ubuntu.
|
||||
|
||||
When PX4 is built, a code generator uses the uORB message definitions in the source tree ([PX4-Autopilot/msg](https://github.com/PX4/PX4-Autopilot/tree/main/msg)) to compile support for the subset of uORB topics in [PX4-Autopilot/src/modules/uxrce_dds_client/dds_topics.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml) into [uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client).
|
||||
|
||||
PX4 main or release builds automatically export the set of uORB messages definitions in the build to an associated branch in [PX4/px4_msgs](https://github.com/PX4/px4_msgs).
|
||||
|
||||
ROS 2 applications need to be built in a workspace that includes the _same_ message definitions that were used to create the uXRCE-DDS client module in the PX4 Firmware.
|
||||
These can be included into a workspace by cloning the interface package [PX4/px4_msgs](https://github.com/PX4/px4_msgs) into your ROS 2 workspace and switching to the appropriate branch.
|
||||
Note that all code generation associated with the messages is handled by ROS 2.
|
||||
|
||||
## Micro XRCE-DDS Agent Installation
|
||||
|
||||
The Micro XRCE-DDS Agent can be installed on the companion computer using a binary package, built and installed from source, or built and run from within a ROS 2 workspace.
|
||||
All of these methods fetch _all_ the dependencies needed to communicate with the client (such as FastCDR).
|
||||
|
||||
:::info
|
||||
The official (and more complete) installation guide is the Eprosima: [micro XRCE-DDS Installation Guide](https://micro-xrce-dds.docs.eprosima.com/en/latest/installation.html).
|
||||
This section summarises the options that have been tested with PX4 during creation of these docs.
|
||||
:::
|
||||
|
||||
:::warning
|
||||
PX4 Micro XRCE-DDS Client is based on version `v2.x` which is not compatible with the latest `v3.x` Agent version.
|
||||
:::
|
||||
|
||||
### 源码安装
|
||||
|
||||
On Ubuntu you can build from source and install the Agent standalone using the following commands:
|
||||
|
||||
```sh
|
||||
git clone -b v2.4.2 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git
|
||||
cd Micro-XRCE-DDS-Agent
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
sudo make install
|
||||
sudo ldconfig /usr/local/lib/
|
||||
```
|
||||
|
||||
:::info
|
||||
There are various build configuration options linked from the corresponding topic in the [official guide](https://micro-xrce-dds.docs.eprosima.com/en/latest/installation.html#installing-the-agent-standalone), but these have not been tested.
|
||||
:::
|
||||
|
||||
使用以下命令从 Ubuntu 的 snap 软件包安装:
|
||||
|
||||
```sh
|
||||
MicroXRCEAgent udp4 -p 8888
|
||||
```
|
||||
|
||||
### 从 Snap 软件包安装
|
||||
|
||||
Install from a snap package on Ubuntu using the following command:
|
||||
|
||||
```sh
|
||||
sudo snap install microxrce-ds-agent --edge
|
||||
```
|
||||
|
||||
To start the agent with settings for connecting to the uXRCE-DDS client running on the simulator (note that the command name is different than if you build the agent locally):
|
||||
|
||||
```sh
|
||||
micro-xrce-dds-agent udp4 -p 8888
|
||||
```
|
||||
|
||||
:::info
|
||||
At time of writing the stable of version installed from snap connects to PX4 but reports errors creating topics.
|
||||
The development version, fetched using `--edge` above, does work.
|
||||
:::
|
||||
|
||||
### Build/Run within ROS 2 Workspace
|
||||
|
||||
The agent can be built and launched within a ROS 2 workspace (or build standalone and launched from a workspace.
|
||||
You must already have installed ROS 2 following the instructions in: [ROS 2 User Guide > Install ROS 2](../ros2/user_guide.md#install-ros-2).
|
||||
|
||||
:::warning
|
||||
This approach will use the existing ROS 2 versions of the Agent dependencies, such as `fastcdr` and `fastdds`.
|
||||
This considerably speeds up the build process but requires that the Agent dependency versions match the ROS 2 ones.
|
||||
:::
|
||||
|
||||
To build the agent within ROS:
|
||||
|
||||
1. Create a workspace directory for the agent:
|
||||
|
||||
```sh
|
||||
mkdir -p ~/px4_ros_uxrce_dds_ws/src
|
||||
```
|
||||
|
||||
2. Clone the source code for the eProsima [Micro-XRCE-DDS-Agent](https://github.com/eProsima/Micro-XRCE-DDS-Agent) to the `/src` directory (the `main` branch is cloned by default):
|
||||
|
||||
```sh
|
||||
cd ~/px4_ros_uxrce_dds_ws/src
|
||||
git clone -b v2.4.2 https://github.com/eProsima/Micro-XRCE-DDS-Agent.git
|
||||
```
|
||||
|
||||
3. Source the ROS 2 development environment, and compile the workspace using `colcon`:
|
||||
|
||||
:::: tabs
|
||||
|
||||
::: tab humble
|
||||
|
||||
```sh
|
||||
source /opt/ros/humble/setup.bash
|
||||
colcon build
|
||||
```
|
||||
|
||||
|
||||
:::
|
||||
|
||||
::: tab foxy
|
||||
|
||||
```sh
|
||||
source /opt/ros/foxy/setup.bash
|
||||
colcon build
|
||||
```
|
||||
|
||||
|
||||
:::
|
||||
|
||||
::::
|
||||
|
||||
This builds all the folders under `/src` using the sourced toolchain.
|
||||
|
||||
To run the micro XRCE-DDS agent in the workspace:
|
||||
|
||||
1. Source the `local_setup.bash` to make the executables available in the terminal (also `setup.bash` if using a new terminal).
|
||||
|
||||
:::: tabs
|
||||
|
||||
::: tab humble
|
||||
|
||||
```sh
|
||||
source /opt/ros/humble/setup.bash
|
||||
source install/local_setup.bash
|
||||
```
|
||||
|
||||
|
||||
:::
|
||||
|
||||
::: tab foxy
|
||||
|
||||
```sh
|
||||
source /opt/ros/foxy/setup.bash
|
||||
source install/local_setup.bash
|
||||
```
|
||||
|
||||
|
||||
:::
|
||||
|
||||
::::
|
||||
|
||||
1) 启动代理并设置以连接运行在模拟器上的 uXRCE-DDS客户端(Client):
|
||||
|
||||
```sh
|
||||
MicroXRCEAgent udp4 -p 8888
|
||||
```
|
||||
|
||||
## Starting Agent and Client
|
||||
|
||||
### Starting the Agent
|
||||
|
||||
The agent is used to connect to the client over a particular channel, such as UDP or a serial connection.
|
||||
The channel settings are specified when the agent is started, using command line options.
|
||||
These are documented in the eProsima user guide: [Micro XRCE-DDS Agent > Agent CLI](https://micro-xrce-dds.docs.eprosima.com/en/latest/agent.html#agent-cli).
|
||||
Note that the agent supports many channel options, but PX4 only supports UDP and serial connections.
|
||||
|
||||
:::info
|
||||
You should create a single instance of the agent for each channel over which you need to connect.
|
||||
:::
|
||||
|
||||
For example, the PX4 simulator runs the uXRCE-DDS client over UDP on port 8888, so to connect to the simulator you would start the agent with the command:
|
||||
|
||||
```sh
|
||||
MicroXRCEAgent udp4 -p 8888
|
||||
```
|
||||
|
||||
When working with real hardware, the setup depends on the hardware, OS, and channel.
|
||||
For example, if you're using the RPi `UART0` serial port, you might connect using this command (based on the information in [Raspberry Pi Documentation > Configuring UARTS](https://www.raspberrypi.com/documentation/computers/configuration.html#configuring-uarts)):
|
||||
|
||||
```sh
|
||||
sudo MicroXRCEAgent serial --dev /dev/AMA0 -b 921600
|
||||
```
|
||||
|
||||
:::info
|
||||
For more information about setting up communications channels see [Pixhawk + Companion Setup > Serial Port setup](../companion_computer/pixhawk_companion.md#serial-port-setup), and sub-documents.
|
||||
:::
|
||||
|
||||
### Starting the Client
|
||||
|
||||
The uXRCE-DDS client module ([uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client)) is included by default in all firmware and the simulator.
|
||||
This must be started with appropriate settings for the communication channel that you wish to use to communicate with the agent.
|
||||
|
||||
:::info
|
||||
The simulator automatically starts the client on localhost UDP port `8888` using the default uxrce-dds namespace.
|
||||
:::
|
||||
|
||||
The configuration can be done using the [UXRCE-DDS parameters](../advanced_config/parameter_reference.md#uxrce-dds-client):
|
||||
|
||||
- [UXRCE_DDS_CFG](../advanced_config/parameter_reference.md#UXRCE_DDS_CFG): Set the port to connect on, such as `TELEM2`, `Ethernet`, or `Wifi`.
|
||||
|
||||
- If using an Ethernet connection:
|
||||
|
||||
- [UXRCE_DDS_PRT](../advanced_config/parameter_reference.md#UXRCE_DDS_PRT):
|
||||
Use this to specify the agent UDP listening port.
|
||||
The default value is `8888`.
|
||||
- [UXRCE_DDS_AG_IP](../advanced_config/parameter_reference.md#UXRCE_DDS_AG_IP):
|
||||
Use this to specify the IP address of the agent.
|
||||
The IP address must be provided in `int32` format as PX4 does not support string parameters.
|
||||
The default value is `2130706433` which corresponds to the _localhost_ `127.0.0.1`.
|
||||
|
||||
You can use [Tools/convert_ip.py](https://github.com/PX4/PX4-Autopilot/blob/main/Tools/convert_ip.py) to convert between the formats:
|
||||
|
||||
- To obtain the `int32` version of an IP in decimal dot notation the command is:
|
||||
|
||||
```sh
|
||||
python3 ./PX4-Autopilot/Tools/convert_ip.py <the IP address in decimal dot notation>
|
||||
```
|
||||
|
||||
- To get the IP address in decimal dot notation from the `int32` version:
|
||||
|
||||
```sh
|
||||
python3 ./PX4-Autopilot/Tools/convert_ip.py -r <the IP address in int32 notation>
|
||||
```
|
||||
|
||||
- If using a serial connection:
|
||||
|
||||
- [SER_TEL2_BAUD](../advanced_config/parameter_reference.md#SER_TEL2_BAUD), [SER_URT6_BAUD](../advanced_config/parameter_reference.md#SER_URT6_BAUD) (and so on):
|
||||
Use the `_BAUD` parameter associated with the serial port to set the baud rate.
|
||||
For example, you'd set a value for `SER_TEL2_BAUD` if you are connecting to the companion using `TELEM2`.
|
||||
For more information see [Serial port configuration](../peripherals/serial_configuration.md#serial-port-configuration).
|
||||
|
||||
- Some setups might also need these parameters to be set:
|
||||
|
||||
- [UXRCE_DDS_KEY](../advanced_config/parameter_reference.md#UXRCE_DDS_KEY): The uXRCE-DDS key.
|
||||
If you're working in a multi-client, single agent configuration, each client should have a unique non-zero key.
|
||||
This is primarily important for multi-vehicle simulations, where all clients are connected in UDP to the same agent.
|
||||
(See the [official eprosima documentation](https://micro-xrce-dds.docs.eprosima.com/en/stable/client_api.html#session) , `uxr_init_session`.)
|
||||
- [UXRCE_DDS_DOM_ID](../advanced_config/parameter_reference.md#UXRCE_DDS_DOM_ID): The DDS domain ID.
|
||||
This provides a logical separation between DDS networks, and can be used to separate clients on different networks.
|
||||
By default, ROS 2 operates on ID 0.
|
||||
- [UXRCE_DDS_PTCFG](../advanced_config/parameter_reference.md#UXRCE_DDS_PTCFG): uXRCE-DDS participant configuration.
|
||||
It allows to restrict the visibility of the DDS topics to the _localhost_ only and to use user-customized participant configuration files stored on the agent side.
|
||||
- [UXRCE_DDS_SYNCT](../advanced_config/parameter_reference.md#UXRCE_DDS_SYNCT): Bridge time synchronization enable.
|
||||
The uXRCE-DDS client module can synchronize the timestamp of the messages exchanged over the bridge.
|
||||
This is the default configuration. In certain situations, for example during [simulations](../ros2/user_guide.md#ros-gazebo-and-px4-time-synchronization), this feature may be disabled.
|
||||
|
||||
:::info
|
||||
Many ports are already have a default configuration.
|
||||
To use these ports you must first disable the existing configuration:
|
||||
|
||||
- `TELEM1` and `TELEM2` are set up by default to connect via MAVLink to a GCS and a companion computer (respectively).
|
||||
Disable by setting [MAV_0_CONFIG=0](../advanced_config/parameter_reference.md#MAV_0_CONFIG) or [MAV_1_CONFIG=0](../advanced_config/parameter_reference.md#MAV_1_CONFIG) to zero.
|
||||
See [MAVLink Peripherals](../peripherals/mavlink_peripherals.md) for more information.
|
||||
- Other ports can similarly be configured.
|
||||
See [Serial port configuration](../peripherals/serial_configuration.md#serial-port-configuration).
|
||||
|
||||
:::
|
||||
|
||||
Once set, you may need to reboot PX4 for the parameters to take effect.
|
||||
They will then persist through subsequent reboots.
|
||||
|
||||
You can also start the [uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client) using a command line.
|
||||
This can be called as part of [System Startup](../concept/system_startup.md) or through the [MAVLink Shell](../debug/mavlink_shell.md) (or a system console).
|
||||
This method is useful when you need to set a custom client namespace, as no parameter is provided for this purpose.
|
||||
For example, the following command can be used to connect via Ethernet to a remote host at `192.168.0.100:8888` and to set the client namespace to `/drone/`.
|
||||
|
||||
```sh
|
||||
uxrce_dds_client start -t udp -p 8888 -h 192.168.0.100 -n drone
|
||||
```
|
||||
|
||||
Options `-p` or `-h` are used to bypass `UXRCE_DDS_PRT` and `UXRCE_DDS_AG_IP`.
|
||||
|
||||
#### Starting the Client in Simulation
|
||||
|
||||
The simulator [startup logic](../concept/system_startup.md) ([init.d-posix/rcS](https://github.com/PX4/PX4-Autopilot/blob/main/ROMFS/px4fmu_common/init.d-posix/rcS)) uses the client startup commands for single and [multi vehicle simulations](../ros2/multi_vehicle.md), enabling the setting of appropriate instance ids and DDS namespaces.
|
||||
By default the client is started on localhost UDP port `8888` with no additional namespace.
|
||||
|
||||
Environment variables are provided that override some [UXRCE-DDS parameters](../advanced_config/parameter_reference.md#uxrce-dds-client).
|
||||
These allow users to create custom startup files for their simulations:
|
||||
|
||||
- `PX4_UXRCE_DDS_NS`: Use this to specify the topic [namespace](#customizing-the-namespace)).
|
||||
- `ROS_DOMAIN_ID`: Use this to replace [UXRCE_DDS_DOM_ID](../advanced_config/parameter_reference.md#UXRCE_DDS_DOM_ID).
|
||||
- `PX4_UXRCE_DDS_PORT`: Use this to replace [UXRCE_DDS_PRT](../advanced_config/parameter_reference.md#UXRCE_DDS_PRT).
|
||||
|
||||
For example, the following command can be used to start a Gazebo simulation with che client operating on the DDS domain `3`, port `9999` and topic namespace `drone`.
|
||||
|
||||
```sh
|
||||
ROS_DOMAIN_ID=3 PX4_UXRCE_DDS_PORT=9999 PX4_UXRCE_DDS_NS=drone make px4_sitl gz_x500
|
||||
```
|
||||
|
||||
## Supported uORB Messages
|
||||
|
||||
The set of [PX4 uORB topics](../msg_docs/index.md) that are exposed through the client are set in [dds_topics.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml).
|
||||
|
||||
The topics are release specific (support is compiled into [uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client) at build time).
|
||||
While most releases should support a very similar set of messages, to be certain you would need to check the yaml file for your particular release.
|
||||
|
||||
<!-- Jublish the set we use?: https://github.com/PX4/px4_msgs/issues/22 -->
|
||||
|
||||
Note that ROS 2/DDS needs to have the _same_ message definitions that were used to create the uXRCE-DDS client module in the PX4 Firmware in order to interpret the messages.
|
||||
The message definitions are stored in the ROS 2 interface package [PX4/px4_msgs](https://github.com/PX4/px4_msgs), and they are automatically synchronized by CI on the `main` and release branches.
|
||||
Note that all the messages from PX4 source code are present in the repository, but only those listed in `dds_topics.yaml` will be available as ROS 2 topics.
|
||||
Therefore,
|
||||
|
||||
- If you're using a main or release version of PX4 you can get the message definitions by cloning the interface package [PX4/px4_msgs](https://github.com/PX4/px4_msgs) into your workspace.
|
||||
- If you're creating or modifying uORB messages you must manually update the messages in your workspace from your PX4 source tree.
|
||||
Generally this means that you would update [dds_topics.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml), clone the interface package, and then manually synchronize it by copying the new/modified message definitions from [PX4-Autopilot/msg](https://github.com/PX4/PX4-Autopilot/tree/main/msg) to its `msg` folders.
|
||||
Assuming that PX4-Autopilot is in your home directory `~`, while `px4_msgs` is in `~/px4_ros_com/src/`, then the command might be:
|
||||
|
||||
```sh
|
||||
rm ~/px4_ros_com/src/px4_msgs/msg/*.msg
|
||||
cp ~/PX4-Autopilot/mgs/*.msg ~/px4_ros_com/src/px4_msgs/msg/
|
||||
```
|
||||
|
||||
::: info
|
||||
Technically, [dds_topics.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml) completely defines the relationship between PX4 uORB topics and ROS 2 messages.
|
||||
For more information see [DDS Topics YAML](#dds-topics-yaml) below.
|
||||
|
||||
:::
|
||||
|
||||
## Customizing the Namespace
|
||||
|
||||
Custom topic and service namespaces can be applied at build time (changing [dds_topics.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml)) or at runtime (which is useful for multi vehicle operations):
|
||||
|
||||
- One possibility is to use the `-n` option when starting the [uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client) from command line.
|
||||
This technique can be used both in simulation and real vehicles.
|
||||
- A custom namespace can be provided for simulations (only) by setting the environment variable `PX4_UXRCE_DDS_NS` before starting the simulation.
|
||||
|
||||
:::info
|
||||
Changing the namespace at runtime will append the desired namespace as a prefix to all `topic` fields in [dds_topics.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml) and all [service servers](#dds-ros-2-services).
|
||||
Therefore, commands like:
|
||||
|
||||
```sh
|
||||
uxrce_dds_client start -n uav_1
|
||||
```
|
||||
|
||||
或
|
||||
|
||||
```sh
|
||||
PX4_UXRCE_DDS_NS=uav_1 make px4_sitl gz_x500
|
||||
```
|
||||
|
||||
will generate topics under the namespaces:
|
||||
|
||||
```sh
|
||||
/uav_1/fmu/in/ # for subscribers
|
||||
/uav_1/fmu/out/ # for publishers
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
## PX4 ROS 2 QoS Settings
|
||||
|
||||
PX4 QoS settings for publishers are incompatible with the default QoS settings for ROS 2 subscribers.
|
||||
So if ROS 2 code needs to subscribe to a uORB topic, it will need to use compatible QoS settings.
|
||||
One example of which is shown in [ROS 2 User Guide > ROS 2 Subscriber QoS Settings](../ros2/user_guide.md#ros-2-subscriber-qos-settings).
|
||||
|
||||
PX4 uses the following QoS settings for publishers:
|
||||
|
||||
```cpp
|
||||
uxrQoS_t qos = {
|
||||
.durability = UXR_DURABILITY_TRANSIENT_LOCAL,
|
||||
.reliability = UXR_RELIABILITY_BEST_EFFORT,
|
||||
.history = UXR_HISTORY_KEEP_LAST,
|
||||
.depth = 0,
|
||||
};
|
||||
```
|
||||
|
||||
PX4 uses the following QoS settings for subscribers:
|
||||
|
||||
```cpp
|
||||
uxrQoS_t qos = {
|
||||
.durability = UXR_DURABILITY_VOLATILE,
|
||||
.reliability = UXR_RELIABILITY_BEST_EFFORT,
|
||||
.history = UXR_HISTORY_KEEP_LAST,
|
||||
.depth = queue_depth,
|
||||
};
|
||||
```
|
||||
|
||||
ROS 2 uses the following QoS settings (by default) for publishers and subscriptions: "keep last" for history with a queue size of 10, "reliable" for reliability, "volatile" for durability, and "system default" for liveliness.
|
||||
Deadline, lifespan, and lease durations are also all set to "default".
|
||||
|
||||
<!-- From https://github.com/PX4/PX4-user_guide/pull/2259#discussion_r1099788316 -->
|
||||
|
||||
## DDS Topics YAML
|
||||
|
||||
The PX4 yaml file [dds_topics.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml) defines the set of PX4 uORB topics that are built into firmware and published.
|
||||
More precisely, it completely defines the relationship/pairing between PX4 uORB and ROS 2 messages.
|
||||
|
||||
The file is structured as follows:
|
||||
|
||||
```yaml
|
||||
publications:
|
||||
|
||||
- topic: /fmu/out/collision_constraints
|
||||
type: px4_msgs::msg::CollisionConstraints
|
||||
|
||||
...
|
||||
|
||||
- topic: /fmu/out/vehicle_odometry
|
||||
type: px4_msgs::msg::VehicleOdometry
|
||||
|
||||
- topic: /fmu/out/vehicle_status
|
||||
type: px4_msgs::msg::VehicleStatus
|
||||
|
||||
- topic: /fmu/out/vehicle_trajectory_waypoint_desired
|
||||
type: px4_msgs::msg::VehicleTrajectoryWaypoint
|
||||
|
||||
subscriptions:
|
||||
|
||||
- topic: /fmu/in/offboard_control_mode
|
||||
type: px4_msgs::msg::OffboardControlMode
|
||||
|
||||
...
|
||||
|
||||
- topic: /fmu/in/vehicle_trajectory_waypoint
|
||||
type: px4_msgs::msg::VehicleTrajectoryWaypoint
|
||||
|
||||
subscriptions_multi:
|
||||
|
||||
- topic: /fmu/in/vehicle_optical_flow_vel
|
||||
type: px4_msgs::msg::VehicleOpticalFlowVel
|
||||
|
||||
...
|
||||
|
||||
```
|
||||
|
||||
Each (`topic`,`type`) pairs defines:
|
||||
|
||||
1. A new `publication`, `subscription`, or `subscriptions_multi`, depending on the list to which it is added.
|
||||
2. The topic _base name_, which **must** coincide with the desired uORB topic name that you want to publish/subscribe.
|
||||
It is identified by the last token in `topic:` that starts with `/` and does not contains any `/` in it.
|
||||
`vehicle_odometry`, `vehicle_status` and `offboard_control_mode` are examples of base names.
|
||||
3. The topic [namespace](https://design.ros2.org/articles/topic_and_service_names.html#namespaces).
|
||||
By default it is set to:
|
||||
- `/fmu/out/` for topics that are _published_ by PX4.
|
||||
- `/fmu/in/` for topics that are _subscribed_ by PX4.
|
||||
4. The message type (`VehicleOdometry`, `VehicleStatus`, `OffboardControlMode`, etc.) and the ROS 2 package (`px4_msgs`) that is expected to provide the message definition.
|
||||
|
||||
`subscriptions` and `subscriptions_multi` allow us to choose the uORB topic instance that ROS 2 topics are routed to: either a shared instance that may also be getting updates from internal PX4 uORB publishers, or a separate instance that is reserved for ROS2 publications, respectively.
|
||||
Without this mechanism all ROS 2 messages would be routed to the _same_ uORB topic instance (because ROS 2 does not have the concept of [multiple topic instances](../middleware/uorb.md#multi-instance)), and it would not be possible for PX4 subscribers to differentiate between streams from ROS 2 or PX4 publishers.
|
||||
|
||||
Add a topic to the `subscriptions` section to:
|
||||
|
||||
- Create a unidirectional route going from the ROS2 topic to the _default_ instance (instance 0) of the associated uORB topic.
|
||||
For example, it creates a ROS2 subscriber of `/fmu/in/vehicle_odometry` and a uORB publisher of `vehicle_odometry`.
|
||||
- If other (internal) PX4 modules are already publishing on the same uORB topic instance as the ROS2 publisher, the instance's subscribers will receive all streams of messages.
|
||||
The uORB subscriber will not be able to determine if an incoming message was published by PX4 or by ROS2.
|
||||
- This is the desired behavior when the ROS2 publisher is expected to be the sole publisher on the topic instance (for example, replacing an internal publisher to the topic during offboard control), or when the source of multiple publishing streams does not matter.
|
||||
|
||||
Add a topic to the `subscriptions_multi` section to:
|
||||
|
||||
- Create a unidirectional route going from the ROS2 topic to a _new_ instance of the associated uORB topic.
|
||||
For example, if `vehicle_odometry` has already `2` instances, it creates a ROS2 subscriber of `/fmu/in/vehicle_odometry` and a uORB publisher on instance `3` of `vehicle_odometry`.
|
||||
- This ensures that no other internal PX4 module will publish on the same instance used by uXRCE-DDS.
|
||||
The subscribers will be able to subscribe to the desired instance and distinguish between publishers.
|
||||
- Note, however, that this guarantees separation between PX4 and ROS2 publishers, not among multiple ROS2 publishers.
|
||||
In that scenario, their messages will still be routed to the same instance.
|
||||
- This is the desired behavior, for example, when you want PX4 to log the readings of two equal sensors; they will both publish on the same topic, but one will use instance 0 and the other will use instance 1.
|
||||
|
||||
You can arbitrarily change the configuration.
|
||||
For example, you could use different default namespaces or use a custom package to store the message definitions.
|
||||
|
||||
## DDS (ROS 2) Services
|
||||
|
||||
PX4 uXRCE-DDS middleware supports [ROS 2 services](https://docs.ros.org/en/jazzy/Concepts/Basic/About-Services.html).
|
||||
These are remote procedure calls, from one node to another, which return a result.
|
||||
They simplify communication between ROS 2 nodes and PX4 by grouping the request and response behaviour, and ensuring that replies are only returned to the specific requesting user.
|
||||
|
||||
A service server is the entity that will accept a remote procedure request, perform some computation on it, and return the result.
|
||||
For example, the `/fmu/vehicle_command` service server defined in [`px4_msgs::srv::VehicleCommand`](https://github.com/PX4/px4_msgs/blob/main/srv/VehicleCommand.srv) can be called by ROS 2 applications to send PX4 [VehicleCommand](../msg_docs/VehicleCommand.md) uORB messages and receive PX4 [VehicleCommandAck](../msg_docs/VehicleCommandAck.md) uORB messages in response.
|
||||
|
||||
For a list of services, details and examples see the [service documentation](../ros2/user_guide.md#px4-ros-2-service-servers) in the ROS 2 User Guide.
|
||||
|
||||
## Fast-RTPS to uXRCE-DDS Migration Guidelines
|
||||
|
||||
These guidelines explain how to migrate from using PX4 v1.13 [Fast-RTPS](../middleware/micrortps.md) middleware to PX4 v1.14 `uXRCE-DDS` middleware.
|
||||
These are useful if you have [ROS 2 applications written for PX4 v1.13](https://docs.px4.io/v1.13/en/ros/ros2_comm.html), or you have used Fast-RTPS to interface your applications to PX4 [directly](https://docs.px4.io/v1.13/en/middleware/micrortps.html#agent-in-an-offboard-fast-dds-interface-ros-independent).
|
||||
|
||||
:::info
|
||||
This section contains migration-specific information.
|
||||
You should also read the rest of this page to properly understand uXRCE-DDS.
|
||||
:::
|
||||
|
||||
#### Dependencies do not need to be removed
|
||||
|
||||
uXRCE-DDS does not need the dependencies that were required for Fast-RTPS, such as those installed by following the topic [Fast DDS Installation](https://docs.px4.io/v1.13/en/dev_setup/fast-dds-installation.html).
|
||||
You can keep them if you want, without affecting your uXRCE-DDS applications.
|
||||
|
||||
If you do choose to remove the dependencies, take care not to remove anything that is used by applications (for example, Java).
|
||||
|
||||
#### `_rtps` targets have been removed
|
||||
|
||||
Anywhere you previously used a build target with extension `_rtps`, such as `px4_fmu-v5_rtps` or `px4_sitl_rtps`, you can now use the equivalent default target (for these cases `px4_fmu-v5_default` and `px4_sitl_default`).
|
||||
|
||||
The make targets with extension `_rtps` were used to build firmware that included client side RTPS code.
|
||||
The uXRCE-DDS middleware is included by default in builds for most boards, so you no longer need a special firmware to work with ROS 2.
|
||||
|
||||
To check if your board has the middleware, look for `CONFIG_MODULES_UXRCE_DDS_CLIENT=y` in the `.px4board` file of your board.
|
||||
Those files are nested in [PX4-Autopilot/boards](https://github.com/PX4/PX4-Autopilot/tree/main/boards).
|
||||
|
||||
If it is not present, or if it is set to `n`, then you have to clone the PX4 repo, modify the board configuration and manually [compile](../dev_setup/building_px4.md) the firmware.
|
||||
|
||||
#### New client module and new start parameters
|
||||
|
||||
As the client is implemented by a new PX4 module, you now have new parameters to start it.
|
||||
Take a look at the [client startup section](#starting-the-client) to learn how this is done.
|
||||
|
||||
#### New file for setting which topics are published
|
||||
|
||||
The list of topics that are published and subscribed for a particular firmware is now managed by the [dds_topic.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml) configuration file, which replaces [urtps_bridge_topics.yaml](https://github.com/PX4/PX4-Autopilot/blob/release/1.13/msg/tools/urtps_bridge_topics.yaml)
|
||||
|
||||
See [Supported uORB Messages](#supported-uorb-messages) and [DDS Topics YAML](#dds-topics-yaml) sections for more information.
|
||||
|
||||
#### Topics no longer need to be synced between client and agent.
|
||||
|
||||
The list of bridged topics between agent and client no longer needs to be synced for ROS 2, so the `update_px4_ros2_bridge.sh` script is no longer needed.
|
||||
|
||||
#### Default topic naming convention has changed
|
||||
|
||||
The topic naming format changed:
|
||||
|
||||
- Published topics: `/fmu/topic-name/out` (Fast-RTPS) to `/fmu/out/topic-name` (XRCE-DDS).
|
||||
- Subscribed topics: `/fmu/topic-name/in`(Fast-RTPS) to `/fmu/in/topic-name` (XRCE-DDS).
|
||||
|
||||
You should update your application to the new convention.
|
||||
|
||||
:::info
|
||||
You might also edit [dds_topic.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml) to revert to the old convention.
|
||||
This is not recommended because it means that you would have to always use custom firmware.
|
||||
:::
|
||||
|
||||
#### XRCE-DDS-Agent
|
||||
|
||||
The XRCE-DDS agent is "generic" and independent of PX4: [micro-xrce-dds-agent](https://micro-xrce-dds.docs.eprosima.com/en/latest/agent.html).
|
||||
There are many ways to install it on your PC / companion computer - for more information see the [dedicated section](#micro-xrce-dds-agent-installation).
|
||||
|
||||
#### Application-Specific Changes
|
||||
|
||||
If you where not using ROS 2 alongside the agent ([Fast DDS Interface ROS-Independent](https://docs.px4.io/v1.13/en/middleware/micrortps.html#agent-in-an-offboard-fast-dds-interface-ros-independent)), then you need to migrate to [eProsima Fast DDS](https://fast-dds.docs.eprosima.com/en/latest/index.html).
|
||||
|
||||
ROS 2 applications still need to compile alongside the PX4 messages, which you do by adding the [px4_msgs](https://github.com/PX4/px4_msgs) package to your workspace.
|
||||
You can remove the [px4_ros_com](https://github.com/PX4/px4_ros_com) package as it is no longer needed, other than for example code.
|
||||
|
||||
In your ROS 2 nodes, you will need to:
|
||||
|
||||
- Update the [QoS](#px4-ros-2-qos-settings) of your publishers and subscribers as PX4 does not use the ROS 2 default settings.
|
||||
- Change the names of your topics, unless you edited [dds_topic.yaml](https://github.com/PX4/PX4-Autopilot/blob/main/src/modules/uxrce_dds_client/dds_topics.yaml).
|
||||
- Remove everything related to time synchronization, as XRCE-DDS automatically takes care of agent/client time synchronization.
|
||||
|
||||
In C++ applications you can set the `timestamp` field of your messages like this:
|
||||
|
||||
```cpp
|
||||
msg.timestamp = this->get_clock()->now().nanoseconds() / 1000;
|
||||
```
|
||||
|
||||
In Python applications you can set the `timestamp` field of your messages like this:
|
||||
|
||||
```python
|
||||
msg.timestamp = int(self.get_clock().now().nanoseconds / 1000)
|
||||
```
|
||||
|
||||
## Helpful Resources
|
||||
|
||||
- [ROS 2 in PX4: Technical Details of a Seamless Transition to XRCE-DDS](https://www.youtube.com/watch?v=F5oelooT67E) - Pablo Garrido & Nuno Marques (youtube)
|
||||
- [PX4 ROS 2 offboard tutorial](https://gist.github.com/julianoes/adbf76408663829cd9aed8d14c88fa29) (Github gist - JulianOes)
|
||||
- [ROS 2 PX4 Offboard Tutorial](https://github.com/Jaeyoung-Lim/px4-offboard/blob/2d784532fd323505ac8a6e53bb70145600d367c4/doc/ROS2_PX4_Offboard_Tutorial.md) (Jaeyoung-Lim).
|
||||
|
||||
<!---
|
||||
Some of this might be useful.
|
||||
I'd like to see a real example first.
|
||||
|
||||
## Setting up the bridge with real hardware
|
||||
|
||||
This section is work-in-progress.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Client reports that selected UART port is busy
|
||||
|
||||
If the selected UART port is busy, it's possible that the MAVLink application is already being used.
|
||||
If both MAVLink and RTPS connections are required you will have to either move the connection to use another port or using the available protocol splitter for PX4 and companion computers.
|
||||
|
||||
:::tip
|
||||
A quick/temporary fix to allow bridge testing during development is to stop MAVLink from *NuttShell*:
|
||||
```sh
|
||||
mavlink stop-all
|
||||
```
|
||||
:::
|
||||
|
||||
### Enable UART on a companion computer
|
||||
|
||||
For UART transport on a Raspberry Pi or any other companion computer you will have to enable the serial port:
|
||||
|
||||
1. Make sure the `userid` (default is pi on a Raspberry Pi) is a member of the `dialout` group:
|
||||
|
||||
```sh
|
||||
groups pi
|
||||
sudo usermod -a -G dialout pi
|
||||
```
|
||||
1. For the Raspberry Pi in particular, you need to stop the GPIO serial console that is using the port:
|
||||
|
||||
```sh
|
||||
sudo raspi-config
|
||||
```
|
||||
|
||||
In the menu showed go to **Interfacing options > Serial**.
|
||||
Select **NO** for *Would you like a login shell to be accessible over serial?*. Valid and reboot.
|
||||
1. Check UART in kernel:
|
||||
|
||||
```sh
|
||||
sudo vi /boot/config.txt
|
||||
```
|
||||
|
||||
And make sure that the `enable_uart` value is set to 1:
|
||||
```
|
||||
enable_uart=1
|
||||
```
|
||||
-->
|
||||
Reference in New Issue
Block a user