# RTPS/DDS 接口:PX4-Fast RTPS(DDS)桥接器

PX4-Fast RTPS(DDS)桥接器也被称为 microRTPS 桥接器在 PX4 自动驾驶仪上增加了实时发布订阅(RTPS)接口,可以交换实时数据,从而使 PX4 自动驾驶仪的性能得到提高。 uORB 信息 各种 PX4 自动驾驶仪内部组件和(机载)外部组件之间的连接。 快速 DDS 实时应用。

这使我们能够更好地与在 DDS 域(包括 ROS 节点)中运行和链接的应用程序集成,从而轻松共享传感器数据、命令和其他载具信息。

下面的指南介绍了 RTPS/DDS 桥接架构,并向读者展示了如何编写一个简单的 快速 DDS 应用程序来订阅 PX4 自动驾驶仪的遥测更新。

备注

RTPS 是对象管理集团(OMG)数据分发服务(DDS)标准的基础协议。其目的是利用发布/订阅模式实现可扩展、实时、可靠、高性能和可互操作的数据通信。

快速 DDS 是 RTPS 协议/DDS 中间件最新版本的轻量级跨平台实现。它的前身是 快速 RTPS.

# 何时使用 RTPS?

当需要在飞行控制器和机外组件之间可靠地共享时间关键/实时信息时,应使用 RTPS。在机外软件需要成为飞行控制器和机外组件之间的 同龄人 在 PX4 中运行的软件组件(发送和接收 uORB 主题)。

可能的用例包括与用于计算机视觉的机器人库进行通信,以及对载具控制至关重要的执行器和传感器之间的实时数据通信。

快速 DDS 并不能替代 MAVLink。 MAVLink 仍然是与地面站、云台、摄像机和其他机外组件进行通信的最合适协议(尽管 快速 DDS 可能会为在更高频率下使用某些外设提供其他机会)。

TIP

在速度较慢的链路(如无线电遥测)上使用快速 RTPS(DDS)是可行的,但要注意链路的额外限制。请记住,遥测通道很容易超载。

# 建筑概览

# microRTPS 桥接器

microRTPS 桥接器在 PX4 和 DDS 参与者应用程序之间交换信息,在 PX4 和 DDS 之间进行无缝转换。 uORB 以及每个系统使用的 RTPS/DDS 报文。

基本示例流程

架构的主要元素是上图所示的客户端和代理进程。

# microRTPS 客户端

客户 是在飞行控制器上运行的 PX4 Autopilot 中间件守护进程。该客户端订阅其他 PX4 Autopilot 组件发布的 uORB 主题,并将任何更新发送至 代理 (通过 UART 或 UDP 端口),还可以接收来自 代理 并将其作为 uORB 信息发布到 PX4 自动驾驶仪。

# microRTPS 代理

代理 作为一个守护进程运行在机载计算机上(飞行控制器之外)。该代理从 客户 并通过 RTPS(重新)发布它们,还订阅来自其他 DDS 参与者应用程序的 RTPS/DDS 消息,并将它们转发到 客户.

# microRTPS 代理/客户端通信

代理客户 通过串行链路(UART)或 UDP 网络连接,而 uORB 信息是 CDR 序列化 (打开新窗口) 在发送之前 (CDR 序列化 为不同平台之间交换串行数据提供了通用格式)。

代理 和任何 快速 DDS 应用程序通过 UDP 连接,可能在同一设备上,也可能在其他设备上。在典型的配置中,它们将在同一系统上(如开发计算机、Linux 配套计算机或计算板),连接到 客户.可以通过 Wifi 链接或 USB。

# 代码生成

# 依赖关系

必须安装 Fast DDS 2.0.0 或更高版本和 Fast-RTPS-Gen 1.0.4(非更高版本!),才能生成所需的代码,并继续下一步。 按照安装指南进行操作。

备注

RTPS 已被采用为 ROS 2(机器人操作系统)的中间件。

有关如何在 ROS 2 应用程序和开发工作流程中使用该界面的信息,请参阅 PX4-ROS 2 桥接器.

# 快速 RTPS(DDS)应用(独立于 ROS)

