5iMX宗旨:分享遥控模型兴趣爱好

5iMX.com 我爱模型 玩家论坛 ——专业遥控模型和无人机玩家论坛(玩模型就上我爱模型,创始于2003年)
查看: 2722|回复: 12
打印 上一主题 下一主题

APM 定高模式下,容易受风影响的优化。[INav_TC_Z]

[复制链接]
跳转到指定楼层
楼主
发表于 2018-6-4 17:49 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 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,感觉还是很贵。想找个便宜,而且定高效果好的,造福模友。





欢迎继续阅读楼主其他信息

沙发
发表于 2018-6-4 18:21 | 只看该作者
楼主得到的结论,
是因为气压传感计得到的数据计算出的高度不对?
3
 楼主| 发表于 2018-6-4 18:30 | 只看该作者
本帖最后由 skypup 于 2018-6-4 18:31 编辑
Yliangding 发表于 2018-6-4 18:21
楼主得到的结论,
是因为气压传感计得到的数据计算出的高度不对?

气压计自身是没问题的,是因为伯努利原理造成的。

气压分布,可以参考最上面从鬼佬贴子转来的图。


4
发表于 2018-6-4 18:40 | 只看该作者
pix适用不?
来自安卓客户端来自安卓客户端
5
 楼主| 发表于 2018-6-4 18:41 | 只看该作者
本帖最后由 skypup 于 2018-6-4 18:43 编辑

关于振动的控制,气压计填充海棉,这2个对于 Pix 也是需要的。

高版本的固件中,没有 INav_TC_Z 这个参数。
Pix 固件,如果是 3.4.3 或以上版本,似乎已经解决这个问题。我们 Pix 的飞机,感觉定高还算稳,就没有深究定高的问题了。


6
发表于 2018-6-4 18:47 | 只看该作者
感觉pix在飞的时候还是会有掉我高度的情况。有风的时候控制精准度还会变差。
来自安卓客户端来自安卓客户端
7
发表于 2018-6-4 19:32 | 只看该作者
skypup 发表于 2018-6-4 18:30
气压计自身是没问题的,是因为伯努利原理造成的。

气压分布,可以参考最上面从鬼佬贴子转来的图。

风吹了一下,应该是气压变低。相对于是更高的高度,这时候飞控以为飞机跳高了,就应该降低高度。这时候就掉高度了。是这样的吗?
来自苹果客户端来自苹果客户端
8
 楼主| 发表于 2018-6-5 01:19 | 只看该作者
Yliangding 发表于 2018-6-4 19:32
风吹了一下,应该是气压变低。相对于是更高的高度,这时候飞控以为飞机跳高了,就应该降低高度。这时候就 ...

是的, 我也认为掉高是这个原因。

9
发表于 2018-6-5 01:25 | 只看该作者
skypup 发表于 2018-6-5 01:19
是的, 我也认为掉高是这个原因。

猜中了
来自苹果客户端来自苹果客户端
10
发表于 2018-6-6 01:31 | 只看该作者
11
发表于 2018-6-11 09:15 | 只看该作者
技术贴 学习了
来自苹果客户端来自苹果客户端
12
发表于 2018-6-20 00:27 | 只看该作者
用lidar啊 100多米高度都没问题 别用不靠谱的气压计了
13
 楼主| 发表于 2018-6-20 08:22 | 只看该作者
本帖最后由 skypup 于 2018-6-20 08:25 编辑
ezk 发表于 2018-6-20 00:27
用lidar啊 100多米高度都没问题 别用不靠谱的气压计了

Lidar One 要 1000+ CNY 而且最可气的是,原厂的工程师说:“我们就是要卖这么贵,因为你找不到可以与我们竞争的产品;如果你找到了与我们性能相当的,请一定告诉我们,到时我们会降价的。”(意译)
一个气压计才几元钱。


您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

关闭

【站内推荐】上一条 /1 下一条

快速回复 返回顶部 返回列表