|
楼主 |
发表于 2005-10-26 17:46:44
|
显示全部楼层
3、数据的高级加工——复杂地面情况的模糊识别算法。
以上的算法的确可以应付规范场地下的情况了,但是由于其类似查表式的数据处理方式,一旦出现真值表中没有的情况——哪怕是很明显的直线存在——机器人都没有办法处理了。典型的就是在地上有大块的白色斑点,导致机器人对白线视而不见。
解决以上问题的方法还要从人眼识别白线的原理上说起。在破坏严重的场地上,人类的眼睛仍然可以识别出原先的白线,这是为什么呢?通过重心。人类的眼睛通过捕捉白线的重心确立白线的大体轨迹,从而辨认出白线的位置。从概率的角度上说,在破坏严重的场地上,出现在白线两边的浅色干扰的概率是一样的,即使不同,由于白线本身的存在,其重心至少是不会偏离白线很远的,所以,只要简单的获得地面浅色标志的重心,就可以大体确立白线的所在。我们可以利用物理学上质心的算法获得这一信息。忘了说一点,要想机器人增强对环境的适应力,就需要增加传感器的数目。我们不妨用8个红外管作为传感器。这样通过处理后获得的场地信息就整整1个字节了。假设1个光电管的1拥有1单位的重量,八个光电管的坐标分别为 -7 -5 -3 -1 1 3 5 7,其间距都是2个单位,通过置信公式很容易计算出质心的坐标,通过这个坐标和0的绝对值,就可以知道当前机器人偏离白线的多少,而这个偏离值则可以通过简单的比例直接指导运动函数。典型实例如下:
/********************************************************
* 函数说明:电机动作调速函数 *
* 说明: 该函数放在定时器或者主循环里面用于产生软PWM*
********************************************************/
void SpeedPWM(char PWMLine)
{
char PWMLine_L = PWMLine;
char PWMLine_R = PWMLine;
static char PWMCount_L = 0;
static char PWMCount_R = 0;
char Temp = 0;
if (FollowLineEnable == True)
{
Temp = (char)fabs((float)CG_X);
if (AdcValueFlag == 0)
{
Temp = 0;
}
else
{
if (CG_X <0)
{
if ((Temp<<4) <= PWMLine_R)
{
PWMLine_R -= ((Temp<<5)+Temp<<2);
}
else
{
PWMLine_R = 0;
}
}
else
{
if ((Temp<<4) <= PWMLine_L)
{
PWMLine_L -= (Temp<<5);
}
else
{
PWMLine_L = 0;
}
}
}
}
PWMCount_L ++;
PWMCount_R ++;
if (PWMCount_L > Fastest)
{
PWMCount_L = Stop;
}
if (PWMCount_R > Fastest)
{
PWMCount_R = Stop;
}
if (PWMCount_L < PWMLine_L)
{
switch (GoDirection)
{
case Front:
Motor_Left_GoFront;
break;
case Back:
Motor_Left_GoBack;
break;
case Left:
Motor_Left_GoFront;
break;
case Right:
Motor_Left_GoBack;
break;
case Stop:
Motor_Left_Stop_Free;
break;
}
}
else
{
Motor_Left_Stop_Free;
}
if (PWMCount_R < PWMLine_R)
{
switch (GoDirection)
{
case Front:
Motor_Right_GoFront;
break;
case Back:
Motor_Right_GoBack;
break;
case Left:
Motor_Right_GoBack;
break;
case Right:
Motor_Right_GoFront;
break;
case Stop:
Motor_Right_Stop_Free;
break;
}
}
else
{
Motor_Right_Stop_Free;
}
}
/********************************************************
* 函数说明:获取偏离轨迹线的数值 *
* 输入: 表明寻线状态的字节 *
* [说明] *
* 通过类质心算法获取当前机器人偏离轨迹线的量 *
* - 表示偏左 + 表示偏右 *
********************************************************/
signed char GetCG_X(unsigned char AdcValues)
{
signed char a = 0;
signed char Temp = 0;
signed char Totals = 0;
for (a = 0;a<8;a++)
{
if ((AdcValues <<a)>>7)
{
Temp += ((-7)+ (a<<1));
Totals++;
}
}
if (Totals ==0)
{
return 0;
}
return (Temp / Totals);
}
函数调用GetCG_X函数,用来获取CG_X,CG_X直接在PWM输出函数里面指导机器人的运动。
以上方法的好处是,提供了一个比例调节循线动作的可能。支持多传感器的情况,尤其适合线性CCD类的线性数据的处理。为机器人提供了一个相对完整的视觉,不可能出现无法识别的情况,而且,这种情况可以使机器人在不加修改程序的情况下直接在在白线循线和黑线循线状态下切换。 |
|