2021年电赛陕西省七校联赛D题解析

2.1k 词

题目分析

2021年电赛陕西省七校联赛D题下载

  根据题目要求可以看出,该装置要测量滚筒的水平、倾斜、滚动、转动等参数,显而易见的该题希望我们用MPU6050去获得这些参数。值得注意的是,这道题的MPU6050的三轴都要用上,所以要谨慎考虑MPU6050的放置姿态。在这道题中我的姿态规划是:pitch->滚筒于水平面夹角,roll->滚筒滚动的方向,yaw->滚筒横滚的方向。在这里多说两句,每年的七校联赛出的题都是一些系统体积小、机械结构简单、不需要控制系统、测量系统偏多且计算偏多的装置。

基本要求

  1. 对水平测量的这一轴设置阈值,一般上下二十度即可。
  2. 和前一题一样,只不过要将这一轴的角度实时显示出来
  3. 这道题需要我们测量滚动的距离,我们已知该滚筒的直径R,所以我们可以得出滚筒的周长$C=πR$,我们滚筒转一圈是360°,所以我们可以把滚筒的周长映射到转一圈的度数上。在这里我们使用的可乐的易拉罐做为滚筒外壳,其直径R为6.6cm,可得出周长C为20.724cm,MPU6050的精度为0.1°,所以我们可以达到的最小精度A为0.005cm,也就是说我们每滚动0.1°,就滚过了0.005cm的长度,这远远的达到了题目要求精度。

发挥部分

  1. 该题让我们测量滚筒的水平滚动圈数,我们已知滚筒横转一圈是360°,所以我们只需要将转过的总度数/360°即可。
  2. 这道题要求我们算出滚筒在斜板上的放置高度,一个很好想出来的计算方法就是用三角函数算出。但由于该题的倾角是一个不固定的值,且滚动的长度也是一个不固定的值,所以这道题的计算思路就变成了如何去计算倾角和滚动过的斜板长度。计算滚动过的距离在基础题第三题我们已经计算过了,所以可以直接拿来用,至于倾角的计算,我们可以用pitch角得到倾角,用最后停住时的pitch角度与刚开始的pitch角度做差,就可以获得到斜板的倾角,但是我们怎么知道什么时候滚筒停下来了呢?我们可以利用roll轴(没有roll轴这个说法,在这里懒得建系,代表的是roll角度对应的方向)的加速度进行判断,整个滚筒在沿着斜板向下滚动时加速度一定会一直累加,在我们的手抓住滚筒时,滚筒会立马停下,所以我们只需要找到roll轴加速度在一直增加后突变的时刻,这个时刻就是滚筒要停住的时刻,在这个时间再采样MPU6050的pitch角去做计算即可。此时我们已经拿到这个直角三角形的倾角和斜边长,那么我们的直角边就很好算了。

硬件设计

​  和每年的七校联赛一样,这道题的硬件设计也同样简单,将整个测量系统放在滚筒里面,保证不会在滚筒里面晃动即可。唯一值得注意的是MPU6050的放置姿态,在前面已经说过了。

软件设计

​  前两题没有什么好说的。

​  第三题在我们处理roll角数据时有一些好的想法,pitch角的范围为:-180.0°<—> +180.0°,在我们对角度的规定为0.0°<—> 360.0°,所以在拿到pitch角数据时我们首先给pitch角加180°保证pitch角的变化范围在我们的预期范围之内。接下来我们要去计算距离,我们最后要的是转过的总角度,我们可以保留上次测量的值和这次测量值,将差值累加起来,但是当角度达到了360°时角度会从360°突变到0°,且如果滚筒反过来转时角度有可能会从0°突变到360°,这样累加时会出现错误,所以在这里我们需要做一些处理。首先我们要判断滚筒到底是在正转还是反转,如果这次角度和上次角度的差值C在(C<=0 && C>=180) || (C>=180 && C<=360)这个范围中我们就认为是正传,反之则是反转,至于为什么是这个范围,大家可以推一下,这里就不展开说了。在知道正反转时,我们再处理一下突变点即可完成整个测量过程了,下面附上核心代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int get_dir()
{
cha=cur_angle-pre_angle;
if((cha<=0&&cha>=-180)||(cha>=180&&cha<=360)) return 1;
else return -1;
}
pre_angle=cur_angle;
get_angle();
cur_angle=roll+180;
sta=get_dir();  
if(sta==1)
{
if(pre_angle>cur_angle) sum+=pre_angle-cur_angle;
if(pre_angle<cur_angle) sum+=(360-cur_angle)+pre_angle;
} else
{
if(pre_angle<cur_angle) sum-=cur_angle-pre_angle;
if(pre_angle>cur_angle) sum-=(360-pre_angle)+cur_angle;    
}

​  剩下的题就没有什么特殊处理方法了,总体来说这道题还是相对简单的。

留言