DIY:在家制作一个战斗机器人。第2部分“史诗失败”

这是关于开发无智能战斗机器人的简短故事延续,有关燃烧控制器和Arduino 2560的简短指南。关于我们参加“装甲船:秋天的热身”表演的信息。还有我的经验,将Arduino和两个RC接收器与步进电机和换向器电机相连。

品牌名称GeekTimes


可移动面板贴有Habrahabr贴纸。失去了该面板以减轻重量后,我手动为机器人打上了商标。GT前进!




准确连接所有系统元件



1-Arduino 2560
2-RC接收器
3.4-集电极电机驱动器
5-块继电器
6-电池

系统的逻辑


机械手(流动站)由两个收发器设备的无线电控制装置控制。主操作员的第一个控制台用于控制机器人和枪支的运动,第二个操作员复制枪支的控制。在流动站上,两个接收器都连接到Arduino,在其中我们以编程方式从接收器读取PWM,打开/关闭继电器以控制气动系统的阀,并为电机驱动器发出PWM。
素描Arduino
#include <math.h>

#define STEP_PIN1  12
#define STEP_PIN2  10

#define RELEPIN0 2
#define RELEPIN1 3
#define RELEPIN2 4
#define RELEPIN3 5
#define RELEPIN4 6
#define RELEPIN5 7
#define RELEPIN6 8
#define RELEPIN7 9
     
#define a0 = A0;
#define a1 = A1;
#define a2 = A2;
#define a3 = A3;
#define a4 = A4;
#define a5 = A5;
// 
//   
//#define a6 = A8;
//#define a7 = A9;
int ch0,ch1,ch2,ch3,ch4,ch5,ch6,ch7;
//        
const int min0=1094;
const int  min1=1094;
const int  max0=813;
const int  max1=813;
int speed1,speed2,speedmot1,speedmot2,sd1,sd2;
byte ch2st,ch3st,ch4st,ch5st,ch6st,ch7st;
byte tormozcount1=0;
byte tormozcount2=0;
byte wasdir1=2;
byte wasdir2=2;
byte skolkotormozit = 7;
int skolkotormozim=0;

void setup() {
  Serial.begin(9600); 
  Serial.println("start");  
 
  pinMode(a0, INPUT);
  pinMode(a1, INPUT);
  pinMode(a2, INPUT);
  pinMode(a3, INPUT);
  pinMode(a4, INPUT);
  pinMode(a5, INPUT);  
  //   
  //pinMode(a6, INPUT);
  //pinMode(a7, INPUT);
  
  pinMode(STEP_PIN1, OUTPUT);
  pinMode(STEP_PIN2, OUTPUT);
  pinMode(RELEPIN0,  OUTPUT);
  pinMode(RELEPIN1,  OUTPUT);
  pinMode(RELEPIN2,  OUTPUT);
  pinMode(RELEPIN3,  OUTPUT);
  pinMode(RELEPIN4,  OUTPUT);
  pinMode(RELEPIN5,  OUTPUT);
  pinMode(RELEPIN6,  OUTPUT);
  pinMode(RELEPIN7,  OUTPUT);
}

