前言
前几天打完比赛,收获还是挺大的,数字识别部分基本上浪费了绝大部分时间。先将思路简单说明。
1、题目
2、思路
针对笔迹检测,我们首先考虑的肯定是陀螺仪来测量加速度方向来判断书写的方向,从而得到书写的数字。
我们的方案是不断记录四个方向的加速度最大值,如果有某个方向的最大值最先达到某个阈值,则判定在该方向上移动。
但在实际测量的时候会遇到两个问题:
①:重力加速度的影响,因为陀螺仪本身会有z轴向下的重力加速度,在书写时难免会有倾斜,而且书写的时候加速度本身就很小,约0.2左右,就会导致重力加速度在x轴或y轴上的分量影响很大;
②:在书写的时候,由于惯性,会产生一个反方向的加速度,这个加速度也比较影响书写方向的判断;
解决方案:
针对问题①,解决方案也很明显,因为陀螺仪本身就可以检测自身角度,我们只需要根据角度计算出水平方向的分量再将它减掉就行(fAcc[0]表示x轴加速度,fAcc[1]表示y轴加速度)
fAcc[0]=fAcc[0]+sin(fAngle[1]*(M_PI/180));
fAcc[1]=fAcc[1]-sin(fAngle[0]*(M_PI/180));
针对问题②,我们最终还是没解决,所以我们索性直接判断两个方向,即x轴和y轴。
识别的思路是:如果笔是倾斜的,会进入一个循环开始不断读取mpu6050数据,如果识别到某个方向移动,则进入另一个循环,如果笔竖直,则退出此循环,并返回该方向。这便记作判断画了一笔,最后根据笔画方向排序判断数字。
void task_4(void)//功能4
{int i=0,direction_now=0;// 初始化数组
// memset(shu, 0, sizeof(shu));while(1){direction_now=get_direction();if(direction_now==1){shu[i++]='x';u3_printf("page4.t3.txt=\"X\"\xff\xff\xff");u3_printf("page4.n1.val=%d\xff\xff\xff",i);}else if(direction_now==2){shu[i++]='y';u3_printf("page4.t3.txt=\"Y\"\xff\xff\xff");u3_printf("page4.n1.val=%d\xff\xff\xff",i);}else{u3_printf("page4.t3.txt=\"error\"\xff\xff\xff");break;}u3_printf("page4.r0.val=0\xff\xff\xff");printf("第%d次书写成功,书写内容为%d\r\n,",i,direction_now);}show_num=number_ordinary();u3_printf("page4.n0.val=%d\xff\xff\xff",show_num);}
//用来检测笔的移动方向
//返回0~2,表示2个方向
int get_direction(void)
{float accX;float accY;float maxAccX=0.0,minAccX=0.0;float maxAccY=0.0,minAccY=0.0;//进行清零count[0] = 0.0;count[1] = 0.0;printf("开始书写\r\n");printf("%f\r\n", rangle);while (rangle > 15 ){gryo_get(); // 获取传感器数据rangle = 39 - fAngle[0]; // 计算角度if(rangle>50){continue;}// 获取当前加速度值accX = fAcc[0];accY = fAcc[1];// 更新 x 轴的最大值和最小值if (accX > maxAccX) {maxAccX = accX;}if (accX < minAccX) {minAccX = accX;}// 更新 y 轴的最大值和最小值if (accY > maxAccY) {maxAccY = accY;}if (accY < minAccY) {minAccY = accY;}printf("maxAccX = %f mixAccX = %f maxAccY = %f mixAccY = %f\r\n",maxAccX,minAccX,maxAccY,minAccY);if (max(maxAccX,minAccX) > max(maxAccY,minAccY) && max(maxAccX,minAccX) > 0.25) {while (rangle<70) {u3_printf("page4.r0.val=1\xff\xff\xff");u3_printf("page6.r0.val=1\xff\xff\xff");gryo_get(); // 获取传感器数据rangle = 39 - fAngle[0]; // 计算角度}return 2;} else if ( max(maxAccY,minAccY) > max(maxAccX,minAccX) && max(maxAccY,minAccY) > 0.25){while (rangle<70) {u3_printf("page4.r0.val=1\xff\xff\xff");u3_printf("page6.r0.val=1\xff\xff\xff");gryo_get(); // 获取传感器数据rangle = 39 - fAngle[0]; // 计算角度}return 1;}delay_ms(50);}return 0; // 未检测到显著的运动方向
}