ArduPilot开源代码之AP_DAL_Baro
1. 源由
AP_DAL_Baro
主要功能是模拟气压计接口,并提供了获取传感器数据和处理消息的方法。
它使用了结构体 _RBRH
和 _RBRI
来存储传感器的重要信息,并通过公共方法来访问这些信息。
2. 框架设计
2.1 类定义和成员变量
class AP_DAL_Baro {
public:
// methods so we look like AP_Baro:
// 获取主传感器编号
uint8_t get_primary() const {
return _RBRH.primary;
}
// 获取传感器实例数
uint8_t num_instances() const {
return _RBRH.num_instances;
}
// 检查传感器健康状态
bool healthy(uint8_t sensor_id) const {
return _RBRI[sensor_id].healthy;
}
// 获取指定传感器最后更新时间(毫秒)
uint32_t get_last_update(uint8_t sensor_id) const {
return _RBRI[sensor_id].last_update_ms;
}
// 获取主传感器最后更新时间(毫秒)
uint32_t get_last_update() const {
return get_last_update(get_primary());
}
// 获取指定传感器海拔高度
float get_altitude(uint8_t sensor_id) const {
return _RBRI[sensor_id].altitude;
}
// 获取主传感器海拔高度
float get_altitude() const {
return get_altitude(get_primary());
}
// update_calibration 在回放中是一个空操作,因为它只是修改数据
// 而我们将记录这些数据以输入到扩展卡尔曼滤波器(EKF)中。
void update_calibration();
// methods for being part of AP_DAL:
// 构造函数
AP_DAL_Baro();
// 开始帧
void start_frame();
// 处理消息:处理 log_RBRH 类型的消息
void handle_message(const log_RBRH &msg) {
_RBRH = msg;
}
// 处理消息:处理 log_RBRI 类型的消息
void handle_message(const log_RBRI &msg) {
_RBRI[msg.instance] = msg;
}
private:
// 内部结构体定义
struct log_RBRH _RBRH;
struct log_RBRI _RBRI[BARO_MAX_INSTANCES];
};
这段代码定义了一个类 AP_DAL_Baro
,用于模拟某种气压计的接口。让我们逐段分析它:
2.2 Public 成员函数
uint8_t get_primary() const
: 返回主传感器的编号。uint8_t num_instances() const
: 返回传感器实例的数量。bool healthy(uint8_t sensor_id) const
: 检查特定传感器的健康状态。uint32_t get_last_update(uint8_t sensor_id) const
: 返回特定传感器的最后更新时间(毫秒)。uint32_t get_last_update() const
: 返回主传感器的最后更新时间(毫秒)。float get_altitude(uint8_t sensor_id) const
: 返回特定传感器的海拔高度。float get_altitude() const
: 返回主传感器的海拔高度。
2.3 Private 成员函数
void update_calibration()
: 在回放时是一个空操作,因为它仅修改数据以记录到扩展卡尔曼滤波器(EKF)中。
2.4 Public 方法
AP_DAL_Baro()
: 构造函数,可能用于初始化类的成员变量。void start_frame()
: 开始帧,可能是某种数据处理的初始化操作。
2.5 消息处理方法
void handle_message(const log_RBRH &msg)
: 处理log_RBRH
类型的消息,将消息内容保存到_RBRH
成员变量中。void handle_message(const log_RBRI &msg)
: 处理log_RBRI
类型的消息,根据消息的实例号将消息内容保存到_RBRI
数组中的对应位置。
2.6 Private 成员变量
_RBRH
: 类型为log_RBRH
的结构体变量,保存主传感器的信息。_RBRI
: 类型为log_RBRI
的结构体数组,保存多个传感器实例的信息,数组大小由BARO_MAX_INSTANCES
定义。
3. 重要例程
3.1 重要函数
3.1.1 get_primary
获取主气压传感器实例
uint8_t get_primary() const {
return _RBRH.primary;
}
3.1.2 num_instances
获取气压传感器实例数量
uint8_t num_instances() const {
return _RBRH.num_instances;
}
3.1.3 healthy
获取指定气压传感器健康度
bool healthy(uint8_t sensor_id) const {
return _RBRI[sensor_id].healthy;
}
3.1.4 get_last_update
获取指定气压计最近更新时间 或 主气压计最近更新时间
uint32_t get_last_update(uint8_t sensor_id) const {
return _RBRI[sensor_id].last_update_ms;
}
uint32_t get_last_update() const {
return get_last_update(get_primary());
}
3.1.5 get_altitude
获取指定气压计指示高度 或 主气压计指示高度
float get_altitude(uint8_t sensor_id) const {
return _RBRI[sensor_id].altitude;
}
float get_altitude() const {
return get_altitude(get_primary());
}
3.2 其他函数
3.2.1 AP_DAL_Baro
构造函数,初始化气压计序号
AP_DAL_Baro::AP_DAL_Baro()
{
for (uint8_t i=0; i<BARO_MAX_INSTANCES; i++) {
_RBRI[i].instance = i;
}
}
3.2.2 update_calibration
校准气压计
void AP_DAL_Baro::update_calibration()
{
AP::baro().update_calibration();
}
3.2.3 start_frame
AP_DAL::start_frame
└──> AP_DAL_Baro::start_frame
void AP_DAL_Baro::start_frame()
{
const auto &baro = AP::baro();
const log_RBRH old_RBRH = _RBRH;
_RBRH.primary = baro.get_primary();
_RBRH.num_instances = baro.num_instances();
WRITE_REPLAY_BLOCK_IFCHANGED(RBRH, _RBRH, old_RBRH);
for (uint8_t i=0; i<_RBRH.num_instances; i++) {
log_RBRI &RBRI = _RBRI[i];
log_RBRI old = RBRI;
RBRI.last_update_ms = baro.get_last_update(i);
RBRI.healthy = baro.healthy(i);
RBRI.altitude = baro.get_altitude(i);
WRITE_REPLAY_BLOCK_IFCHANGED(RBRI, _RBRI[i], old);
}
}
3.2.4 handle_message
AP_DAL::handle_message
└──> AP_DAL_Baro::handle_message
void handle_message(const log_RBRH &msg) {
_RBRH = msg;
}
void handle_message(const log_RBRI &msg) {
_RBRI[msg.instance] = msg;
}
4. 总结
AP_DAL_Baro
主要功能是模拟气压计接口,并提供访问接口进行直接状态访问。
5. 参考资料
【1】ArduPilot开源飞控系统之简单介绍
【2】ArduPilot之开源代码Task介绍
【3】ArduPilot飞控启动&运行过程简介
【4】ArduPilot之开源代码Library&Sketches设计
【5】ArduPilot之开源代码Sensor Drivers设计
【6】ArduPilot开源代码之EKF系列研读