多数陀螺仪 Z 轴方向角度变化如下图所示:
为方便进行 PID,需要对其进行线性化处理
观察图像不难发现,由于非线性是跳跃间断点造成的,所以间断点两端会存在巨大的数值跳变,这个跳变就是我们可以利用的地方
定义一个圈数变量,初值为0,每判定一次越界则圈数变量的值发生 1 的变化 。假设采样频率无限大,那么检测到角度发生了360°变化时就可以判定发生了越界,圈数就可以相应变化,这种理想条件下的伪代码可以写成:
int 圈数 = 0;
if(这一圈角度 - 上一圈角度 == -360) 圈数++;
else if(这一圈角度 - 上一圈角度 == 360) 圈数--;
处理后的角度 = 圈数 * 360 + 这一圈角度;
但是实际情况下受采样周期的限制,这一圈角度和上一圈角度采样点可能像下图中 G 和 H 一样,
可以看到 G 和 H 之间的角度差就小于 360°
可以发现采样周期角速度与判定界限之间满足一下关系式:
同时还要防止误触发,也就是正常旋转的时候不能记成圈数变化:
综合上面两个式子,angelBound 为 180° 的时候,可以适应 最大的角速度 和 最低的采样频率
完整源码如下:
每次传入当前的角度,就会返回线性化处理后的角度
double getLinearAngel(double angelNow){
static double angelLast = 0;
static int roundCount = 0;
double err = angelNow - angelLast;
if(err < -180) roundCount++;
else if (err > 180) roundCount--;
angelLast = angelNow;
return roundCount * 360 + angelNow;
}
在此基础上可以进行推广,所有图像类似于下图的数据都可以用这种方法进行线性化处理,记最大值为 max,最小值为 min,则最优界限为 (max + min)/2
代码也可以推广为:
double getLinearData(double dataNow){
static double dataLast = 0;
static int count = 0;
double err = dataNow - dataLast;
if(err < -BOUND) count++;
else if (err > BOUND) count--;
dataLast = dataNow;
return count * BOUND * 2 + dataNow;
}
标签:err,陀螺仪,double,圈数,角度,线性化,360
From: https://www.cnblogs.com/Sound-Sleep/p/linearGryo.html