# MAVLink 消息传送
MAVLink (打开新窗口) 是一个非常轻量级的消息传输协议,专为无人机生态系统设计。
PX4 的用途 MAVLink 沟通 QGroundControl (和其他地面站),以及作为与飞行控制器以外的无人机组件连接的集成机制:配套计算机、支持 MAVLink 的相机等。
该协议定义了一系列标准 信息 (打开新窗口) 和 微服务 (打开新窗口) 用于交换数据(PX4 中实现了许多(但不是全部)信息/服务)。
本教程介绍如何为自己的新 "custom" 消息添加 PX4 支持。
备注
本教程假定您拥有 自定义 uORB ca_trajectory
信息中 msg/ca_trajectory.msg
和定制的 MAVLink ca_trajectory
信息中 mavlink/include/mavlink/v2.0/custom_messages/mavlink_msg_ca_trajectory.h
.
# 定义自定义 MAVLink 信息
PX4 包括 mavlink/mavlink (打开新窗口) repo 下的一个子模块 /src/modules/mavlink (打开新窗口)并在构建时生成 MAVLink 2 C 头文件。
在 /mavlink/messages/1.0/ (打开新窗口).使用变量 mavlink_dialect
于 /src/modules/mavlink/CMakeLists.txt (打开新窗口)默认为 development.xml (打开新窗口).文件会生成到构建目录中: /build/<build target>/mavlink/
.
为了添加您的信息,我们建议您在同一目录下的新方言文件中创建信息,例如 PX4-Autopilot/src/modules/mavlink/mavlink/message_definitions/v1.0/custom_messages.xml
并设置 mavlink_dialect
来创建新文件。该方言文件应包括 development.xml
.
您也可以将信息添加到 common.xml
或 development.xml
.无论您使用什么方言文件,最终都必须在 QGroundControl(或您用来与 PX4 通信的任何软件)中构建。
MAVLink 开发人员指南解释了如何在 如何定义 MAVLink 消息和枚举 (打开新窗口).
您可以通过检查编译目录中生成的报文头来检查新报文是否已编译。如果报文没有生成,它们可能格式不正确,或使用了冲突的 ID。请查看编译日志了解相关信息。
备注
MAVLink 开发人员指南 (打开新窗口) 有更多关于使用 MAVLink 工具链的信息。
# 发送自定义 MAVLink 信息
本节将介绍如何使用自定义 uORB 信息并将其作为 MAVLink 信息发送。
将 MAVLink 和 uORB 信息的标题添加到 mavlink_messages.cpp (打开新窗口)
#包括 <uORB/topics/ca_trajectory.h>;
#包括 <v2.0/custom_messages/mavlink.h>;
在 mavlink_messages.cpp (打开新窗口)
类 MavlinkStreamCaTrajectory : 公共 MavlinkStream
{
公:
缢 烧焦 *获取名称() 缢
{
返回 MavlinkStreamCaTrajectory::获取静态名称();
}
天电 缢 烧焦 *获取静态名称()
{
返回 "CA_TRAJECTORY";;
}
天电 uint16_t get_id_static()
{
返回 mavlink_msg_id_ca_trajectory;
}
uint16_t 获取()
{
返回 get_id_static();
}
天电 MavlinkStream *新实例(Mavlink *多点连接)
{
返回 新 MavlinkStreamCaTrajectory(多点连接);
}
无符号 get_size()
{
返回 mavlink_msg_id_ca_trajectory_len + mavlink_num_non_payload_bytes;
}
私人:
uORB::订阅 _sub{ORB_ID(ca_trajectory)};
/* 不允许在顶部复制该类 */
MavlinkStreamCaTrajectory(MavlinkStreamCaTrajectory 及样品;);
MavlinkStreamCaTrajectory及样品; 操作员 = (缢 MavlinkStreamCaTrajectory 及样品;);
受保护的:
不含糊 MavlinkStreamCaTrajectory(Mavlink *多点连接) : MavlinkStream(多点连接)
{}
bool 发送() 否决
{
结构 ca_traj_struct_s _CA_轨迹; //确保 ca_traj_struct_s 是你的 uORB 主题的定义
如果 (_子.更新(及样品;_CA_轨迹)) {
mavlink_ca_trajectory_t _msg_ca_轨迹; //确保 mavlink_ca_trajectory_t 是自定义 MAVLink 消息的定义
_msg_ca_轨迹.时戳 = _CA_轨迹.时戳;
_msg_ca_轨迹.开始时间 = _CA_轨迹.开始时间;
_msg_ca_轨迹.停止时间 = _CA_轨迹.停止时间;
_msg_ca_轨迹.系数 =_CA_轨迹.系数;
_msg_ca_轨迹.seq_id = _CA_轨迹.seq_id;
mavlink_msg_ca_trajectory_send_struct(_mavlink->;获取频道(), 及样品;_msg_ca_轨迹);
返回 真;
}
返回 错误;
}
};
最后将流类附加到 流列表
在
mavlink_messages.cpp (打开新窗口)
StreamListItem *流列表[] = {
...
创建流列表项目<;MavlinkStreamCaTrajectory>;(),
...
然后确保启用数据流,例如在 启动脚本 例如 /ROMFS/px4fmu_common/init.d-posix/rcS (打开新窗口) 或 ROMFS/px4fmu_common/init.d-posix/rcS (打开新窗口))对海丰国际信托有限公司的影响。注意 -r
配置流传输速率和 -u
确定 UDP 端口 14556 上的 MAVLink 通道)。
mavlink stream -r 50 -s CA_TRAJECTORY -u 14556
TIP
您可以使用 uorb top [<信息名称>]
命令来实时验证信息是否已发布以及发布率(请参阅 uORB 消息传送).这种方法也可用于测试发布 uORB 主题的传入信息(对于其他信息,可使用 printf
并在 SITL 中进行测试)。
要在 QGroundControl 您需要 用您的 MAVLink 库构建它 (打开新窗口)然后使用 MAVLink 检查器小工具 (打开新窗口) (或其他 MAVLink 工具)。
# 接收自定义 MAVLink 信息
本节介绍如何通过 MAVLink 接收信息并将其发布到 uORB。
添加一个函数,用于在 mavlink_receiver.h (打开新窗口)
#包括 <uORB/topics/ca_trajectory.h>;
#包括 <v2.0/custom_messages/mavlink_msg_ca_trajectory.h>;
添加一个函数,在 MavlinkReceiver
类中
mavlink_receiver.h (打开新窗口)
空白 处理 CA_trajectory_msg 消息(mavlink_message_t *信息);
在 MavlinkReceiver
类中
mavlink_receiver.h (打开新窗口)
uORB::出版物<;ca_trajectory_s>; _ca_traj_msg_pub{ORB_ID(ca_trajectory)};
实施 处理 CA_trajectory_msg 消息
在 mavlink_receiver.cpp (打开新窗口)
空白 MavlinkReceiver::处理 CA_trajectory_msg 消息(mavlink_message_t *信息)
{
mavlink_ca_trajectory_t traj;
mavlink_msg_ca_trajectory_decode(信息, 及样品;traj);
结构 ca_traj_struct_s f;
memset(及样品;f, 0, 尺寸(f));
f.时戳 = hrt_absolute_time();
f.seq_id = traj.seq_id;
f.开始时间 = traj.开始时间;
f.停止时间 = traj.停止时间;
对于(int i=0;i<;28;i++)
f.系数[i] = traj.系数[i];
_ca_traj_msg_pub.发布(f);
}
最后确保在 MavlinkReceiver::handle_message() (打开新窗口)
MavlinkReceiver::处理信息(mavlink_message_t *信息)
{
开关 (信息->;msgstr) {
...
个案 mavlink_msg_id_ca_trajectory:
处理 CA_trajectory_msg 消息(信息);
断裂;
...
}
# 创建自定义 MAVLink 信息的替代方案
有时需要定制 MAVLink 信息,其内容尚未完全定义。
例如,当使用 MAVLink 连接 PX4 和嵌入式设备时,自动驾驶仪和设备之间交换的信息可能会经过多次反复,才能稳定下来。在这种情况下,重新生成 MAVLink 标头并确保两台设备使用相同版本的协议既耗时又容易出错。
另一个临时解决方案是重新利用调试信息。而不是创建一个自定义的 MAVLink 消息 CA_TRAJECTORY
您可以发送信息 DEBUG_VECT
用字符串键 CA_TRAJ
中的数据 x
, y
和 z
领域。参见 本教程调试信息的使用示例。
备注
该解决方案通过网络发送字符串并涉及字符串比较,因此效率不高。它只能用于开发!
# 测试
最终,您需要通过提供相应的地面站或 MAVSDK 实现来测试新的 MAVLink 接口是否正常工作。作为第一步,在调试过程中,您通常只想确认您创建的任何信息是否按照您的预期发送/接收。
有几种方法可以用来查看流量:
- 创建一个 Wireshark MAVLink 插件 (打开新窗口) 为您的方言。这样,您就可以检查 IP 接口上的 MAVLink 流量,例如在 QGroundControl 或 MAVSDK 以及 PX4 的真实或模拟版本。
- 记录 uORB 主题 与您的 MAVLink 信息相关联。
- 在 QGroundControl 中查看收到的信息 MAVLink 检查员 (打开新窗口).要显示信息,您需要 构建 QGroundControl (打开新窗口) 包括一个预建的 C 库,其中包含您自定义的信息。
- QGC 使用一个预建的 C 库,该库必须位于 /qgroundcontrol/libs/mavlink/include/mavlink (打开新窗口) 在 QGC 源代码中。默认情况下,它作为子模块预先包含在 https://github.com/mavlink/c_library_v2 中,但您可以 生成自己的 MAVLink 库 (打开新窗口)
- QGC 默认使用 ArduPilotMega.xml 方言,其中包括 common.xml.您可以在任一文件或自己的方言中加入信息。但是,如果您使用自己的方言,那么它应该包括 ArduPilotMega.xml(否则它将错过所有现有信息),而且您需要在
MAVLINK_CONF
(打开新窗口) 运行时 qmake.
# 一般情况
# 设置流速率
有时,提高单个主题的流速率(例如在 QGC 中进行检查)非常有用。这可以通过在 shell 中键入以下一行来实现:
mavlink stream -u <;端口号>; -s <;mavlink 主题名称>; -r <;费率>;
您可以使用 mavlink 状态
将输出(其中包括) 传输协议:UDP(<端口号>)。
.例如
mavlink stream -u 14556 -s OPTICAL_FLOW_RAD -r 300