智能车心得分享(六)-- 电磁入环

这一篇算是为智能车画上个句号吧,之后看会不会分享下其他的东西,有点懒,一开始还想着能不能周更,最后变成年更了,hhh,不知道之前说的东西有没有帮助到大家。

电磁入环分几部分来讲,首先要给大家介绍一个思想,就是摄像头可以补线,为什么电磁不能补线呢?我们可以通过补偿差比和的值来达到入环的需要。

电磁入环分为下面几部分:1.检测环岛(预环岛),2.确定环岛,3.入环,4.再次检测环岛,5.出环

以左环岛为例子:
智能车心得分享(六)-- 电磁入环
根据代码来讲解:
链接
https://gitee.com/HSqian/zhinengchexiaosaisanlun.git
智能车心得分享(六)-- 电磁入环

  1. 差比和结果(adc_RTT文件中)
if (Compensate_flag == 1)
		{
			dif_and_add = ADC_Compensate + 100 * err_get(Horizontal_L, Chevron_inL, Chevron_inR, Horizontal_R, Turn_A, Turn_B);
		}
else
		{	
			//滑动均值滤波
			cur_tem = 100 * err_get(Horizontal_L, Chevron_inL, Chevron_inR, Horizontal_R, Turn_A, Turn_B); //差比和(差)求偏离程度
			dif_and_add = 0.5 * cur_tem + 0.5 * last_nine;
			last_nine = moving_filter(cur_tem);
		}

这一部分就是计算差比和的结果,如果需要补偿,会给一个补偿值Compensate,不然就进行一阶滤波和窗口滤波。
这里比较精髓的就是Compensate这个值,所有的入环和出环都是通过补偿来进行操作的。
Turn_A是用来控制横电感的,Turn_B是用来控制内八字电感的
Turn_A是用来控制横电感的,Turn_B是用来控制内八字电感的
Turn_A是用来控制横电感的,Turn_B是用来控制内八字电感的
Turn_A是用来控制横电感的,Turn_B是用来控制内八字电感的
Turn_A是用来控制横电感的,Turn_B是用来控制内八字电感的
Turn_A是用来控制横电感的,Turn_B是用来控制内八字电感的
为了防止没看懂,多重复几遍
走直线用的主要是横电感,故Turn_A大;入环用的是内八,故Turn_B大

