# ROS 2 机外控制示例

下面的 C++ 示例展示了如何在 离机模式 来自 ROS 2 节点。

该示例开始发送设定点、进入离机模式、启动、上升到 5 米处并等待。该示例虽然简单,但却展示了如何使用离机控制以及如何发送载具指令的主要原则。

已在 Ubuntu 20.04 上使用 ROS 2 Foxy 和 PX4 进行了测试。 主要 PX4 v1.13 之后。

警告

机外 控制是很危险的。如果您要在真实载具上进行操作,请务必想办法重新获得手动控制权,以防出现意外。

备注

ROS 和 PX4 做出了许多不同的假设,特别是在以下方面 框架公约.在发布或订阅主题时,框架类型之间没有隐式转换!

本示例按照 PX4 的要求以 NED 框架发布位置。要订阅来自以不同框架(例如 ROS/ROS 2 的标准参照框架 ENU)发布数据的节点的数据,请使用 帧变换 (打开新窗口) 图书馆

# 试用

请按照 ROS 2 用户指南 安装 PX 并运行模拟器,安装 ROS 2 并启动 XRCE-DDS 代理。

之后,我们可以按照类似于 ROS 2 用户指南 > 构建 ROS 2 工作区 运行示例。

构建并运行示例

  1. 打开一个新终端。

  2. 使用以下命令创建并导航到新的 colcon 工作区目录:

    mkdir -p ~/ws_offboard_control/src/
    CD ~/ws_offboard_control/src/
    
  3. 克隆 px4_msgs (打开新窗口)/src 目录(每个 ROS 2 PX4 工作区都需要该 repo!):

    Git 克隆 https://github.com/PX4/px4_msgs.git
    # 如果不使用 PX4 主分支,则签出与之匹配的发布分支。
    
  4. 克隆示例资源库 px4_ros_com (打开新窗口)/src 目录:

    Git 克隆 https://github.com/PX4/px4_ros_com.git
    
  5. 将 ROS 2 开发环境的源代码导入当前终端,并使用以下命令编译工作区 胶管:

    • 资料来源 local_setup.bash:

      消息来源 install/local_setup.bash
      
    • 启动示例。

      ros2 run px4_ros_com offboard_control
      

    载具应启动,上升 5 米,然后等待(永久等待)。

    # 实施情况

    机外控制示例的源代码可在以下网站找到 PX4/px4_ros_com (打开新窗口) 目录中的 /src/examples/offboard/offboard_control.cpp (打开新窗口).

    备注

    PX4 默认将本例中使用的所有信息都发布为 ROS 主题(请参阅 dds_topics.yaml (打开新窗口)).

    PX4 要求载具已经接收到 机外控制模式 信息,然后才会在离机模式下上膛,或在飞行时切换到离机模式。此外,PX4 会在以下情况下切换出离线模式 机外控制模式 信息的频率下降到大约 2 赫兹以下。如下图所示,ROS 2 节点中的主循环旋转实现了所需的行为:

    汽车 定时器回调 = []() ->; 空白 {
    
    	如果 (离板设定点计数器 == 10) {
    		// 10 个设定点后改为离板模式
    		->;发布载具命令(载具指令::vehicle_cmd_doo_set_mode, 1, 6);
    
    		// 解除载具上膛
    		->;上膛();
    	}
    
    	// OffboardControlMode 需要与 TrajectorySetpoint 配对
    	发布控制模式();
    	发布轨迹设置点();
    
    	// 计数器运行到 11 时停止
    	如果 (离板设定点计数器 <; 11) {
    		离板设定点计数器++;
    	}
    };
    定时器 = ->;创建隔离墙计时器(100毫秒, 定时器回调);
    

    循环在一个 100ms 的定时器上运行。在前 10 个循环中,它会调用 publish_offboard_control_mode()publish_trajectory_setpoint()机外控制模式轨迹设置点 向 PX4 发送信息。信息 机外控制模式 信息流,以便 PX4 在切换到离板模式后允许上膛,而 轨迹设置点 信息将被忽略(直到载具进入离车模式)。

    10 个周期后 publish_vehicle_command() 会被调用来切换到离板模式,而 arm() 会被调用来上膛载具。载具上膛并切换模式后,将开始跟踪位置设定点。设定点仍会在每个周期内发送,这样载具就不会脱离离车模式。

    的实施 publish_offboard_control_mode()publish_trajectory_setpoint() 方法如下所示。这些方法可发布 机外控制模式轨迹设置点 分别向 PX4 发送信息。

    机外控制模式 需要通知 PX4 类型 使用的机外控制。在这里,我们只使用 位置控制因此 位置 字段设置为 而所有其他字段都设置为 错误.

    /** * @brief 发布机外控制模式。* 在本例中,只有位置和高度控制处于激活状态。*/
    空白 机外控制::发布控制模式()
    {
    	离机控制模式 msg{};
    	信息.位置 = ;
    	信息.速度 = 错误;
    	信息.加速度 = 错误;
    	信息.态度 = 错误;
    	信息.身体速率 = 错误;
    	信息.时戳 = ->;获取时钟()->;现在().纳秒() / 1000;
    	船外控制模式发布者->;发布(信息);
    }
    

    轨迹设置点 提供位置设定点。在这种情况下 x, y, z打呵欠 字段被硬编码为特定值,但它们可以根据算法动态更新,甚至可以通过订阅回调对来自其他节点的消息进行更新。

    /** * @brief 发布轨迹设定点 * 在本例中,它发送了一个轨迹设定点,使 * 载具悬停在 5 米处,偏航角为 180 度。*/
    空白 机外控制::发布轨迹设置点()
    {
    	轨迹设置点 msg{};
    	信息.位置 = {0.0, 0.0, -5.0};
    	信息.打呵欠 = -3.14; // [-PI:PI]
    	信息.时戳 = ->;获取时钟()->;现在().纳秒() / 1000;
    	轨迹设定点发布者->;发布(信息);
    }
    

    publish_vehicle_command() 发送 载具指令 信息,向飞行控制器发出指令。我们在上面使用它将模式更改为离机模式,在 arm() 上膛载具。虽然我们不称 解除警报() 在本例中,它也用于该函数的实现。

    /** * @brief 发布载具命令 * @param command 命令代码(与 VehicleCommand 和 MAVLink MAV_CMD 代码匹配) * @param param1 命令参数 1 * @param param2 命令参数 2 */
    空白 机外控制::发布载具命令(uint16_t 指挥部, 浮动 参数1, 浮动 参数2)
    {
    	载具指令 msg{};
    	信息.参数1 = 参数1;
    	信息.参数2 = 参数2;
    	信息.指挥部 = 指挥部;
    	信息.目标系统 = 1;
    	信息.目标组件 = 1;
    	信息.源系统 = 1;
    	信息.源组件 = 1;
    	信息.来自外部 = ;
    	信息.时戳 = ->;获取时钟()->;现在().纳秒() / 1000;
    	载具命令发布者->;发布(信息);
    }
    

    备注

    载具指令 是指挥 PX4 最简单、最强大的方法之一,通过订阅 载具指令应答 还可以确认特定命令的设置是否成功。参数和命令字段映射到 MAVLink 命令 (打开新窗口) 及其参数值。