系列文章
【智能车Code review】—曲率计算、最小二乘法拟合

智能车复工日记【1】——菜单索引回顾
智能车复工日记【2】——普通PID、变结构PID、微分先行PID、模糊PID、专家PID
智能车复工日记【3】:图像处理——基本扫线和基本特征提取和十字补线

智能车复工日记【4】:关于图像的上下位机的调整问题总结
智能车复工日记【5】:起跑线的识别与车库入库
智能车复工日记【6】:有bug的模糊PID记录

智能车复工日记【7】:关于会车的图像问题

坡道处理概述

坡道可分为大坡和小坡。
坡道图像遵循状态机的原则,分为上坡、在坡顶、下坡;
由于摄像头限制,坡道顶部的图像能用的范围很少且图像很乱,所以在坡顶采取锁中线或者是重新找中线。

图像处理部分

清除标志位函数clear_po()
清除坡道保护标志位:po_protect
清除坡道标志位:podao_flag
清除上坡标志位:podaoup_flag
清除坡顶标志位:podaoding_flag
清除下坡标志位:podaodown_flag
在判断成下坡时调用

void clear_po()
{
    po_protect = 0;
    podao_flag = 0;
    podaoup_flag = 0;
    podaoding_flag = 0;
    podaodown_flag = 0;
}

坡道判断函数juge_po()

上坡分为斜入坡道、正入坡道判断;
long_turn_flag_left :左线连续程度
long_turn_flag_right :右线连续程度
rou_of_left :左线方差
rou_of_right :右线方差
fiv_width[i]:第i行的赛道宽度
k_left:最小二乘法拟合出来的左线斜率
k_right:最小二乘法拟合出来的左线斜率
lostright_times:右线丢失行数
l_start:左线第一个不为白的点
break_hangshu:中线break行数
fps_up_and_on_po :上坡和在坡顶的帧数,用于强制出坡状态
must_out_po_fps :人工设置的出坡状态的帧数

#region[坡道]
void juge_po()
{
    byte jugetime = 0;
    //正入坡道
    //大坡
    if (po_protect == 0 && podaodown_flag == 0 && podao_flag == 0 && long_turn_flag_left >= 55 && long_turn_flag_right >= 55 && rou_of_left >= 5 && rou_of_left <= 440 && rou_of_right >= 5 && rou_of_right <= 440)
    {
        if (fiv_width[40] >= 90 && fiv_width[45] >= 70 && fiv_width[50] >= 75 && fiv_width[55] >= 67)
        {
            jugetime = 1;
        }
        if (jugetime >= 1 && k_left >= -1.1 && k_left <= 0.15 && k_right >= -0.15 && k_right <= 1.1)
        {
            podao_flag = 1;
            podaoup_flag = 1;
            SetText("往坡上走");
        }
    }
    //右斜入坡道
    if (po_protect == 0 && podaodown_flag == 0 && podao_flag == 0 && l_start <= 10 && lostright_times >= 48 && break_hangshu >= 63 && long_turn_flag_left >= 60 && long_turn_flag_right >= 60 && rou_of_left >= 5 && rou_of_left <= 1000 && rou_of_right >= 0 && rou_of_right <= 220)
    {

        if (fiv_width[45] >= 60 && fiv_width[50] >= 55)
        {
            jugetime = 1;
        }
        if (jugetime >= 1 && k_left >= -2 && k_left <= -0.35)
        {
            podao_flag = 1;
            podaoup_flag = 1;
            SetText("往坡上走(右斜入)");
        }
    }
    //左斜入坡道
    if (po_protect == 0 && podaodown_flag == 0 && podao_flag == 0 && r_start <= 10 && lostleft_times >= 48 && break_hangshu >= 63 && long_turn_flag_left >= 60 && long_turn_flag_right >= 60 && rou_of_right >= 5 && rou_of_right <= 1000 && rou_of_left >= 0 && rou_of_left <= 220)
    {

        if (fiv_width[45] >= 60 && fiv_width[50] >= 55)
        {
            jugetime = 1;
        }
        if (jugetime >= 1 && k_left >= -2 && k_left <= -0.35)
        {
            podao_flag = 1;
            podaoup_flag = 1;
            SetText("往坡上走(左斜入)");
        }
    }
    if (podao_flag == 1 && long_turn_flag_left < 40 && long_turn_flag_right < 40)
    {
        podaoup_flag = 0;
        podaoding_flag = 1;
        old = 93;
        SetText("在坡道顶部");
    }
    if (street_flag == 17 || street_flag == 18)
    {
        fps_up_and_on_po++;
        setText用户自定义("坡道状态第" + fps_up_and_on_po + "帧");
    }
    if (fps_up_and_on_po >= must_out_po_fps || (podaoding_flag == 1 && break_hangshu >= 45 && (long_turn_flag_left >= 40 || long_turn_flag_right >= 40) && fiv_width[10] >= 110 && fiv_width[20] >= 100 && fiv_width[25] >= 90))
    {
        podao_flag = 0;
        podaoup_flag = 0;
        podaoding_flag = 0;
        podaodown_flag = 1;
        not_rush_flag = 1;
        fps_up_and_on_po = 0;
        SetText("往坡下走");
    }
    po_protect_timer();
}
#endregion

坡道保护函数po_protect_timer()(多少帧之内不判坡道)

这是由于上坡图像和下坡图像比较相似造成的,为了不在下坡的时候再次进入上坡状态,特加入此函数用于保护。

void po_protect_timer()
{
    if (podaoding_flag == 1) po_protcectflag = 1;
    if (po_protcectflag == 1)
    {
        timer++;
        po_protect = 1;
        if (timer >= fps_po_protect)
        {
            po_protcectflag = 0;
            timer = 0;
            po_protect = 0;
        }
    }

}

获取详情请订阅:https://blog.csdn.net/qq_42604176/category_9858434.html?spm=1001.2014.3001.5482