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系列研读

  • 13
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的三层架构DAL代码示例: 1. 数据访问层接口 ```csharp public interface IProductRepository { IEnumerable<Product> GetAllProducts(); Product GetProductById(int id); void AddProduct(Product product); void UpdateProduct(Product product); void DeleteProduct(int id); } ``` 2. 数据访问层实现 ```csharp public class ProductRepository : IProductRepository { private readonly IDbConnection _connection; public ProductRepository(IDbConnection connection) { _connection = connection; } public IEnumerable<Product> GetAllProducts() { return _connection.Query<Product>(&quot;SELECT * FROM Products&quot;); } public Product GetProductById(int id) { return _connection.QuerySingle<Product>(&quot;SELECT * FROM Products WHERE Id = @Id&quot;, new { Id = id }); } public void AddProduct(Product product) { _connection.Execute(&quot;INSERT INTO Products (Name, Price) VALUES (@Name, @Price)&quot;, product); } public void UpdateProduct(Product product) { _connection.Execute(&quot;UPDATE Products SET Name = @Name, Price = @Price WHERE Id = @Id&quot;, product); } public void DeleteProduct(int id) { _connection.Execute(&quot;DELETE FROM Products WHERE Id = @Id&quot;, new { Id = id }); } } ``` 3. 依赖注入配置 ```csharp services.AddTransient<IDbConnection>(sp => new SqlConnection(Configuration.GetConnectionString(&quot;Default&quot;))); services.AddTransient<IProductRepository, ProductRepository>(); ``` 上述代码中,数据访问层接口定义了对产品实体进行增删改查的方法;数据访问层实现通过连接到数据库并执行SQL语句来实现接口的方法;依赖注入配置将数据访问层接口与具体实现关联起来,使其可以在应用程序中被使用。注意,这里使用了Dapper库来简化数据访问层的实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值