赞
踩
之前一段时间在处理手头的一些事情,将算法开源系列搁置了一段时间(主要是懒了)。之前介绍了预处理,边线,拐点等,这一章主要介绍环岛。
在我比赛的算法,通常在处理元素之前,需要具备良好的图像边界,拐点,边界起始行,边界截止行等主要条件。之前系列文章介绍过了边界,和拐点。有人留言提到过拐点的程序,其实最简单的方法,就是连续几行的边界做差,差值满足条件就判断为拐点。
圆环!!这个在我做车三年一直都是噩梦存在的元素,虽然16届增加了新元素三岔,我依然在圆环花费了最多的时间。因为今年选用的是摄像头入环,所以在处理圆环的时候,不仅仅要考虑如何识别,还需要在入环,环内进行补线处理。于是我在处理圆环大致分为识别,入环切线,入环 ,环内,出环,出环切线,完全出环这几个阶段。
- void R_uppoint( unsigned char Row_START,unsigned char Row_END ,unsigned char Col_START,unsigned char Col_END,unsigned char Edge_ROW)
- {
- int Col;
- //uint8 N_P=0;
- int C1=0;
- int Row=Edge_ROW;
-
- for(Row=Edge_ROW;Row>Edge_ROW-7 && Row>ROW_START+1;Row--)//从本行开始向上扫10行
- {
- for(Col=Col_END-2;Col>15;Col--)//初始值固定
- {
- if(difference_sum(image[Row][Col-COL_SPACE],image[Row][Col])>=g_threshold_value)//检测到跳变点
- {
- if( abs(Col-COL_SPACE-C1)<2&& Col-COL_SPACE<=C1)//如果两列差值小于3,说明C为拐点
- {
- Inflection_point.R_up_point.x=Row;
- Inflection_point.R_up_point.y=C1;
- return;
- }
- C1=Col-COL_SPACE;
- break;
-
- }
- }
- }
- }
顾名思义吧,起始行就是第一次扫到边界的那一行,截止行是最后一次找到边界的行。这两个特征代表了边界的可用范围。
圆环的特征还是相当明显,一边边线,连续,一边边线,缺失。这里我采用的方式是在识别到一边拐点存在,一边拐点不存在,并且存在的拐点距离最远端很近,这里我以当拐点距离最远行小于5行为标准。当存在这些条件后,再进行拐点上面几行边线缺失判断。以左环为例,当左边存在拐点,并且拐点上方有三行不存在边线。就行下面的右边线计数,当右边先满足远小近大的条件,并且连续存在13行边线就满足圆环的识别。这种识别是很稳定的,但由于车库的存在通常会与车库误识别,所以对于两者区别还需要想办法解决。
- round->Entrance_count=0;//圆环入口计数清零
- if(point->L_down_point.x+5>ROW_END-1)
- Round_row=ROW_END-1;
- else
- Round_row=point->L_down_point.x+5;
- for(;Round_row>point->L_down_point.x-10&&Round_row>=ROW_START;Round_row--)//从左拐点下面5行到上面10行进行搜索
- {
- if(str->RightEdge[Round_row+1]!=0&&str->RightEdge[Round_row]!=0)
- {
- //如果右边正常递减,且不丢线 斜率符合要求
- if(str->RightEdge[Round_row+1]-str->RightEdge[Round_row]>=0 &&str->RightEdge[Round_row+1]-str->RightEdge[Round_row]<=2)
- {
- round->Entrance_count++; //圆环入口计数增加
- }
- }
- }
- if(round->Entrance_count>=13)//min修改,其中有13行满足条件即可判定为圆环
- {
- round->Round_flag=1;
- RoundType=Left_Round;
- RoundProcess=Find_Round;
-
- RoadType= Round_Road;
- // BlueRing;
- //RoundSize=Large_Round; //待定
- }
我们在识别到环的时候,是在环外的,所以需要保持一段距离直行到环的切点A。我的方法是通过 B点之前的斜率进行补线。
- for(Round_row=ROW_END;Round_row>=ROW_START;Round_row--)
- {
- if(str->RightEdge[Round_row])
- {
- char temp_r;
- char temp_l;
- char track;
- temp_r=str->RightEdge[Round_row];
- track=Boundary.track_Width[Round_row];
- temp_l=temp_r-track-1;
- if(temp_l>=79)
- {
- temp_l=78;
-
- }
- if(temp_l<=1)
- {
- temp_l=1;
-
- }
- str->LeftEdge[Round_row]=temp_l;
- // str->LeftEdge[Round_row]=str->RightEdge[Round_row]-str->track_Width[Round_row];//左边界等于右边界减半宽
- }
- else
- {
- str->LeftEdge[Round_row]=0;
- }
- }
对于进环,需要将右边线通过补线方式补成一个类似与弯道的情况。然后通过陀螺仪积分判断旋转的角度,当角度满足车身已经进入到环里的条件,就可以正常的巡线走了。
- case Into_Round://进环 关键 分两步
- {
- // lcd_showint8(110,6, 2);
- /*进环的补线处理*/
- if(!Inflection_point.L_down_point.x&&!Inflection_point.L_up_point.x&&str->LeftEdge[ROW_END-5])//&&str->LeftEdge[ROW-4])
- // if(Inflection_point.L_up_point.x==0&&Inflection_point.L_down_point.x&&str->LeftEdge[ROW_END-3])
- // if(Inflection_point.L_up_point.x&&(left_ad>=220||right_ad>200)&&!str->LeftEdge[ROW_END-1])
- {
-
- RoundProcess=Into_Round2;
- }
-
- else
- { //获取补线点信息
- if(point->L_down_point.x>5) //记录上一次拐点存在的信息
- {
- Inflection_Temp_x=point->L_down_point.x;
- Inflection_Temp_y=point->L_down_point.y;
- }
- //得到信息后,开始补线
- for(uint8 i=Inflection_Temp_x;i>2;i--)
- {
- if(image[i][Inflection_Temp_y]>=Threshold&&image[i-1][Inflection_Temp_y]<Threshold)
- {
- LeftLoopTemp_R=i-1;
- str->EndLine=i-1;
- break;
- }
- }
- for(uint8 i=Inflection_Temp_y;i<75;i++)
- {
- if((image[LeftLoopTemp_R-1][i+1]>=Threshold)&&(image[LeftLoopTemp_R-1][i]<Threshold))
- {
- LeftLoopTemp_C=i;
-
- break;
- }
- }
-
- /*进环斜率*/
- LeftLoopSlope=1.3;//*(str->RightEdge[aa1]-aa2)/(aa1-LeftLoopTemp_R);
-
- for(uint8 i=0;i<=28;i++)
- {
- str->RightEdge[LeftLoopTemp_R+i]=(int)(i*LeftLoopSlope+LeftLoopTemp_C);
-
- str->RightEdge[LeftLoopTemp_R+i]=int8_range_protect(str->RightEdge[LeftLoopTemp_R+i],1,79) ;
-
- if(str->RightEdge[LeftLoopTemp_R+i]>78||LeftLoopTemp_R+i>ROW_END)
- break;
- }
- }
-
- for(uint8 i=str->EndLine;i<ROW_END;i++)
- {
- for(uint8 j=1;j<=79;j++)
- {
- if(image[i][j]>=Threshold&&image[i][j+1]<Threshold)
- {
- if(str->RightEdge[i]>j+1)
- str->RightEdge[i]=j+1;
- break;
- }
- }
- }
- break;
- }
- case Into_Round2://进环 关键 4
- {
- // lcd_showint8(110,6, 3);
- /*判断是否进入环岛*/
- if(angle_z<=-40)//&&str->L_StartLine==0&& RoundSize==Small_Round) //定距离一段
- {
- RoundProcess=In_Round;
- Inflection_Temp_x=0;
- Inflection_Temp_y=0;
- //lcd_showint8(80,5, 4);
- }
-
- #if 1 //补线
- for(uint8 i=str->EndLine;i<=ROW_END;i++)
- {
- for(uint8 j=1;j<=75;j++)
- {
- if(image[i][j]>=Threshold&&image[i][j+1]<Threshold&&image[i][j+2]<Threshold&&image[i][j+3]<Threshold)
- //if (difference_sum(image[i][j],image[i][j-COL_SPACE])>=g_threshold_value)
- {
- if(str->RightEdge[i]>j+1)
- str->RightEdge[i]=j+1;
-
- break;
- }
- }
- }
-
-
- /*进环斜率*/
- LeftLoopSlope=2.0;
- for(uint8 i=ROW_END;i>ROW_START;i--)
- {
- // lcd_showint8(80,5, 5);
- if(str->RightEdge[i]!=0)
- str->RightEdge[i]=str->RightEdge[i]<(int)(LeftLoopSlope*i+5)?str->RightEdge[i]:(int)(LeftLoopSlope*i+5);
- else
- str->RightEdge[i]=(int)(LeftLoopSlope*i+5);
- if(str->RightEdge[i]>79)
- str->RightEdge[i]=0;
- }
- for(uint8 i=29;i>str->EndLine&&i>ROW_START+2;i--)
- {
- //lcd_showint8(80,5, 6);
- if(image[i][10]>=Threshold&&image[i-1][10]<Threshold&&image[i-2][10]<Threshold)
- //if (difference_sum(image[i-2][10],image[i][10])>=g_threshold_value)
- {
- for(uint8 j=i;j>str->EndLine&&j>ROW_START;j--)
- {
- str->LeftEdge[j]=0;
- }
- str->EndLine=i-1; //改变endline
- break;
- }
- if(str->LeftEdge[i]>30)
- {
- str->LeftEdge[i]=0; //限幅
- }
- }
- #endif
- break;
- }
在出环时,由于左边线不存在,因此也需要进行补线操作。目的就是为了出环时车转弯方向是正确的,
- case Leave_Round://离开圆环
- {
- // lcd_showint8(110,4, 6);
- Round_num=0;
- for(Round_row=str->R_StartLine;Round_row>str->EndLine+1&&Round_row>ROW_START+10;Round_row--)
- {
- if(str->RightEdge[Round_row]==0)
- {
- Round_num++;
- }
- }
- if(Round_num<3&&((str->R_StartLine-str->EndLine)>22||str->RightEdge[str->EndLine]>18)) //30需要调 huo 判断斜率
- {
- RoundProcess=Leave_Round2;//暂定
- }
- else
- {
- LeftLoopSlope=2.5;
- for(uint8 i=29;i>5;i--)
- {
- if(str->RightEdge[i]!=0)
- str->RightEdge[i]=str->RightEdge[i]<(unsigned char)(LeftLoopSlope*i+5)?str->RightEdge[i]:(unsigned char)(LeftLoopSlope*i+5);
- else
- str->RightEdge[i]=(unsigned char)(LeftLoopSlope*i+5);
- if(str->RightEdge[i]>79)
- str->RightEdge[i]=0;
- }
-
- for(uint8 i=29;i>str->EndLine;i--) //消除左线误搜索
- {
- if(str->LeftEdge[i]>40)
- {
- str->LeftEdge[i]=0;
- }
- if(i<29&&i>ROW_START)
- {
- if(str->LeftEdge[i]!=0&&str->LeftEdge[i-1]==0&&str->LeftEdge[i+1]==0)
- str->LeftEdge[i]=0;
- }
- }
- }
- break;
- }
在出环后,由于环岛元素存在的缺口,仍需要补线进行引导。也是通过斜率来进行补线。
- Round_num=0;
- for(Round_row=str->R_StartLine;Round_row>str->EndLine+1&&Round_row>ROW_START+10;Round_row--)
- {
- if(str->RightEdge[Round_row]==0)
- {
- Round_num++;
- }
- }
- if(Round_num<3&&((str->R_StartLine-str->EndLine)>22||str->RightEdge[str->EndLine]>18)) //30需要调 huo 判断斜率
- {
- RoundProcess=Leave_Round2;//暂定
- }
- else
- {
- LeftLoopSlope=2.5;
- for(uint8 i=29;i>5;i--)
- {
- if(str->RightEdge[i]!=0)
- str->RightEdge[i]=str->RightEdge[i]<(unsigned char)(LeftLoopSlope*i+5)?str->RightEdge[i]:(unsigned char)(LeftLoopSlope*i+5);
- else
- str->RightEdge[i]=(unsigned char)(LeftLoopSlope*i+5);
- if(str->RightEdge[i]>79)
- str->RightEdge[i]=0;
- }
-
- for(uint8 i=29;i>str->EndLine;i--) //消除左线误搜索
- {
- if(str->LeftEdge[i]>40)
- {
- str->LeftEdge[i]=0;
- }
- if(i<29&&i>ROW_START)
- {
- if(str->LeftEdge[i]!=0&&str->LeftEdge[i-1]==0&&str->LeftEdge[i+1]==0)
- str->LeftEdge[i]=0;
- }
- }
- }
之后当车行过缺口就可以恢复正常巡线,这里可以积路程,简单一点,也可以采用起始行是否在图像最底端来判断。
底下附上完整过程代码,以便大家推导理解,对于代码,不建议直接拿去用,因为图像与摄像头参数都不一样。可以根据上面提到的思路,自己写一遍。分阶段来实现进环,至少这套方法我在圆环这里基本没出现过问题,除了速度快了,麦轮没办法很及时的转弯进去。
多嘴一句,这里的方法也不是最好的,但之于我是很有效的。可能也有更快,更好,更丝滑的进环算法。我就充当一个抛砖引玉的角色,希望能帮助没有思路的车友有一种简单有效的方法去实现进环。这一章也是自己用手画的图,在我看来在调试元素的时候,趴赛道才是最好的方法。需要各位仔细琢磨,不断完善,才可以有适合自己的算法。
- void Round_Process(Str_Boundary *str,Str_Round *round,Str_Inflection_point *point)
- {
- float LeftLoopSlope;
- float RightLoopSlope;
- uint8 break_point_num;
- uint8 many_bp_row;
- uint8 white_point_num;
-
- uint8 Round_num=0;
- break_point_num=0;
- switch(RoundType)
- {
- case Left_Round: //左环
- {
- switch(RoundProcess)
- {
- case Find_Round://发现圆环
- {
- // mark_garage();
- // lcd_showint8(110,4, 0);
- for(uint8 i=29;i>=0&&i>Boundary.EndLine;i--)
- {
- if( Boundary.LeftEdge[i]==0 && Boundary.RightEdge[i] )
- {
- for(uint8 j=Boundary.RightEdge[i];j-1>5;j--)
- {
- if(mark_middle_num(image[i][j],image[i][j-1],Threshold)
- && abs( difference_sum(image[i][j],image[i][j-1]) )>=g_threshold_value-10 )//跳变
- {
- break_point_num++;
- if(break_point_num>7 )
- {
- many_bp_row++;
- break;
- }
- }
- }
-
- }
-
- if(many_bp_row>3)//黑白跳变点数 90
- {
- round->Round_flag=0;
- RoadType= else_road;
- return;
- }
- }
- // lcd_showint8(120,5,many_bp_row);
- //*进入下个阶段的判定*/
- if(str->L_StartLine<25) //da待改进
- {
- Round_num=0;
- for(Round_row=str->L_StartLine;Round_row>=str->L_StartLine-4&&Round_row>=ROW_START+1;Round_row--) //防止误判 检测换中心岛
- {
- if(str->LeftEdge[Round_row]!=0)
- {
- Round_num+=str->LeftEdge[Round_row]-str->LeftEdge[Round_row+1] ;
- }
- else
- {
- Round_num=0;
- }
- }
- if(Round_num>10)
- {
- Round_num=0;
- RoundProcess=Find_Gap;//就认为有缺口
- // lcd_showint8(80,1, 1);
- }
- }
- //*入环的补线*/
- for(Round_row=ROW_END;Round_row>=ROW_START;Round_row--)
- {
- if(str->RightEdge[Round_row])
- {
- char temp_r;
- char temp_l;
- char track;
- temp_r=str->RightEdge[Round_row];
- track=Boundary.track_Width[Round_row];
- temp_l=temp_r-track-1;
- if(temp_l>=79)
- {
- temp_l=78;
-
- }
- if(temp_l<=1)
- {
- temp_l=1;
-
- }
- str->LeftEdge[Round_row]=temp_l;
- // str->LeftEdge[Round_row]=str->RightEdge[Round_row]-str->track_Width[Round_row];//左边界等于右边界减半宽
- }
- else
- {
- str->LeftEdge[Round_row]=0;
- }
- }
- break;
- }
- case Find_Gap://发现圆环中心
- {
- // lcd_showint8(110,6, 1);
- /*下一阶段的判定*/
- //底部三行左边界都不丢线
- // if(str->LeftEdge[ROW_END-2]&&str->LeftEdge[ROW_END-1]&&str->LeftEdge[ROW_END-3])//&&str->LeftEdge[ROW_END-2]
- // if(Inflection_point.L_up_point.x&&Inflection_point.L_down_point.x&&(Inflection_point.L_down_point.x-Inflection_point.L_up_point.x)<15)
- // if(str->LeftEdge[ROW_END-2]&&str->LeftEdge[ROW_END-1]&&str->LeftEdge[ROW_END-3]&&Inflection_point.L_up_point.x)
- // mark_garage();
- // if(str->LeftEdge[ROW_END-1]-str->LeftEdge[ROW_END-2]>0&&str->LeftEdge[ROW_END-2]-str->LeftEdge[ROW_END-3]>0)
- // for(uint8 i=29;i>=0&&i>Boundary.EndLine;i--)
- // {
- //
- //
- if( Boundary.LeftEdge[i]==0 && Boundary.RightEdge[i] )
- {
- // for(uint8 j=Boundary.RightEdge[i];j-1>COL_END-10;j++)
- // {
- // if(mark_middle_num(image[i][j],image[i][j-1],Threshold)
- // && abs( difference_sum(image[i][j],image[i][j-1]) )>=g_threshold_value-10 )//跳变
- // {
- // break_point_num++;
- // if(break_point_num>7 )
- // {
- // many_bp_row++;
- // break;
- // }
- // }
- // }
-
- }
- //
- // if(many_bp_row>2)//黑白跳变点数 90
- // {
- // round->Round_flag=0;
- // RoadType= else_road;
- // return;
- // }
- // }
-
- if(e_distance>1000)
- {
- if(Inflection_point.L_up_point.x)
- {
-
- RoundProcess=Into_Round;
- }
- }
-
- /*左补线*/
- for(Round_row=ROW_END;Round_row>=ROW_START;Round_row--)
- {
- if(str->RightEdge[Round_row])
- {
- // str->LeftEdge[Round_row]=str->RightEdge[Round_row]-str->track_Width[Round_row];//左边界等于右边界减半宽
- char temp_r;
- char temp_l;
- char track;
- temp_r=str->RightEdge[Round_row];
- track=Boundary.track_Width[Round_row];
- temp_l=temp_r-track;
- if(temp_l>=79)
- {
- temp_l=78;
-
- }
- if(temp_l<=1)
- {
- temp_l=1;
-
- }
- str->LeftEdge[Round_row]=temp_l;
- }
- else
- {
- str->LeftEdge[Round_row]=0;
- }
- }
- break;
- }
- case Into_Round://进环 关键 分两步
- {
- // lcd_showint8(110,6, 2);
- /*进环的补线处理*/
- if(!Inflection_point.L_down_point.x&&!Inflection_point.L_up_point.x&&str->LeftEdge[ROW_END-5])//&&str->LeftEdge[ROW-4])
- // if(Inflection_point.L_up_point.x==0&&Inflection_point.L_down_point.x&&str->LeftEdge[ROW_END-3])
- // if(Inflection_point.L_up_point.x&&(left_ad>=220||right_ad>200)&&!str->LeftEdge[ROW_END-1])
- {
-
- RoundProcess=Into_Round2;
- }
-
- else
- { //获取补线点信息
- if(point->L_down_point.x>5) //记录上一次拐点存在的信息
- {
- Inflection_Temp_x=point->L_down_point.x;
- Inflection_Temp_y=point->L_down_point.y;
- }
- //得到信息后,开始补线
- for(uint8 i=Inflection_Temp_x;i>2;i--)
- {
- if(image[i][Inflection_Temp_y]>=Threshold&&image[i-1][Inflection_Temp_y]<Threshold)
- {
- LeftLoopTemp_R=i-1;
- str->EndLine=i-1;
- break;
- }
- }
- for(uint8 i=Inflection_Temp_y;i<75;i++)
- {
- if((image[LeftLoopTemp_R-1][i+1]>=Threshold)&&(image[LeftLoopTemp_R-1][i]<Threshold))
- {
- LeftLoopTemp_C=i;
-
- break;
- }
- }
-
- /*进环斜率*/
- LeftLoopSlope=1.3;//*(str->RightEdge[aa1]-aa2)/(aa1-LeftLoopTemp_R);
-
- for(uint8 i=0;i<=28;i++)
- {
- str->RightEdge[LeftLoopTemp_R+i]=(int)(i*LeftLoopSlope+LeftLoopTemp_C);
-
- str->RightEdge[LeftLoopTemp_R+i]=int8_range_protect(str->RightEdge[LeftLoopTemp_R+i],1,79) ;
-
- if(str->RightEdge[LeftLoopTemp_R+i]>78||LeftLoopTemp_R+i>ROW_END)
- break;
- }
- }
-
- for(uint8 i=str->EndLine;i<ROW_END;i++)
- {
- for(uint8 j=1;j<=79;j++)
- {
- if(image[i][j]>=Threshold&&image[i][j+1]<Threshold)
- {
- if(str->RightEdge[i]>j+1)
- str->RightEdge[i]=j+1;
- break;
- }
- }
- }
- break;
- }
- case Into_Round2://进环 关键 4
- {
- // lcd_showint8(110,6, 3);
- /*判断是否进入环岛*/
- if(angle_z<=-40)//&&str->L_StartLine==0&& RoundSize==Small_Round) //定距离一段
- {
- RoundProcess=In_Round;
- Inflection_Temp_x=0;
- Inflection_Temp_y=0;
- //lcd_showint8(80,5, 4);
- }
-
- #if 1 //补线
- for(uint8 i=str->EndLine;i<=ROW_END;i++)
- {
- for(uint8 j=1;j<=75;j++)
- {
- if(image[i][j]>=Threshold&&image[i][j+1]<Threshold&&image[i][j+2]<Threshold&&image[i][j+3]<Threshold)
- //if (difference_sum(image[i][j],image[i][j-COL_SPACE])>=g_threshold_value)
- {
- if(str->RightEdge[i]>j+1)
- str->RightEdge[i]=j+1;
-
- break;
- }
- }
- }
-
-
- /*进环斜率*/
- LeftLoopSlope=2.0;
- for(uint8 i=ROW_END;i>ROW_START;i--)
- {
- // lcd_showint8(80,5, 5);
- if(str->RightEdge[i]!=0)
- str->RightEdge[i]=str->RightEdge[i]<(int)(LeftLoopSlope*i+5)?str->RightEdge[i]:(int)(LeftLoopSlope*i+5);
- else
- str->RightEdge[i]=(int)(LeftLoopSlope*i+5);
- if(str->RightEdge[i]>79)
- str->RightEdge[i]=0;
- }
- for(uint8 i=29;i>str->EndLine&&i>ROW_START+2;i--)
- {
- //lcd_showint8(80,5, 6);
- if(image[i][10]>=Threshold&&image[i-1][10]<Threshold&&image[i-2][10]<Threshold)
- //if (difference_sum(image[i-2][10],image[i][10])>=g_threshold_value)
- {
- for(uint8 j=i;j>str->EndLine&&j>ROW_START;j--)
- {
- str->LeftEdge[j]=0;
- }
- str->EndLine=i-1; //改变endline
- break;
- }
- if(str->LeftEdge[i]>30)
- {
- str->LeftEdge[i]=0; //限幅
- }
- }
- #endif
- break;
- }
- case In_Round://在环内 5
- {
- // lcd_showint8(110,4,4);
- //记录上一次拐点存在的信息
- if(point->R_down_point.x&&image[point->R_down_point.x][point->R_down_point.y-2]>=Threshold&&image[point->R_down_point.x][point->R_down_point.y-3]>=Threshold&&image[point->R_down_point.x-1][point->R_down_point.y]>=Threshold&&image[point->R_down_point.x-2][point->R_down_point.y]>=Threshold)
- {
- Inflection_Temp_x=point->R_down_point.x;
- Inflection_Temp_y =point->R_down_point.y;
- //判断下一阶段
- if(point->R_down_point.x>5)
- {
- uint8 hang_num=0; //清除白块计数值 8
- for(Round_row=point->R_down_point.x-1; Round_row>=point->R_down_point.x-6&&Round_row>ROW_START ; Round_row-- ) //在搜索到的黑白跳变点后,向上搜索白点,判断是否为干扰点
- {
- if(str->RowLose[Round_row]==4)
- {
- hang_num++;
- }
- }
- if( hang_num>2|| point->R_down_point.x>20||Inflection_point.R_down_point.y>30)
- {
- RoundProcess=Out_Round;
- // lcd_showint8(110,4, 4);
- }
- }
- }
-
- if(Inflection_Temp_x>0)
- {
- //补线
- LeftLoopSlope=2.0;
- for(uint8 i=Inflection_Temp_x+1;i>ROW_START;i--)
- {
-
- str->RightEdge[i]=(int)((i-Inflection_Temp_x)*LeftLoopSlope+Inflection_Temp_y); //fuhao
- if (str->RightEdge[i]<COL_START)
- {
- str->EndLine =i;
- break;
- }
- }
- //str->StartLine=ROW_END;
- //memset(str->LeftEdge, 0,sizeof(str->LeftEdge) ); //z左线清空
- }
- for(uint8 i=29;i>str->EndLine;i--) //消除左线误搜索
- {
- if(str->LeftEdge[i]>30)
- {
- str->LeftEdge[i]=0;
- }
- }
- break;
- }
-
- case Out_Round://出环 6
- {
- // BlueRing;
- // lcd_showint8(110,4, 5);
- LeftLoopSlope=2.1;
- for(uint8 i=29;i>5;i--)//取小值
- {
- if(str->RightEdge[i]!=0)
- str->RightEdge[i]=str->RightEdge[i]<(unsigned char)(LeftLoopSlope*i+7)?str->RightEdge[i]:(unsigned char)(LeftLoopSlope*i+7);
- else
- str->RightEdge[i]=(unsigned char)(LeftLoopSlope*i+7);
- if(str->RightEdge[i]>79)
- str->RightEdge[i]=0;
- }
- // str->StartLine=ROW_END;
- // memset(str->LeftEdge, 0,sizeof(str->LeftEdge) );
- //
- if(angle_z<-85) //下一阶段标志
- {
- RoundProcess=Leave_Round;
- }
- for(uint8 i=29;i>str->EndLine;i--) //消除左线误搜索
- {
- if(str->LeftEdge[i]>35)
- {
- str->LeftEdge[i]=0;
- }
- if(i<29&&i>ROW_START)
- {
- if(str->LeftEdge[i]!=0&&str->LeftEdge[i-1]==0&&str->LeftEdge[i+1]==0)
- str->LeftEdge[i]=0;
- }
- }
- /*下一阶段的判定*/
-
- break;
- }
- case Leave_Round://离开圆环
- {
- // lcd_showint8(110,4, 6);
- Round_num=0;
- for(Round_row=str->R_StartLine;Round_row>str->EndLine+1&&Round_row>ROW_START+10;Round_row--)
- {
- if(str->RightEdge[Round_row]==0)
- {
- Round_num++;
- }
- }
- if(Round_num<3&&((str->R_StartLine-str->EndLine)>22||str->RightEdge[str->EndLine]>18)) //30需要调 huo 判断斜率
- {
- RoundProcess=Leave_Round2;//暂定
- }
- else
- {
- LeftLoopSlope=2.5;
- for(uint8 i=29;i>5;i--)
- {
- if(str->RightEdge[i]!=0)
- str->RightEdge[i]=str->RightEdge[i]<(unsigned char)(LeftLoopSlope*i+5)?str->RightEdge[i]:(unsigned char)(LeftLoopSlope*i+5);
- else
- str->RightEdge[i]=(unsigned char)(LeftLoopSlope*i+5);
- if(str->RightEdge[i]>79)
- str->RightEdge[i]=0;
- }
-
- for(uint8 i=29;i>str->EndLine;i--) //消除左线误搜索
- {
- if(str->LeftEdge[i]>40)
- {
- str->LeftEdge[i]=0;
- }
- if(i<29&&i>ROW_START)
- {
- if(str->LeftEdge[i]!=0&&str->LeftEdge[i-1]==0&&str->LeftEdge[i+1]==0)
- str->LeftEdge[i]=0;
- }
- }
- }
- break;
- }
- case Leave_Round2://离开圆环 7
- {
- //可以拉长视野
- // lcd_showint8(110,4, 7);
- for(Round_row=ROW_END;Round_row>=ROW_START;Round_row--)
- {
- if(str->RightEdge[Round_row])
- {
- // str->LeftEdge[Round_row]=str->RightEdge[Round_row]-str->track_Width[Round_row];//左边界等于右边界减半宽
- //if(str->RightEdge[Round_row])
- char temp_r;
- char temp_l;
- char track;
- temp_r=str->RightEdge[Round_row];
- track=str->track_Width[Round_row]+2.8;
- temp_l=temp_r-track;
- if(temp_l>=79)
- {
- temp_l=78;
-
- }
- if(temp_l<=1)
- {
- temp_l=1;
-
- }
- str->LeftEdge[Round_row]=temp_l;
- }
- else
- {
- str->LeftEdge[Round_row]=0;
- }
- }
-
- if (Lost_num<2)
- {
-
- if(str->L_StartLine&&str->R_StartLine&&str->L_StartLine==29&&str->R_StartLine==29&&Inflection_point.L_down_point.x==0&&Inflection_point.L_up_point.x==0)
- {
- // lcd_showint8(110,4, 7);
- if(str->LeftEdge[ROW_END-2]-str->LeftEdge[ROW_END-1]>0&&str->LeftEdge[ROW_END-4]-str->LeftEdge[ROW_END-3]>0)
- {
- RoundProcess=Round_Not_Found;//暂定
- round->Round_flag=0;
- RoadType= else_road;
- // BlueQuiet;
- }
- }
-
- }
- break;
- }
- default:
- {
- break;
- }
- }
- break;
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。