一、前言
在前中期通过识别直道、弯道等元素可进行加减速操作实现速度的控制,可进一步缩减一圈的运行速度,但会出现刹车不及时、加速不及时、车辆路径较差等问题,反而导致处理后运行一圈时间多于之前。由此我们引入多个方法,使车辆能自行解算并自行控制速度、转向力度等,以跑出最好效果。
当然有部分代码为了提高摩托车模运行稳定性的,对于四轮车模反而是一种限制,需读者使用时自行删减。
二、动态权
1.概述
如果图像有六十行,那我们可以得到六十行有效偏差值(弯道时有效行数会减少),我们在计算偏差值时,常用的方法是将所有有效行的偏差值相加,再取均值。
但调过车的都知道,当所有行取均值时,会导致弯道打角力度不够,直线打角力度过大导致车辆摆动的情况。
参考我们平时开车或者骑车时的情形,车快时眼睛看得远,车速慢时眼睛看得近。由此我们可以优化上述情况,引入加权。
最简单且繁琐的方法是引入固定权值(提前录入权值数组),即提前设定好不同元素的加权情况:
- 如识别出直线时,我们将图像远端的权值加大,而图像中端和近端的权值减小,在远端出现弯道时,会让车辆高速情况下提前出现打角倾向。
- 当贴近弯道时,我们将图像中端的权值加大,就可以减少底端较小偏差值的干扰,保证车的打角力度。
- 识别出小 S 弯时,我们将权值情况如同直线处理,高权值放在远端,那么就可以发现,车在跑小 S 弯时几乎无左右摆动情况,直线路径穿过小 S 弯,在提高车速的同时也减少了打角消耗的时间。
- 在处理十字和环岛时,我们可以对多个状态设定权值,可以优化在元素不同状态时的转向效果。
但上述方法存在弊端:一方面元素与元素之间权值会切换得很生硬,使车辆出现摆动;另一方面当我们需要加速时,所有的元素权值都需要调整,十分繁琐。由此我们引入动态权。
2.给偏差值加动态权
控制动态权我们使用一个数据,为爬线相遇点的 Y 值(一个可以反映偏差值有效行的数据)。那么在直线和小 S 弯等地方,Y 贴近图像最远端,那么高权值就自动滑动到最远端。在由直线靠近弯道时,相遇点 Y 值不断下压,那么高权值就随着 Y 值向下滑动到中间区域,整个过程很丝滑,不会出现强硬的切换,并且十分易于修改。下面上代码:
//相遇点滑动均值滤波
uint8 Y_Meet_Max = 0;
uint8 Y_Meet_Min = 0;
uint16 Y_Meet_Sum = 0;
uint8 Y_Meet_Average = 0;
Y_Meet_Min = Y_Meet_Array[0];
Y_Meet_Max = Y_Meet_Array[0];
for(i = 0; i < 19; i++) {
Y_Meet_Array[i + 1] = Y_Meet_Array[i];
}
Y_Meet_Array[0] = start;
for(i = 0; i < 20; i++) {
if(Y_Meet_Array[i] < Y_Meet_Min) {
Y_Meet_Min = Y_Meet_Array[i];
}
if(Y_Meet_Array[i] > Y_Meet_Max) {
Y_Meet_Max = Y_Meet_Array[i];
}
}
for(i = 0; i < 20; i++) {
Y_Meet_Sum += (uint16)Y_Meet_Array[i];
}
Y_Meet_Sum = Y_Meet_Sum - (uint16)Y_Meet_Min - (uint16)Y_Meet_Max;
Y_Meet_Average = (uint8)(Y_Meet_Sum / 18);
(Y_Meet_Average > ) {
Y_Meet_Average = ;
} (Y_Meet_Average < ) {
Y_Meet_Average = ;
}
Temp_Float = ()(Y_Meet_Average - );
(Temp_Float > )
{
Temp_Float = ;
}
(Temp_Float < )
{
Temp_Float = ;
}
uint8 Base_Weight[] = {, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , };
uint8 Trends_Weight[] = {, , , , , , , , , , , , , , , , , , };
uint8 Start_Line = (uint8)(Temp_Float / * + );
(i = ; i < ; i ++) {
Base_Weight[Start_Line - i] = Trends_Weight[i];
}
(i = Y_Meet_Average + ; i < ; i++)
{
Sum += (int32)Base_Weight[i] * (int32)C_Line[i];
Weight_Sum += (int32)Base_Weight[i];
}


