ArduPilot开源代码之AP_DAL_GPS

1. 源由

AP_DAL_GPS主要功能是处理和管理GPS数据,并处理不同类型的消息,以更新GPS状态和相关信息。

2. 框架设计

2.1 类和枚举定义

class AP_DAL_GPS {
public:

    /// GPS status codes
    enum GPS_Status : uint8_t {
        NO_GPS = GPS_FIX_TYPE_NO_GPS,                     ///< 无GPS连接/检测
        NO_FIX = GPS_FIX_TYPE_NO_FIX,                     ///< 接收到有效的GPS消息但没有锁定
        GPS_OK_FIX_2D = GPS_FIX_TYPE_2D_FIX,              ///< 接收到有效的消息并且2D锁定
        GPS_OK_FIX_3D = GPS_FIX_TYPE_3D_FIX,              ///< 接收到有效的消息并且3D锁定
        GPS_OK_FIX_3D_DGPS = GPS_FIX_TYPE_DGPS,           ///< 接收到有效的消息并且3D锁定,具有差分改进
        GPS_OK_FIX_3D_RTK_FLOAT = GPS_FIX_TYPE_RTK_FLOAT, ///< 接收到有效的消息并且3D RTK浮动
        GPS_OK_FIX_3D_RTK_FIXED = GPS_FIX_TYPE_RTK_FIXED, ///< 接收到有效的消息并且3D RTK固定
    };
  • AP_DAL_GPS 类:用于GPS数据的处理和管理。
  • GPS_Status 枚举:定义了不同的GPS状态,如无GPS、无锁定、2D锁定、3D锁定等。

2.2 构造函数

    AP_DAL_GPS();
  • 默认构造函数。

2.3 状态方法

  • status(uint8_t sensor_id):返回指定传感器的GPS状态。
  • status():返回主传感器的GPS状态。

2.4 位置和速度方法

  • location(uint8_t instance):返回指定实例的位置信息。
  • location():返回主传感器的位置信息。
  • velocity(uint8_t instance):返回指定实例的速度信息。
  • velocity():返回主传感器的速度信息。

2.5 其他方法

  • 提供了对各种GPS数据的访问,如垂直速度、水平精度、垂直精度、HDOP、最后消息时间、卫星数量、滞后时间、速度精度和GPS航向角度等。

2.6 消息处理

  • handle_message(const log_RGPH &msg):处理 log_RGPH 类型的消息。
  • handle_message(const log_RGPI &msg):处理 log_RGPI 类型的消息。
  • handle_message(const log_RGPJ &msg):处理 log_RGPJ 类型的消息,并更新临时位置数据。

2.7 私有成员变量

  • 这些私有成员变量用于存储GPS数据,包括日志结构 _RGPH_RGPI_RGPJ,以及临时位置数组 tmp_location

3. 重要例程

3.1 构造和状态

3.1.1 AP_DAL_GPS

构造函数,初始化GPS模块序号

AP_DAL_GPS::AP_DAL_GPS()
{
    for (uint8_t i=0; i<ARRAY_SIZE(_RGPI); i++) {
        _RGPI[i].instance = i;
        _RGPJ[i].instance = i;
    }
}

3.1.2 status

获取指定GPS模块状态 或 主GPS模块状态

    GPS_Status status(uint8_t sensor_id) const {
        return (GPS_Status)_RGPI[sensor_id].status;
    }
    GPS_Status status() const {
        return status(primary_sensor());
    }

3.1.3 primary_sensor

获取主GPS模块传感器序号

    uint8_t primary_sensor(void) const {
        return _RGPH.primary_sensor;
    }

3.2 位置和速度

3.2.1 location

获取指定GPS模块位置信息 或 主GPS模块位置信息

    const Location &location(uint8_t instance) const {
        return tmp_location[instance];
    }

    // TODO: decide if this really, really should be here!
    const Location &location() const {
        return location(_RGPH.primary_sensor);
    }

3.2.2 velocity

获取指定GPS模块速度矢量 或 主GPS模块速度矢量

    const Vector3f &velocity(uint8_t instance) const {
        return _RGPJ[instance].velocity;
    }
    const Vector3f &velocity() const {
        return velocity(primary_sensor());
    }

3.3 辅助函数

3.3.1 have_vertical_velocity

指定GPS模块是否有垂直速度 或 主GPS模块是否有垂直速度

    bool have_vertical_velocity(uint8_t instance) const {
        return _RGPI[instance].have_vertical_velocity;
    }
    bool have_vertical_velocity() const {
        return have_vertical_velocity(primary_sensor());
    }

3.3.2 horizontal_accuracy

获取指定GPS模块水平精度 或 主GPS模块水平精度

    bool horizontal_accuracy(uint8_t instance, float &hacc) const {
        hacc = _RGPJ[instance].hacc;
        return _RGPI[instance].horizontal_accuracy_returncode;
    }
    bool horizontal_accuracy(float &hacc) const {
        return horizontal_accuracy(primary_sensor(),hacc);
    }

3.3.3 vertical_accuracy

获取指定GPS模块垂直精度 或 主GPS模块垂直精度

