中学灭火机器人共享方案
常用算法介绍
1)溜边法 就是*墙走,包括左手法则和右手法则,这是最基本的机器人灭火走迷宫算法,是其他算法的基础。但仅仅使用简单的左手法则或右手法则只能完成小学组比赛,初中组由于要灭4个房间的火并且要回家,高中组还要完成搜救、回家等任务,所以需要组合应用左右手法则。该方法的速度比较慢,适合初学者使用,多见于县、市级比赛。
2)固定线路走法
该方法组合应用走直线和走弧线的方法,很容易受电池电量和地面粗糙程度等因素的影响,算法的稳定性低,使用的人比较少。
3)一技必杀法
该算法的要点就是在出发点就查找火焰在哪个房间,直接向需要灭火的房间前进。由于该算法没有任何加分,并且对场地的要求很高,
使用的人很少
4)无火不进房间
该方法的要点是在房间的门口看一下,如果房间内有火,则进去灭火,否则去其他房间寻找火焰,比简单使用左右手法则速度要快很多
。该算法实际上是左手法则、右手法则、固定线路法的综合应用,是目前国内的主流算法,多见于省级和国家级比赛。
本实验室做了化了两个多月时间,做了近千次试验,终于实现了1-2-3-4号房间的无火不进房间算法,现对其中比较成功的部分向大家作一简单介绍。至于规则,由于篇幅所限,请大家自己到网络上去搜索。本学校使用的机器人基本组件由纳英特公司提供。
一)场地
机器人灭火竞赛场地平面示意图(单位:cm)
其中“H”为出发点,角落的是火焰,墙中间的是家具。
二) 传感器接法
左红外避障传感器接数字15口,
左45度角红外避障传感器接数字10口,
右红外避障传感器接数字14口,
右左45度角红外避障传感器接数字8口,
前红外避障传感器接数字9口,
声控传感器接模拟2口,
左火焰传感器接模拟3口,
右火焰传感器接模拟4口,
前地面灰度传感器接模拟5口,
后地面灰度传感器接模拟6口,
三) 总体算法
有火
无火
有火
无火
有火
转身,走右手数秒。走夹道到4号房间墙壁,走右手去4号房间,灭火,回家。
|
无火
四) 特殊点的检测
本校对纳英特技术人员在网站上提供的算法做了较大改进,使用一前一后两个灰度传感器,测试上千次无一失手,可*性大大提高,现介绍如下:
1) 出发点的检测
其中bs=80 hs=120是常数,分别表示白线和地面灰度。
while((analog(5)< bs)&&(analog(6)<bs))//位于出发点
{ motor(0,100);
motor(1,100);}
motor(0,100);
motor(1,100);
sleep(0.5);
gotofangjian1();//走出出发点去1号房间
2) 终点的检测
outtime=mseconds();//出门时间
while(1) // {
if (analog(5)<bs &&analog(6)<bs&&digital(9)==0)//如果前后灰度都是白色并且前面有墙壁
{
if (mseconds()-outtime>3000l)//防止在灭火圈或门口错误地停止
{ motor(0,-20);//到家刹车
motor(1,-20);
sleep(0.1);
stop();
break;}}
//其他回家代码
}
3) 房间门口线的检测
if(( analog(5)<bs && analog(6)>hs)||( analog(6)<bs && analog(5)>hs))//如果前白后黑或前黑后白则到门口
4) 灭火线的检测
if((((analog(5)<bs)&&(analog(6)>hs))||((analog(5)>hs)&&(analog(6)<bs))) &&((analog(3)<30|| (analog(4)<30))
//如果前白后黑或前黑后白并且火焰很强
{findhuoyanquan=1;//找到灭火圈
break;}
五) 灭火技巧
1)摇头灭火算法
在京沪对抗赛上,很多学校使用了左右摇晃脑袋的算法进行灭火,
本校首先试验了大范围摇头的算法,发现这种算法十分危险,一旦前几次摇头灭火不成功,就有可能出现南猿北撤的现象,原因是左右轮胎的摩擦系数有差异,导致风扇远离火焰。算法如下:
{
motor(0,-60);
motor(1,60);
sleep(0.8);
motor(0,60);
motor(1,-60);
sleep(0.8);
}
改进后的算法如下:
motor(3,100);//开启灭火风扇
tzcs=0;
while(tzcs<35)
{
if (analog(3)<analog(4))//左边火焰强,向左多摇动一点。
{
motor(0,-60);
motor(1,60);
sleep(0.3);
motor(0,60);
motor(1,-60);
sleep(0.1);
}
else if (analog(4)<analog(3)) //右边火焰强,向右多摇动一点。
{
motor(0,60);
motor(1,-60);
sleep(0.3) ;
motor(0,-60);
motor(1,60);
sleep(0.1) ;
}
else //正对火焰,左右摇动幅度一样。 {
motor(0,60);
motor(1,-60);
sleep(0.1) ;
motor(0,-60);
motor(1,60);
sleep(0.1) ;
}
tzcs++;
}
该算法的优点是能逐渐对准火焰,不会出现南猿北撤的现象。
2)接近火焰的算法
有时候由于离火焰比较远,导致风扇吹了很长时间也没有熄灭火焰,为了避免这一情况,我们使用了下列算法:
miehuotime=mseconds();
if( mseconds()-miehuotime>800L)//每灭火0.8秒前进0.2秒
{ miehuotime=mseconds();
motor(0,30);
motor(1,30);
sleep(0.2);
}
3)防止死灰复燃的算法
很多学校使用下面的简单算法来灭火,如果有火焰,开风扇3秒钟,无火焰,回家。这一算法十分危险,很可能在检测火焰的瞬间,火焰接近熄灭状态,等机器人回家时,死灰复燃,从而导致灭火失败。
本校使用连续3次确认灭火成功的方法来防止死灰复燃,每次检测1秒钟,其中menkouhuoyan=240是门口火焰值,是个常数。
motor(3,100);
try=0;
if (try<3)
{
while(try<3)
{
trytime=mseconds();
trycg=1;
while(mseconds()-trytime<1000L)
{
if ((analog(3)<menkouhuoyan)||(analog(4)<menkouhuoyan))
trycg=0;
}
if (trycg==0)
try=0;
motor(3,100);
sleep(2.0);
try++;
}
六) 回家算法
1)1号房间回家
走右手法则回家。
2)4号房间回家
走右手法则回家。
3)3号房间回家
走左手法则回家。
4)2号房间回家
走特殊的左手法则回家,实际上是左手法则和固定线路的组合。
由于2号房间回家对初学者是一个难点,现介绍算法如下:
首先走左手一段时间以调整身体姿态,在2号房间墙壁中间位置开始闭着眼睛走直线,走到3号号房间墙壁中间位置恢复走左手,回家。这种走法有较大的误差容限,比较可*。
void gohome2()
{
motor(0,30);//转身回家,因为右手进门,现在要左手出门。
motor(1,-90);
sleep(0.3);
stop();
zc=0;//直走标志为未走
outtime=mseconds(); //回家时间
outdoortime=mseconds()+3000L;//出门口时间初值
while(1) //
{
if (mseconds()-outtime>2000L)//防止以为灭火线为门口线
if ((analog(5)<bs&&analog(6)>hs)||(analog(5)>hs&&analog(6)<bs))
outdoortime=mseconds();//记下出门口时间
if (analog(5)<bs &&analog(6)<bs)//如果回到家
{
if (mseconds()-outtime>3000l)
{ motor(0,-20);
motor(1,-20);
sleep(0.1);
stop();
break;}}
if ((mseconds()-outdoortime>1300L)&&(zc==0))//出门1.3秒开始走直道
{
zc=1;//走直道只一次,置已经走过标志
beep();
motor(0,100);
motor(1,100);
sleep(1.1); // 走直道1.1秒
}
else//其他时间走左手法则回家
{//下面是左手法则代码
if (digital(9)==0 || digital(10)==0) // 前面有墙右转
{
motor(0, 10); //
motor(1, -100);
}
else if (digital(15) == 0) // 左边有墙直行
{
motor(0, 100); //?
motor(1, 100);
}
else //前无墙并且左无墙,左转。
{
motor(0, -100);
motor(1, 100);
motor(0, -10); //
motor(1, 100);
}
}
}
}
七) 3号房间到4号房间的走夹道算法
在3号房间先转身,走右手数秒,走夹道到4号房间墙壁,走右手进4号房间。其中走夹道算法如下:
while(digital(9)!=0)//走夹道直到前面看到4号房间墙壁
{
if (digital(15)==0&&digital(14)==0)//左有墙并且右有墙,前进
{motor(0,80);
motor(1,80);}
else if (digital(15)!=0&&digital(14)!=0) //左无墙并且右无墙,前进
{motor(0,80);
motor(1,80);}
else if (digital(10)==0&&digital(8)==0) //左45度有墙并且右45度有墙,前进
{motor(0,80);
motor(1,80);}
else if (digital(10)!=0&&digital(8)!=0) //左45度无墙并且右45度无墙,前进
{motor(0,80);
motor(1,80);}
else if (digital(14)==0||digital(8)==0) // 只是右有墙,左转
{motor(0,-80);
motor(1,30);}
else if (digital(15)==0||digital(10)==0) // 只是左有墙,右转
{motor(0,30);
motor(1,-80);}
}