DIY: Machen Sie einen Kampfroboter zu Hause. Teil 2 "Epic Fail"

Dies ist eine Fortsetzung einer Kurzgeschichte über die Entwicklung eines Kampfroboters ohne Intelligenz, eine kurze Anleitung zum Brennen von Controllern und dem Arduino 2560. Über unsere Teilnahme an der Show „Armored Boat: Autumn Warm Up“. Und auch meine Erfahrung, Arduino und zwei RC-Empfänger mit Schritt- und Kommutatormotoren zu verbinden.

Unter dem Markennamen GeekTimes


Die abnehmbare Platte hatte einen Habrahabr-Aufkleber. Nachdem ich dieses Panel verloren hatte, um Gewicht zu sparen, markierte ich den Roboter manuell. GT mach weiter!




Genaue Verbindung aller Systemelemente



1-Arduino 2560
2-RC-Empfänger
3,4-Kollektor-Motortreiber
5-Block-Relais
6-Batterie

Die Logik des Systems


Der Roboter (Rover) wird durch die Funksteuerung von zwei Transceivervorrichtungen gesteuert. Die erste Konsole des Hauptbedieners dient zur Steuerung der Bewegung des Roboters und der Pistolen, der zweite Bediener dupliziert die Steuerung der Pistolen. Auf dem Rover sind beide Empfänger mit dem Arduino verbunden, in dem wir programmgesteuert die PWM vom Empfänger ablesen, die Relais ein- und ausgeschaltet werden, um die Ventile des pneumatischen Systems zu steuern, und die PWM wird für die Motortreiber ausgegeben.
Skizze 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{
//    
    }
}



In der ersten Version des Roboters haben wir NEMA 43-Schrittmotoren verwendet, für die das Skizzieren etwas schwieriger war, weil Ich musste entweder die PWM aus den Empfängern in der Timer-Funktion berechnen oder den Schrittmotor steuern. Für diese Zwecke habe ich die TimerOne-Bibliothek verwendet.

Skizzieren Sie die Arduino RC Schrittmotorsteuerung

#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();


Design und Brennen von Arduino


Das Design wurde überdacht und getestet, um eine starre Struktur zu schaffen.

Es scheint mir, dass im Rahmen darunter dieser Moment aufgezeichnet wurde, als beim Schweißen das Kabel vom Arduino 2560 auf das Gehäuse traf. Infolgedessen brannte unser UART aus und wir konnten kein Flashen mehr über USB durchführen. Die schnellste Lösung war der Wechsel zu Arduino Uno, das zur Hand war. Sie verließen die Konsole des zweiten Operators, es gab genau die richtigen Ports.




Pneumatischer Systemtest


Von allen geplanten Waffen musste nur der Aufzug übrig bleiben, da sie ihn für die effektivste hielten. Das pneumatische System wurde an einem 6-atm-Kompressor getestet. Im Kampf haben wir bereits einen Zylinder mit CO2 und einem Druck nach einem Druckminderer von 10 atm verwendet, wir haben auch das Rohr durch einen größeren Durchmesser ersetzt.


Waffentest


Roboter fahren lernen
Bei einem dieser Tests haben wir Feldarbeiter an Steuerungen verbrannt. Auf der anderen Seite blieb ein Relais stecken und kehrte den Rückwärtsgang um. Dann gab ich den Rotorauslauf im Arduino-Code ein, eine gewisse Wartezeit, bevor ich die Richtung des Motors änderte. Die Kontrolle über den Roboter ist schlechter geworden, aber die Steuerungen sind ganz.


Straßentests des Roboters


Episches Versagen


Es sollte sofort angemerkt werden, dass wir keine Gewichte hatten. Wir haben den Roboter einfach zusammen gehoben, niemand wollte sagen, dass es schwer für ihn war, und wir alle nickten und waren uns einig, dass der Roboter leicht war.

Die Organisatoren, insbesondere die Arena-Wächter, nehmen das Sicherheitsproblem sehr ernst, viele Roboter haben sich vor dem Kampf einfach nicht qualifiziert. Beim Wiegen stellte sich heraus, dass unser Roboter 161,5 kg wiegt, mit einem maximal zulässigen Gewicht von 105. Peter Redmond weigerte sich, uns für einen Schnitt auf die Bühne gehen zu lassen. Wir mussten das gesamte pneumatische System und die Pistolen entfernen, die Schürze entfernen, die uns vor dem Werfen schützte, die Schutzwand entfernen und durch Plexiglas ersetzen, aus dem die Wände der Arena bestehen. Von 6 Batterien mussten 3 aufgegeben werden.

Wir haben uns qualifiziert, aber in der Arena konnten wir nur rammen. Wir wurden als Dunstabzugshaube bezeichnet, und unser Feind wurde Kühlschrank genannt. Wenn sie sagen "Der erste Pfannkuchen ist klumpig", meinen sie wahrscheinlich genau dieses Szenario, aber wir haben es genossen.

Video vom gepanzerten Boot


Viel Spaß beim Anschauen des Videos aus der Schlacht.


PS: Die Organisation der Aufführung war ein wenig verärgert, weil Dem Team, das den Roboter zusammenbaute, und den Bedienern, die ihn kontrollierten, wurde keine Aufmerksamkeit geschenkt. Wir haben Kostüme vorbereitet, wir wollten Freimaurer mit einer freimaurerischen Pyramide sein, aber wir haben gerade eine Kapuze bekommen, die über die Bühne fuhr ...


PPS: Wir haben bereits darüber nachgedacht, den Körper und das Konzept des Roboters für den nächsten Wettbewerb komplett zu ändern, aber "Sie geben zwei ungeschlagen für einen Schlag." Mit unseren Opener-Narben ist der Fall als Geschichte wertvoll. Auf der Unterschrift von Peter Redmond und anderen Gästen der Irish League, den Organisatoren und anderen Teilnehmern.


PPPS: Folgen Sie unserem vk- Team . Machen Sie sich bereit für den Roboter-Rasenmäherwettbewerb. Der Wettbewerb kündigte mehr als 10 Teams aus ganz Russland an. Uns wurde angeboten, einen Wettbewerb in Skolkovo abzuhalten.

Source: https://habr.com/ru/post/de386047/


All Articles