    bool vertical_accuracy(uint8_t instance, float &vacc) const {
        vacc = _RGPJ[instance].vacc;
        return _RGPI[instance].vertical_accuracy_returncode;
    }
    bool vertical_accuracy(float &vacc) const {
        return vertical_accuracy(primary_sensor(), vacc);
    }

3.3.4 get_hdop

获取指定GPS模块HDOP值 或 主GPS模块HDOP值

    uint16_t get_hdop(uint8_t instance) const {
        return _RGPJ[instance].hdop;
    }
    uint16_t get_hdop() const {
        return get_hdop(primary_sensor());
    }

3.3.5 last_message_time_ms

获取最近一次消息的时间戳

    uint32_t last_message_time_ms(uint8_t instance) const {
        return _RGPJ[instance].last_message_time_ms;
    }

3.3.6 num_sats

获取指定GPS模块卫星数量 或 主GPS模块卫星数量

    uint8_t num_sats(uint8_t instance) const {
        return _RGPI[instance].num_sats;
    }
    uint8_t num_sats() const {
        return num_sats(primary_sensor());
    }

3.3.7 get_lag

获取指定GPS模块滞后时间 或 主GPS模块滞后时间

    bool get_lag(uint8_t instance, float &lag_sec) const {
        lag_sec = _RGPI[instance].lag_sec;
        return _RGPI[instance].get_lag_returncode;
    }
    bool get_lag(float &lag_sec) const {
        return get_lag(primary_sensor(), lag_sec);
    }

3.3.8 speed_accuracy

获取指定GPS模块速度精度 或 主GPS模块速度精度

    bool speed_accuracy(uint8_t instance, float &sacc) const {
        sacc = _RGPJ[instance].sacc;
        return _RGPI[instance].speed_accuracy_returncode;
    }
    bool speed_accuracy(float &sacc) const {
        return speed_accuracy(primary_sensor(), sacc);
    }

3.3.9 num_sensors

获取GPS模块数量

    uint8_t num_sensors(void) const {
        return _RGPH.num_sensors;
    }

3.3.10 gps_yaw_deg

获取指定GPS模块yaw角度

    bool gps_yaw_deg(uint8_t instance, float &yaw_deg, float &accuracy_deg, uint32_t &time_ms) const {
        yaw_deg = _RGPJ[instance].yaw_deg;
        accuracy_deg = _RGPJ[instance].yaw_accuracy_deg;
        time_ms = _RGPJ[instance].yaw_deg_time_ms;
        return _RGPI[instance].gps_yaw_deg_returncode;
    }

3.3.11 get_antenna_offset

获取指定GPS模块位置相对偏移