在编译 PX4-Autopilot 时,会自动生成创建、构建和使用桥接器所需的所有代码。

客户 作为正常构建过程的一部分,应用程序也会编译并内置到固件中。该 代理 必须为目标计算机单独/手动编译。

TIP

大多数用户并不需要这样做。不过,网桥可以 手动生成提供更详细的构建过程概览,有助于排除故障。

# 支持的 uORB 报文

生成的桥接代码将使指定的 uORB 主题子集能够通过 RTPS 发布/订阅,无论您是否部署了 ROS 应用程序。

对于 自动生成代码 有一个 yaml 中的定义文件 PX4-Autopilot/msg/tools/ 名为 uorb_rtps_message_ids.yaml.该文件定义了与 RTPS 一起使用的 uORB 报文集、报文的发送、接收或两者,以及将在 DDS/RTPS 中间件中使用的报文的 RTPS ID。

备注

必须注意的是,每个 RTPS 报文 需要 要在该文件中设置的 ID。

rtps:
  - 信息: 已上膛的致动器
    本我: 0
  - 信息: 致动器控制
    本我: 1
  - ...
  - 信息: 空速
    本我: 5
    发送: 
  - 信息: 电池状态
    本我: 6
    发送: 
  - 信息: 摄像头捕捉
    本我: 7
  - 信息: 摄像机触发器
    本我: 8
    接收: 
  - ...
  - 信息: 传感器_巴罗
    本我: 63
    接收: 
    发送: 

# 客户端(PX4/PX4-自动驾驶仪)

客户 作为正常构建流程的一部分,PX4 自动驾驶仪固件会生成、编译并内置源代码。

要为 NuttX/Pixhawk 飞行控制器构建 PX4 自动驾驶仪固件,请使用 _rtps 配置目标中的功能。

例如,为 px4_fmu-v4 构建 RTPS:

生产 PX4_FMU-V4_RTPS

为 SITL 目标构建固件:

生产 px4_sitl_rtps

客户 应用程序可从 NuttShell/系统控制台.命令语法如下所示(可指定不同数量的参数):

>; micrortps_client 启动|停止|地位 [选项]
  -t <;运输>;          [UART|UDP] 默认 UART -d <;装置>;             UART 设备。默认 /dev/ttyACM0 -l <;环路>;              这个程序有多少次迭代?-1 对于 无限。默认值-1。 <;睡眠时间>;      时间  毫秒 对于 其中 每次迭代的睡眠时间。默认为 1ms -b <;波特率>;           UART 设备波特率。默认值 460800
  -p <;poll_ms>;            时间  通过 UART 轮询的毫秒数。默认为 1ms -r <;接收端口>;     UDP 端口 对于 接收。默认值 2019
  -s <;发送端口>;       UDP 端口 对于 发送。默认值 2020
  -i <;IP 地址>;         选择 IP 地址 (远程) 价值观 <;x.x.x.x>;.默认值: 127.0.0.1

备注

默认情况下 客户 作为守护进程运行,但它不会自动启动,必须手动启动。

PX4 自动驾驶仪固件初始化代码将来可能会自动启动自动驾驶仪。 客户 作为永久守护进程。

例如,为了运行 客户 通过 UDP 连接到代理的 SITL 守护进程:

micrortps_client start -t UDP

# 机外快速 DDS 接口中的代理(独立于 ROS)

代理 代码会自动 生成的 您可以在这里找到源代码: build/<target-platform>/src/modules/micrortps_bridge/micrortps_client/micrortps_agent/.

建立 代理 应用程序,编译代码:

CD 建立/<;目标平台>;/src/modules/micrortps_bridge/micrortps_client/micrortps_agent
mkdir 构建 &&; CD 构建 cmake ..
生产

的命令语法 代理 如下所示:

$ ./micrortps_agent [选项]
  -t <;运输>;          [UART|UDP] 默认 UART。-d <;装置>;             UART 设备。默认为 /dev/ttyACM0。-w <;睡眠时间>;      时间  我们 对于 其中 每次迭代的睡眠时间。默认为 1ms。-b <;波特率>;           UART 设备波特率。默认值 460800.-p <;poll_ms>;            时间  通过 UART 轮询的毫秒数。默认为 1ms。-r <;接收端口>;     UDP 端口 对于 接收。默认值 2019.-s <;发送端口>;       UDP 端口 对于 发送。默认值 2020.-n <;设置命名空间>;      设置命名空间 对于 微ortps_agent。

