PX4模块设计之十四:Event设计
Posted lida2003
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PX4模块设计之十四:Event设计相关的知识,希望对你有一定的参考价值。
PX4模块设计之十四:Event设计
事件接口将事件uORB消息发布到系统内,其主要作用是通过MAVLink传输层,将消息发送到GCS和其他组件。该接口可用于发布状态变化或任何其他类型事件的事件,包括待命准备、校准完成和达到目标起飞高度等。
PX4系统里面将这部分内容抽象出一个模块libevents,并在repo上通过submodule的方式引入,体现了设计的模块化。
[submodule "src/lib/events/libevents"]
path = src/lib/events/libevents
url = https://github.com/mavlink/libevents.git
1. Event主要接口
- event_name: the event name (events::ID(event_name)) 在PX4的整个源代码中必须是唯一的。一般来说,在其前面加上模块名,或较大模块的源文件。
- Log Level
Emergency,
Alert,
Critical,
Error,
Warning,
Notice,
Info,
Debug,
Disabled,
- Event Message 单行短字符串。它可能包含参数的模板占位符。
- Arguments and Enums 事件可以有一组固定的参数,这些参数可以使用模板占位符插入到消息或描述中。
1.1 字符串消息接口
platforms\\common\\include\\px4_platform_common\\events.h
inline void send(uint32_t id, const LogLevels &log_levels, const char *message)
EventType e;
e.log_levels = ((uint8_t)log_levels.internal << 4) | (uint8_t)log_levels.external;
e.id = id;
CONSOLE_PRINT_EVENT(e.log_level_external, e.id, message);
send(e);
1.2 参数消息接口
platforms\\common\\include\\px4_platform_common\\events.h
inline void send(uint32_t id, const LogLevels &log_levels, const char *message, Args... args)
EventType e;
e.log_levels = ((uint8_t)log_levels.internal << 4) | (uint8_t)log_levels.external;
e.id = id;
static_assert(util::sizeofArguments(args...) <= sizeof(e.arguments), "Too many arguments");
util::fillEventArguments((uint8_t *)e.arguments, args...);
CONSOLE_PRINT_EVENT(e.log_level_external, e.id, message);
send(e);
1.3 内部uORB实现
platforms\\common\\events.cpp,通过ORB_ID(event)消息发不到系统内部,在GCS代码中订阅该消息,并针EventType进行解析。
void send(EventType &event)
event.timestamp = hrt_absolute_time();
// We need some synchronization here because:
// - modifying orb_event_pub
// - the update of event_sequence needs to be atomic
// - we need to ensure ordering of the sequence numbers: the sequence we set here
// has to be the one published next.
pthread_mutex_lock(&publish_event_mutex);
event.event_sequence = ++event_sequence; // Set the sequence here so we're able to detect uORB queue overflows
if (orb_event_pub != nullptr)
orb_publish(ORB_ID(event), orb_event_pub, &event);
else
orb_event_pub = orb_advertise_queue(ORB_ID(event), &event, event_s::ORB_QUEUE_LENGTH);
pthread_mutex_unlock(&publish_event_mutex);
struct EventType
uint32_t id;
uint8_t log_levels;
uint8_t arguments[40];
;
注:关于uORB和MAVLink详见参考资料,这里不再展开。
2. PX4 Events框架
事件定义由命名空间分隔。每个名称空间都有一个名称和一个8位组件ID(通常与MAVLink组件ID匹配)。在命名空间中,每个事件都有一个唯一的名称和子ID(24位)。事件ID是具有子ID的组合组件ID。因此,可以通过ID或::。
在整合libevents到PX4飞控系统时,通过src/lib/events/CMakeLists.txt将PX4和常用的消息定义从代码和配置转换成jason,以便GCS作为配置输入使用。
总体上,分为两部分:
- 通过配置文件汇总,提供GCS或其他应用程序。
- 通过代码内嵌(未见明显应用,不过如果该消息是飞控内部使用,可以使用该方式)
2.1 配置文件
build/holybro_kakutef7_default/events/all_events.json
├──> build/holybro_kakutef7_default/events/px4.json
│ └──> $all_px4_src_files //PX4工程源代码
└──> build/holybro_kakutef7_default/events/common_with_enums.json
├──> src/lib/events/enums.json
└──> src/lib/events/libevents/events/libevents/events/common.json
2.2 内嵌代码
build/holybro_kakutef7_default/events/events_generated.h
└──> build/holybro_kakutef7_default/events/common_with_enums.json
├──> src/lib/events/enums.json
└──> src/lib/events/libevents/events/common.json
3. 使用方法
注:关于代码中消息将会在CMakeList.txt编译之前转换成jason或者.h文件。(编译工具提供的自动化功能)
3.1 Step 1:包含消息接口头文件
#include <px4_platform_common/events.h>
3.2 Step 2:使用合适的API接口
字符串消息接口
events::send(events::ID("navigator_mis_multi_land"), events::Log::Error, events::LogInternal::Info,
"Mission rejected: more than one land start commands");
或者 参数消息接口
events::send<int32_t, int32_t>(events::ID("navigator_mis_land_approach"), events::Log::Error, events::LogInternal::Info,
"Mission rejected: adjust landing approach",
(int)ceilf(slope_alt_req - missionitem_previous.altitude),
(int)ceilf(wp_distance_req - wp_distance));
3.3 注意事项
- 有效参数类型: uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t and float.
- 枚举类型定义
- PX4和自定义枚举定义:src/lib/events/enums.json
- MAVLink公共事件和枚举定义:mavlink/libevents/events/common.json
- 参数插入事件消息字符串:n
- 事件描述并非必须,如下例子所述
/* EVENT
* @description
* Land immediately and check the system.
*/
events::send<uint8_t, events::px4::enums::sensor_failover_reason_t>(
events::ID("sensor_failover_baro"), events::Log::Emergency, "Baro sensor #1 failure: 2", failover_index,
failover_reason);
- 参数表达方式:ARG_IDX[:.NUM_DECIMAL_DIGITS][UNIT]
m: horizontal distance in meters
m_v: vertical distance in meters
m^2: area in m^2
m/s: speed in m/s
C: temperature in degrees celsius
NUM_DECIMAL_DIGITS only makes sense for real number arguments
4. 参考资料
【1】PX4开源软件框架简明简介
【2】PX4 Events Interface
【3】PX4模块设计之二:uORB消息代理
【4】PX4模块设计之三:自定义uORB消息
【5】PX4模块设计之四:MAVLink简介
【6】PX4模块设计之五:自定义MAVLink消息
以上是关于PX4模块设计之十四:Event设计的主要内容,如果未能解决你的问题,请参考以下文章