ArduPilot开源飞控之GCS显示DPS310异常问题
- 1. 源由
- 2. 现象
- 3. 分析
- 3.1 Mission Planner
- 3.2 Ardupilot
- 3.3 AP_Baro分析
- 3.4 AP_Baro定位
- 4. 修复
- 5. 效果
- 6. 参考资料
- 7. 补充
- 7.1 Ardupilot提交PR注意事项
- 7.2 修复主要使用到的命令
1. 源由
2020年Ardupilot官网论坛就有开始讨论DPS310芯片在GCS系统上显示为DPS280的问题。
但是直到最近在使用H743飞控板子的时候,发现问题依然存在。初步看了下,不是太复杂的问题,因此进行了一些分析。
2. 现象
Mission Planner上显示DPS280芯片。
- 硬件规格书上是DPS310芯片。
- 经飞控板确认,实际使用的是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.
那么为什么现在有问题???
进一步搜索代码:
- 发现AP_Baro_DPS310 继承自AP_Baro_DPS280
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_DPS280
和DEVTYPE_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注意事项
- 代码
详见:ArduPilot Style Guide - 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