前言
前几天打完比赛,收获还是挺大的,数字识别部分基本上浪费了绝大部分时间。先将思路简单说明。
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; // 未检测到显著的运动方向
}