void loop() {
 
ch0 =pulseIn(a0, HIGH,30000);
if(ch0<900){
//    
Serial.println("first no signal"); 
digitalWrite(STEP_PIN1,LOW);
digitalWrite(STEP_PIN2,LOW);
digitalWrite(RELEPIN0,LOW);  
digitalWrite(RELEPIN1,LOW);  
digitalWrite(RELEPIN2,LOW);  
digitalWrite(RELEPIN3,LOW);  
digitalWrite(RELEPIN4,LOW);  
digitalWrite(RELEPIN5,LOW);  
digitalWrite(RELEPIN6,LOW);  
digitalWrite(RELEPIN7,LOW);  

}
//      
ch1 =pulseIn(a1, HIGH);
ch2 =pulseIn(a2, HIGH);
ch3 =pulseIn(a3, HIGH);
ch4 =pulseIn(a4, HIGH);
ch5 =pulseIn(a5, HIGH);
//   
ch6 =1250; //pulseIn(a6, HIGH,2020);
ch7 =1250; //pulseIn(a7, HIGH,2020);

         if(ch2>1500){
          ch2st=1;
             }else{
                  ch2st=0;
                 }
         if(ch3>1500){
          ch3st=0;
             }else if(ch3>0){
                  ch3st=1;
                 }
         if(ch4>1500){
          ch4st=1;
             }else{
                  ch4st=0;
                 }
         if(ch5>1500){
          ch5st=1;
             }else{
                  ch5st=0;
                 }
         //      
         if(ch6>1800){
          ch6st=2;
             }else if(ch6<1200){
              ch6st=1;
                 }else{
                  ch6st=0;
                 }
         if(ch7>1800){
          ch7st=2;
             }else if(ch7<1200){
              ch7st=1;
                 }else{
                  ch7st=0;
                 }
                 


  // ----------------------------------------------
if(ch2st==1 or ch6st==1){
     digitalWrite(RELEPIN0,HIGH); 
  }else{
     digitalWrite(RELEPIN0,LOW); 
}

 
 // ----------------------------------------------
 if(ch3st==1 or ch6st==2){
     digitalWrite(RELEPIN1,HIGH); 
  }else {
    digitalWrite(RELEPIN1,LOW); 
}

// ----------------------------------------------
 if(ch4st==1 or ch7st==1){
     digitalWrite(RELEPIN2,HIGH); 
  }else {
    digitalWrite(RELEPIN2,LOW); 
}

//     
    if(ch0>0){  
    ch0=(ch0<55 && ch0>45)?50:ch0; 
    ch1=(ch1<55 && ch1>45)?50:ch1; 
           
    ch0 =ch0-min0;
    ch1 =ch1-min1;
    //       0  100
    ch0 =map(ch0,0,max0,0,100);
    ch1 =100-map(ch1,0,max1,0,100);  

        //          
        speed1=round((ch0-50)*(abs(ch1-50)+50)/50);
        speed2=round((ch1-50)*(abs(ch0-50)+50)/50);
        
        //     
        speedmot1=speed1+speed2;
        speedmot2=speed1-speed2;        
            //  
        speedmot1=(speedmot1>100)?100:speedmot1;
        speedmot2=(speedmot2>100)?100:speedmot2;
        speedmot1=(speedmot1<-100)?-100:speedmot1;
        speedmot2=(speedmot2<-100)?-100:speedmot2;
        speedmot1=(speedmot1<20 && speedmot1>-20)?0:speedmot1;
        speedmot2=(speedmot2<20 && speedmot2>-20)?0:speedmot2;

              sd1=map(abs(speedmot1),0,100,0,255);
              sd2=map(abs(speedmot2),0,100,0,255);

              //   
              Serial.print(ch0);
              Serial.print(";");
              Serial.print(ch1);              
              Serial.print(";");              
              Serial.print(";");
              Serial.print(speed1);
              Serial.print(";");
              Serial.print(speed2);
              Serial.print(";");
              Serial.print(speedmot1);
              Serial.print(";");
              Serial.print(speedmot2);
              Serial.print(";");
              Serial.print(sd1);
              Serial.print(";");
              Serial.print(sd2);
              Serial.print(";wasdir");
              Serial.print(wasdir1);
              Serial.print(";");
              Serial.print(wasdir2);
              Serial.println(";");

              //   ,      
              if(tormozcount1==0 and tormozcount2==0){
                 if(sd1<220){
              analogWrite(STEP_PIN1,sd1);
                 }else{
              digitalWrite(STEP_PIN1,HIGH);
                 }

              if(sd2<220){   
              analogWrite(STEP_PIN2,sd2);
              }else{
              digitalWrite(STEP_PIN2,HIGH);
                 }
              
              }else{
              digitalWrite(STEP_PIN1,LOW);
              digitalWrite(STEP_PIN2,LOW);
              }

//,  
        if(speedmot1<40 and speedmot1>-40){
          Serial.println("Tormoz menshe 40 1 dvig;");
          digitalWrite(RELEPIN3,HIGH); 
          digitalWrite(STEP_PIN1,LOW); 
          tormozcount1=0;
        }else{
          digitalWrite(RELEPIN3,LOW);
          
        }
        if(speedmot2<40 and speedmot2>-40 ){ 
          Serial.println("Tormoz menshe 40 2 dvig;");
        digitalWrite(RELEPIN4,HIGH);  
        digitalWrite(STEP_PIN2,LOW);
        tormozcount2=0;
        }else{
          digitalWrite(RELEPIN4,LOW);
        }

//    ,     ,   
if(speedmot1<40 and speedmot1>-40 and speedmot2<40 and speedmot2>-40){
skolkotormozim++;
}else{
 skolkotormozim=0; 
}

if( skolkotormozim>skolkotormozit){
  wasdir1=2;
  wasdir2=2;
  digitalWrite( RELEPIN5, LOW);
  digitalWrite( RELEPIN6, LOW);
  Serial.println("Stop for 10 cicles");
}

//  
        if((speedmot1 < -10 and wasdir1==1) || (speedmot1 >=5 and wasdir1==0)){
          //     
              if(tormozcount1<=0){
                //  0 
                Serial.println("Tormoz vibeg rotora 1 dvig;");
                digitalWrite(STEP_PIN1,LOW);
                digitalWrite(RELEPIN3,HIGH); 
                 tormozcount1=skolkotormozit;
              }
              if(tormozcount1>0){
                //  
                digitalWrite(STEP_PIN1,LOW);
                tormozcount1--;
              }   
              if(tormozcount1==1){
                // 
                tormozcount1--;
                digitalWrite(RELEPIN3,LOW); 
                Serial.println("Change 1dvig ");
                
                if(speedmot1 < 0){
                    wasdir1=0;
                    digitalWrite( RELEPIN5, HIGH);
                    Serial.println("vzad");
                  }else{
                    wasdir1=1;
                    digitalWrite( RELEPIN5, LOW);                    
                    Serial.println("vpered");
                 }
              }
        }

        if((speedmot2 < -10 and wasdir2==1) || (speedmot2 >=5 and wasdir2==0)){
          //     
              if(tormozcount2<=0){
                //  0 
                Serial.println("Tormoz vibeg rotora 2 dvig;");
                digitalWrite(STEP_PIN2,LOW);
                digitalWrite(RELEPIN4,HIGH); 
                 tormozcount2=skolkotormozit;
              }
              if(tormozcount2>0){
                //  
                digitalWrite(STEP_PIN2,LOW);
                tormozcount2--;
              }   
              if(tormozcount2==1){
                // 
                tormozcount2--;
                digitalWrite(RELEPIN4,LOW); 
                 Serial.print("Change 2dvig ");
                
                  if(speedmot2 < 0){
                    wasdir2=0;
                    digitalWrite( RELEPIN6, HIGH);
                    Serial.println("vzad");
                  }else{
                    wasdir2=1;
                    digitalWrite( RELEPIN6, LOW);
                    Serial.println("vpered");
                    }
              }
        }

//        
if(speedmot1 < -40 and wasdir1==2){
wasdir1=0;
digitalWrite( RELEPIN5, HIGH); 
  Serial.println("Reverse 1 motor");
}

if(speedmot1 > 40 and wasdir1==2){
wasdir1=1;
digitalWrite( RELEPIN5, LOW); 
Serial.println("Forward 1 motor");
}

if(speedmot2 < -40 and wasdir2==2){
wasdir2=0;
digitalWrite( RELEPIN6, HIGH); 
Serial.println("Reverse 2 motor");
}

if(speedmot2 > 40 and wasdir2==2){
wasdir2=1;
digitalWrite( RELEPIN6, LOW); 
Serial.println("Forward 2 motor");
}
        
   /*   
//
Serial.print(tormozcount1);
Serial.print(";");
Serial.print(tormozcount2); 
Serial.print(";");
Serial.print(wasdir1);
Serial.print(";");
Serial.print(wasdir2); 
Serial.print(";");
*/
//delay(1000);        
    }else{
//    
    }
}



