跳至内容

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 开发环境的源代码导入当前终端,并使用以下命令编译工作区 胶管:

  6. 资料来源 local_setup.bash:

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

    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 节点中的主循环旋转实现了所需的行为:

cpp
汽车 定时器回调 = []() ->; 空白 {

	如果 (offboard_setpoint_counter_ == 10) {
		// 10 个设定点后改为离板模式
->;发布载具命令(载具指令:: vehicle_cmd_do_set_mode、 1, 6);

		// 解除载具上膛
->;上膛();
	}

	// OffboardControlMode 需要与 TrajectorySetpoint 配对
	发布控制模式();
	发布轨迹设置点();

	// 计数器运行到 11 时停止
	如果 (offboard_setpoint_counter_ <; 11) {
		离板设定点计数器++;
	}
};
定时器 =->;创建隔离墙计时器(100毫秒, timer_callback);

循环在一个 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 类型 在这里,我们只使用机载控制装置。在这里,我们只使用 位置控制因此 位置 字段设置为 而所有其他字段都设置为 错误.

cpp
/**
 * @brief 发布机外控制模式。
 * 在本示例中,只有位置和高度控制处于激活状态。
 */
空白 机外控制::发布控制模式()
{
	离机控制模式 msg{};
	msg.position =;
	msg.velocity = 错误;
	msg.acceleration = 错误;
	msg.attitude = 错误;
	msg.body_rate = 错误;
	msg.thrust_and_torque = 错误;
	msg.direct_actuator = 错误;
	msg.timestamp =->;获取时钟()->;现在().纳秒() / 1000;
	offboard_control_mode_publisher_->;发布(毫秒);
}

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

cpp
/**
 * @brief 发布轨迹设定点
 * 在这个例子中,它发送了一个轨迹设定点,使
 * 载具在 5 米处悬停,偏航角为 180 度。
 */
空白 机外控制::发布轨迹设置点()
{
	轨迹设置点 msg{};
	msg.position = {0.0, 0.0, -5.0};
	msg.yaw = -3.14; // [-PI:PI]
	msg.timestamp =->;获取时钟()->;现在().纳秒() / 1000;
	trajectory_setpoint_publisher_->;发布(毫秒);
}

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

cpp
/**
 * @brief 发布载具指令
 * @ 参数 指挥部   命令代码(与 VehicleCommand 和 MAVLink MAV_CMD 代码匹配)
 * @ 参数 参数1    命令参数 1
 * @ 参数 参数2    命令参数 2
 */
空白 机外控制::发布载具命令(uint16_t 指挥部, 浮动 参数1, 浮动 参数2)
{
	载具指令 msg{};
	msg.param1 = 参数1;
	msg.param2 = 参数 2;
	msg.command = 指挥;
	msg.target_system = 1;
	msg.target_comonent = 1;
	msg.source_system = 1;
	msg.source_component = 1;
	msg.from_external =;
	msg.timestamp =->;获取时钟()->;现在().纳秒() / 1000;
	vehicle_command_publisher_->;发布(毫秒);
}

信息

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