PX4混控
https://blog.****.net/qq_27016651/article/details/81123204 感谢博主的无私分享!
混控步骤:
一、忽略偏航进行融合处理
1根据混控矩阵计算得到out,这一步已经包含油门,同时记录下最大输出和最小输出,outputs保存四个电机的输出值。
2第一种情况,min小于0,max大于0,min,max之差小于1,可以通过偏移解决。加油油门增加幅度大于|min|,可以通过增加油门的方式解决,boost = -min_out;如果油门增加幅度太小,需要把roll和pitch的缩小后再计算。代码如下如图。
举个例子,当前thrust为0.2,计算得到新的输出值之后,min为-0.2,max为0.6,roll和pitch带来转速上的变化是0.4,由于只计算了Roll和Pitch,所以在旋翼里面,min和max到thrust的距离一定是一样的。这种情况就是第一种情况,并且油门增大幅度为0.2*0.5=0.1,不足以平衡min的大小。需要对Roll和Pitch进行缩放。计算得到boost=0.1,roll_pitch_scale=0.75,然后再计算下面的代码。可以知道min=0,max=0.6,没有饱和。
二、添加偏航后进行处理
首先分析out<0的情况,通过第一步的处理可知out在0到1范围内,假设此时out=0.2;当加上偏航后,out=-0.1,因此偏航就占用了-0.3,但是出现了下溢出,为了防止溢出yaw只能占用-out也即是-0.2,因此对-out进行除以_rotors[i].yaw_scale处理,得到处理后的yaw值,从而有效抑制下溢出;
然后是out>1的情况,通过第一步的处理可知out在0到1范围内,假设此时out=0.8;当加上偏航后,out=1.1,因此偏航就占用了0.3,但是出现了上溢出,为了防止溢出yaw只能占用1-out也即是1-0.8=0.2,因此对1-out进行除以_rotors[i].yaw_scale处理,得到处理后的yaw值,从而有效抑制上溢出;yaw处理也到此结束战斗。
三、融合怠速处理
这个相对比较容易理解就不说了,一般会把_idle_speed赋0;
四、对整体输出的处理(专业说法叫slew rate limiting)
其实这个地方感觉有点像滤波处理,当当前时刻比上一时刻的变化大与最大阈值时,就要省掉当前的值,用上一刻的值加上最大阈值进行代替,当当前时刻比上一时刻的变化小于最小阈值时,就要省掉当前的值,用上一刻的值加上最小阈值进行代替,我感觉就是为了是控制更平稳,增加一定的抗干扰能力,但响应有可能会变慢。接下来就是细节分析了
在文件Firmware-master\ROMFS\px4fmu_common\mixers中预定机身的类型,打开quad_+.main如下:
它们可以用作为定制或者一般测试目的的基础。
语法
混频器的定义是一个文本文件:每行以一个简单的大写字母开头,后面跟着一个重要的冒号。其他的所有行都被忽略,意味着解释性文本可以自由地与定义混合。
每个文件可能定义不止一个混频器。混频器给执行器的分配就是指定读取混频器定义的设备
一个混频器以下面这样一行的形式开始
<tag>:<mixer arguments>
标签选择了混频器的类型,‘M’表示一个简单的加法混频器,‘R’表示多旋翼混频器等。
上面的函数表示数据读取函数,即是将quad_+.main文件中的数据存放到相关参数中,
同时返回数据
通过函数
返回到实际中(以quad_+.main为例),也即是
再根据下面的程序,将roll_scale,pitch_scale,raw_scale,idle_speed分别映射到_roll_scale,_pitch_scale,_yaw_scale,_idle_speed中
接下来就是下面程序中未知数的确定了,
可以知道_rotors为一结构体变量数组,数组的大小为_rotor_count, 在mc_mixer.cpp中还定义了一下结构体变量
通过mc_mixer.cpp中的以下代码将*_rotors与这些数据联系在一起
、
这一部分感觉不像是多旋翼多控制输出的控制,这部分的控制输出是被限制在4,暂不考虑这一块,通过查阅资料,有一下说明:
对应的定义在程序中未能找到,查看PX4源程序发现:
mixer混控器根据机型进行力矩分配。根据叶素理论,螺旋桨旋转产生的s升力/扭矩与转速的平方以及拉力系数/扭矩系数相关。构造力矩分配矩阵,通过一些资料获得了一些相关矩阵,如下所示:
当使用不同的Layout时,对应不同的力矩矩阵,矩阵的第一行对应第一个电机的输出,第一行中的数据分别对应
_rotors1.roll_scale,_rotors1.pitch_scale,_rotors1.raw_scale,_rotors1.out_scale
具体的赋值过程在程序中并未发现,只能根据资料获得,
这个程序中出现了FLT_EPSILON,这个参数表示最小浮点数,在float.h中有相关定义,具体定义也可以参考下图: