问题:
Stm32处理角度数据时,比如接受姿态传感器数据,偏航角范围在-180度到180度,那么我们控制系统输入误差信号时,角度差就会产生突变问题,比如说:从170度转到179度,等于179-170=9度,正方向旋转9度,从170度转到-179度,等于-179-170=-349度,但其实我们只需要正向旋转11度即可。问题在于,我们的减法作用于线性区域,而角度域应为环形域。
解决方案一:
作差限幅法,对于角度差值,小于-180,加上360,对于角度差值,大于180,减上360。上例中,-349<-180,那么-349+360=11度,为正确输入信号。我们将上述过程写成函数,每次角度作差调用函数即可。函数较简单,这里不列出。
解决方案二:
复数计算法,上文提到,问题的主要来源在于角度域是环形域,那么有没有可以表示环形域的量进行运算可以解决这个问题。答案是利用单位复数向量,我们将角度转化为单位复数向量,两个复数相除,获得的新复数取其相角即为答案,上例过程如下:
由于手动计算,中间保留过程造成了误差扩大,但C语言计算,误差非常小,完全可以忽略。
下面贴出stm32代码:
#include <math.h>
#include <complex.h>
float subangle(float angle0, float angle1)
{
float complex comangle0, comangle1;
comangle0 = cos(angle0 / 180 * Pi) + sin(angle0 / 180 * Pi) * I;
comangle1 = cos(angle1 / 180 * Pi) + sin(angle1 / 180 * Pi) * I;
float y = 180.0 * carg(comangle0 / comangle1) / Pi;
return y;
}
注意:这段代码在STM32F103的工程中,KEIL 的AC6会报错无法运行,KEIL的AC5可以正常运行,我这里用的是v5.06update7(bulid 960)。希望有大佬可以试试AC6怎样配置才可以运行,顺便踢我一下。
当然,在函数的第二个参数取相反数可以完成求和操作。