智能车学习日记【三】————车库判别

这篇具有很好参考价值的文章主要介绍了智能车学习日记【三】————车库判别。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

这里记录一下我的第一版出入库,我觉得出入库最重要的还是判别斑马线和正确拉线。这里感谢我的队友DZH和学长们给我提供不同的出入库方法,斑马线的判断方法和拉线方法有来自拾牙慧者的文章进行改动的。现在可以在速度不快的情况下正常出入库且误判情况较少,由于这两天刚刚完成,还有较多不足,欢迎大家提出意见和修改! 一些数组和参数定义在前几篇文章有说明,如果觉得这篇文章有帮助就点个赞支持一下吧!


一、斑马线的判别

这里以向右入库为例,左入库思路类似。

思路:
1.设置一个栈,用来存储黑色元素。
2.从规定行的第0列开始往左扫(左入库则相反),如果遇到黑色元素,入栈。
3.如果遇到白色元素,出栈,出栈的同时统计栈中元素个数,如果栈中元素为4–8个(也就是黑胶的宽度),black_blocks++,否则不加。然后将栈中元素清掉。
4.如果此行的black_blocks在8个左右,times++。
5.遍历规定行,如果,times在4个左右,则确定为斑马线。
智能车入库,智能车,c语言,单片机

flag_find_cheku : 远端发现斑马线,补线直行,直到近处发现才补线入库
flag_starting_line : 24-29行判断拉线入库
byte flag_ruku : 入库标志位


        void check_starting_line(byte start_point, byte end_point)
        {
            byte times = 0;
            for (byte y = start_point; y <= end_point; y++)
            {
                byte black_blocks = 0;
                byte cursor = 0;    //指向栈顶的游标
                for (byte x = 0; x <= 185; x++)
                {
                    if (Pixels[y, x] == 0)
                    {
                        if (cursor >= 20)
                        {
                            break;          //当黑色元素超过栈长度的操作   break;    
                        }
                        else
                        {
                            cursor++;
                        }
                    }
                    else
                    {
                        if (cursor >= 4 && cursor <= 8)
                        {
                            black_blocks++;
                            cursor = 0;
                        }
                        else
                        {
                            cursor = 0;
                        }
                    }
                }
                if (black_blocks >= 6 && black_blocks <= 9) times++;
            }
            if (times >= 1)
            {
                flag_starting_line = 1;
                flag_ruku = 1;
                flag_find_cheku = 0;
                SetText("入库状态");
            }
            else
            {
                flag_starting_line = 0;
            }
        }

二、出入库

1.入库

入库我分成了2个阶段:
1、远处发现斑马线,这个时候由于斑马线的影响,上边的线是乱的,而我们这个时候就需要补线继续直行。
2、近处发现斑马线,这时要分2个方面,要拉线入库,还是要补线直行。补线直行的思路与第一点相同。

一、远处发现斑马线
智能车入库,智能车,c语言,单片机

思路:下拐点的找法和正常找下拐点的方法类似。上拐点不同,因为斑马线会导致上边的线混乱,可能上边的线会偏移的很离谱,不能通过正常扫线判断来获取上拐点,所以我们可以从下拐点那一行的第0处开始往上找,找到黑白交界处,这时往左扫线,再找到黑白交界处,就是一个上拐点的位置。为了更准确一点,我们用同样的再往上多找几行,就能找到多个上拐点,取最大的上拐点作为真正右上拐点即可。
智能车入库,智能车,c语言,单片机

