其他分享
首页 > 其他分享> > 2020第十五届全国大学生智能汽车竞赛——结合线性CCD出入库

2020第十五届全国大学生智能汽车竞赛——结合线性CCD出入库

作者:互联网

结合线性CCD出入库

写在前面

十五届智能车里面添加了车库元素,如下图,计时要求就是需要我们从车库出发开始计时,入库结束计时,不入库没成绩,因此出入库是非常重要的过程
在这里插入图片描述
因为我们选择的是电磁车,没有摄像头,所以我选择了线性CCD作为感知斑马线的元件,我把他挂在了电磁车的前瞻
在这里插入图片描述
我们先来看一下斑马线的CCD图像
在这里插入图片描述
所以,入库实际上就是需要我们能准确识别上面的那个图像,接下来我就来介绍我的出入库方案

线性CCD

我们采用的是逐飞科技的线性CCD,代码在开源文件这里
在这里插入图片描述

void CCD_Collect(uint16_t *p) 
{
	uint16 i = 0;
	unsigned int  temp = 0;
	
    CCD_CLK(1);
    CCD_SI(0);
    
    CCD_SI(1);
    CCD_CLK(0);

    CCD_CLK(1);
    CCD_SI(0);
    
    for(i=0;i<128;i++)
    {
        CCD_CLK(0);   
        temp = ADC_Ave(ADC1, AD_CHANNEL, ADC_12bit, 5);   
        *p++ = temp;   
        CCD_CLK(1);
    }
}

这个是获取CCD 摄像头数据的函数,主要用的是A/D转换,我用的是K66,180M主频,还算高,所以我选择了12位A/D转换。

我设置了一个10ms的中断,中断里会调用图像处理函数,在图像函数里面做数据获取以及斑马线的判断
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

出库

方案

我采用了编码器积分+丢线设置的方案。
首先设置一个较低的车速,保持小车的稳定性。然后当我发车的时候首先进行编码器的积分,当编码器的积分累加值大于特定数值的时候设置左右丢线然后进入正常巡迹(因为发车方向是没有规定的,因此我通过按键设置左转或者右转的方向
在这里插入图片描述

因为编码器积分大于特定数值说明小车已经前进了特定距离,小车前轮已经出库(驾校老师告诉我们前轮出车位再打死角即可完成出入车位,受此启发),然后可以直接往某个方向设置丢线左出车库左丢线,右出车库右丢线)。接着小车就会按照正常的流程完成巡迹了。
在这里插入图片描述

5ms中断里面判断编码器积分的数据,大于特定数值之后才能算是前轮出库,这个特定数值在自家实验室测试得出,写入片内flash以供比赛直接调用或者比赛时做微调即可

在这里插入图片描述

原因及效果

车子出库的状态直接决定了他接下来的稳定性,因此我牺牲了一些出库的速度保证了车子的稳定性,而且经过实测,该编码器积分+丢线设置能很好的保证小车的出库姿态,记得放车的时候把车往旁边放一点,假如左边出库就把车子放在车库右边一点的敌方

入库

方案

入库需要感知这个信号
在这里插入图片描述
线性CCD采集的数据放到ccd_buf[128]中,是128个0,1信号,黑色(斑马线)对应1,白色(赛道)对应0,所以我们的思路就是识别黑白色块的跳变沿连续判断4个数据来判断跳变沿从而最大程度上减小误差

CCD_Collect(ccd_buf);//ccd_buf里面是ccd数据,是128个0,1信号,0代表白色,1代表黑色
for (uint8_t i = 0; i <= 123; i++)
{
  if ((ccd_buf[i] > start_line_thres) && (ccd_buf[i + 1 < 128 ? (i + 1) : 127] > start_line_thres) && (ccd_buf[i + 2 < 128 ? (i + 2) : 127] < start_line_thres) && (ccd_buf[i + 3 < 128 ? (i + 3) : 127] < start_line_thres) && (ccd_buf[i + 4 < 128 ? (i + 4) : 127] < start_line_thres))
  {
    jLeft = i + 2;    //黑块左侧位置
    iTmp = jLeft;
    for (; iTmp <= 123; iTmp++)
    {
      if ((ccd_buf[iTmp] < start_line_thres) && (ccd_buf[iTmp + 1] < start_line_thres) && (ccd_buf[iTmp + 2] > start_line_thres) && (ccd_buf[iTmp + 3] > start_line_thres) && (ccd_buf[iTmp + 4] > start_line_thres))
      {
        jRight = iTmp + 1;   //黑块右侧问题
        break;
      }
    }
    if (jRight - jLeft > 2)  //黑块宽度大于2才判定为有效的起跑线
    {
      cntColorChange++;
    }
    if(cntColorChange >= 5)//有5个黑块才判定为起跑线
    {
      cntColorChange = 0;
      getinto_garage_flag = 1;
      break;
    }
  }

当识别到车库之后就进行入库动作,方案就是左出库,左入库,那么左轮速度设为0,右轮给一个特定的速度漂移入库。这个过程中用陀螺仪记录车身漂移的角度角度大于特定数值的时候说明车身完全在车库里面了,然后就进行停车,既两轮速度均设置为0,最后小车就会稳稳的停在车库中
在这里插入图片描述
在这里插入图片描述
入库主要需调整的参数有getinto_speed(漂移时的单轮速度),gyro_garage(入库漂移角度,决定小车是否能停进车库或者漂移过头冲出车库)还有光照对于CCD二值化赛道的影响比较大,所以CCD的阈值需要在比赛场地进行调整,我这里的参数是start_line_thres

原因及效果

漂移入库能最大程度上减小入库时间,而且按照我这个方案入库非常稳健

注意点

CCD的阈值(start_line_thres)比赛的时候一定要调过!!!

标签:出入库,start,2020,ccd,CCD,line,thres,buf
来源: https://blog.csdn.net/weixin_43454320/article/details/110092656