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)))

到这里就更加奇怪了,貌似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<AP_HAL::Device> dev);
};

在硬件芯片驱动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<AP_HAL::Device> _dev)
{
    // same as DPS280 but with is_dps310 set for temperature fix
    return AP_Baro_DPS280::probe(baro, std::move(_dev), true);
}

该变量的主要目的是为了解决温度传感器的设置问题。
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);
    }
}

至此,大体上理解了两个芯片的主要差异就在与寄存器初始化部分对于温度方面的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;
}

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<AP_HAL::Device> 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);

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

确认版本

$ 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

板子配置文件

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

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

git submodule update --init --recursive

编译、构建指令。

./waf distclean
./Tools/scripts/build_bootloaders.py Aocoda-H743BMI270Dual
./Tools/gittools/submodule-sync.sh
./waf configure --board Aocoda-H743BMI270Dual
./waf copter
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值