下面的(图中X处)都是if判断的位置!!!
2. 预环岛(图中1处)

 switch (ring_state)
    {
    case ring_noring:
    {
        /*
        	@明显可以看出 Chevron_outR/Chevron_outL 中的某一个为判断到了环岛的必要条件
        	@主要区别和十字还有车身歪了的时候导致的误判
        	@
        */

           if (Chevron_outL > 15) //右侧环岛,此时需要保证右侧水平的值大于一个值,保证不是因为车歪了导致达到较大值
        {
            ring_state = ring_rightring;
            right_ring_mode = 1; //此标志位是为了在real_out阶段中使用,判断左侧出环还是右侧出环

            flag_buzzer = 1;
            flag.ring = 1;
            flag.fork = 0;
            flag.ramp = 0; //当在进入环岛时将其他所有的标志位记为0

            //------------------此处修改三岔大小
            Ring_Size = Midring;
#if TIMES //多环岛?
            if (right_time == 0)
            {
                Ring_Size = Midring;
            }
            else if (right_time == 1)
            {
                Ring_Size = Midring;
            }

#endif

        } //-------第一声

        //if (Chevron_outL >= 90 && Horizontal_L > 20 && Chevron_inL > 15 && Chevron_inR >10&&((30>Chevron_outR)&& (Chevron_outR>15)))//力创条件
        else if (Chevron_outL >= 90 && Horizontal_L > 20 && Chevron_inL > 15 && Chevron_inR > 10 && zebra_flag == 0)//斑马线标志位0菜鸟判断
        {
            ring_state = ring_leftring;
            left_ring_mode = 1; //此标志位是为了在real_out阶段中使用,判断左侧出环还是右侧出环

            flag_buzzer = 1;
            flag.ring = 1;
            flag.fork = 0;
            flag.ramp = 0; //当在进入环岛时将其他所有的标志位记为0

            //------------------此处修改三岔大小
            Ring_Size = Midring;
#if TIMES //多环岛?
            if (left_time == 0)
            {
                Ring_Size = Midring;
            }
            else if (left_time == 1)
            {
                Ring_Size = Midring;
            }
#endif
        }
    };
    break; //-------第一声

这一部分是用来判断是左环岛还是右环岛,并修改环岛的大小(不同环岛的补偿和补偿时间需要调整),只是进行判断,以及给定 Ring_Size的大小(后面需要使用)。

  1. 入左环(图中2处)
   case ring_leftring:
    {
        Turn_B = 0.8;
        Turn_A = 0.2;
        if (Compensate_flag == 0)
        {
            Ringin_Size_Chose(Ring_Size);
        }

        if (Ring_Delay == 0) //根据引导长度修改“Ring_Delay”的值
        {
            ring_state = ring_prein;
            flag_buzzer = 1;
#if TIMES //多环岛?
            left_time += 1;
#endif
        }
    };

Turn_B = 0.8,Turn_A = 0.2;修改差比和差中电感的权重,并且执行 Ringin_Size_Chose()函数。
接下来讲解 Ringin_Size_Chose()

void Ringin_Size_Chose(int Size)
{
    Compensate_flag = 1;

    switch (Size)
    {
    case Bigring:
    {
        if (right_ring_mode == 1)
        {
            Ring_Delay = 130;
            ADC_Compensate = -30; //左侧要补正,右侧为负
        }
        else if (left_ring_mode == 1)
        {
            Ring_Delay = 130;
            ADC_Compensate = 30; //左侧要补正,右侧为负
        }
    }
    break;

    case Midring:
    {
        if (right_ring_mode == 1)
        {
            Ring_Delay = 100;
            ADC_Compensate = -30; //左侧要补正,右侧为负
        }
        else if (left_ring_mode == 1)
        {
            Ring_Delay = 200;
            ADC_Compensate = 30; //左侧要补正,右侧为负
        }
    }
    break;

    case Smallring:
    {
        if (right_ring_mode == 1)
        {
            Ring_Delay = 80;
            ADC_Compensate = -30; //左侧要补正,右侧为负
        }
        else if (left_ring_mode == 1)
        {
            Ring_Delay = 80;
            ADC_Compensate = 30; //左侧要补正,右侧为负
        }
    }
    break;

    default:
        break;
    }
}

首先,将Compensate_flag = 1,意味着1中差比和的值需要进行补偿,而补充的大小则是通过Ring_Size左右环来确定,Ring_Delay就是补偿的时间,不同的车速,这个值是有区别的,需要修改,相当于强制把车推进环岛的时间。

  1. 预入环(图中3处)
   case ring_prein:
    {
        Compensate_flag = 0;
        if (Horizontal_R + Horizontal_R < 120)
        {
            ring_state = ring_ringin;
            flag_buzzer = 1;
            Ring_Delay = 50;
        }
    };
    break; //-------第三声

把补偿置0,停止补偿

  1. 入环(图中3处)(没错和预入环差不多是在一个位置)
   case ring_ringin:
    {
        Target_Speed = Gear[0];
        Turn_A = 0.8;
        Turn_B = 0.2;
        if (Chevron_outL > 90 || Chevron_outR > 90 || Ring_Delay == 0)
        {
            ring_state = ring_out;
            flag_buzzer = 1;
            Ring_Delay = 50;
        }
    };
    break; //-------第四声

修改权值,改变环内速度

  1. 出环(图中4处)
   case ring_out:
    {
        Target_Speed = Gear[0];
        Turn_A = 0.8;
        Turn_B = 0.2;
        if ((GFP_abs(Horizontal_R - Horizontal_L) < 10 &&
             (Horizontal_R < 90 || Horizontal_L < 90)) ||
            Ring_Delay == 0)
        {
            ring_state = ring_realout;
            flag_buzzer = 1;
            Ring_Delay = 50;
        }
    }
    break;

重新给权值,用来出环

  1. 雀食出环(图中5处)
   case ring_realout:
    {
        Ringout_Size_Chose(Ring_Size);

        if (Horizontal_L + Horizontal_R < 100 || Ring_Delay == 0)
        {
            Turn_A = 1;
            flag_buzzer = 1;
            ring_state = ring_noring;
            Compensate_flag = 0;

            flag.ring = 0; //将环岛标志位置为0
            left_ring_mode = 0;
            right_ring_mode = 0;
        }
    };
    break;

Ringout_Size_Chose(Ring_Size)这个和进去的类似,就是补偿值是反的。

会发现里面有很多 Ring_Delay,一个目的是为了防止连续判断标志位,做间隔(防误判),另一个目的是为了做延时进入。

以上就是所有了。江湖有缘再见。

上一篇:03-Docker Engine详解


下一篇:vue 使用turn.js 翻书效果