要启动 代理运行 micrortps_agent 和适当的选项,用于指定与 客户 (默认选项是从 Linux 设备连接到 客户 通过 UART 端口)。

例如,要启动 micrortps_agent 通过 UDP 连接,问题:

./micrortps_agent -t UDP

# 创建快速 DDS 监听器应用程序

一旦 客户 (飞行控制器上)和 代理 (在车载计算机上)运行并连接、 快速 DDS 应用程序可以使用 RTPS 在 PX4 自动驾驶仪上发布和订阅 uORB 主题。

本例演示了如何创建一个 快速 DDS 监听器" 应用程序,该应用程序会订阅 综合传感器 并打印 PX4 自动驾驶仪发布的更新。连接的 RTPS 应用程序可在与 PX4 自动驾驶仪位于同一网络的任何计算机上运行。 代理.在本例中 代理监听器应用程序 将在同一台计算机上运行。

fastrtpsgen 脚本可用于从 IDL 消息文件生成一个简单的 RTPS 应用程序。

备注

RTPS 报文在 IDL 文件中定义,并使用 fastrtpsgen.

在构建桥接代码时,会为可能发送/接收的 uORB 消息生成 IDL 文件,在创建快速 DDS 应用程序与 PX4 自动驾驶仪通信时需要这些 IDL 文件。

您可以在每个构建目标的以下路径中找到它们: build/BUILDPLATFORM/src/modules/micrortps_bridge/micrortps_agent/idl/*.idl.

输入以下命令创建应用程序:

CD /path/to/PX4/PX4-Autopilot
CD build/px4_sitl_rtps/src/modules/micrortps_bridge
mkdir micrortps_listener
CD micrortps_listener fastrtpsgen -example x64Linux2.6gcc ../micrortps_agent/idl/sensor_combined.idl

这将创建一个基本的订阅者和发布者,以及一个可以运行的主应用程序。

为了打印来自传感器组合主题的数据,请修改以下方法 sensor_combined_Subscriber.cxx:

  • 启动():更改订阅主题名称(默认情况下,micrortps 代理会在命名的主题上发布数据): FMU/SENSOR_COMBED/UT),
  • onNewDataMessage():打印接收到的传感器综合数据。
bool 传感器综合订阅者::启动(订阅者* 字幕)
{
    // 创建 RTPSParticipant

    参与者属性 PParam;
    PParam.rtps.设置名称("Participant_subscriber";); //您可以输入您想要的名称
    mp_participant = 域名::创建参与者(PParam);
    如果(mp_participant == nullptr)
    {
        返回 错误;
    }

    //注册类型

    域名::注册类型(mp_participant, 静态投射<;主题数据类型*>;(及样品;我的类型));

    // 创建订阅者

    订阅者属性 Rparam;
    Rparam.主题.topicKind = NO_KEY;
    Rparam.主题.topicDataType = 我的类型.获取名称(); //必须在创建用户前注册
    Rparam.主题.主题名 = "fmu/sensor_combined/out";;
    mp_subscriber = 域名::创建订阅者(mp_participant,Rparam, 静态投射<;订阅者监听器*>;(及样品;m_listener));
    如果(mp_subscriber == nullptr)
    {
        返回 错误;
    }
    返回 ;
}
空白 传感器综合订阅者::子监听器::onNewDataMessage(订阅者* 字幕)
{
    // 获取数据
    综合传感器;

    如果(字幕->;takeNextData(及样品;, 及样品;m_info))
    {
        如果(m_info.样本种类 == 活着)
        {
            // 在此打印结构数据。
            ++n_msg;
            标准::cout <<; "\n\n\n\n\n\n\n\n\n\n";
            标准::cout <<; "收到样本,count="; <<; n_msg <<; 标准::endl;
            标准::cout <<; "=============================" <<; 标准::endl;
            标准::cout <<; "gyro_rad:"; <<;.陀螺仪().(0);
            标准::cout <<; ","; <<;.陀螺仪().(1);
            标准::cout <<; ","; <<;.陀螺仪().(2) <<; 标准::endl;
            标准::cout <<; "gyro_integral_dt: "; <<;.陀螺积分() <<; 标准::endl;
            标准::cout <<; "accelerometer_timestamp_relative: "; <<;.相对加速度计时间戳() <<; 标准::endl;
            标准::cout <<; "accelerometer_m_s2: "; <<;.加速度计_m_s2().(0);
            标准::cout <<; ","; <<;.加速度计_m_s2().(1);
            标准::cout <<; ","; <<;.加速度计_m_s2().(2) <<; 标准::endl;
            标准::cout <<; "accelerometer_integral_dt: "; <<;.加速度计积分() <<; 标准::endl;
            标准::cout <<; "magnetometer_timestamp_relative: "; <<;.磁强计相对时间戳() <<; 标准::endl;
            标准::cout <<; "magnetometer_ga: "; <<;.磁强计_ga().(0);
            标准::cout <<; ","; <<;.磁强计_ga().(1);
            标准::cout <<; ","; <<;.磁强计_ga().(2) <<; 标准::endl;
            标准::cout <<; "baro_timestamp_relative: "; <<;.相关时间戳() <<; 标准::endl;
            标准::cout <<; "baro_alt_meter: "; <<;.盐度计() <<; 标准::endl;
            标准::cout <<; "baro_temp_celcius: "; <<;.温度计() <<; 标准::endl;

        }
    }
}

在 Linux 上构建并运行应用程序:

生产 -f makefile_x64Linux2.6gcc bin/*/sensor_combined_PublisherSubscriber subscriber

