# ROS 2 用户指南(PX4-ROS 2 桥接器)

本主题介绍如何在 PX4 中设置和使用 ROS 2。

它概述了 ROS2-PX4 桥接架构和应用管道,以及如何安装所有所需软件和构建 ROS 2 应用程序的说明。

备注

任何在 DDS 域(包括 ROS 节点)中运行和链接的应用程序都可以利用 PX4 自动驾驶仪中的快速 DDS 接口。

有关使用 微型 RTPS 桥接器 无 ROS 2RTPS/DDS 接口部分.

备注

有关如何将 PX4 与 ROS 2 结合使用的更详细、更直观的说明,请参阅 PX4 维护者的介绍:

  1. ROS World 2020 - ROS 2 和 PX4 入门 (打开新窗口)
  2. PX4 Dev Summit 2019 - "ROS 2 Powered PX4"; (打开新窗口)

警告

PX4 v1.13 不支持 XRCE-DDS 作为 ROS 2 中间件。在 PX4 v1.13 中使用 MicroRTPS 如下所述。

# 概述

得益于本地通信中间件(DDS/RTPS),ROS 2 的应用管道非常简单。其 microRTPS 桥接器 它由运行在 PX4 上的客户端和运行在任务/同伴计算机上的代理组成,两者通过通信提供 UORB 和 ROS 2 信息格式之间的双向数据交换和信息转换。这样就可以创建直接与 PX4 UORB 主题连接的 ROS 2 订阅者或发布者节点!如下图所示。

使用 ROS 2 的架构

ROS 2 使用 px4_msgs (打开新窗口)px4_ros_com (打开新窗口) 软件包,以确保在创建客户端和代理代码时使用匹配的消息定义(这一点很重要),同时还能在构建 ROS 代码时取消对 PX4 的要求。

  • px4_msgs 包含 PX4 ROS 消息定义。构建该项目时,它会生成相应的 ROS 2 兼容类型支持(ROS 2 节点使用)和 IDL 文件(ROS 2 节点使用)。 fastddsgen 来生成 microRTPS 代理代码。
  • px4_ros_com 包含用于代理发布者和订阅者的 microRTPS 代理代码模板。构建过程会运行 fastddsgen 实例来生成 micrortps_agent,编译成一个单一的可执行文件。

PX4 自动驾驶仪项目自动更新 px4_msgs (打开新窗口) 每当有新的报文定义更改时(在 分支)。

备注

ROS 应用程序可以访问的 uORB 主题子集可以在 桥接配置 yaml 文件 (打开新窗口).

PX4 固件根据其构建时的信息定义包含 microRTPS 客户端。

备注

精明的读者会注意到,生成的代理可能不是用同一套定义构建的(除非它们都是用同一个 "主 "提交构建的)。

现在这不是问题,因为 PX4 信息集/定义相对稳定,更新/新信息会自动部署到 px4_msgs.

在不久的将来,我们打算

  1. 也在以下两个版本中为每个版本创建一个分支 px4_ros_compx4_msgs因此,信息定义和代理代码都与发布时 PX4/客户端上的信息定义和代理代码一致。
  2. 对网桥配置进行初始报文交换,使用报文结构 MD5SUM 验证报文定义是否相同,如果不相同,则禁用其流并向用户发出警告。

警告

您不能在 ROS 2 中使用作为 "normal"PX4 构建一部分而生成的代理(例如,如果用户使用了 BUILD_MICRORTPS_AGENT=1 make px4_sitl_rtps).虽然 microRTPS 客户端是一样的,但 ROS 2 使用的 IDL 文件与 PX4 生成的独立于 ROS 的文件.另一个细节是,PX4 的正常构建不使用 fastddsgen 为 ROS 2 网络提供类型支持--这也是我们在 ROS 2 网络中使用单独的 microRTPS 代理的主要原因之一。 px4_ros_com完全兼容 ROS 2 网络。我们使用 px4_msg 生成相应的 IDL 文件 micrortps_agentpx4_ros_com.

