智能车制作

 找回密码
 注册

扫一扫,访问微社区

查看: 11829|回复: 48
打印 上一主题 下一主题

单CCD 直道,障碍,单线,斜入黑线,稳定算法解决方案。

    [复制链接]

1

主题

13

帖子

0

精华

高级会员

Rank: 4

积分
686
威望
357
贡献
211
兑换币
222
注册时间
2013-8-24
在线时间
59 小时
跳转到指定楼层
1#
发表于 2015-7-21 14:50:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 枫华幻吟 于 2015-7-21 14:52 编辑

抛砖引玉,下面的算法都是使用单CCD使用120度广角镜下完成的算法。
算法的第一要务是稳定,不会出现误判,下面将列举单线,直道,障碍物,以及斜入直角前的黑线。
1.跳变沿法(自定义的)
  在说这些东西的时候,好的方法可以事半功倍。这个方法下面将用到
  上图看特点
  
单线:
这个是单线下的图像,纵轴0表示黑线,255表示白线,首先我们需要记录这条线上的所有的上升沿和下降沿,红色表示下降沿,绿色表示上升沿,红绿数字表示下标,如何统计呢,看程序,(线性CCD有效范围5-122)。
void find_TiaoBian1(uint8 *buf,uint16 len)
{  
  int fall_num = 0,rase_num = 0,barrier_flag_t = 0;
  int fall_index[128] ={0},rase_index[128] ={0};

  if(white_flag1 == 0 && black_flag1==0 )   //不是全白且不是全黑的情况下
  {
    for(int i=5;i<(len-7);i++)
    {
      if((buf
-buf[i+1]) == 255 && (buf-buf[i+2]) == 255)   //从白到黑的下降沿(方向从左往右)
      {
         fall_index[fall_num] = i;      //记录所有的下降沿位置下标
         fall_num++;
      }
    }

    for(int i=122;i>7;i--)
    {
      if((buf
-buf[i-1]) == 255 && (buf-buf[i-2]) == 255)   //从黑到白的上升沿(方向从左往右)
      {
         rase_index[rase_num] = i;   //记录所有的上升沿的位置下标
         rase_num++;
      }
    }

    fall = fall_num;     //全局变量直道要用
    rase = rase_num;

    if(Oneflag == 1 && fall_num == 1 && rase_num == 0) //只有右边有下降沿(单线时)
    {
       if(fall_index[0] <= 120)                        //判断是不是进入双线状态,黑点太多127-15.下标。
       {
          Oneflag = 0;                                 //判断进入双线
       }
    }
    else if(Oneflag == 1 && fall_num == 0 && rase_num == 1) //只有右边有上升沿(单线时)
    {
       if(rase_index[0] >= 18)                              //判断是不是进入双线状态,黑点太多127-15.下标。
       {
          Oneflag = 0;                                      //判断进入双线
       }
    }

    for(int i=0;i<fall_num;i++)
    {
       for(int j=0;j<rase_num;j++)
       {
          if((rase_index[j]-fall_index)<=13 && (rase_index[j]-fall_index)>=3)    //找到了单线

          {
             lastmid3 = (int)((fall_index
+ rase_index[j])/2);
             Oneflag = 1;
             break;
          }
          else
          {
            Oneflag = 0;
          }
}

Oneflag = 1;的时候就是进入单线的时候,明白了么黑线的宽度范围是3-13,实际检测单线的宽度在6-8之间变化。此方法适用于直入单线,斜入单线,以及单线丢线的情况,100%不会出现问题。
2.障碍:
会使用跳变沿法找到单线,那么障碍物同理也会很容易找到。方法如下
上图

看着这个图发现一个问题,它和单线有点相似,唯一不同的地方是中间的黑线变宽了,宽度大概多少呢,经过测算宽度在18到22之间,程序就不发了,和上面一样,检测到障碍物,但是障碍物到底在左边还是右边呢,这个很简单,找到障碍物黑线两边的下标相加除2得到的值大于63就是在右边,反之在左边。
3,直道(记忆法)
对于直道很多人使用很多方法会误判,单ccd很难去识别。
这里提供一个记忆法,我们没法判断当前状态时,我们可以尝试判断过去,怎样判断呢,直接上程序,你看懂就行、此方法效果明显,避免了十字道丢线法的误判。
void find_Ensure(void)
{
  int stack_mid_Left[151] = {0};
  int stack_mid_Right[151] = {0};
  int Sum_Left_index = 0,Sum_Right_index = 0;

  if((fall+rase)>0 && (fall+rase)<=2)     //发现呢么这里的fall和rase用到了前面的跳变沿算法他是全局变量
  {
    mid_num_index++;
    if(fall==1)
    {
      stack_mid_Right[mid_num_index] = 1;   //右边下降沿
    }
    else if(rase==1)
    {
      stack_mid_Left[mid_num_index] = 1;    //左边上升沿
    }
    if(mid_num_index>=70)    //70根据速度快慢自己调大小
    {
      mid_num_index = 0;
    }
  }
  if(black_flag1==1)                        //如果出现全黑CCD1
  {
    for(int i=0;i<=70;i++)
    {
      Sum_Left_index+=stack_mid_Left
;         //左边黑线数量统计
      Sum_Right_index+=stack_mid_Right
;       //右边黑线数量统计
    }
  }

//判断右边直道data_T按键调节大小默认20,我称之为判断灵敏度,防止将黑线判断为直道
   if(black_flag1==1 && LR_flag==0 && (Sum_Left_index-Sum_Right_index)>=data_T)  
    {
       Right_TT = 1;
       LR_flag = 1;
    }
    else if(black_flag1==1 && LR_flag==0 && (Sum_Right_index-Sum_Left_index)>=data_T)  //判断左边直道
    {
       Left_TT = 1;
       LR_flag = 1;
    }

4,斜入直角前的黑线这个也可以用跳变沿法进行判断,这里不再列举,自己养成习惯,画个图,用跳变沿法就能找到特点。我们经常使用上次的中线值作为下次开始的起点,向两边找黑线,这种方法会有误判,是用跳变沿法特点可以用很简短的代码解决这一问题,前面写了很多道路路径识别,识别出来了,怎么去控制小车呢,最笨的方法在直道和障碍物时直接给出中线偏差值,大死角,这个是最笨的方法,很不稳定车体摇晃,易出赛道,可以采用补线的方法。
写了这么久大家如果觉得好,给点鼓励了,拜托了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

11

主题

91

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1551
威望
759
贡献
520
兑换币
452
注册时间
2015-1-6
在线时间
136 小时
毕业学校
放松放松
推荐
发表于 2015-7-21 18:01:45 | 只看该作者
赞赞赞
回复 支持 1 反对 0

使用道具 举报

32

主题

3009

帖子

0

精华

杰出人士

学期班的来卖萌?

Rank: 12Rank: 12Rank: 12

积分
14832

在线王奖章活跃会员奖章优秀会员奖章论坛元老奖章资源大师奖章

威望
5952
贡献
3172
兑换币
4257
注册时间
2013-11-26
在线时间
2854 小时
2#
发表于 2015-7-21 15:13:27 | 只看该作者
赛场条件好的话,也许有用。
回复 支持 反对

使用道具 举报

18

主题

301

帖子

0

精华

常驻嘉宾

Rank: 8Rank: 8

积分
4946
威望
2641
贡献
1439
兑换币
1337
注册时间
2014-8-31
在线时间
433 小时
毕业学校
河海大学
3#
发表于 2015-7-21 16:05:37 | 只看该作者
的确该养成好习惯,赞一个
回复 支持 反对

使用道具 举报

5

主题

26

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1061
威望
525
贡献
308
兑换币
329
注册时间
2014-10-18
在线时间
114 小时
4#
发表于 2015-7-21 17:57:28 | 只看该作者
怎么处理啊,求指导。单道能识别,就是不好处理
回复 支持 反对

使用道具 举报

1

主题

13

帖子

0

精华

高级会员

Rank: 4

积分
686
威望
357
贡献
211
兑换币
222
注册时间
2013-8-24
在线时间
59 小时
6#
 楼主| 发表于 2015-7-21 18:08:43 | 只看该作者
本帖最后由 枫华幻吟 于 2015-7-21 18:36 编辑
何必入戲 发表于 2015-7-21 17:57
怎么处理啊,求指导。单道能识别,就是不好处理

lastmid3 = (int)((fall_index + rase_index[j])/2);//上面可能网页问题出错了
fall_index后面加个中括号i,网页没法显示
回复 支持 反对

使用道具 举报

1

主题

12

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
219
威望
125
贡献
62
兑换币
71
注册时间
2015-4-28
在线时间
16 小时
毕业学校
西安工程大学
7#
发表于 2015-7-21 20:01:44 | 只看该作者
大神,可以说下如何处理十字的吗
回复 支持 反对

使用道具 举报

3

主题

17

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
410
威望
206
贡献
126
兑换币
131
注册时间
2014-12-8
在线时间
39 小时
毕业学校
天津科技大学
8#
发表于 2015-7-21 21:40:53 | 只看该作者
很棒
回复 支持 反对

使用道具 举报

3

主题

82

帖子

0

精华

高级会员

Rank: 4

积分
743
威望
299
贡献
286
兑换币
198
注册时间
2015-1-5
在线时间
79 小时
毕业学校
..
9#
发表于 2015-7-21 22:09:53 | 只看该作者
很赞,!
回复 支持 反对

使用道具 举报

2

主题

11

帖子

0

精华

注册会员

Rank: 2

积分
174
威望
99
贡献
39
兑换币
48
注册时间
2015-2-4
在线时间
18 小时
毕业学校
南京工业大学
10#
发表于 2015-7-22 12:02:49 | 只看该作者
mark一下,学习一下
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关于我们|联系我们|小黑屋|智能车制作 ( 黑ICP备2022002344号

GMT+8, 2024-9-29 05:27 , Processed in 0.168080 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表