赞
踩
以右圆环为例
(1)找到近端右拐点,且左边界不丢线
(2)找到右边中间拐点,定位近端右拐点,拉线
(3)右边界底部丢线,结束拉线,找远端右拐点
(4)定位远端右拐点,补线进环
(5)编码器计步大于某阈值,停止补线,进普通循迹状态
(6)赛道宽度突变,补线出环
(7)找远端右拐点,补线不入环
(8)结束,清空状态
- void Right_Roll_Judge(void)
- {
- extern int Distance_L;
- extern int Distance_R;
-
- int erro_x,erro_y;
- if(XK.roll_flag==0&&XK.roll_situation==0)//初始状态
- {
- if((Right_NearInflection_Judge(40,30)==1)&&(Left_Road_Lose(10,60)==1))//找到右拐点且左边界不丢失
- {
- XK.roll_situation=1;
- XK.roll_flag=1;
- XK.y3=28;
- erro_x=0;
- erro_y=0;
- XK.y2=0;
- XK.x2=0;
- }
- }
- if(XK.roll_situation==1)//找拐点,定位
- {
- Right_NearInflection_Catch(XK.y,60,XK.x,XK.y);//近拐点定位
- Right_RoundInflection_Catch(XK.y,1,XK.x2,XK.y2);//中间拐点定位
- if(XK.y>0&&XK.y2>0)//找到两个拐点,准备拉线
- {
- erro_x=0;
- erro_y=0;
- XK.y1=XK.y2;
- XK.x1=XK.x2;
- XK.roll_situation=2;
- }
- }
- if(XK.roll_situation==2)//拉线
- {
-
- Right_NearInflection_Catch((XK.y-2),60,XK.x2,XK.y2);
- erro_y=abs(XK.y2-20);
-
- XK.y3=XK.y;
- XK.y4=XK.y1+erro_y;
- XK.x3=XK.x;
- XK.x4=XK.x1;
- XK.line=1;
- if(XK.right_line[100]>160)//当右边界底部丢线,结束拉线
- {
- XK.line=0;
- XK.y2=0;
- XK.roll_situation=3;
- }
- }
- if(XK.roll_situation==3)//找远拐点
- {
- Right_FarInflection_Catch(1,40,XK.x2,XK.y2);//远拐点定位
- if((XK.y2>0)&&(XK.right_line[20]>150))//找到远拐点且右边界前端丢线,准备拉线
- {
- XK.y1=XK.y2;
- XK.x1=XK.x2;
- Distance_L=0;
- Distance_R=0;
- XK.Encoder_distance=0;
- XK.roll_situation=4;
- }
- }
- if(XK.roll_situation==4)//入环补线
- {
-
- XK.y3=25;
- XK.y4=55;
- XK.x3=110;
- XK.x4=45;
- XK.line=1;
-
- if(XK.Encoder_distance>5)//编码器计步(走一段距离,结束补线)
- {
- XK.y2=0;
- XK.line=0;
- Distance_L=0;
- Distance_R=0;
- XK.Encoder_distance=0;
- XK.roll_situation=6;
- }
- }
- if(XK.roll_situation==6)//环内状态
- {
- if((XK.road_width[29]-XK.road_width[30]>50)||XK.road_width[30]>150)//赛道宽度突变
- {
- XK.y1=XK.y2;
- XK.x1=XK.x2;
- XK.y2=0;
- Distance_L=0;
- Distance_R=0;
- XK.Encoder_distance=0;
- XK.roll_situation=7;
- }
- }
- if(XK.roll_situation==7)//出环补线
- {
- XK.y3=25;
- XK.y4=60;
- XK.x3=115;
- XK.x4=30;
- XK.line=1;
- Right_FarInflection_Catch(1,30,XK.x2,XK.y2);找远端拐点
- distence_count();
- if((XK.y2>0)&&XK.Encoder_distance>7)//不入环判断:在走一段距离的情况下,找到远端拐点
- {
- XK.y1=XK.y2;
- XK.x1=XK.x2;
- XK.roll_situation=8;
- }
- }
- if(XK.roll_situation==8)//不入环补线
- {
- XK.y3=100;
- XK.y4=20;
- XK.x3=136;
- XK.x4=113;
- XK.line=1;
- }
- if(XK.roll_situation==8)//不入环补线
- {
- Distance_L=0;
- Distance_R=0;
- XK.Encoder_distance=0;
- XK.y3=100;
- XK.y4=20;
- XK.x3=136;
- XK.x4=113;
- XK.line=1;
- }
- if((Left_Road_Lose(20,60)==1)&&XK.roll_situation==8)//右边界不丢失,圆环标志位清零
- {
- XK.roll_situation=0;
- XK.roll_flag=0;
- XK.line=0;
- }
-
- }
-
- void draw_line(void)//补线处理函数
- {
- if(XK.line==1)
- {
- ips114_add_line(XK.y,XK.x+0,XK.y1,XK.x1+0,0x00);
- ips114_add_line(XK.y,XK.x+1,XK.y1,XK.x1+1,0x00);
- ips114_add_line(XK.y,XK.x+2,XK.y1,XK.x1+2,0x00);
- ips114_add_line(XK.y,XK.x+3,XK.y1,XK.x1+3,0x00);
- ips114_add_line(XK.y,XK.x-1,XK.y1,XK.x1-1,0x00);
- ips114_add_line(XK.y,XK.x-2,XK.y1,XK.x1-2,0x00);
- }
- }
关于如何在图像数组中补线,基于逐飞的IPS114画线函数更改即可
- void ips114_add_line (uint16 x_start, uint16 y_start, uint16 x_end, uint16 y_end, const uint16 color)
- {
-
- int16 x_dir = (x_start<x_end ? 1:-1);
- int16 y_dir = (y_start<y_end ? 1:-1);
- float temp_rate = 0;
- float temp_b = 0;
-
- if(x_start != x_end)
- {
- temp_rate = (float)(y_start-y_end)/(float)(x_start-x_end);
- temp_b = (float)y_start-(float)x_start*temp_rate;
- }
- else
- {
- while(y_start != y_end)
- {
- mt9v03x_image_copy[x_start][ y_start]=0x00;//根据需要更改的图像数组
-
- y_start += y_dir;
- }
- return;
- }
- if(abs(y_start-y_end)>abs(x_start-x_end))
- {
- while(y_start != y_end)
- {
- mt9v03x_image_copy[x_start][ y_start]=0x00;//根据需要更改的图像数组
- y_start += y_dir;
- x_start = (int16)(((float)y_start-temp_b)/temp_rate);
- }
- }
- else
- {
- while(x_start != x_end)
- {
- mt9v03x_image_copy[x_start][ y_start]=0x00;//根据需要更改的图像数组
- x_start += x_dir;
- y_start = (int16)((float)x_start*temp_rate+temp_b);
- }
- }
- }
- void elec_roll_judge(void)
- {
- // ********* 摄像头区分左右环(这一段可单独放在图像处理函数里) ***********
- if(XK.roll_flag==1&&XK.roll_situation==1)
- {
- XK.rolldirr=rroll_dir_judge(10,50,65);
- XK.rolldirl=lroll_dir_judge(10,50,65);
- }
- // *****************************************************************
- extern float AD[6];
- if(XK.roll_flag==0&&XK.roll_situation==0)
- {
- if(AD[1]>3000&&AD[0]>3000)//中间电感大于一定阈值
- {
- XK.roll_flag=1;
- XK.roll_situation=1;
- Distance_L=0;
- Distance_R=0;
- XK.Encoder_distance=0;
- }
- }
- if(XK.roll_flag==1&&XK.roll_situation==1)
- {
-
- if(XK.rolldirr==1)//右圆环状态
- {
- XK.roll_flagr=1;
- XK.roll_flagl=0;
- XK.roll_situation=2;
- Distance_L=0;
- Distance_R=0;
- XK.Encoder_distance=0;
- }
- else if(XK.rolldirl==1)//左圆环状态
- {
- XK.roll_flagr=0;
- XK.roll_flagl=1;
- XK.roll_situation=2;
- Distance_L=0;
- Distance_R=0;
- XK.Encoder_distance=0;
- }
- if(XK.Encoder_distance>15)//计步大于某值,跳出圆环
- {
- XK.roll_situation=0;
- XK.roll_flag=0;
- XK.roll_flagl=0;
- XK.roll_flagr=0;
- Distance_L=0;
- Distance_R=0;
- XK.Encoder_distance=0;
- }
- }
- if(XK.roll_flag==1&&XK.roll_situation==2)
- {
- if(XK.roll_flagl==1&&XK.roll_flagr==0)//右圆环状态
- {
- if(AD[3]>3300)//右斜电感大于阈值,舵机打角
- {
- XK.roll_situation=3;
- Distance_L=0;
- Distance_R=0;
- XK.Encoder_distance=0;
- }
- }
-
- if(XK.roll_flagl==0&&XK.roll_flagr==1)//左圆环状态
- {
- if(AD[4]>3400)//左斜电感大于阈值,舵机打角
- {
- XK.roll_situation=3;
- Distance_L=0;
- Distance_R=0;
- XK.Encoder_distance=0;
- }
- }
- }
- if(XK.roll_flag==1&&XK.roll_situation==3)//环内状态
- {
- if(XK.Encoder_distance>9)//计步
- {
- XK.roll_situation=5;
- Distance_L=0;
- Distance_R=0;
- XK.Encoder_distance=0;
- }
- }
- if(XK.roll_flag==1&&XK.roll_situation==5)
- {
- if(XK.roll_flagl==1&&XK.roll_flagr==0)//右圆环出环判断
- {
- if(AD[5]>1700)//右侧电感大于某阈值,右打角
- {
- XK.roll_situation=6;
- Distance_L=0;
- Distance_R=0;
- XK.Encoder_distance=0;
- }
- }
- if(XK.roll_flagl==0&&XK.roll_flagr==1)//左圆环出环判断
- {
- if(AD[2]>2800)//左侧电感大于某阈值,左打角
- {
- XK.roll_situation=6;
- Distance_L=0;
- Distance_R=0;
- XK.Encoder_distance=0;
- }
- }
- }
-
- if(XK.roll_flag==1&&XK.roll_situation==6)//计步大于某阈值,结束圆环,标志位清零
- {
- if(XK.Encoder_distance>3)
- {
- XK.roll_situation=0;
- XK.roll_flag=0;
- XK.roll_flagr=0;
- XK.roll_flagl=0;
- Distance_L=0;
- Distance_R=0;
- XK.Encoder_distance=0;
- }
- }
- }
这里需要用到编码器计行驶圈数
- #define ENCORDER_PRCISION 1024.f //512线、1024线等
- #define ENCORDER_D 19.2f //编码器齿轮直径 齿数30
- #define WHEEL_D 64.0f //车轮直径
- #define WHEEL_GEAR_D 41.0f //车轮直连齿轮直径 齿数 68
- #define GET_DISTANCE_M(val) ((((val/ENCORDER_PRCISION)*ENCORDER_D*PI )*WHEEL_D)/WHEEL_GEAR_D/1000)
-
-
- void distence_count(void)
- {
-
- Distance_L = Distance_L + XK.speedl;
- Distance_R = Distance_R + XK.speedr;
- XK.Encoder_distance=GET_DISTANCE_M((Distance_L + Distance_R) / 2);
-
- }
- void barrier (void)
- {
- extern int Distance_L;//左轮距
- extern int Distance_R;//右轮距
-
- if(dl1a_distance_mm<XK.dis1&&XK.barrier_judge==0)//避障预判断
- {
- Gyro_qin0();//陀螺仪数值清零
- XK.barrier_in=1;//避障状态
- XK.barrier_judge=1;//避障进入标志位
- XK.Encoder_distance=0;//测距距离
-
- }
- if(XK.barrier_judge==1)
- {
- switch (XK.barrier_in)
- {
- case 1:
- {
- if(dl1a_distance_mm<=XK.dis2)//行进距离
- {
- if((mt9v03x_image[2][94]+mt9v03x_image[3][94]+mt9v03x_image[3]
- [93]+mt9v03x_image[3][95])/4<55)//tof测距小于某阈值且图像灰度像素小于某阈值
- (区分坡道与避障)
- {
- Distance_L=0;
- Distance_R=0;
- XK.Encoder_distance=0;
- XK.barrier_in=2;
- Gyro_qin0();
- wireless_uart_send_string("6");//与后车通信
- }
- else//未达条件跳出状态
- {
- Distance_L=0;
- Distance_R=0;
- XK.time=0;
- XK.Encoder_distance=0;
- XK.barrier_in=0;
- XK.barrier_judge=0;
- Gyro_qin0();
- }
- }
- }
- break;
- case 2://打角避障
- {
-
- if(XK.dash_dir==1)//右边避障
- {
- if(eulerAngle.yaw<-3.1)//右航向角
- {
- Distance_L=0;
- Distance_R=0;
- XK.time=0;
- XK.Encoder_distance=0;
- XK.barrier_in=3;
- Gyro_qin0();//陀螺仪数值清零
- }
- }
- if(XK.dash_dir==0)//左边避障
- {
- if(eulerAngle.yaw>1.6)//左航向角
- {
- Distance_L=0;
- Distance_R=0;
- XK.time=0;
- XK.Encoder_distance=0;
- XK.barrier_in=3;
- Gyro_qin0();//陀螺仪数值清零
-
- }
- }
- }
- break;
- case 3://直行
- {
- distence_count();//编码器测距
- if(XK.Encoder_distance>3)//行进距离
- {
- Distance_L=0;
- Distance_R=0;
- XK.time=0;
- XK.Encoder_distance=0;
- XK.barrier_in=4;
- Gyro_qin0();
- }
- }
- break;
- case 4://打角
- {
-
- if(XK.dash_dir==1)//左边避障
- {
- if(eulerAngle.yaw>3.6)//左航向角
- {
- Distance_L=0;
- Distance_R=0;
- XK.time=0;
- XK.Encoder_distance=0;
- XK.barrier_in=5;
- Gyro_qin0();
- }
- }
- if(XK.dash_dir==0)//右边避障
- {
- if(eulerAngle.yaw<-6.0)//右航向角
- {
- Distance_L=0;
- Distance_R=0;
- XK.time=0;
- XK.Encoder_distance=0;
- XK.barrier_in=5;
- Gyro_qin0();
- }
- }
- }
- break;
- case 5://直行
- {
- distence_count();//编码器测距
- if(XK.Encoder_distance>1)//行进距离
- {
- Distance_L=0;
- Distance_R=0;
- XK.time=0;
- XK.Encoder_distance=0;
- XK.barrier_in=6;
- Gyro_qin0();
- }
- }
- break;
- case 6://打角
- {
-
- if(XK.dash_dir==1)//左边避障
- {
- if(eulerAngle.yaw>5.0)//左航向角
- {
- Distance_L=0;
- Distance_R=0;
- XK.time=0;
- XK.Encoder_distance=0;
- XK.barrier_in=7;
- Gyro_qin0();
- }
- }
- if(XK.dash_dir==0)//右边避障
- {
- if(eulerAngle.yaw<-5.9)//右航向角
- {
- Distance_L=0;
- Distance_R=0;
- XK.time=0;
- XK.Encoder_distance=0;
- XK.barrier_in=7;
- Gyro_qin0();
- }
- }
- }
- break;
- case 7://直行,回赛道
- {
- extern float AD[6];
- distence_count();//编码器测距
- if(XK.dash_dir==1)
- {
- if((mt9v03x_image[110][140]+mt9v03x_image[110][141]+mt9v03x_image[110]
- [139])/3>100)//图像灰度像素大于某阈值(白色赛道)
-
- {
- Distance_L=0;
- Distance_R=0;
- XK.time=0;
- XK.Encoder_distance=0;
- XK.barrier_in=0;
- XK.barrier_judge=0;
-
- }
- }
- if(XK.dash_dir==0)
- {
- if((mt9v03x_image[110][48]+mt9v03x_image[110][49]+mt9v03x_image[110]
- [50])/3>100)//图像灰度像素大于某阈值(白色赛道)
-
- {
- Distance_L=0;
- Distance_R=0;
- XK.time=0;
- XK.Encoder_distance=0;
- XK.barrier_in=0;
- XK.barrier_judge=0;
-
- }
- }
- }
- break;
- }
- }
- }
本文旨在本校智能车实验室教学,若有错漏,欢迎指正
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。