# 安装和设置

要设置 ROS 2 以与 PX4 配合使用,您需要

# 安装快速 DDS

按照 快速 DDS 安装指南 安装 快速 RTPS(DDS) 2.0.2 (或更高版本)和 Fast-RTPS-Gen 1.0.4 (不是以后!)及其依赖关系。

警告

检查指南以确认最新的依赖关系!在正确版本的 快速 RTPS(DDS)Fast-RTPS-Gen 已安装。

# 安装 ROS 2

备注

本安装和构建指南涵盖 Ubuntu 20.04 中的 ROS 2 Foxy。

警告

如果在 ROS2 教程的环境变量中设置了 ROS_DOMAIN_ID,则需要取消设置 ROS_DOMAIN_ID 才能在 ROS2 和 microRTPS-agent 之间建立连接。

安装 ROS 2 及其依赖项:

  1. 安装 ROS 2 Foxy (打开新窗口)

  2. 安装过程还应安装 胶管 不过,如果没有,你也可以手动安装这些工具:

    苏都 适切 安装 python3-colcon-common-extensions
    
  3. eigen3_cmake_module 也是必需的,因为 Eigen3 用于变换库:

    苏都 适切 安装 ros-foxy-eigen3-cmake 模块
    
  4. 还必须安装一些 Python 依赖项(使用 核心适切):

    苏都 管道3 安装 -U empy pyros-genmsg setuptools
    

# 构建 ROS 2 工作区

本节将介绍如何创建一个 ROS 2 工作区,将其托管在你的 主目录 (根据需要修改命令,将源代码放在其他地方)。命令 px4_ros_compx4_msg 软件包克隆到工作区文件夹,然后使用脚本构建工作区。

备注

构建过程将在控制台上打开新的标签页,这些标签页与构建过程的不同阶段相对应,这些阶段需要获取不同的环境配置。

创建和构建工作区:

  1. 使用
    $ mkdir -p ~/px4_ros_com_ros2/src
    
  2. 克隆 ROS 2 桥接软件包 px4_ros_compx4_msgs/src 目录(该 版本/1.13 分支必须克隆):
    $ Git clone -b release/1.13 https://github.com/PX4/px4_ros_com.git ~/px4_ros_com_ros2/src/px4_ros_com $ Git clone -b release/1.13 https://github.com/PX4/px4_msgs.git ~/px4_ros_com_ros2/src/px4_msgs
    
  3. 使用 build_ros2_workspace.bash 脚本来构建 ROS 2 工作区(包括 px4_ros_compx4_msgs).
    $ CD ~/px4_ros_com_ros2/src/px4_ros_com/scripts $ 消息来源 build_ros2_workspace.bash
    

TIP

通过使用 --帮助 论点。特别是 --verbose 参数显示完整的 胶管 构建输出。

备注

px4_ros_com/scripts 目录中包含多个脚本,用于构建不同类型的工作区。

# 检查安装是否合理

检查安装/设置是否成功的方法之一是测试网桥是否能与 PX4 通信。我们可以通过在模拟器中运行 PX4 来实现这一目的。

  1. 设置 PX4 Ubuntu Linux 开发环境 - 的默认指令获得 最新 版本的 PX4 源代码,并安装所有需要的工具。

    备注

    要获取 PX4 源程序 v1.13 版本,必须调整上述说明。

    Git 克隆 -b <;标签>; https://github.com/PX4/PX4-Autopilot.git --recursive
    

    其中 <标签>; 可以是 版本/1.13 或任何 v.13.* 标签取决于用户的具体情况。否则,请参考 最新 (打开新窗口) 文件。

  2. PX4 自动驾驶仪 项目,然后开始使用 PX4 Gazebo 仿真:

    生产 PX4_SITL_RTPS 仿真场景Gazebo
    

    PX4 完全启动后,终端将显示 NuttShell/系统控制台.还请注意,PX4 SITL 将自动启动 micrortps_client 连接到 UDP 端口 2019 和 2020。

  3. 在一个 终端、 消息来源 ROS 2 工作区,然后启动 micrortps_agent 守护进程,以 UDP 作为传输协议:

    $ 消息来源 ~/px4_ros_com_ros2/install/setup.bash $ micrortps_agent -t UDP
    
  4. 打开一个新终端,使用提供的启动文件启动监听器:

    $ 消息来源 ~/px4_ros_com_ros2/install/setup.bash $ ros2 launch px4_ros_com sensor_combined_listener.launch.py
    

    如果网桥工作正常,您就可以在启动 ROS 监听器的终端/控制台上看到打印的数据:

    传感器接收到的综合数据
    ================================
    ts: 870938190
    陀螺仪[0]: 0.00341645
    陀螺仪[1]: 0.00626475
    陀螺仪[2]: -0.000515705 gyro_integral_dt: 4739
    相对加速度计时间戳: 0
    加速度计_m_s2[0]: -0.273381 加速度计_m_s2[1]: 0.0949186
    加速度计_m_s2[2]: -9.76044 加速度计积分 dt: 4739
    

