智能车打工日记(二):关于起跑线与出入车库

车库元素一览

车库元素是今年赛道元素新增的元素。车库赛道元素是在起跑线旁设置的方形区域,它的尺寸如下图所示:
在这里插入图片描述
车模出发是从车库驶出,在运行一周之后在驶入车库内。比赛时间是从车模驶出车库和返回车库之间的时间差计算。因此计时线圈是放置在车库门口处。赛道上的斑马线和斑马线下的磁铁放置与往届规则相同。
车库应用于“基础四轮组”,“直立节能组”,“双车接力组”

入车库

20cm摄像头拍下的车库图

在这里插入图片描述

起跑线的识别

因为时间紧迫,这里采用最简单的入车库(左入)斑马线识别方法:

  1. 找到左前边线的拐点
  2. 从下(拐点的y坐标)向上(拐点的y坐标+m),从左(拐点的x坐标)到右(中线位置),进行寻找由黑到白的转变边界像素点。
  3. 找到了第一个边界,以固定的y坐标(转变边界像素点的y坐标+n),从左到右,重新扫线。
  4. 找到第一个由白转黑的像素点和第一个由黑转白的像素点,记录距离(length),作为判断之后斑马线长度的依据
  5. 持续向右扫线,每找到一个疑似斑马线的像素块,就把边界像素的距离与length进行比较,在设定误差之内,判定斑马线。
  6. 记录斑马线数量,与判定起跑线的斑马线数量阈值比较。

代码:

byte Garage_Judge(byte i)
        {
            byte y = 0, x = 0, count = 0, pixel_cnt = 0, zebraWidth = 0;
            //左边车库
            if (i == 0)
            {
                for (OlRow = LeftLine_1.Agl_Row; OlRow <= LeftLine_1.Agl_Row + 20; OlRow++)
                {
                    for (OlLine = (byte)(LeftLine_1.Agl_Line - 5); OlLine >= 93; OlLine--)
                    {
                        //SetText_1("Zerba Scan :"+ OlRow+" "+ OlLine);
                        if (J_Pixels[OlRow][OlLine] == white && J_Pixels[OlRow][OlLine - 1] == black)
                        {
                            y = (byte)(OlRow + 3);
                            //x = (byte)(OlLine-1);
                            SetText_1("Find Zebra Point: " + y + " " + OlLine);
                            break;
                        }
                    }
                    if (y != 0)
                        break;
                }
                if (y == 0)
                {
                    SetText_1("Lost Zebra Point");
                    return 0;
                }
                for (x = LeftLine_1.Agl_Line; x >= 185 - LeftLine_1.Agl_Line; x--)
                {
                    if (J_Pixels[y][x + 1] == white && J_Pixels[y][x] == black)
                    {
                        //SetText_1("Zebra Scan Start: " + y + " " + x);
                        pixel_cnt = 1;
                    }
                    else if (J_Pixels[y][x + 1] == black && J_Pixels[y][x] == black)
                    {
                        //SetText_1("Zebra Add: " + y + " " + x);
                        pixel_cnt++;
                    }
                    else if (J_Pixels[y][x + 1] == black && J_Pixels[y][x] == white)
                    {
                        if (count == 0 && pixel_cnt >= 3 && pixel_cnt <= 10)
                        {
                            zebraWidth = pixel_cnt;
                            SetText_1("zebraWidth = " + zebraWidth);
                            SetText_1("zebraStart Point: " + x + " " + y);
                            count = 1;
                        }
                        else if (count > 0 && my_fabs(pixel_cnt - zebraWidth) <= 4)
                        {
                            //SetText_1("Zebra End: " + y + " " + (x - 1));
                            count++;
                        }
                        else
                        {
                            // SetText_1("Zebra Error: " + y + " " + (x - 1));
                        }
                    }
                }
                SetText_1("Zebra Count = " + count);
                if (count >= 6)
                {
                    SetText_1("Proved to be Garage");
                    return 1;
                }
                else
                {
                    SetText_1("Not Proved to be Garage");
                    return 0;
                }
            }
            else  //右边车库
            {
                for (OlRow = RightLine_1.Agl_Row; OlRow <= RightLine_1.Agl_Row + 20; OlRow++)
                {
                    for (OlLine = (byte)(RightLine_1.Agl_Line + 5); OlLine <= 93; OlLine++)
                    {
                        //SetText_1("Zerba Scan :"+ OlRow+" "+ OlLine);
                        if (J_Pixels[OlRow][OlLine] == black && J_Pixels[OlRow][OlLine - 1] == white)
                        {
                            y = (byte)(OlRow + 3);
                            //x = (byte)(OlLine-1);
                            SetText_1("Find Zebra Point: " + y + " " + OlLine);
                            break;
                        }
                    }
                    if (y != 0)
                        break;
                }
                if (y == 0)
                {
                    SetText_1("Lost Zebra Point");
                    return 0;
                }
                for (x = RightLine_1.Agl_Line; x <= 185 - RightLine_1.Agl_Line; x++)
                {
                    if (J_Pixels[y][x - 1] == white && J_Pixels[y][x] == black)
                    {
                        //SetText_1("Zebra Scan Start: " + y + " " + x);
                        pixel_cnt = 1;
                    }
                    else if (J_Pixels[y][x - 1] == black && J_Pixels[y][x] == black)
                    {
                        //SetText_1("Zebra Add: " + y + " " + x);
                        pixel_cnt++;
                    }
                    else if (J_Pixels[y][x - 1] == black && J_Pixels[y][x] == white)
                    {
                        if (count == 0 && pixel_cnt >= 3 && pixel_cnt <= 10)
                        {
                            zebraWidth = pixel_cnt;
                            SetText_1("zebraWidth = " + zebraWidth);
                            SetText_1("zebraStart Point: " + x + " " + y);
                            count = 1;
                        }
                        else if (count > 0 && my_fabs(pixel_cnt - zebraWidth) <= 4)
                        {
                            //SetText_1("Zebra End: " + y + " " + (x - 1));
                            count++;
                        }
                        else
                        {
                            // SetText_1("Zebra Error: " + y + " " + (x - 1));
                        }
                    }
                }
                SetText_1("Zebra Count = " + count);
                if (count >= 6)
                {
                    SetText_1("Proved to be Garage");
                    return 1;
                }
                else
                {
                    SetText_1("Not Proved to be Garage");
                    return 0;
                }
            }
        }

由于入库图像与环岛入环图像较为相似,入车库判断函数的优先级需要高于入环判断函数。
实践证明,识别成功率很高。

入车库的拉线

拉线分为4个阶段:

  1. 阶段0:判断为车库在这里插入图片描述
  2. 阶段1:左前拐点消失在这里插入图片描述
  3. 阶段2:低行右边边线消失在这里插入图片描述
  4. 阶段3:右边边线重新出现在这里插入图片描述
  5. 阶段4:左边边线出现在这里插入图片描述

出车库

目前最稳定的方法为直接控制出库。

  • 32
    点赞
  • 311
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值