    // return a 3D vector defining the offset of the GPS antenna in meters relative to the body frame origin
    const Vector3f &get_antenna_offset(uint8_t instance) const {
        return _RGPI[instance].antenna_offset;
    }

3.4 其他函数

3.4.1 start_frame

AP_DAL::start_frame
 └──> AP_DAL_GPS::start_frame
void AP_DAL_GPS::start_frame()
{
    // 获取GPS对象
    const auto &gps = AP::gps();

    // 备份旧的RGPH日志
    const log_RGPH old_RGPH = _RGPH;
    // 更新RGPH中的主传感器和传感器数量
    _RGPH.primary_sensor = gps.primary_sensor();
    _RGPH.num_sensors = gps.num_sensors();

    // 如果RGPH发生变化,写入重放块
    WRITE_REPLAY_BLOCK_IFCHANGED(RGPH, _RGPH, old_RGPH);

    // 遍历所有GPS传感器
    for (uint8_t i=0; i<ARRAY_SIZE(_RGPI); i++) {
        log_RGPI &RGPI = _RGPI[i];  // 获取当前传感器的RGPI日志
        log_RGPJ &RGPJ = _RGPJ[i];  // 获取当前传感器的RGPJ日志
        const log_RGPI old_RGPI = RGPI;  // 备份旧的RGPI日志
        const log_RGPJ old_RGPJ = RGPJ;  // 备份旧的RGPJ日志

        // 更新RGPI和RGPJ中的数据
        RGPI.status = (GPS_Status)gps.status(i);  // 更新传感器状态
        RGPI.antenna_offset = gps.get_antenna_offset(i);  // 更新天线偏移

        const Location &loc = gps.location(i);  // 获取传感器位置
        RGPJ.last_message_time_ms = gps.last_message_time_ms(i);  // 更新最后消息时间
        RGPJ.lat = loc.lat;  // 更新纬度
        RGPJ.lng = loc.lng;  // 更新经度
        RGPJ.alt = loc.alt;  // 更新高度
        RGPI.have_vertical_velocity = gps.have_vertical_velocity(i);  // 更新是否有垂直速度

        // 更新水平和垂直精度
        RGPI.horizontal_accuracy_returncode = gps.horizontal_accuracy(i, RGPJ.hacc);
        RGPI.vertical_accuracy_returncode = gps.vertical_accuracy(i, RGPJ.vacc);
        RGPJ.hdop = gps.get_hdop(i);  // 更新HDOP
        RGPI.num_sats = gps.num_sats(i);  // 更新卫星数量
        RGPI.get_lag_returncode = gps.get_lag(i, RGPI.lag_sec);  // 更新延迟

        RGPJ.velocity = gps.velocity(i);  // 更新速度
        RGPI.speed_accuracy_returncode = gps.speed_accuracy(i, RGPJ.sacc);  // 更新速度精度
        RGPI.gps_yaw_deg_returncode = gps.gps_yaw_deg(i, RGPJ.yaw_deg, RGPJ.yaw_accuracy_deg, RGPJ.yaw_deg_time_ms);  // 更新航向角

        // 如果RGPI和RGPJ发生变化,写入重放块
        WRITE_REPLAY_BLOCK_IFCHANGED(RGPI, RGPI, old_RGPI);
        WRITE_REPLAY_BLOCK_IFCHANGED(RGPJ, RGPJ, old_RGPJ);

        // 更新临时位置
        tmp_location[i].lat = RGPJ.lat;
        tmp_location[i].lng = RGPJ.lng;
        tmp_location[i].alt = RGPJ.alt;
    }
}

3.4.2 handle_message

AP_DAL::handle_message
 └──> AP_DAL_Baro::handle_message
    void handle_message(const log_RGPH &msg) {
        _RGPH = msg;
    }
    void handle_message(const log_RGPI &msg) {
        _RGPI[msg.instance] = msg;
    }
    void handle_message(const log_RGPJ &msg) {
        _RGPJ[msg.instance] = msg;

        tmp_location[msg.instance].lat = msg.lat;
        tmp_location[msg.instance].lng = msg.lng;
        tmp_location[msg.instance].alt = msg.alt;
    }

4. 总结

AP_DAL_GPS主要功能是处理和管理GPS数据,并提供访问接口进行直接状态访问。

5. 参考资料

【1】ArduPilot开源飞控系统之简单介绍
【2】ArduPilot之开源代码Task介绍
【3】ArduPilot飞控启动&运行过程简介
【4】ArduPilot之开源代码Library&Sketches设计
【5】ArduPilot之开源代码Sensor Drivers设计
【6】ArduPilot开源代码之EKF系列研读

相关推荐

  1. ArduPilot源代码AP_MSP

    2024-07-17 18:44:04       28 阅读
  2. ArduPilot源代码AP_OpticalFlow_MSP

    2024-07-17 18:44:04       26 阅读
  3. ArduPilot源代码AP_OpticalFlow_UPFLOW

    2024-07-17 18:44:04       25 阅读
  4. ArduPilot源代码AP_OpticalFlow_CXOF

    2024-07-17 18:44:04       32 阅读
  5. ArduPilot源代码OpticalFlow_backend

    2024-07-17 18:44:04       27 阅读
  6. ArduPilot源代码AP_AHRS_View

    2024-07-17 18:44:04       22 阅读
  7. ArduPilot源代码AP_DAL_GPS

    2024-07-17 18:44:04       23 阅读
  8. ArduPilot源代码AP_DAL_RangeFinder

    2024-07-17 18:44:04       22 阅读
  9. ArduPilot源代码AP_DAL研读系列

    2024-07-17 18:44:04       20 阅读
  10. ArduPilot开源飞控AP_VisualOdom

    2024-07-17 18:44:04       21 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-17 18:44:04       101 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-17 18:44:04       109 阅读
  3. 在Django里面运行非项目文件

    2024-07-17 18:44:04       87 阅读
  4. Python语言-面向对象

    2024-07-17 18:44:04       96 阅读

热门阅读

  1. 江苏服务器租用:算力服务器适用于哪些场景?

    2024-07-17 18:44:04       24 阅读
  2. C语言求阶乘

    2024-07-17 18:44:04       20 阅读
  3. 力扣每日一题:2956. 找到两个数组中的公共元素

    2024-07-17 18:44:04       29 阅读
  4. 星月工作室信息组团队/XYOI

    2024-07-17 18:44:04       29 阅读
  5. EXIT_SUCCESS、EXIT_FAILURE、return的区别和用法

    2024-07-17 18:44:04       26 阅读
  6. 07 - FFmpeg 更改视频分辨率 - 保存 yuv420p

    2024-07-17 18:44:04       23 阅读
  7. Nacos 服务发现(订阅)源码分析(客户端)

    2024-07-17 18:44:04       21 阅读
  8. Flask核心面试题

    2024-07-17 18:44:04       24 阅读
  9. opencv—常用函数学习_“干货“_8

    2024-07-17 18:44:04       28 阅读
  10. QT QGridLayout设置网格间距以及边框的颜色

    2024-07-17 18:44:04       23 阅读