您还可以使用 ros2 主题 hz.例如 综合传感器 使用 ros2 topic hz /fmu/sensor_combined/out:

平均率: 248.187
	分钟 0最多 0.000 秒: 0.012s std dev: 0.00147 秒窗口: 2724
平均率: 248.006
	分钟 0最多 0.000 秒: 0.012s std dev: 0.00147 秒窗口: 2972
平均率: 247.330
	分钟 0最多 0.000 秒: 0.012s std dev: 0.00148s 窗口: 3212
平均率: 247.497
	分钟 0最多 0.000 秒: 0.012s std dev: 0.00149 秒窗口: 3464
平均率: 247.458
	分钟 0最多 0.000 秒: 0.012s std dev: 0.00149 秒窗口: 3712
平均率: 247.485
	分钟 0最多 0.000 秒: 0.012s std dev: 0.00148s 窗口: 3960

# ROS 2 应用实例

# 创建 ROS 2 监听器

随着 px4_ros_com 现在,我们可以利用生成的 microRTPS 代理应用程序,以及来自 px4_msgs代表与 uORB 对应的一对一匹配。

要在 ROS 2 上创建一个监听节点,让我们以 sensor_combined_listener.cpp 节点下 px4_ros_com/src/examples/listeners.

代码首先导入与 ROS 2 中间件连接所需的 C++ 库和所需的消息头文件:

#包括 <rclcpp/rclcpp.hpp>;
#包括 <px4_msgs/msg/sensor_combined.hpp>;

然后创建一个 传感器组合监听器 类的子类。 rclcpp::Node 基类。

/** * @brief 传感器组合 uORB 主题数据回调 */
 传感器组合监听器 :  rclcpp::节点
{

会创建一个回调函数,当 综合传感器 接收 uORB 报文(现在是 RTPS/DDS 报文),并在每次接收报文时输出报文字段的内容。

:
	不含糊 传感器组合监听器() : 节点("sensor_combined_listener";) {
		订阅_ = ->;创建订阅<;px4_msgs::信息::传感器组合>;(
			"fmu/sensor_combined/out";,
			10,
			[]( px4_msgs::信息::传感器组合::UniquePtr msg) {
			标准::cout <<; "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
			标准::cout <<; "接收到的传感器综合数据";   <<; 标准::endl;
			标准::cout <<; "============================="   <<; 标准::endl;
			标准::cout <<; ts: ";          <<; 信息->;时戳    <<; 标准::endl;
			标准::cout <<; "gyro_rad[0]:"; <<; 信息->;陀螺仪[0]  <<; 标准::endl;
			标准::cout <<; "gyro_rad[1]: "; <<; 信息->;陀螺仪[1]  <<; 标准::endl;
			标准::cout <<; "gyro_rad[2]: "; <<; 信息->;陀螺仪[2]  <<; 标准::endl;
			标准::cout <<; "gyro_integral_dt: "; <<; 信息->;陀螺积分 <<; 标准::endl;
			标准::cout <<; "accelerometer_timestamp_relative: "; <<; 信息->;相对加速度计时间戳 <<; 标准::endl;
			标准::cout <<; "accelerometer_m_s2[0]: "; <<; 信息->;加速度计_m_s2[0] <<; 标准::endl;
			标准::cout <<; "加速度计_m_s2[1]: "; <<; 信息->;加速度计_m_s2[1] <<; 标准::endl;
			标准::cout <<; "accelerometer_m_s2[2]: "; <<; 信息->;加速度计_m_s2[2] <<; 标准::endl;
			标准::cout <<; "accelerometer_integral_dt: "; <<; 信息->;加速度计积分 <<; 标准::endl;
		});
	}

下面几行为 综合传感器 uORB 主题,该主题可与一个或多个兼容的 ROS2 订阅者相匹配。 FMU/SENSOR_COMBED/UT ROS2 主题。

私人:
	rclcpp::订阅<;px4_msgs::信息::传感器组合>;::SharedPtr subscription_;
};