代码如下:

            else if (type == 3)           
            {
                for (i = 1; i < 65; i++)
                {
                    if (abs(R_black[i] - R_black[i - 1]) < 3 && R_black[i + 1] - R_black[i] <= -3)
                    {
                        righty[0] = i;
                        rightx[0] = R_black[i];
                        break;
                    }
                }
                if (righty[0] > 0)
                {
                    for (y = (byte)(i + 2); y < 69; y++)
                    {
                        if (Pixels[y, 0] == 0 && Pixels[y + 1, 0] == 0)
                        {
                            y1 = y;
                            break;
                        }
                    }
                }
                else
                {
                    for (y = 35; y < 69; y++)
                    {
                        if (Pixels[y, 0] == 0 && Pixels[y + 1, 0] == 0)
                        {
                            y1 = y;
                            break;
                        }
                    }
                }
                for (x = 0; x < 185; x++)
                {
                    if (Pixels[y1, x] != 0)
                    {
                        x1 = x;
                        break;
                    }
                }
                byte y_zhengque = 0;
                for (y = (byte)(y1 + 1); y <= y1 + 3; y++)
                {
                    byte X = 0;
                    for (x = 0; x < 185; x++)
                    {
                        if (Pixels[y, x] != 0)
                        {
                            X = x;
                            break;
                        }
                    }
                    if (X >= x1)
                    {
                        x1 = X;
                        y_zhengque = y;
                    }
                }
                y1 = y_zhengque;
                righty[1] = y1;
                rightx[1] = x1;
                if (rightx[0] > rightx[1])         //普通扫线扫到斑马线有时会扫出几个很远的点
                {
                    rightx[0] = 0;
                    righty[0] = 0;
                    last_guaix = 0;
                    last_guaiy = 0;

                }
                SetText("车库右下拐点为y=" + righty[0] + " x=" + rightx[0] + "右上拐点为y=" + righty[1] + " x=" + rightx[1]);
                SetText("上一帧右下拐点 y=" + last_guaiy + " x=" + last_guaix);
            }

二、近处斑马线
智能车入库,智能车,c语言,单片机

思路:近处发现了斑马线的时候,下拐点就不太重要了,主要就是通过找到右上拐点,与左下边线拉线入库。右上拐点的找寻方法依旧和上边是一样的,然后找左边线第一个不丢线的点作为左下拐点。
智能车入库,智能车,c语言,单片机
代码如下:

            if (type == 2)         //右
            {
                if (Pixels[0, 185] != 0)   
                {

                    for (y = 1; y < 70; y++)
                    {
                        if (Pixels[y, 185] == 0)
                        {
                            y1 = y;
                            break;
                        }
                    }
                }
                else
                {
                    y1 = 0;
                }
                for (x = 185; x > 1; x--)
                {
                    if (Pixels[y1, x] != 0)
                    {
                        x1 = x;
                        break;
                    }
                }
                lefty[0] = y1;
                leftx[0] = x1;
                //开始找右上拐点
                if (Pixels[0, 0] == 0 && Pixels[1, 0] == 0 && Pixels[2, 0] == 0 && Pixels[3, 0] == 0 && Pixels[4, 0] == 0)
                {
                    for (y = 5; y < 70; y++)
                    {
                        if (Pixels[y, 0] != 0 && y >= 8)//为白
                        {
                            y1 = y;
                            break;
                        }

                    }
                    for (y = y1; y < 68; y++)
                    {
                        if (Pixels[y, 0] == 0 && y >= 15 && Pixels[y + 2, 0] == 0)
                        {
                            y1 = y;
                            break;
                        }

                    }
                }
                else
                {
                    for (y = 10; y < 70; y++)
                    {
                        if (Pixels[y, 0] == 0 && y >= 15 && Pixels[y + 2, 0] == 0)
                        {
                            y1 = y;
                            break;
                        }
                    }
                }
                for (x = 0; x < 185; x++)
                {
                    if (Pixels[y1, x] != 0)
                    {
                        x1 = x;
                        break;
                    }
                }
                byte y_zhengque = 0;
                for (y = (byte)(y1 + 1); y <= y1 + 2; y++)
                {
                    byte X = 0;
                    for (x = 0; x < 185; x++)
                    {
                        if (Pixels[y, x] != 0)
                        {
                            X = x;
                            break;
                        }
                    }
                    if (X >= x1)
                    {
                        x1 = X;
                        y_zhengque = y;
                    }
                }
                y1 = y_zhengque;
                righty[1] = y1;
                rightx[1] = x1;
                SetText("车库左下拐点为y=" + lefty[0] + " x=" + leftx[0] + "右上拐点为y=" + righty[1] + " x=" + rightx[1]);
            }