在机器人的第一个版本中,我们使用了NEMA 43步进电机,对于它们来说,绘制草图有点困难,因为 我必须在计时器功能中从接收器计算PWM,或者控制步进电机。为此,我使用了TimerOne库。

素描Arduino RC步进电机控制

#include <TimerOne.h>  

setup .
  Timer1.initialize(500000);         // initialize timer1, and set a 1/2 second period
  Timer1.pwm(9, 512,300);                // setup pwm on pin 9, 50% duty cycle
  Timer1.attachInterrupt(callback); 


void callback()
{
digitalWrite(STEP_PIN1, digitalRead(STEP_PIN1) ^ 1);
delayMicroseconds(10);
digitalWrite(STEP_PIN1, digitalRead(STEP_PIN1) ^ 1);
}

.
Timer1.pwm(9, 512,speedmot1); 


 Timer1.detachInterrupt();


设计和刻录Arduino


设计经过深思熟虑并经过测试,以创建坚固的结构。

在我看来,当使用焊接时,Arduino 2560的电缆碰到外壳时,记录在该瞬间的下方。结果,我们的UART烧坏了,无法再通过USB进行刷新。最快的解决方案是切换到临近的Arduino Uno。他们放弃了第二个操作员的控制台,正好有足够的端口。




气动系统测试


