|
本帖最后由 skypup 于 2018-6-5 17:43 编辑
APM 的定高(在 AltHold、Loiter、PosHold 模式下)有个不好的体验,可能比玩具飞机的体验还差:
当悬停在一个位置时,突然一阵风吹过,飞机会明显掉高,突风比较大的时候,可以掉 1-2米,如果这时正在很低的高度悬停,有可能会直接接触到地面。
当做机动的时候,飞机会掉高,再快速刹住并悬停,这时飞机会快速上升。
github 上面有贴子进行了讨论,供参考:
github.com/ArduPilot/ardupilot/issues/1277
是因为伯努利原理,气压发生了变化,气压计的读数也会相应改变。
=====================================================
先针对小白,直接说结论:
1 控制住飞机的振动,例如:X、Y、Z 都在 ±1 以内,可以加减震解决。
2 气压计周围用黑色海棉填充。
3 把 INav_TC_Z 参数,从默认值 5,逐步增加到 10. 如果第一步振动未控制好,增加到一定数值后,飞机会抽的,这时就不要更加大了。4 ANGLE_MAX 参数,如果是默认值 4500,改为 3000.
=====================================================
如果不是小白,可以看一看具体的解释:
1 振动的控制。
首先,飞控需要一个靠谱的供电。例如这样:
一般是用 BEC 或者电流计供电,日志中,飞控的电压最大值与最小值之间不要超过 100mV 的。超过 100mV 的,就把 BEC 或者电流计给扔了吧。
10 元不到的国产 DC-DC 都可以做到。
然后,IMU 或者飞控,需要做好减振。
我比较懒,没有去做桨和电机的平衡,最省事的方法是直接用减震棉一贴,就凑合了。
但是,如果想钉钉子那样稳,机架、电机、桨平衡这些细节肯定要处理好。
定高与主要与 Z 轴有关系:
X 与 Y 轴的振动,也需要控制好:
2 气压计用黑色海棉填充。
例如这样,3D 打印个壳:
黑色:
为了避免阳光或其它光线对气压计的影响。一个不透光的外壳是需要的,再用上黑色的海棉进一步减小光线的影响。
海棉:
因为大家都这样做,海棉还可以压缩的很薄,使用方便。
填充:
在最上面鬼佬们讨论的贴子里,他们提到的方法是填充,而不是仅仅压住气压计。
3 对 INav_TC_Z 参数的调整。这一步很重要,否则达不到效果。
请尽可能的把 INav_TC_Z 调整到 10,而飞机不会有忽上忽下抽风的感觉。控制好振动就没问题了。
默认值是 5,数值越大,气压计的数据对定高的影响越缓慢。
每次增加 1,可以感觉到定高的效果会有变化,当从 5 增加到 7 的时候,已经能感觉到受风的影响掉高的问题已明显改善。做机动飞行时,高度变化的问题也明显改善。
当从 7 增加到 10 之后,能感觉到效果进一步的改善。
4 限制姿态角度,变相降低飞行速度,减小风的影响。
ANGLE_MAX 参数,默认值 4500(允许飞机倾斜45度角),改为 3000(最大倾斜角度是 30 度). 这样,摇杆打到底,就没那么暴力了,也就不会飞的那么快,气流变化也就没那么大。
=====================================================
以下内容,适合喜欢深究原理的模友。
INav_TC_Z 是这样影响飞控的:libraries\AP_InertialNav\AP_InertialNav.cpp 文件中,INav_TC_Z 的值,被保存在:_time_constant_z 这个变量中。
AP_GROUPINFO("TC_Z", 2, AP_InertialNav, _time_constant_z, AP_INTERTIALNAV_TC_Z),
_time_constant_z 的作用是:
生成 _k1_z, _k2_z, _k3_z 这3个参数,_time_constant_z 是分母,所以 INav_TC_Z 越大,这3个参数越小。
// Z axis time constant
if (_time_constant_z == 0.0f) {
_k1_z = _k2_z = _k3_z = 0.0f;
}else{
_k1_z = 3.0f / _time_constant_z;
_k2_z = 3.0f / (_time_constant_z*_time_constant_z);
_k3_z = 1.0f / (_time_constant_z*_time_constant_z*_time_constant_z);
}
而在 void AP_InertialNav::update(float dt) 函数中,有这样3句代码,用到变量。 accel_correction_hbf.z += _position_error.z * _k3_z * dt;
....
_velocity.z += _position_error.z * _k2_z * dt;
....
_position_correction.z += _position_error.z * _k1_z * dt;
其中的 _position_error.z 是在 void AP_InertialNav::correct_with_baro(float baro_alt, float dt) 被赋值:
// calculate error in position from baro with our estimate
_position_error.z = baro_alt - (hist_position_base_z + _position_correction.z);
这个 baro_alt 看字面意思,就是气压计相关的,它的值由 _baro.get_altitude() 确定: correct_with_baro(_baro.get_altitude()*100.0f, dt);
在 libraries\AP_Baro\AP_Baro.cpp 中,有 get_altitude 的实现:
float AP_Baro::get_altitude(void)
{
if (_ground_pressure == 0) {
// called before initialisation
return 0;
}
if (_last_altitude_t == _last_update) {
// no new information
return _altitude + _alt_offset;
}
float pressure = get_pressure();
float alt = get_altitude_difference(_ground_pressure, pressure);
// record that we have consumed latest data
_last_altitude_t = _last_update;
// sanity check altitude
if (isnan(alt) || isinf(alt)) {
_flags.alt_ok = false;
} else {
_altitude = alt;
_flags.alt_ok = true;
}
// ensure the climb rate filter is updated
_climb_rate_filter.update(_altitude, _last_update);
return _altitude + _alt_offset;
}
其中 _alt_offset 这个值,保存在参数 GND_ALT_OFFSET.
isnan() 与 isinf() 是 Arduino 的原生函数,用来判断数据是否合法。
_climb_rate_filter 只是滤波,在文件夹:libraries\Filter
一个关键的原始数据,get_pressure() 是在传感器里定义的,如 AP_Baro_MS5611.cpp
float AP_Baro_MS5611::get_pressure()
{
return Press;
}
这个 Press 的计算,就在 void AP_Baro_MS5611::_calculate() 中,只是传感器原始数据的读取与解算,这里就不贴出来了。
根据对代码的解读,可以判断 INav_TC_Z 的值越大,气压计对定高的影响越缓慢。
当长时间机动飞机之后,突然刹车,飞机仍会慢慢爬升 2 米左右。因为 INav_TC_Z 只是减缓了气压计对定高的影响而已。
长时间的机动飞行,受伯努利原理的影响,气压计的读数会一直偏小(动压增加、静压减小);当刹住之后,动压基本消失、静压增加,使得气压计读数判断高度减小了。这个误差,会缓慢影响到飞机高度的解算,所以我们看到飞机会爬升1-2米。
有的玩具飞控,这个高度能控制在 0.5米或者更小,我想他们应当是用了一些算法来补偿,但是这几款飞控经常发疯伤人,不知道与这类补偿算法考虑的不周全是否有关系。
想幸灾乐祸,看别人炸机伤人、一键放生、一键返厂的,可以关注网站: kanzhaji点com (看炸机),也就是之前的 sb-dji.
借贴子问一问,对这方面比较熟悉的模友:大家都在用哪种气压计,又便宜,定高效果又好的?
我目前的测试结果是 MS5611 与 MS5607 区别看不出,但是 BMP280 初步测试比 MS5607 的效果差好多。
所以,我用的是 MS5607,感觉还是很贵。想找个便宜,而且定高效果好的,造福模友。
|
欢迎继续阅读楼主其他信息
|