# 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.

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.xmldevelopment.xml.无论您使用什么方言文件,最终都必须在 QGroundControl(或您用来与 PX4 通信的任何软件)中构建。

MAVLink 开发人员指南解释了如何在 如何定义 MAVLink 消息和枚举 (打开新窗口).

您可以通过检查编译目录中生成的报文头来检查新报文是否已编译。如果报文没有生成,它们可能格式不正确,或使用了冲突的 ID。请查看编译日志了解相关信息。

备注

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 接收信息并将其发布到 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 连接 PX4 和嵌入式设备时,自动驾驶仪和设备之间交换的信息可能会经过多次反复,才能稳定下来。在这种情况下,重新生成 MAVLink 标头并确保两台设备使用相同版本的协议既耗时又容易出错。

另一个临时解决方案是重新利用调试信息。而不是创建一个自定义的 MAVLink 消息 CA_TRAJECTORY您可以发送信息 DEBUG_VECT 用字符串键 CA_TRAJ 中的数据 x, yz 领域。参见 本教程调试信息的使用示例。

备注

该解决方案通过网络发送字符串并涉及字符串比较,因此效率不高。它只能用于开发!

# 测试

最终,您需要通过提供相应的地面站或 MAVSDK 实现来测试新的 MAVLink 接口是否正常工作。作为第一步,在调试过程中,您通常只想确认您创建的任何信息是否按照您的预期发送/接收。

有几种方法可以用来查看流量:

# 一般情况

# 设置流速率

有时,提高单个主题的流速率(例如在 QGC 中进行检查)非常有用。这可以通过在 shell 中键入以下一行来实现:

mavlink stream -u <;端口号>; -s <;mavlink 主题名称>; -r <;费率>;

您可以使用 mavlink 状态 将输出(其中包括) 传输协议:UDP(<端口号>)。.例如

mavlink stream -u 14556 -s OPTICAL_FLOW_RAD -r 300