智能车心得分享(六)-- 电磁入环
作者:互联网
这一篇算是为智能车画上个句号吧,之后看会不会分享下其他的东西,有点懒,一开始还想着能不能周更,最后变成年更了,hhh,不知道之前说的东西有没有帮助到大家。
电磁入环分几部分来讲,首先要给大家介绍一个思想,就是摄像头可以补线,为什么电磁不能补线呢?我们可以通过补偿差比和的值来达到入环的需要。
电磁入环分为下面几部分:1.检测环岛(预环岛),2.确定环岛,3.入环,4.再次检测环岛,5.出环
以左环岛为例子:
根据代码来讲解:
链接
https://gitee.com/HSqian/zhinengchexiaosaisanlun.git
- 差比和结果(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的大小(后面需要使用)。
- 入左环(图中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就是补偿的时间,不同的车速,这个值是有区别的,需要修改,相当于强制把车推进环岛的时间。
- 预入环(图中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,停止补偿
- 入环(图中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; //-------第四声
修改权值,改变环内速度
- 出环(图中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;
重新给权值,用来出环
- 雀食出环(图中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,一个目的是为了防止连续判断标志位,做间隔(防误判),另一个目的是为了做延时进入。
以上就是所有了。江湖有缘再见。
标签:入环,--,Turn,flag,Chevron,ring,心得,Ring,Size 来源: https://blog.csdn.net/HAsqian/article/details/122342604