2.出库

出库的方法有很多,可以计时打角,也可以拉线。这里分享一下我的拉线方法。
智能车入库,智能车,c语言,单片机
思路:拉线转弯的思路还是比较简单,因为两边都丢线,右边就往上找一个拉线点,与左下边边界拉线即可
代码如下:

                if (flag_chukechange == 1)
                {
                    SetText("状态: 转弯");
                    SetText("b=" + b);
                    advanced_regression(1, 0, 5, 10, 15);
                    SetText("左斜率=" + parameterB);
                    float k1;
                    k1 = parameterB;
                    byte y1 = 0;
                    byte x1 = 0;
                    if (Pixels[10, 0] != 0)
                    {
                        for (y = 11; y < 70; y++)
                        {
                            if (Pixels[y, 0] == 0)
                            {
                                y1 = y;
                                break;
                            }
                        }
                    }
                    else
                    {
                        cnt = 0;
                        for (y = 1; y < 70; y++)
                        {
                            if (Pixels[y, 0] != 0 && Pixels[y - 1, 0] == 0)
                            {
                                cnt = 1;
                            }
                            if (Pixels[y, 0] == 0 && Pixels[y - 1, 0] != 0 && cnt == 1)
                            {
                                cnt = 2;
                                y1 = y;
                                break;
                            }
                        }
                        for (y = y1; y < 70; y++)
                        {
                            if (Pixels[y1, 0] == 0)
                                break;
                        }
                    }
                    for (x = 0; x < 186; x++)
                    {
                        if (Pixels[y1, x] != 0)
                        {
                            righty[1] = y1;
                            rightx[1] = x;
                            SetText("右上拐点: y=" + righty[1] + " x=" + rightx[1]);
                            break;
                        }
                        if (x > 93)
                        {
                            righty[1] = y1;
                            rightx[1] = 0;
                            SetText("右上拐点: y=" + righty[1] + " x=" + rightx[1]);
                            break;
                        }
                    }
                    for (y = 5; y < 70; y++)
                    {
                        if (Pixels[y, 185] != 0)
                        {
                            lefty[0] = y;
                            leftx[0] = 185;
                            SetText("左下拐点: y=" + lefty[0] + " x=" + leftx[0]);
                            break;
                        }
                        if (y > 10)
                        {
                            lefty[0] = 5;
                            leftx[0] = 185;
                            SetText("左下拐点: y=" + lefty[0] + " x=" + leftx[0]);
                            break;
                        }
                    }
                    parameterB = (float)((rightx[1] - leftx[0]) * 1.0 / (righty[1] - lefty[0]));
                    parameterA = rightx[1] - parameterB * righty[1];
                    run(1, 0, righty[1], parameterB, parameterA);
                    for (y = 0; y < 70; y++)
                    {
                        R_black[y] = 0;
                    }
                    for (y = (byte)(righty[1]); y < 70; y++)
                    {
                        L_black[y] = L_black[righty[1] - 1];
                    }
                    run(0, 0, 69, parameterB, parameterA);
                    cnt = 0;
                    juge_lineContinuity(0, b, 3, -3, 2);
                    if (b > 50 && k1 >= -1.6 && k1 <= -0.5 && fps_cheku_times > fps_cheku_project)
                    {
                        outcarku = 0;
                        SetText("右边不为0 cnt=" + cnt + " 右边连续数=" + long_turn_flag_right);
                        SetText("退出出库状态机");
                    }
                    else
                    {
                        fps_cheku_times++;
                    }
                }

总结

这些代码在正常速度的情况下能较准确的判别和补好线,但速度加大后由于车子的控制不好等原因,导致判断会比较慢,拉线比较晚,后续也要加强判断的条件,改良车子的控制。如果你觉得文章有所帮助还希望点赞鼓励一下!欢迎大家在评论区提出改进意见!
最后的最后如果想看看我这一年智能车的经历和建议可以到第一篇文章最下面浏览一下 智能车学习日记【一】文章来源地址https://www.toymoban.com/news/detail-596646.html

