金牌会员
- 积分
- 1416
- 威望
- 1049
- 贡献
- 297
- 兑换币
- 128
- 注册时间
- 2015-12-2
- 在线时间
- 35 小时
|
15点考完,第一时间来更一贴,明天要去北京,过三天回来继续更。
今天更一个障碍和终点线。
我个认为这两个是很容易混淆的,尤其是起跑线会误判成障碍,理由如下:
如果障碍反光(障碍的斜面及其容易导致其反射体育馆顶部灯光)导致其特征与起跑线较像(间隔的白黑);
因此无法限制障碍的宽度与起跑线区分;而且障碍的远近也会影响障碍宽度;
所以一开始我使用的直接简单粗暴的方法:左右都是障碍则是起跑线,这样连起跑线都不用写了;
这样嘚瑟了没几天就发现远么有想象中简单。。。如果起跑线斜了或者不整齐,可能一边判到另一边没有判到;
在起跑线一打角,gg;所以除非连续判断几次来确认是否是真障碍,这样的缺点是会有延迟,
要保证足够及时的话又得继续提前判断,图像越远信息量越少,可判的依据就更少了,一米之外障碍的长度只有不到10行;
所以最后还是将障碍与起跑分别判断;
一般判断障碍又有两种方法,
1.从边线往中线搜索,会搜到白黑黑白,且仅有一次白黑黑白,最后还可以根据最后搜到的黑白开始描绘出障碍的一边,
与另一边线计算中线;这样存在的问题还是一个。。。反光,如果障碍上面贴的黑胶带不是亚光的,恭喜你,障碍即将gg;
如果反光无法确认只有一次白黑黑白,可能出现多次,与起跑线同;这样无法确认是否搜索到障碍的边,更无法计算中线;
还有一个问题才想起,如果因为阴影或者障碍摆放的问题,从边线开始的白色很少或者没有(自行想象障碍直接贴边放),
这样就不满足开始的白黑黑白了;
2.从中线往边线搜索,简单暴力,确认得到障碍的跳变之后,描绘出障碍的边线,限制这个边线的形态可以解决一些误判,
比如障碍的边不应该太斜(如角度不超过45度或者斜率满足什么什么的),
然后要排除掉起跑的误判,可以从障碍的边往另一边搜索应该持续一定宽度的白。。。
下面是确认是障碍之后,怎么走的问题:
使用障碍的边线与另一边线计算中线,这样中线是会向车的方向延伸的,自带补线的感觉。。。
- if(Left_zhangai_find != 0 && Right_zhangai_find == 0)//左边障碍
- {
- memset(LeftLineY,0,200);
- memset(LeftLineX,0,200);
-
- LeftLineX[1] = black2white_X[4];//使用后面一点的点 ,避免因为畸变 在障碍 底边开始搜线
- LeftLineY[1] = black2white_Y[4];
- LeftLineX[2] = black2white_X[5];
- LeftLineY[2] = black2white_Y[5];
- LineSerch(image,LeftLineY,LeftLineX,RightLineY,RightLineX,&LeftLineDot,&RightLineDot,Search_Line_Th,0,1);//只搜左边线
-
- if (Left_zhangai_find_count<255) //防溢出
- Left_zhangai_find_count ++;
- if (Left_zhangai_find_count >= 3)// && Zhangai_find != 6)//上一次 不是 左右障碍
- Zhangai_find = 1;
-
- }
复制代码
以上搜索出障碍的边,
以下按照边线比例计算中线,
- /***********************************************************
- * * 函数名称 GetCenterLine_ByRat
- * * 参 数 :
- * * 功 能
- * * 日 期 :2017/5/1
- * * 作 者 :水滴
- ************************************************************/
- void GetCenterLine_ByRat(uint8* LeftLineY,uint8* LeftLineX,uint8* RightLineY,uint8* RightLineX,uint8* CenterLineY,uint8* CenterLineX,uint8* LeftLineDot,uint8* RightLineDot,uint8* CenterLineDot)
- {
- double Rat;//边线比
- static uint8 Dot=0;
- if (*LeftLineDot>*RightLineDot)
- {
- Rat=(*LeftLineDot)/(*RightLineDot);
- for (Dot=1;Dot<=*RightLineDot;Dot++)
- {
- CenterLineY[Dot]=(uint8)(((RightLineY[Dot]+LeftLineY[(uint8)(Dot*Rat+0.5)])/2)+0.5);
- CenterLineX[Dot]=(uint8)(((RightLineX[Dot]+LeftLineX[(uint8)(Dot*Rat+0.5)])/2)+0.5);
- }
- *CenterLineDot=*RightLineDot;
- }
- else
- {
- Rat=(*RightLineDot)/(*LeftLineDot);
- for (Dot=1;Dot<=*LeftLineDot;Dot++)
- {
- CenterLineY[Dot]=(uint8)(((LeftLineY[Dot]+RightLineY[(uint8)(Dot*Rat+0.5)])/2)+0.5);
- CenterLineX[Dot]=(uint8)(((LeftLineX[Dot]+RightLineX[(uint8)(Dot*Rat+0.5)])/2)+0.5);
- }
- *CenterLineDot=*LeftLineDot;
- }
- }
复制代码
好,现在成功识别了障碍并打角,而且打角的偏差是通过障碍的一个比较真实的偏差。
好,问题来了,进入障碍之后呢?已经无法使用前面说的特征判断障碍了,所以干脆直接延时过就好了额,
问题是延时的偏差怎么来?我觉得对于三米的直立可以不用处理这部分,毕竟晃一下就过去了,奈何是渣渣小车,
还得处理,我处理的方法如下:
进入障碍之后,如果前瞻已经出了障碍,那么此时将障碍的那边线向前补线到超过前瞻,
- if ((Distance_cm - zhangai_start_Distance_cm) < 80 && (sys_time - zhangai_start_time) < 600)//||障碍延时100ms
- {
- Zhangai_find_realtime = 1;
- if (Zhangai_find == 1)//左障碍
- {
- if(LeftLineY[LeftLineDot - 1] > get_hang)//没到前瞻 补到前瞻 {
- if (LeftLineDot>13 )
- {
- float LKcof;
- uint8 LeftLineDot_temp = LeftLineDot-3;
- uint8 buxian_count = LeftLineY[LeftLineDot_temp] - get_hang;
- Line_Fit(LeftLineX,LeftLineY,LeftLineDot-12,LeftLineDot_temp,&LKcof );//最前端的点不用 可能不准
-
- if (LKcof < 0)
- {
- uint8 i;
- for ( i = 1;i<buxian_count;i++)
- {
- LeftLineX[LeftLineDot_temp+i] = (int)(-1.0/LKcof*(i) + LeftLineX[LeftLineDot_temp] + 0.5);
- LeftLineY[LeftLineDot_temp+i] = (int)(LeftLineY[LeftLineDot_temp] - i);
- }
- LeftLineDot = LeftLineDot_temp+i - 1;
-
- }
- else if (LKcof == 0)//直着补
- {
- uint8 i;
- for ( i = 1;i<buxian_count;i++)
- {
- LeftLineX[LeftLineDot_temp+i] = (int)(LeftLineX[LeftLineDot_temp] );
- LeftLineY[LeftLineDot_temp+i] = (int)(LeftLineY[LeftLineDot_temp] - i);
- }
- LeftLineDot = LeftLineDot_temp+i - 1;
-
- }
- }
- else
- Zhangai_find_realtime = 0;//出障碍
- }
-
- }
- }
复制代码
其中处理了一下斜率为0的情况,在拟合斜率时斜率小时截断误差大,拟合斜率时在斜率接近0时就已经认为斜率是0,
所以此时直接向正上方补线即可,以上代码的斜率大于零并没有计算,因为正常情况下障碍的一边只会向中间倾斜,
如果向外,那就应该是搜线错了,或者其他的问题。
这样基本能够完美出障碍了,不会因为偏差提前给到了赛道中央而使小车提前出障碍而压障碍!
最后再出障碍后的一段时间内把偏差平滑以下,避免抖动,或者直接加大D(陀螺仪方向D)。
至此障碍完美通过,对于卓大大说了障碍一边没有路肩,为了保险不压障碍,可以将偏差向外平移 n 个像素点;
毕竟如果计算的中线稍微有差,就可能撵上障碍。。。。除非你绝对自信
再就是起跑线,不想描述太多,直接刷代码了,比较简单,看看就能懂,
开始我想的复杂了点,起始的条件比较高(看我注释掉的部分代码),但是对于智能车,简单粗暴就好了,要什么自行车。。。。
直接从中间往左右搜大概多少列就好了。。。。。。
因为我最后只在比较近端搜索起跑线,所以注释了前面的部分代码,如果要在较远处判断,为了减少误判,应该是要加上那一堆。。。
谁叫我不是双车呢。。。不然我会提前两米识别起跑线然后超车并排冲线的。。。。
吹牛逼了哈。
障碍部分代码都只给了一半,给大家一个思路而已。
实际测试障碍大概一米处检测到,然后开始拐,障碍之后慢回归正常中线。
再啰嗦一个起跑线的问题,有的人的搜线算法是从图像低端开始,这样如果起跑线正好在图像低端时要特殊处理,
保证搜线的正确。。。
再啰嗦一个,如果障碍在起跑线后,要能够忽略起跑线搜索到真的障碍,不然等你过了起跑线再搜到就GG了;
可以参考我障碍部分的代码,处理了这部分的问题。思想就是如果是起跑线误判障碍就继续往下搜索障碍就好了!
以上都是我自己胡说八道,万万不可全信,大神们就请默默路过求轻喷。。。
待我从北京回来之后更一些方向环相关的东西,主要涉及 模糊方向参数,前瞻,跳轮,等问题,
|
|