DIY: faites un robot de combat à la maison. Partie 2 «Échec épique»

Il s'agit d'une continuation d'une histoire courte sur le développement d'un robot de combat sans intelligence, un petit guide sur les contrôleurs de gravure et l'Arduino 2560. À propos de notre participation à l'émission "Armored Boat: Autumn Warm Up". Et aussi mon expérience en connectant Arduino et deux récepteurs RC avec des moteurs pas à pas et à collecteur.

Sous le nom de marque GeekTimes


Le panneau amovible avait un autocollant Habrahabr. Ayant perdu ce panneau pour réduire le poids, j'ai marqué le robot manuellement. GT allez-y!




Connexion précise de tous les éléments du système



1-Arduino 2560
2-RC Receiver
3.4-Collector Motor Drivers
5-Block Relay
6-Battery

La logique du système


Le robot (mobile) est contrôlé par les moyens de radiocommande de deux émetteurs-récepteurs. La première console de l'opérateur principal est utilisée pour contrôler le mouvement du robot et des pistolets, le deuxième opérateur duplique le contrôle des pistolets. Sur le mobile, les deux récepteurs sont connectés à l'Arduino, dans lequel nous lisons par programmation le PWM du récepteur, les relais sont activés / désactivés pour contrôler les vannes du système pneumatique, et le PWM est émis pour les pilotes de moteur.
Croquis 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{
//    
    }
}



Dans la première version du robot, nous avons utilisé des moteurs pas à pas NEMA 43, pour eux c'était un peu plus difficile à dessiner, car J'ai dû soit calculer le PWM à partir des récepteurs dans la fonction de minuterie, soit contrôler le moteur pas à pas. À ces fins, j'ai utilisé la bibliothèque TimerOne.

Sketch Arduino RC Stepper Motor Control

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


Conception et gravure d'Arduino


Le design a été pensé et testé afin de créer une structure rigide.

Il me semble dans le cadre ci-dessous que ce moment a été enregistré lorsque, lors de l'utilisation de la soudure, le câble de l'Arduino 2560 a heurté le boîtier. À la suite de cela, notre UART a grillé et nous ne pouvions plus effectuer de clignotement via USB. La solution la plus rapide était de passer à Arduino Uno, qui était à portée de main. Ils ont abandonné la console du deuxième opérateur, il y avait suffisamment de ports juste à droite.




Test du système pneumatique


De tous les canons prévus, seul l'ascenseur devait être laissé, car ils le considéraient comme le plus efficace. Le système pneumatique a été testé à partir d'un compresseur de 6 atm. Au combat, nous utilisions déjà un cylindre avec du CO2 et une pression après un détendeur de 10 atm, nous avons également remplacé le tube par un diamètre plus grand.


Test d'armes à feu


Apprendre à piloter un robot
Lors d'un de ces tests, nous avons brûlé des agents de terrain sur des contrôleurs. De l'autre, un relais bloqué inversant l'inverse. J'ai ensuite entré le faux-rond du rotor dans le code Arduino, un certain temps d'attente avant de changer la direction du moteur. Le robot a empiré, mais les contrôleurs sont entiers.


Tests de rue du robot


Échec épique


Il convient de noter tout de suite que nous n'avions pas de poids. Nous avons simplement soulevé le robot ensemble, personne ne voulait dire que c'était difficile pour lui, et nous avons tous hoché la tête et convenu que le robot était léger.

Les organisateurs, en particulier les gardiens de l'arène, prennent la question de la sécurité très au sérieux; de nombreux robots ne se sont tout simplement pas qualifiés avant le combat. Une fois pesé, il s'est avéré que notre robot pèse 161,5 kg., Avec un poids maximum autorisé de 105. Peter Redmond a refusé de nous laisser monter sur scène pour une coupe. Nous avons dû retirer tout le système pneumatique, les pistolets, retirer la jupe qui nous protégeait du lancer, retirer le mur de protection et le remplacer par du plexiglas à partir duquel les murs de l'arène sont faits. Sur 6 batteries, 3 ont dû être abandonnées.

Nous nous sommes qualifiés, mais dans l'arène, nous ne pouvions que bélier. Nous étions surnommés la hotte et notre ennemi s'appelait un réfrigérateur. Probablement, quand ils disent "La première crêpe est grumeleuse", cela signifie exactement un tel scénario, mais nous l'avons apprécié.

Vidéo du bateau blindé


Profitez de regarder la vidéo de la bataille.


PS: L' organisation de la performance a été un peu contrariée, car il n'y avait aucune attention à l'équipe qui assemblait le robot et aux opérateurs qui le contrôlaient. Nous avons préparé des costumes, nous voulions être francs-maçons avec une pyramide maçonnique, mais nous venons de recevoir une capuche qui a fait le tour de la scène ...


PPS: Nous avons déjà pensé à changer complètement le corps et le concept du robot pour la prochaine compétition, mais "Ils donnent deux invaincus pour un battement." Avec nos cicatrices d'ouverture, l'affaire est précieuse comme histoire. Sur le corps de la signature de Peter Redmond et d'autres invités de la Ligue irlandaise, les organisateurs et les autres participants.


PPPS: suivez notre équipe vk . Préparez-vous pour le concours de tondeuse robot. La compétition a annoncé plus de 10 équipes de toute la Russie. On nous a proposé d'organiser un concours à Skolkovo.

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


All Articles