到了这里,关于智能车学习日记【三】————车库判别的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 物联网项目分享 单片机 图像分类 智能识别机器人 - 物联网 深度学习 AI

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月21日
    浏览(52)
  • 关于TC264单片机与智能车摄像头循迹的一些学习心得

    前言:最近一段时间在准备智能车考核,其中要求使用TC264单片机实现PID控制的小车摄像头循迹。其中关于PID的部分在之前我已经上传过了,这篇文章主要讲怎么实现循迹与舵机的位置式PID调参和电机的增量式调参的一些心得。 一、摄像头循迹的实现 首先我们要明白英飞凌公

    2024年02月04日
    浏览(40)
  • stm32毕设分享 单片机 图像分类 智能识别机器人 - 物联网 深度学习 AI

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年01月16日
    浏览(81)
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯

      前言:感谢您的关注哦,我会持续更新编程相关知识,愿您在这里有所收获。如果有任何问题,欢迎沟通交流!期待与您在学习编程的道路上共同进步。       目录 一.  延时函数的生成  1.通过延时计算器得到延时函数  2.可赋值改变的延时函数  二.  LED模块编写原理 

    2024年02月19日
    浏览(42)
  • 单片机毕设 基于单片机的智能快递柜设计与实现

    Hi,大家好,这里是丹成学长,今天向大家介绍一个 单片机项目 基于单片机的智能快递柜设计与实现 大家可用于 课程设计 或 毕业设计 🧿 毕设项目分享:见文末! 一般来说,传统快递服务方式是人对人,即快递员进行揽件派送,与签收人进行面对面签收,确认无误后服务终

    2024年04月09日
    浏览(53)
  • 【毕业设计】基于单片机的智能鱼缸系统设计与实现 - 嵌入式 物联网 stm32 51单片机 智能鱼缸

    Hi,大家好,今天向大家介绍一个 单片机项目, 大家可用于 课程设计 或 毕业设计 基于单片机的智能鱼缸系统设计与实现 🔥 项目分享与指导: https://gitee.com/sinonfin/sharing 近年以来,随着我国综合实力飞速飙升,人们对物质和精神生活质量的要求也不断提升,各式各样的智能

    2024年02月04日
    浏览(85)
  • 单片机设计基于51单片机的智能风扇控制系统设计与实现

      我们常见的电风扇一般只有四、五个风速档,用的是人工开关,而且并不是每个人家里都会有空调,或者在一些小型的工厂或者一些小型加工厂,这些地方都可能没有配备大型的中央空调系统这些东西,所以这些东西往往都会采用风扇这种小成本的东西来代替,但是不清楚

    2024年02月03日
    浏览(65)
  • 基于单片机的智能小车设计

    随着科技的发展,智能机器人在日常生活中的应用越来越广泛。智能小车作为智能机器人的一种,具有便携性和多功能的特点,在教育、娱乐和工业等领域得到了广泛关注和应用。智能小车可以通过远程控制实现各种动作,如前进、后退、转弯等,并且可以通过搭载传感器实

    2024年02月06日
    浏览(55)
  • 基于单片机的智能风扇设计

    单片机类型:51单片机(普中) 传感器的使用: DS18B20温度传感器、LD3320语音模块、JQ8900-16P语音播报、LCD1602显示屏、hc-sr501人体感应模块等 设计有三个模式: 模式1:根据温度变化进行风扇速度的调节 模式2:自主控制温度的风扇变化 模式3:采用人体感应模块,监测风扇前是

    2024年01月18日
    浏览(45)
  • 基于单片机的智能衣柜设计

    随着科技的不断发展,人们对于生活品质的要求越来越高。智能衣柜作为智能家居的一个重要组成部分,能够为用户提供便捷、个性化的衣物管理服务。本文主要研究了基于单片机的智能衣柜设计,通过对硬件系统和软件系统的设计与实现,实现了衣柜的智能化管理。 智能衣

    2024年04月08日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包