在所有计划中的枪支中,仅需离开电梯,因为他们认为这是最有效的。气动系统是通过6 atm压缩机进行测试的。在战斗中,我们已经使用了装有二氧化碳和压力为10 atm的减压器的气瓶,我们还更换了直径更大的气管。


枪测试


学习骑机器人
在其中一项测试中,我们烧毁了控制器上的现场工作人员。另一方面,继电器卡住了反向。然后,我在arduino代码中输入了转子跳动,这是在改变引擎方向之前一定的等待时间。机器人的控制能力变差,但是控制器是完整的。


机器人的路测


史诗般的失败


应当立即指出,我们没有权重。我们只是简单地将机器人举起来,没有人想说这对他来说很辛苦,我们所有人都点了点头,并同意机器人很轻。

组织者,特别是竞技场管理员,非常重视安全问题;许多机器人在战斗前根本没有资格。称重后,我们的机器人的重量为161.5千克,最大允许重量为105。彼得·雷德蒙德(Peter Redmond)拒绝让我们上台进行切割。我们必须拆除整个气动系统,枪支,拆除保护我们不受折腾的裙边,拆除防护墙,并用制成竞技场墙的有机玻璃代替。在6个电池中,必须丢弃3个。

我们有资格,但是在竞技场上我们只能撞。我们被称为吸油烟机,我们的对手被称为冰箱。大概,当他们说“第一块煎饼是块状的”时,他们的意思就是这样,但是我们很喜欢。

装甲船的录像


欣赏战斗中的视频。


PS:演出组织有些沮丧,因为 没有人关注组装机器人的团队以及控制机器人的操作员。我们当时正在准备服装,我们想成为共济会金字塔的共济会成员,但我们只是在舞台上开车兜帽而已...


PPS:我们已经考虑过彻底改变机器人的身体和概念以备下次比赛使用,但“他们一跳就给了两个人。” 有了我们的开场白,这个案例就很有价值了。彼得·雷德蒙德(Peter Redmond)和其他来自爱尔兰联赛的嘉宾,组织者和其他参与者的签名。


PPPS:关注我们的vk团队机器人割草机比赛做准备比赛宣布了来自俄罗斯各地的10支队伍。我们被邀请在斯科尔科沃举行比赛。

Source: https://habr.com/ru/post/zh-CN386047/


All Articles