你并没有看错,为了更好地玩儿,我们搞了四台sumorobot,让它们对战。
虽然他们都是同一类型的机器人,但是为了让一切更刺激,我们修改了代码,用了三套方案,让它们都有属于自己的战斗方式。
相扑机器人比赛,世界上最热门的新机器人运动之一。在这个竞赛中使用的机器人被称为相扑机器人。这项赛事的挑战在于参赛机器人需要寻找其对手(通常是通过红外线或超声波传感器),将对手推出竞技场。参赛机器人为避免尴尬离开舞台,通常自备传感器,以检测边缘。
(视频在后面)
一、硬件组装
1. 小零件们
大概有上面这些图片中这些小零件,看起来也不多,安装起来也挺容易的。每一个零件分别是什么我就不再赘述了,DF官方商城里有的。
2. 底板安装——万向轮
底板下面我们要安装万向轮,两边要安装轮胎,当然还有底板下面的巡线传感器 万向轮:
将大滚珠放进去,然后在四个缝隙里放入小滚珠,接着把盖片贴上去,最后贴合者小车的底板然后用螺丝固定住就好了。
底部为啥加了这么多螺丝?
这是因为心机婊们都想通过这个方法让自己的sumorobot更重,不容易被对手推出场地。
3. 底板安装——轮胎
底板两侧有两个专门为安装轮胎所预留的两个比较大的空隙,我们将轮胎放进空隙里
然后把轮胎固定件卡到电机上,注意螺丝孔要对齐。之后,将螺母放到固定件的凹槽中,然后用螺丝将固定件固定住,这样也就能将电机和轮胎固定住了。
下面是已经固定好的侧面图以及俯视图,我们要注意螺丝的朝向,不要安装反了。
如果担心玩得太嗨,撞击得太剧烈导致电机的线断掉的话,可以像我们一样将可能断裂的地方用热熔胶加固。
4. 红外距离传感器及巡线传感器安装
底板的上部安装红外距离传感器,底板的下部我们安装红外巡线传感器,为了节省资源,我们用一个短铜柱将它们安装在一起。
5. 电池固定件安装
考虑到玩的时间较长,我们选择了更方便安装和拆卸的充电电池组
于是在固定上,我们利用3D打印机为这款电池量身定做了一个固定件。(这让一切都方便了不少)此外还有两个90°金属挡片,这是为了保护电池,不让它在小车转弯太快的时候飞出去。
6. 主板安装
这里我们利用三根或者四根稍长的铜柱,就可以把主控板固定住了。
7. 电机电源和传感器连接及正中距离传感器
正中间我们还需要一个精度比较好的红外距离传感器,我们直接用热熔胶固定就ok了,传感器连接上我们需要注意不要将正负极接反了,左右电机和左右传感器接反没有问题,后面在代码上做一点修改就好了。 左电机连接M2,右电机连接M1,电源接线有很明显的标志,正接正,负接负就好。
左红外距离传感器连接A0,右红外距离传感器连接A3,左巡线传感器连接D8,右巡线传感器连接D9中间的红外距离传感器连接D10。值得一提的是,正中间的红外测距传感器可以直接用热熔胶来固定在底板上。
8. 小车组装完成
三、代码实现
为了让这一切更刺激,我们根据最原始的代码最初了修改,得到了三不同的代码,以求让sumorobot们都有着不同的进攻方式。
1. 直接型
运用直接型的机器人是marcus、和matt这两台sumoRobot的名字就是它们持有者的名字,可见其主人对它们的心爱程度,也从侧面反映了这两位玩家的懒癌程度。
这种代码是这一套sumorobot的初始进攻模式,一开始会以较慢的速度直行,然后根据底板上面的红外测距传感器返回的参数值来确定敌人在哪个方向,然后朝改防线猛烈的撞击。程序框图如下: 代码如下:
- <blockquote>#defineLEFT_A A0 //analog Left -->IR distance sensor in theleft
复制代码
2. 搜索型
Searching,它的战斗方式就是它的名字。一开始运行的时候,它就会转动它的身子以90°的范围来搜索前方是否有敌人,一旦探测到前方某个位置有敌人的存在,它就会立即以最大的速度充装上去,fighting。它的优势在于,在确定敌情之前绝不轻举妄动,一旦行动,必如脱兔。
程序流图如下:
其代码如下: - #defineLEFT_A A0 //analog Left -->IR distance sensor inthe left
- #defineRIGHT_A A3 //analog Right-->IR distance sensor intheright
- #defineMIDDLE 10 //10cm switch sensor in themiddle ---> less than 10cm return 0
- #defineLEFT_D 8 //Line Tracking Sensor in the left ---->find white return 1
- #defineRIGHT_D 9 //Line Tracking Sensor inthe right----> find white return 1
- #defineE1 5 //Motor speed controll
- #defineE2 6 //Motor speed controll
- #defineM1 4 //Motor direction controll
- #defineM2 7 //Motot direction controll
- intDistance_L=0,Distance_R=0;
- intSwitch_L,Switch_M,Switch_R;
- intURtime=0;
- //函数功能:定义每个引脚为输入或输出型,只运行一遍
- voidsetup()
- {
- pinMode(LEFT_A,INPUT); //引脚LEFT为接守型的引脚
- pinMode(RIGHT_A,INPUT);
- pinMode(MIDDLE,INPUT);
- pinMode(LEFT_D,INPUT);
- pinMode(RIGHT_D,INPUT);
- for (inti=4;i<8;i++)
- pinMode(i,OUTPUT); //引脚4,5,6,7,为输出型的引脚
- //Serial.begin(9600);
- delay(2000);
- }
- //函数功能:程序运行时loop()会一直循环运行,从而不断获得传感器的值和做出相应的动作。
- voidloop()
- {
- switch(Get_state())
- {
- case 0:{Turn_Left(125,125);Serial.println("L");} break;//收到0,执行左转程序
- case 1:{Turn_Right(125,125);Serial.println("R");} break;//收到1,执行右转程序
- case 2:{Turn_Forward(255,255);Serial.println("Ff");delay(25);} break;
- case 3:{Turn_Forward(125,125);Serial.println("F");} break;
- case 4:{Turn_Back(125,125);Serial.println("B");} break;
- case 5:{Search(88,88);Serial.println("S");}
- default:break;
- }
- //delay(200);
- }
- //函数功能:获得各个传感器的的值并通过传感器的值判断小车处在的状态
- intGet_state()
- {
- intSt=0; //状态值,开始时为0
- Distance_L=analogRead(LEFT_A);//读取左前方距离传感器的值
- Distance_R=analogRead(RIGHT_A);//读取右前方距离传感器的值
- Switch_L =digitalRead(LEFT_D);//读取左前方巡线传感器的值-->对地面的传感器
- Switch_R =digitalRead(RIGHT_D);//读取右前方巡线传感器的值
- Switch_M =digitalRead(MIDDLE);// 读取中间10cm开关传感器的值
- if(Distance_L>150) St=St+1; // 如果左前方距离值大于300,状态值加1
- if(Distance_R>150) St=St+2; // 如果右前方距离值大于300,状态值加2
- if(Switch_L==1) St=St+4; // 如果左前方巡线传感器测到白线,状态值+4
- if(Switch_R==1) St=St+8;//如果右前方巡线传感器测到白线,状态值加8
- if(Switch_M==0) St=St+16;//如果中间测到物体,状态值加16
- //--->测试时输出数据供调试用的,作用为输出各个测得的值以下为状态分类
- if (St==1|| St==8 || St==9 || St==10 || St==11)
- return 0;
- else if (St==2 || St==4 || St==5 || St==6 || St==7 || St==20 || St==21|| St==22 ||St==23)
- return 1;
- else if (St==16 || St==17 || St==18 || St==19 || St==3 )
- return 2;
- elseif(St==0)
- return 5;
- elsereturn 4;
- //以return 0 为例,如果小车在:
- //情况1:左边测到有物体--->St=1
- //情况2:右边巡线传感器测到白线,表示右前方已经在边界上-->St=8
- //情况3:情况1和情况2同时发生-->St=1+8=9
- //情况4:右边测到边界但右边也发现物体,-->St=8+2
- //情况5:右边测到边界且左右都测到物体,-->St=8+2+1=11
- //这几种情况都表示小车需要左转。就返回0给主函数,主函数收到0就会执行左转程序
- }
-
- //功能:左转,左右电机速度为x,y
- voidTurn_Left(int x,int y)
- {
- analogWrite(E1,x); //PWM Speed Control
- digitalWrite(M1,HIGH);
- analogWrite(E2,y);
- digitalWrite(M2,LOW);
- }
- voidTurn_Right(int x,int y)
- {
- analogWrite(E1,x); //PWM Speed Control
- digitalWrite(M1,LOW);
- analogWrite(E2,y);
- digitalWrite(M2,HIGH);
- }
- voidTurn_Forward(int x,int y)
- {
- analogWrite(E1,x); //PWM Speed Control
- digitalWrite(M1,HIGH);
- analogWrite(E2,y);
- digitalWrite(M2,HIGH);
- }
- voidTurn_Back(int x,int y)
- {
- analogWrite(E1,x);analogWrite(E2,y);
- digitalWrite(M1,LOW);digitalWrite(M2,LOW);
- }
- voidSearch(int x,int y)
- {
- if(millis() - URtime > 700&& millis() - URtime < 1400)
- {
- analogWrite(E1,x);
- digitalWrite(M1,HIGH);
- analogWrite(E2,y);
- digitalWrite(M2,LOW);
- }
- elseif(millis()-URtime>1400)
- {
- analogWrite(E1,x);
- digitalWrite(M1,LOW);
- analogWrite(E2,y);
- digitalWrite(M2,HIGH);
- URtime = millis();
- }
- }
复制代码
3. 旋转型
运用这种进攻方式的sumorobot是“战神”(老实说这是一个多么俗气的名字)。这一种模式跟搜索型有着异曲同工之处,一开始运行的时候它也是搜索,不过其搜索方式有所不一样,它的方式是朝着一个方向进行360°的旋转。这种方式有一个有是,另一台小车无论从哪个方向撞击过来,它都能够以最快的速度察觉到敌情,不给敌人可趁之机。程序框图如下:
以下是旋转型的代码: - #defineLEFT_A A0 //analog Left -->IR distance sensor inthe left
- #defineRIGHT_A A3 //analog Right-->IRdistance sensor inthe right
- #defineMIDDLE 10 //10cm switch sensor in themiddle ---> less than 10cm return 0
- #defineLEFT_D 8 //Line Tracking Sensor in the left ---->find white return 1
- #defineRIGHT_D 9 //Line Tracking Sensor inthe right----> find white return 1
- #defineE1 5 //Motor speed controll
- #defineE2 6 //Motor speed controll
- #defineM1 4 //Motor direction controll
- #defineM2 7 //Motot direction controll
- intDistance_L=0,Distance_R=0;
- intSwitch_L,Switch_M,Switch_R;
- //函数功能:定义每个引脚为输入或输出型,只运行一遍
- voidsetup()
- {
- pinMode(LEFT_A,INPUT); //引脚LEFT为接守型的引脚
- pinMode(RIGHT_A,INPUT);
- pinMode(MIDDLE,INPUT);
- pinMode(LEFT_D,INPUT);
- pinMode(RIGHT_D,INPUT);
- for (inti=4;i<8;i++)
- pinMode(i,OUTPUT); //引脚4,5,6,7,为输出型的引脚
- //Serial.begin(9600);
- delay(2000);
- }
- //函数功能:程序运行时loop()会一直循环运行,从而不断获得传感器的值和做出相应的动作。
- voidloop()
- {
- switch(Get_state())
- {
- case 0:{Turn_Left(125,125);Serial.println("L");} break;//收到0,执行左转程序
- case 1:{Turn_Right(125,125);Serial.println("R");} break;//收到1,执行右转程序
- case 2: {Turn_Forward(255,255);Serial.println("F");delay(25);} break;
- case 3:{Turn_Forward(175,175);Serial.println("F");} break;
- case 4:{Turn_Back(250,250);Serial.println("B");delay(20);} break;
- default:break;
- }
- //delay(200);
- }
- //函数功能:获得各个传感器的的值并通过传感器的值判断小车处在的状态
- intGet_state()
- {
- intSt=0; //状态值,开始时为0
- Distance_L=analogRead(LEFT_A);//读取左前方距离传感器的值
- Distance_R=analogRead(RIGHT_A);//读取右前方距离传感器的值
- Switch_L =digitalRead(LEFT_D);//读取左前方巡线传感器的值-->对地面的传感器
- Switch_R =digitalRead(RIGHT_D);//读取右前方巡线传感器的值
- Switch_M =digitalRead(MIDDLE);// 读取中间10cm开关传感器的值
- if(Distance_L>150) St=St+1; // 如果左前方距离值大于300,状态值加1
- if(Distance_R>150) St=St+2; // 如果右前方距离值大于300,状态值加2
- if(Switch_L==1) St=St+4; // 如果左前方巡线传感器测到白线,状态值+4
- if(Switch_R==1) St=St+8;//如果右前方巡线传感器测到白线,状态值加8
- if(Switch_M==0) St=St+16;//如果中间测到物体,状态值加16
- //--->测试时输出数据供调试用的,作用为输出各个测得的值以下为状态分类
- if (St==0|| St==1 || St==8 || St==9 || St==10 || St==11)
- return 0;
- else if (St==2 || St==5 || St==6 || St==7 || St==20 || St==21|| St==22 || St==23)
- return 1;
- else if (St==16 || St==17 || St==18 || St==19 || St==3 )
- return 2;
- //elseif(St==0)
- //return3;
- elsereturn 4;
- //以return 0 为例,如果小车在:
- //情况1:左边测到有物体--->St=1
- //情况2:右边巡线传感器测到白线,表示右前方已经在边界上-->St=8
- //情况3:情况1和情况2同时发生-->St=1+8=9
- //情况4:右边测到边界但右边也发现物体,-->St=8+2
- //情况5:右边测到边界且左右都测到物体,-->St=8+2+1=11
- //这几种情况都表示小车需要左转。就返回0给主函数,主函数收到0就会执行左转程序
- }
-
- //功能:左转,左右电机速度为x,y
- voidTurn_Left(int x,int y)
- {
- analogWrite(E1,x); //PWM Speed Control
- digitalWrite(M1,HIGH);
- analogWrite(E2,y);
- digitalWrite(M2,LOW);
- }
- voidTurn_Right(int x,int y)
- {
- analogWrite(E1,x); //PWM Speed Control
- digitalWrite(M1,LOW);
- analogWrite(E2,y);
- digitalWrite(M2,HIGH);
- }
- voidTurn_Forward(int x,int y)
- {
- analogWrite(E1,x); //PWM Speed Control
- digitalWrite(M1,HIGH);
- analogWrite(E2,y);
- digitalWrite(M2,HIGH);
- }
- voidTurn_Back(int x,int y)
- {
- analogWrite(E1,x);analogWrite(E2,y);
- digitalWrite(M1,LOW);digitalWrite(M2,LOW);
- }
复制代码
四、War begin
开玩笑,花了这么多时间组装和调试代码。当一切完成之后,怎么能不比试比试看看谁的相扑机器人才是战争的王者呢? 所以我们开始了一场没有规则,只注重哪一台车留在台上以及观赏性的乱斗比赛:
begin_with_searching.zip
xiangpuceshi_turn.zip
zhixing.zip
|