logo资料库

FIRA详细的代码注释(避障函数+position函数).doc

第1页 / 共4页
第2页 / 共4页
第3页 / 共4页
第4页 / 共4页
资料共4页,全文预览结束
void Avoid(Robot *robot,Environment *env,double x,double y) { int desired_angle = 0, theta_e = 0, d_angle = 0, vl, vr, vc = 190; int j=1; double dx, dy, d_e, Ka = 10.0/90.0;//给系数 Ka 赋个较小的初值,作为默认 情况的取值 dx = x - robot->pos.x;//目标点与小车在 x 轴方向上的距离 dy = y - robot->pos.y; d_e = sqrt(dx * dx + dy * dy);//小车与目标点之间的距离 if (dx == 0 && dy == 0) desired_angle = 90;//当小车已在目标点时,期望角赋为 90 度 else desired_angle = (int)(180. / PI * atan2((double)(dy), (double)(dx)));// 小车与目标点之间的连线与水平线之间的夹角,即期望角(与 position 函数里 的期望角相同) theta_e = desired_angle - (int)robot->rotation;//用上面一句计算出的期 望角减去小车当前的角度,得到一个差角 theta_e while (theta_e > 180) theta_e -= 360; while (theta_e < -180) theta_e += 360;/*这两句与 position 函数里的相同, 都是为了使得当计算出的差角|theta_e|>180 的时候,加上或减去 360 度以使 theta_e 的绝对值始终小于 180。因为从后面的程序可以看到,theta_e 实际上 是 小车需要旋转的角度(因为小车必须旋转直到其面向目标点,此时往前运动才能 完成朝向目标点的运动),那么与其让它旋转大于 180 度,不如只让其旋转 360-theta_e 度角(这里实在不好表达)*/ if (d_e > 100.) //当小车到目标点的距离大于 100 时,Ka 取 45.0/90(即对不 同长度的距离分别选用不同大小的系数,系数的大小据实际情况定,是试出来的。 该系数后面计算轮速时要用到) Ka=45./90.; else if (d_e > 50) Ka=65./90; else if (d_e > 30) Ka=75./90.; else if (d_e > 20) Ka=85./90.; else Ka=95./90.; if (theta_e > 95 || theta_e < -95) { j=-1; theta_e += 180;//如果差角大于 90 度,将 theta_e 转化成其补角(即如果小车 是屁股朝向目标点的话,它没必要转一大圈将脑袋对着目标点前进,而是直接转
个很小的角度让屁股正对目标点倒退着行进就可以了,这样就节约了时间,这就 是 position 函数里的原理) if (theta_e > 180) theta_e -= 360; if (theta_e > 80) theta_e = 80; if (theta_e < -80) theta_e = -80; if (d_e < 5.0 && abs(theta_e) < 40)//当小车离目标点很近并且差角也不大 的时候,Ka 取个很小的值 Ka = 0.1; vr = (int)(-vc * (1.0 / (1.0 + exp(-3.0 * d_e))-0.3 ) + Ka * theta_e);// 左轮速 vl = (int)(-vc * (1.0 / (1.0 + exp(-3.0 * d_e))-0.3 ) - Ka * theta_e);// 右轮速 /*计算轮速的公式,其中左右轮速的-vc * (1.0 / (1.0 + exp(-3.0 * d_e))-0.3 ) 是一样的,因为这项是赋予左右轮直线行驶的速度,他们大小相同,正负也相同。 从该项里可以看到唯一变化的量是 d_e,说明直线行驶时的轮速只与小车离目标 点的距离有关,距离越大,求出的轮速就越大,当距离为零时轮速也就为零了。 后面的一项 Ka * theta_e 前的正负号,左右轮速是相反的,因为该项是赋予左 右轮不同的轮速以使小车改变方向,这样让左右轮一个快一个慢从而达到使小车 沿弧线运动的目的。 从该项里可以看到变量有两个,一个是系数 Ka 一个是差角 theta_e,当小车没 有完全正对目标点时,差角 theta_e 产生的轮速便会使小车边往前运动边转(又 因为 theta_e 有些大, 可能会有几十度,而轮速的最大值是 125,如果直接加到轮速上的话会使得左右 轮速差过大,效果不好,所以加个系数 Ka 以控制其对轮速的影响) */ /*该轮速的计算公式即为 position 中的公式,之所以没改是发现写得极好,如 果嫌速度不够快的话就将 vc 的值赋为 190(见该函数开头声明变量处), 这样计算出的轮速可使小车在几个周期里立刻达到最大速度 125,对距离很敏感 */ } else if (theta_e < 85 && theta_e > -85) { if (d_e < 5.0 && abs(theta_e) < 40) Ka = 0.1; vr = (int)( vc * (1.0 / (1.0 + exp(-3.0 * d_e)) -0.3) + Ka * theta_e); vl = (int)( vc * (1.0 / (1.0 + exp(-3.0 * d_e))-0.3 ) - Ka * theta_e); // vr = (int)( 120 + Ka * theta_e); // vl = (int)( 120 - Ka * theta_e); } else
{ vr = (int)(+.17 * theta_e); vl = (int)(-.17 * theta_e); } int num; int i; double temp=100;//将循环里要用到的中间变量赋个很大的值 double dis,dir,dis_temp; int ex_vl,ex_vr; for(i=0;i<5;i++)//依次遍历对方五个小车,得到离自己最近的那个小车的编号 以及与自己之间的距离 { dis=GetDis(robot->pos.x,robot->pos.y,env->opponent.pos.x,env->opponen t.pos.y); if(dis<=temp) { temp=dis; num=i; } } dir=Avoiddir(env,robot,num,x,y);//将x,y代入f(x)=kx+h-y计算,如果 f(x)>0说明对方那个机器人在小车与目标点连线的上方,小车就应该从对方机 器人的下方过去以达到壁障的目的 dis_temp=1/(temp-3.1);//小车与对方最近机器人之间的距离(经过了一下下运 算,忘了为什么这么弄了,反正大概就这么个意思) int times=70;//倍数 if(dir>=0)//对方机器人在小车与目标点连线的上方 { ex_vl=j*dis_temp*times;//系数times就有点像上面的Ka那样,起个辅助作用 ex_vr=-j*dis_temp*times;//这里计算出的是为使小车避障而产生的额外的轮 速,实质上就是让左右轮速有个差值从而绕开障碍物 } else { ex_vl=-j*dis_temp*times; ex_vr=j*dis_temp*times; } Velocity(robot, vl+ex_vl, vr+ex_vr);//将的额外的轮速分别加到vl跟vr 里一起赋给左右轮,就达到避障的目的了,实际上就是在position函数里加了 一点点罢了 } double Avoiddir(Environment *env,Robot *robot,int num,double x,double y)//小车与目标点之间的连线设为y=kx+h,解出后再令f(x)=kx+h-y.然后将对 方机器人的坐标x,y代入计算出就可以看出对方机器人在直线上方还是下方了
{ double k,h,a,b,i; k=(y-robot->pos.y)/(x-robot->pos.x); h=y-x*k; a=env->opponent[num].pos.x; b=env->opponent[num].pos.y; i=k*a-b+h; return i; } /*看到有好多新手对平台给的那个程序都不是很了解,今天好不容易有空把注释 添加上,就索性和着position函数里面的一些东东一块儿讲了。我能力有限, 有些地方几句话也不好表达清楚,结合实际理解吧,呵呵,希望能对大家有点帮 助。我花了两个小时才写完。^_^ ~~ */ 看起来有些乱 看起来好像有些乱,最好复制到vc++里面看
分享到:
收藏