4.2.2 线性CCD传感器路径识别算法
路径识别算法是我们使用的是由CCD中心向两侧搜索提取跳变沿的算法,通过提取到的两侧跳变沿即为赛道的左右边界。具体算法介绍如下:
通过CCD返回的像素值,利用阈值来找到跳变沿,得到赛道的左右边界,进一步得到赛道的中线。
式中,Pixel2[i]为对应传感器的状态值。 {
ccd2_single_line_flag=0; single_line_flag=0; left_line=0; right_line=0;
for(i=ccd2_middle[0]+5;i<=127;i++)//左——右:白到黑//实测{ right_line++; if(
(pixel2[i-1]>ccd2latch) &&(pixel2[i]>ccd2latch) &&(pixel2[i+1] {ccd2_rightenable=1;ccd2_right=i;break;} } for(i=ccd2_middle[0]-5;i>0;i--)//右———左:白到黑//实测13 11 { left_line++; if( (pixel2[i+1]>ccd2latch) &&(pixel2[i]>ccd2latch) &&(pixel2[i-1] {ccd2_leftenable=1;ccd2_left=i;break;} } } if(106-ccd2_right<=5) ccd2_rightenable=0;//111 if(ccd2_left-7<5) ccd2_leftenable=0;//12 } else { 31 第九届全国大学生智能汽车邀请赛技术报告 ccd2_rightenable=0; ccd2_leftenable=0; }其中ccd2_rightenable;ccd2_leftenable;是否能够找到左右边界,当左边界小于12,或者右边界大于111时,(这里需要根据实际使用的CCD的情况确定)我们认为丢线。由此可以得到模型车的状态,为下一步控制决策提供必要的信息。 4.3赛道策略分析 对于我们的模型车,这一届新增灯塔起跑与停车,CCD在赛道上可能的状态 有:直道、单线、十字交叉线(包括直入和弯入)、小S弯道、直角弯、坡道、路障。由于规则的变更,使得今年对于赛道识别的工作量变得更加复杂,难度大大增加,情况也显得错综复杂,矛盾点层出不穷。 4.3.1 灯塔策略分析 摄像头组和光电组的比赛分为以下四个阶段: 1.起跑阶段:车模在发车灯塔前一米起跑区内静止,此时车模任何部位不得超过发车灯塔中心对应的起跑线。灯塔灯光熄灭后,比赛计时系统开始计时。车模需要在五秒钟之内冲过起跑区域此期间的车模延迟时间计算在比赛成绩中。如果车模没有能够在五秒钟冲过起跑线,则算作车模冲出赛道一次,重新开始。 2.比赛阶段:车模冲过起跑线在赛道上运行。发车灯塔在 LED 熄灭五秒钟 后重新点亮,为车模到达终点做准备。 3.冲刺阶段:车模运行到终点附近,在尚未通过计时系统光电传感器之前检测到发车灯塔上的LED脉冲灯光。此时车模应该准备减速慢行,直至通过计时系统光电传感器。 4.停止阶段:计时系统检测到车模通过时,比赛计时结束。同时发车灯塔上的LED灯光熄灭。车模检测到LED灯光熄灭时,应该立即停止。如果车模停止在灯塔前,比赛正常结束。如果车模没有能够停止在灯塔前,比赛时间加罚一秒钟。 具体比赛过程参加下图4.3所示: 32 图4.3 灯塔比赛过程 对于灯塔的检测,我们找了好多种红外管进行检测,最终我们选择的是0038b的红外管进行检测(实践证明尽管管子的型号相同但是不同产家生产的在检测强度上还是有很大的差异)。0038b在没有检测到灯塔的红外信号时输出为高电平,检测到灯塔信号后,输出为频率为1KHZ的脉冲信号。我们对信号的处理是通过外部中断检测上升沿来检测灯塔的高低电平个数,通过控制采样时间10ms来检测脉冲个数,将脉冲个数存放在数组light[i]中,通过判断数组light[i]的个数是否在8~12之间,来确定是 否有效(理论上为10个,经过我们的实际测量也为10个,但是为了留有一定的域度我们这里取得是8~12个)。然后通过灯塔的变化情况来进行发车或者停车。具体程序如下: void light_check()//灯塔检测 { uint8 i; light_check_gap++; if(light_check_gap>=5)///控制采样时间10ms { 33 第九届全国大学生智能汽车邀请赛技术报告 light_check_gap=0;//每20ms,脉冲递增量 for(i=9;i>0;i--) light[i]=light[i-1]; light[0]=startline_count-last_startline_count; last_startline_count=startline_count; for(i=0;i<10;i++) { if(light[i]>8&&light[i]<=12)//0.9ms~1.1ms判定是否有效信号 light_enable[i]=1; else light_enable[i]=0; } if(light_enable[0]==0 &&light_enable[1]==1 &&light_enable[2]==1 &&light_enable[3]==1 &&light_enable[4]==1 &&light_enable[5]==1 &&light_enable[6]==1 &&light_enable[7]==1 &&light_enable[8]==1 &&light_enable[9]==1 &&havego==1)//原先亮突然灭,且已发车,就停止 { stop=1; smartstate=3; } if(light_enable[0]==0 &&light_enable[1]==1 &&light_enable[2]==1 &&light_enable[3]==1 &&light_enable[4]==1 &&light_enable[5]==1 &&light_enable[6]==1 &&light_enable[7]==1 &&light_enable[8]==1 &&light_enable[9]==1 &&havego==0)//原先亮突然灭,发车 { gogogo=1; 34