现在,您应该可以看到传感器信息被打印出来:

已收到样品、 计数=10119
接收到的传感器综合数据
=============================
gyro_rad: -0.0103228、 0.0140477, 0.000319406
gyro_integral_dt: 0.004
相对加速度计时间戳: 0
accelerometer_m_s2: -2.82708, -6.34799, -7.41101 accelerometer_integral_dt: 0.004
magnetometer_timestamp_relative: -10210 magnetometer_ga: 0.60171, 0.0405879, -0.040995 baro_timestamp_relative: -17469 baro_alt_meter: 368.647
Baro_temp_celcius: 43.93

备注

确保 客户 运行时,如果 监听器应用程序 不打印任何内容。

# 用真正的硬件设置网桥

本部分正在编写中。

# 故障排除

# 客户端报告所选 UART 端口繁忙

如果所选 UART 端口繁忙,则可能已在使用 MAVLink 应用程序。如果需要同时连接 MAVLink 和 RTPS,则必须将连接转移到另一个端口,或使用 PX4 和配套计算机的可用协议分配器。

TIP

在开发过程中进行桥接测试的快速/临时解决方案是停止 MAVLink 果壳:

mavlink stop-all

# 未构建代理/未找到 ftrpsgen

代理 代码使用 快速 DDS 名为 fastrtpsgen.

如果没有将 Fast DDS 安装在默认路径下,则必须通过设置 fastrtpsgen_dir 环境变量,然后再执行 生产.

在 Linux/Mac 上的操作如下所示:

出口 fastrtpsgen_dir=/path/to/fastrtps/install/folder/bin

# 在配套计算机上启用 UART

要在 Raspberry Pi 或任何其他配套计算机上进行 UART 传输,必须启用串行端口:

  1. 确保 用户名 (在 Raspberry Pi 上默认为 pi)是 拨出 组:

    组别 pi
    苏都 篡改 -a -G dialout pi
    
  2. 特别是对于 Raspberry Pi,您需要停止正在使用该端口的 GPIO 串行控制台:

    苏都 raspi-config
    

    在显示的菜单中,转到 接口选项 > 串行.选择 没有 对于 您希望通过串口访问登录 shell 吗?.有效并重新启动。

  3. 检查内核中的 UART:

    苏都 vi /boot/config.txt
    

    并确保 启用 值设置为 1:

     enable_uart=1
    

# 有用资源