的实例化 传感器组合监听器 类作为 ROS 节点是在 主要 功能。

int 主要(int 参数, 烧焦 *参数[])
{
	标准::cout <<; "Starting sensor_combined listener node..."; <<; 标准::endl;
	setvbuf(数据输出, NULL, _IONBF, BUFSIZ);
	rclcpp::启动(参数, 参数);
	rclcpp::后旋(标准::共享<;传感器组合监听器>;());

	rclcpp::关闭();
	返回 0;
}

# 创建 ROS 2 广告客户

ROS 2 广告节点向 DDS/RTPS 网络(也就是 PX4 自动驾驶仪)发布数据。

例如 debug_vect_advertiser.cpp 根据 px4_ros_com/src/advertisers首先,我们导入所需的头文件,包括 debug_vect msg 标头。

#包括 时间顺序<chrono>;
#包括 <rclcpp/rclcpp.hpp>;
#包括 <px4_msgs/msg/debug_vect.hpp>;

使用 命名空间 标准::计时器;

然后,代码会创建一个 DebugVectAdvertiser 类的子类。 rclcpp::Node 基类。

 DebugVectAdvertiser :  rclcpp::节点
{

下面的代码为何时发送信息创建了一个函数。信息根据定时回调发送,该回调根据定时器每秒发送两条信息。

:
	DebugVectAdvertiser() : 节点("debug_vect_advertiser";) {
		出版商_ = ->;创建出版商<;px4_msgs::信息::调试向量>;("fmu/debug_vect/in";, 10);
		汽车 定时器回调 =
		[]()->;空白 {
			汽车 debug_vect = px4_msgs::信息::调试向量();
			debug_vect.时戳 = 标准::计时器::时间点播报<;标准::计时器::微秒>;(标准::计时器::稳定时钟::现在()).自时间起().计数();
			标准::字符串名称 = "测试";;
			标准::抄袭(名字.兴办(), 名字.最后(), debug_vect.名字.兴办());
			debug_vect.x = 1.0;
			debug_vect.y = 2.0;
			debug_vect.z = 3.0;
			RCLCPP_INFO(->;get_logger(), "\033[97m Publishing debug_vect: time: %llu x: %f y: %f z: %f \033[0m";,
                                debug_vect.时戳, debug_vect.x, debug_vect.y, debug_vect.z);
			->;出版商_->;发布(debug_vect);
		};
		定时器 = ->;创建隔离墙计时器(500毫秒, 定时器回调);
	}

私人:
	rclcpp::定时器基数::SharedPtr timer_;
	rclcpp::出版商<;px4_msgs::信息::调试向量>;::SharedPtr publisher_;
};

的实例化 DebugVectAdvertiser 类作为 ROS 节点是在 主要 功能。

int 主要(int 参数, 烧焦 *参数[])
{
	标准::cout <<; "Starting debug_vect advertiser node..."; <<; 标准::endl;
	setvbuf(数据输出, NULL, _IONBF, BUFSIZ);
	rclcpp::启动(参数, 参数);
	rclcpp::后旋(标准::共享<;DebugVectAdvertiser>;());

	rclcpp::关闭();
	返回 0;
}

