• ArduPilot开源飞控之GCS显示DPS310异常问题


    1. 源由

    2020年Ardupilot官网论坛就有开始讨论DPS310芯片在GCS系统上显示为DPS280的问题

    但是直到最近在使用H743飞控板子的时候,发现问题依然存在。初步看了下,不是太复杂的问题,因此进行了一些分析。

    2. 现象

    Mission Planner上显示DPS280芯片。
    在这里插入图片描述

    1. 硬件规格书上是DPS310芯片。
    2. 经飞控板确认,实际使用的是DPS310芯片。

    3. 分析

    这里整体上牵涉Mission Planner和Ardupilot飞控两部分软件代码,所以如果无法正确显示,两部分代码必须一致。

    3.1 Mission Planner

    通过github很快发现该设备类型存在。
    在这里插入图片描述

    3.2 Ardupilot

    通过github也能发现该定义,且与Mission Planner一致。
    在这里插入图片描述

    3.3 AP_Baro分析

    从Mission Planner和Ardupilot在github上的初步定义情况,从框架设计角度考虑,应该已经支持DPS310.

    那么为什么现在有问题???

    进一步搜索代码:

    1. 发现AP_Baro_DPS310 继承自AP_Baro_DPS280
    2. libraries\AP_HAL_ChibiOS\hwdef\H743_BMI270x2_v30\hwdef.h硬件定义AP_Baro_DPS310
    ---- AP_Baro_DPS310 Matches (3 in 3 files) ----
    AP_Baro_DPS280.cpp (libraries\AP_Baro) line 70 : AP_Baro_Backend *AP_Baro_DPS310::probe(AP_Baro &baro,
    AP_Baro_DPS280.h (libraries\AP_Baro) line 68 : class AP_Baro_DPS310 : public AP_Baro_DPS280 {
    hwdef.h (libraries\AP_HAL_ChibiOS\hwdef\H743_BMI270x2_v30) line 232 : #define HAL_BARO_PROBE1  ADD_BACKEND(AP_Baro_DPS310::probe(*this,GET_I2C_DEVICE(0,0x76)))
    
    • 1
    • 2
    • 3
    • 4

    到这里就更加奇怪了,貌似DPS280和DPS310可能差异并不大,而大部分的方法来DPS280。

    libraries\AP_Baro\AP_Baro_DPS280.h给出AP_Baro_DPS310 定义。

    class AP_Baro_DPS310 : public AP_Baro_DPS280 {
        // like DPS280 but workaround for temperature bug
    public:
        using AP_Baro_DPS280::AP_Baro_DPS280;
        static AP_Baro_Backend *probe(AP_Baro &baro, AP_HAL::OwnPtr dev);
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在硬件芯片驱动probe过程,AP_Baro_DPS310会传如一个变量来区分是DPS280还是DPS310芯片。

    libraries\AP_Baro\AP_Baro_DPS280.cpp给出AP_Baro_DPS310::probe 定义。

    AP_Baro_Backend *AP_Baro_DPS310::probe(AP_Baro &baro,
                                           AP_HAL::OwnPtr _dev)
    {
        // same as DPS280 but with is_dps310 set for temperature fix
        return AP_Baro_DPS280::probe(baro, std::move(_dev), true);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    该变量的主要目的是为了解决温度传感器的设置问题。
    libraries\AP_Baro\AP_Baro_DPS280.cpp给出void AP_Baro_DPS280::set_config_registers 定义。

    void AP_Baro_DPS280::set_config_registers(void)
    {
        dev->write_register(DPS280_REG_CREG, 0x0C, true); // shift for 16x oversampling
        dev->write_register(DPS280_REG_PCONF, 0x54, true); // 32 Hz, 16x oversample
        dev->write_register(DPS280_REG_TCONF, 0x54 | calibration.temp_source, true); // 32 Hz, 16x oversample
        dev->write_register(DPS280_REG_MCONF, 0x07); // continuous temp and pressure.
    
        if (is_dps310) {
            // work around broken temperature handling on some sensors
            // using undocumented register writes
            // see https://github.com/infineon/DPS310-Pressure-Sensor/blob/dps310/src/DpsClass.cpp#L442
            dev->write_register(0x0E, 0xA5);
            dev->write_register(0x0F, 0x96);
            dev->write_register(0x62, 0x02);
            dev->write_register(0x0E, 0x00);
            dev->write_register(0x0F, 0x00);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    至此,大体上理解了两个芯片的主要差异就在与寄存器初始化部分对于温度方面的workaround(芯片相关)。

    3.4 AP_Baro定位

    理解了前面关于DPS280和DPS310芯片的硬件差异以及驱动代码差异,接下来就是定位问题了。

    DEVTYPE_BARO_DPS280DEVTYPE_BARO_DPS310相关的只发生在AP_Baro_DPS280::init过程中,问题是不管是DPS310还是DPS280,都只会dev->set_device_type(DEVTYPE_BARO_DPS280)

    bool AP_Baro_DPS280::init()
    {
        if (!dev) {
            return false;
        }
        dev->get_semaphore()->take_blocking();
    
        // setup to allow reads on SPI
        if (dev->bus_type() == AP_HAL::Device::BUS_TYPE_SPI) {
            dev->set_read_flag(0x80);
        }
    
        dev->set_speed(AP_HAL::Device::SPEED_HIGH);
    
        // the DPS310 can get into a state on boot where the whoami is not
        // read correctly at startup. Toggling the CS line gets its out of
        // this state
        dev->set_chip_select(true);
        dev->set_chip_select(false);
    
        uint8_t whoami=0;
        if (!dev->read_registers(DPS280_REG_PID, &whoami, 1) ||
            whoami != DPS280_WHOAMI) {
            dev->get_semaphore()->give();
            return false;
        }
    
        if (!read_calibration()) {
            dev->get_semaphore()->give();
            return false;
        }
    
        dev->setup_checked_registers(4, 20);
    
        set_config_registers();
    
        instance = _frontend.register_sensor();
    
        dev->set_device_type(DEVTYPE_BARO_DPS280);
        set_bus_id(instance, dev->get_bus_id());
        
        dev->get_semaphore()->give();
    
        // request 64Hz update. New data will be available at 32Hz
        dev->register_periodic_callback((1000 / 64) * AP_USEC_PER_MSEC, FUNCTOR_BIND_MEMBER(&AP_Baro_DPS280::timer, void));
    
        return true;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    4. 修复

    AP_Baro: Fix GCS DPS310 HWID issue #25087

    diff --git a/libraries/AP_Baro/AP_Baro_DPS280.cpp b/libraries/AP_Baro/AP_Baro_DPS280.cpp
    index 5103fb20bc..8eef71f3a7 100644
    --- a/libraries/AP_Baro/AP_Baro_DPS280.cpp
    +++ b/libraries/AP_Baro/AP_Baro_DPS280.cpp
    @@ -60,7 +60,7 @@ AP_Baro_Backend *AP_Baro_DPS280::probe(AP_Baro &baro,
         if (sensor) {
             sensor->is_dps310 = _is_dps310;
         }
    -    if (!sensor || !sensor->init()) {
    +    if (!sensor || !sensor->init(_is_dps310)) {
             delete sensor;
             return nullptr;
         }
    @@ -153,7 +153,7 @@ void AP_Baro_DPS280::set_config_registers(void)
         }
     }
     
    -bool AP_Baro_DPS280::init()
    +bool AP_Baro_DPS280::init(bool _is_dps310)
     {
         if (!dev) {
             return false;
    @@ -190,8 +190,11 @@ bool AP_Baro_DPS280::init()
         set_config_registers();
     
         instance = _frontend.register_sensor();
    -
    -    dev->set_device_type(DEVTYPE_BARO_DPS280);
    +    if(_is_dps310) {
    +	    dev->set_device_type(DEVTYPE_BARO_DPS310);
    +    } else {
    +	    dev->set_device_type(DEVTYPE_BARO_DPS280);
    +    }
         set_bus_id(instance, dev->get_bus_id());
         
         dev->get_semaphore()->give();
    diff --git a/libraries/AP_Baro/AP_Baro_DPS280.h b/libraries/AP_Baro/AP_Baro_DPS280.h
    index 799d71a600..79769261a4 100644
    --- a/libraries/AP_Baro/AP_Baro_DPS280.h
    +++ b/libraries/AP_Baro/AP_Baro_DPS280.h
    @@ -29,7 +29,7 @@ public:
         static AP_Baro_Backend *probe(AP_Baro &baro, AP_HAL::OwnPtr dev, bool _is_dps310=false);
     
     protected:
    -    bool init(void);
    +    bool init(bool _is_dps310);
         bool read_calibration(void);
         void timer(void);
         void calculate_PT(int32_t UT, int32_t UP, float &pressure, float &temperature);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    5. 效果

    在这里插入图片描述

    6. 参考资料

    【1】Ardupilot - Contributing Code
    【2】ArduPilot Style Guide
    【3】Ardupilot - Submitting Patches Back to Master
    【4】DPS310 baro on I2C

    7. 补充

    7.1 Ardupilot提交PR注意事项

    1. 代码
      详见:ArduPilot Style Guide
    2. git注释
      在这里插入图片描述
      e.g.

    在这里插入图片描述

    7.2 修复主要使用到的命令

    针对的版本修复

    git clone git@github.com:lida2003/ardupilot.git
    cd ardupilot/
    $ git checkout  502702d
    Note: switching to '502702d'.
    
    You are in 'detached HEAD' state. You can look around, make experimental
    changes and commit them, and you can discard any commits you make in this
    state without impacting any branches by switching back to a branch.
    
    If you want to create a new branch to retain commits you create, you may
    do so (now or later) by using -c with the switch command. Example:
    
      git switch -c <new-branch-name>
    
    Or undo this operation with:
    
      git switch -
    
    Turn off this advice by setting config variable advice.detachedHead to false
    
    HEAD is now at 502702df62 Copter: version to 4.4.0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    确认版本

    $ git log -n 1
    commit 502702df62572519b56971fe9fed5b2883640879 (HEAD)
    Author: Randy Mackay <rmackay9@yahoo.com>
    Date:   Fri Aug 18 17:27:42 2023 +0900
    
        Copter: version to 4.4.0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    板子配置文件

    cp -r ../arducopter-4.4.0/libraries/AP_HAL_ChibiOS/hwdef/H743_BMI270x2_v30 libraries/AP_HAL_ChibiOS/hwdef/
    mv H743_BMI270x2_v30 Aocoda-H743BMI270Dual
    
    • 1
    • 2

    更新代码,如果不成功,请尝试多次执行,确保成功。

    git submodule update --init --recursive
    
    • 1

    编译、构建指令。

    ./waf distclean
    ./Tools/scripts/build_bootloaders.py Aocoda-H743BMI270Dual
    ./Tools/gittools/submodule-sync.sh
    ./waf configure --board Aocoda-H743BMI270Dual
    ./waf copter
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    微信公众号开发基本流程(记录初级流程)
    cesium 添加纽约城市模型
    web前端期末大作业:个人网站设计——响应式个人小站网站HTML+CSS+JavaScript
    【产品经理修炼之道】- 企业内部礼品库存管理系统设计(从需求到上线)B端
    CNCF项目全景图介绍
    【送面试题】Linux中grep和find的区别及全面使用指南
    Java窗体汽车租赁系统Java共享汽车租赁(租赁系统)
    计算机网络性能指标
    Qt 项目实战 | 音乐播放器
    项目管理基础2021复习笔记
  • 原文地址:https://blog.csdn.net/lida2003/article/details/133297535