Skip to content

事件接口

PX4 v1.13

事件接口 为事件通知提供了一个全系统范围的 API。这些事件通过 MAVLink 事件服务 发布到地面控制站(GCS)(也可发布到其他组件),同时会存储在 系统日志 中。

该接口可用于发布状态变化或其他类型事件的通知,例如解锁准备就绪、校准完成以及达到目标起飞高度等。

INFO

在 PX4 v1.13 及更高版本中,事件接口将取代 PX4 代码中 mavlink_log_* 调用(以及 MAVLink 中的 STATUS_TEXT 消息)来进行事件通知。在过渡期间,两种方法都会被支持

用法

基本用法

要使用该 API,需包含以下头文件:

cpp
#include <px4_platform_common/events.h>

然后在所需的代码位置定义并发送事件:

cpp
events::send(events::ID("mymodule_test"), events::Log::Info, "Test Message");

向后兼容性

对于不支持事件接口的旧版本地面控制站,PX4 目前会将所有事件也作为 mavlink_log_* STATUSTEXT 消息发送出去。此外,消息必须以追加的制表符 (\t) 标记,以便新版本的地面控制站可以忽略该消息,只显示事件。

因此,每当添加一个事件时,务必同时添加一个 mavlink_log_ 调用。例如:

cpp
mavlink_log_info(mavlink_log_pub, "Test Message\t");
events::send(events::ID("mymodule_test"), events::Log::Info, "Test Message");

在下一个版本发布后,所有此类 mavlink_log_ 调用将被移除。

详细用法

上述是一个最小化的示例,下面是一个更详细的示例:

cpp
uint8_t arg1 = 0;
float arg2 = -1.f;
/* EVENT
 * @description
 * 这是详细的事件描述。
 *
 * - arg1 的值: {1}
 * - arg2 的值: {2:.1}
 *
 * <profile name="dev">
 * (这段话仅用于向开发者展示)
 * 此行为可以通过参数 <param>COM_EXAMPLE</param> 进行配置。
 * </profile>
 *
 * 文档链接: <a>https://docs.px4.io</a>
 */
events::send<uint8_t, float>(events::ID("event_name"),
    {events::Log::Error, events::LogInternal::Info}, "Event Message", arg1, arg2);

解释和要求如下:

  • /* EVENT:此标签表示注释定义了后续事件的元数据。

  • 事件名称:即 events::ID(event_name)

    • 在 PX4 的整个源代码中必须唯一。一般惯例是,在名称前加上模块名称,对于较大的模块则加上源文件名称。
    • 必须是有效的变量名,即不能包含空格、冒号等。
    • 通过哈希函数从该名称派生一个 24 位的事件 ID。这意味着只要事件名称不变,ID 也将保持不变。
  • 日志级别

    • 有效的日志级别与 MAVLink MAV_SEVERITY 枚举中使用的级别相同。按重要性降序排列如下:
      plain
      Emergency,
      Alert,
      Critical,
      Error,
      Warning,
      Notice,
      Info,
      Debug,
      Disabled,
    • 上面我们指定了单独的外部和内部日志级别,分别是显示给地面控制站用户和日志文件中的级别:{events::Log::Error, events::LogInternal::Info}。在大多数情况下,可以传递一个单一的日志级别,该级别将同时用于外部和内部情况。在某些情况下,设置两个不同的日志级别是有意义的。例如,返航(RTL)故障安全动作:用户应将其视为警告/错误,而在日志中,它是预期的系统响应,因此可以设置为 Info
  • 事件消息

    • 事件的单行简短消息。它可能包含用于插入参数的模板占位符(例如 {1})。更多信息请见下文。
  • 事件描述

    • 详细的可选事件描述。
    • 可以是多行/段落。
    • 它可能包含用于插入参数的模板占位符(例如 {2})和支持的标签(见下文)。

参数和枚举

事件可以有一组固定的参数,这些参数可以使用模板占位符插入到消息或描述中(例如 {2:.1m} - 见下一节)。

有效类型包括:uint8_tint8_tuint16_tint16_tuint32_tint32_tuint64_tint64_tfloat

也可以使用枚举作为参数:

  • 用于事件的 PX4 特定/自定义枚举应在 src/lib/events/enums.json 中定义,然后可以以 events::send<events::px4::enums::my_enum_t>(...) 的形式用作事件参数。
  • MAVLink “通用” 事件在 mavlink/libevents/events/common.json 中定义,可以以 events::send<events::common::enums::my_enum_t>(...) 的形式用作事件参数。

文本格式

事件消息描述的文本格式如下:

  • 字符可以用 \ 进行转义。 需要转义的字符有:'\\\\''\\<''\\{'

  • 支持的标签:

    • 配置文件:<profile name="[!]NAME">CONTENT</profile> 只有当名称与配置的配置文件匹配时,CONTENT 才会显示。例如,这可用于向最终用户隐藏开发者信息。
    • URL:<a [href="URL"]>CONTENT</a>。 如果未设置 href,则使用 CONTENT 作为 URL(即 <a>https://docs.px4.io</a> 会被解释为 <a href="https://docs.px4.io">https://docs.px4.io</a>
    • 参数:<param>PARAM_NAME</param>
    • 不允许嵌套相同类型的标签。
  • 参数:遵循 Python 语法的模板占位符,索引从 1 开始(而不是 0)。

    • 通用形式:{ARG_IDX[:.NUM_DECIMAL_DIGITS][UNIT]}单位
      • m:水平距离,单位为米
      • m_v:垂直距离,单位为米
      • m^2:面积,单位为平方米
      • m/s:速度,单位为米/秒
      • C:温度,单位为摄氏度
    • NUM_DECIMAL_DIGITS 仅对实数参数有意义。

日志

事件根据内部日志级别进行记录,飞行回顾 会显示这些事件。

INFO

飞行回顾会根据 PX4 主分支下载元数据,因此如果某个定义尚未合并到主分支,它将只能显示事件 ID。

实现

在 PX4 构建过程中,编译器只会将代码(即事件 ID、日志级别和任何参数)直接添加到二进制文件中。

所有事件的元数据会被构建到一个单独的 JSON 元数据文件中(使用一个 Python 脚本扫描整个源代码中的事件调用)。

向地面控制站发布事件元数据

事件元数据 JSON 文件会被编译到固件中(和/或托管在互联网上),并通过 MAVLink 组件元数据服务 提供给地面控制站。这确保了元数据始终与飞行器上运行的代码保持最新。

此过程与 参数元数据 的发布过程相同。更多信息请参阅 PX4 元数据(翻译与发布)