# 机外控制

有关如何在 PX4 上使用板外控制的完整参考示例,请参阅: ROS 2 机外控制示例.

# 使用 ROS1 兼容工作区手动设置工作区(仅供参考)

备注

提供该说明是为了帮助您更好地了解构建过程以及如何包含 ROS1 工作区。构建或使用 ROS 2 不需要它。 ros1_桥 软件包,在 通过 ROS 2 桥接的 ROS (1).

本节介绍了 人工 设置您的工作区并构建 px4_ros_com, px4_msgsros1_桥 包装。该主题有效地解释了 build_ros2_workspace.bash 脚本中的 安装说明).

仅构建 ROS 2 工作区:

  1. CDpx4_ros_com_ros2 目录中的 ROS 2 环境源代码。如果它告诉你之前已经设置了一个工作区,请不要介意:

    CD ~/px4_ros_com_ros2
    消息来源 /opt/ros/foxy/setup.bash
    
  2. 建立工作区:

    colcon build --symlink-install --event-handlers console_direct+
    

同时建立 ROS 2 和 ROS (1) 工作区(替换前面的步骤):

  1. CDpx4_ros_com_ros2 目录中的 ROS 2 环境源代码。如果它告诉你之前已经设置了一个工作区,请不要介意:

    消息来源 /opt/ros/foxy/setup.bash
    
  2. 克隆 ros1_桥 软件包,以便在 ROS 2 工作区中构建:

    Git clone https://github.com/ros2/ros1_bridge.git -b dashing ~/px4_ros_com_ros2/src/ros1_bridge
    
  3. 建立 px4_ros_compx4_msgs 软件包,不包括 ros1_桥 包装

    colcon build --symlink-install --packages-skip ros1_bridge --event-handlers console_direct+
    

    备注

    --事件处理程序 console_direct+ 只是为了增加 胶管 如果想要更安静的构建过程,可以将其移除。

  4. 然后构建 ROS(1) 软件包。首先打开一个 终端窗口,并调用系统上安装的 ROS(1) 环境:

    消息来源 /opt/ros/melodic/setup.bash
    
  5. 建立 px4_ros_compx4_msgs ROS 端上的软件包(使用上一步打开的终端):

    CD ~/px4_ros_com_ros1 &&; colcon build --symlink-install --event-handlers console_direct+
    
  6. 打开另一个新终端,然后按以下顺序为环境和工作区添加源代码:

    消息来源 ~/px4_ros_com_ros1/install/setup.bash
    消息来源 ~/px4_ros_com_ros2/install/setup.bash
    
  7. 最后,建立 ros1_桥:

    CD ~/px4_ros_com_ros2 &&; colcon build --symlink-install --packages-select ros1_bridge --cmake-force-configure --event-handlers console_direct+
    

    备注

    构建过程可能会消耗大量内存资源。在资源有限的机器上,减少并行处理的作业数量(例如,设置环境变量 MAKEFLAGS=-j1).有关构建过程的更多详情,请参阅 ros1_桥 (打开新窗口) 包装页。

# 清洁工作区

在构建工作区后,必须先删除许多文件,然后才能进行清理/重新构建(例如,在更改了某些代码后,想要重新构建)。

不幸的是 胶管 目前没有办法清理生成的 构建, 安装登录 目录,因此必须手动删除这些目录。

clean_all.bash 脚本 px4_ros_com/scripts)可简化清理过程,该脚本可用于清理上述所有工作区选项(ROS 2、ROS 1 和两者)。

最常见的使用方法是将 ROS (1) 工作区目录路径传给它(因为它通常不在默认路径上):

$ 消息来源 clean_all.bash --ros1_ws_dir <;path/to/px4_ros_com_ros1/ws>;

TIP

与构建脚本一样, clean_all.bash 脚本也有一个 --帮助 指导。

# 其他信息