事件接口
PX4 v1.13事件接口 为事件通知提供了一个全系统范围的 API。这些事件通过 MAVLink 事件服务 发布到地面控制站(GCS)(也可发布到其他组件),同时会存储在 系统日志 中。
该接口可用于发布状态变化或其他类型事件的通知,例如解锁准备就绪、校准完成以及达到目标起飞高度等。
INFO
在 PX4 v1.13 及更高版本中,事件接口将取代 PX4 代码中 mavlink_log_*
调用(以及 MAVLink 中的 STATUS_TEXT
消息)来进行事件通知。在过渡期间,两种方法都会被支持。
用法
基本用法
要使用该 API,需包含以下头文件:
#include <px4_platform_common/events.h>
然后在所需的代码位置定义并发送事件:
events::send(events::ID("mymodule_test"), events::Log::Info, "Test Message");
向后兼容性
对于不支持事件接口的旧版本地面控制站,PX4 目前会将所有事件也作为 mavlink_log_*
STATUSTEXT
消息发送出去。此外,消息必须以追加的制表符 (\t
) 标记,以便新版本的地面控制站可以忽略该消息,只显示事件。
因此,每当添加一个事件时,务必同时添加一个 mavlink_log_
调用。例如:
mavlink_log_info(mavlink_log_pub, "Test Message\t");
events::send(events::ID("mymodule_test"), events::Log::Info, "Test Message");
在下一个版本发布后,所有此类 mavlink_log_
调用将被移除。
详细用法
上述是一个最小化的示例,下面是一个更详细的示例:
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
。
- 有效的日志级别与 MAVLink MAV_SEVERITY 枚举中使用的级别相同。按重要性降序排列如下:
事件消息:
- 事件的单行简短消息。它可能包含用于插入参数的模板占位符(例如
{1}
)。更多信息请见下文。
- 事件的单行简短消息。它可能包含用于插入参数的模板占位符(例如
事件描述:
- 详细的可选事件描述。
- 可以是多行/段落。
- 它可能包含用于插入参数的模板占位符(例如
{2}
)和支持的标签(见下文)。
参数和枚举
事件可以有一组固定的参数,这些参数可以使用模板占位符插入到消息或描述中(例如 {2:.1m}
- 见下一节)。
有效类型包括:uint8_t
、int8_t
、uint16_t
、int16_t
、uint32_t
、int32_t
、uint64_t
、int64_t
和 float
。
也可以使用枚举作为参数:
- 用于事件的 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 元数据(翻译与发布)。