Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Tourelle de sentinelle Nerf autonome

Composants et fournitures

Moteur pas à pas OpenBuilds NEMA 17
× 1
Moteur pas à pas DFRobot avec boîte de vitesses
× 1
Driver de moteur pas à pas DFRobot
× 1
DFRobot Pixy 2 Cam
× 1
Arduino Mega 2560
× 1
Capteur à ultrasons - HC-SR04 (Générique)
× 1
Pistolet Nerf Nitron
× 1

Outils et machines nécessaires

Imprimante 3D (générique)
Fer à souder (générique)
Routeur CNC

Applications et services en ligne

Arduino IDE
Autodesk Fusion 360

À propos de ce projet

Idée

Il y a quelques années, j'ai vu un projet qui présentait une tourelle semi-autonome qui pouvait tirer toute seule une fois visée. Cela m'a donné l'idée d'utiliser une caméra Pixy 2 pour acquérir des cibles, puis de viser automatiquement le pistolet nerf, qui pourrait ensuite se verrouiller et tirer tout seul.

Les composants

Pour ce projet, le pistolet aurait besoin d'yeux, j'ai donc choisi d'utiliser le Pixy 2 en raison de la facilité avec laquelle il peut s'interfacer avec la carte mère. Ensuite, j'avais besoin d'un microcontrôleur, j'ai donc choisi un Arduino Mega 2560 en raison du nombre de broches dont il dispose.

Étant donné que le pistolet a besoin de deux axes, lacet et tangage, il nécessite deux moteurs pas à pas. Pour cette raison, DFRobot m'a envoyé sa double carte de commande de moteur DRV8825.

CAD

J'ai commencé par charger Fusion 360 et insérer une toile attachée du pistolet nerf. Ensuite, j'ai créé un corps solide à partir de cette toile. Une fois le pistolet conçu, j'ai fabriqué une plate-forme avec quelques supports à roulement qui permettraient au pistolet de tourner de gauche à droite. J'ai placé un moteur pas à pas à côté de la plate-forme rotative pour l'entraîner.

Mais la plus grande question est de savoir comment faire monter et descendre le pistolet. Pour cela, un système d'entraînement linéaire avec un point attaché au bloc mobile et un autre point à l'arrière du pistolet était nécessaire. Une tige relierait les deux points, permettant au pistolet de pivoter le long de son axe central.

Fabrication des pièces

Presque toutes les pièces de ma conception sont destinées à être imprimées en 3D, j'ai donc utilisé mes deux imprimantes pour les créer. Ensuite, j'ai créé la plate-forme mobile en utilisant d'abord Fusion 360 pour générer les parcours d'outils nécessaires pour mon routeur CNC, puis j'ai découpé le disque dans une feuille de contreplaqué.

Assemblage

Une fois toutes les pièces créées, il était temps de les assembler. J'ai commencé par relier les supports de roulement au disque en rotation. Ensuite, j'ai assemblé l'ensemble à pas linéaire en faisant passer les tiges en aluminium de 6 mm et la tige filetée à travers les pièces.

Enfin, j'ai attaché le pistolet nerf lui-même avec une tige en acier et deux poteaux fabriqués à partir d'extrusions d'aluminium.

Programmation

Passons maintenant à la partie la plus difficile du projet :la programmation. Une machine à projectiles est très complexe et les calculs qui la sous-tendent peuvent être déroutants. J'ai commencé par écrire le déroulement du programme et la logique étape par étape, en détaillant ce qui se passerait à chaque état de la machine. Les différents états sont les suivants :

  • Acquérir la cible
  • Positionner le pistolet
  • Bobine les moteurs
  • Tire le pistolet
  • Détendez les moteurs

L'acquisition de la cible implique d'abord de configurer le Pixy pour suivre les objets rose néon en tant que cibles. Ensuite, le pistolet se déplace jusqu'à ce que la cible soit centrée dans la vue du Pixy, où sa distance entre le canon du pistolet et la cible est ensuite mesurée. En utilisant cette distance, les distances horizontales et verticales peuvent être trouvées en utilisant certaines fonctions trigonométriques de base. Mon code a une fonction appelée get_angle() qui utilise ces deux distances pour calculer l'angle nécessaire pour atteindre cette cible.

Le pistolet se déplace ensuite vers cette position et allume les moteurs via un MOSFET. Après avoir tourné pendant cinq secondes, il déplace ensuite le servomoteur pour appuyer sur la gâchette. Le MOSFET éteint ensuite le moteur, puis le pistolet nerf retourne à la recherche de cibles.

S'amuser

J'ai mis une fiche rose fluo au mur pour tester la précision de l'arme. Cela a bien fonctionné, car mon programme calibre et ajuste l'angle pour la distance mesurée. Voici une vidéo montrant le fonctionnement du pistolet :

Code

  • Schéma
SchémaC/C++
Télécharger sur Arduino Mega
#include #include #include "BasicStepperDriver.h"#include #include //X est le pas, Y est yawconst int pins[] ={6,7,8,5,4,12} ; //MX STEP, DIR, EN, MY STEP, DIR, ENconst int limit_switch =26, laser_pin =11, spool_pin =10, servo_pin =13, distance_trig =29, distance_echo =30;double speed =21.336;double speed_squared =455.225; float current_angle =0.0;float hyp_distance; //distance du canon à la cible en mètres#define X_MID 164#define Y_MID 150#define DEADZONE 15#define G 9.8#define STP_PER_DEG_YAW 3.333#define STP_PER_DEG_PITCH 184859#define MICROSTEPS 32#define RPM 120#define MOTOR_STEPS_YAW_Y 200#define MOTOR_STEPS_Y_Y 200 /17.7777 pas/degréBasicStepperDriver pitch_stepper(MOTOR_STEPS_X, pins[1], pins[0]);BasicStepperDriver yaw_stepper(MOTOR_STEPS_X, pins[4], pins[3]);Servo trigger;Pixy2I2C pixy;enum States { ACQUIRE, POSITION, SPOOL , FIRE, WIND_DOWN, RETURN};States state =ACQUIRE;void setup() { Serial.begin(115200); init_pins(); retard(1000); //home_pitch(); pixie.init(); Serial.println("Prêt...");}boucle void() { switch(state){ case ACQUIRE:Acquisition_target(); état =POSITION ; digitalWrite(laser_pin,HIGH); Pause; case POSITION:Serial.println("positionnement"); position_gun(); état =SPOOL ; Pause; case SPOOL:Serial.println("spooling"); digitalWrite(spool_pin,HIGH); retard (5000); état =FEU ; Pause; cas INCENDIE :fire_gun(); état =WIND_DOWN ; Pause; case WIND_DOWN :Serial.println("s'arrête" ); digitalWrite(spool_pin,LOW); retard (2000); état =RETOUR; digitalWrite(laser_pin,LOW); état =ACQUÉRIR ; Pause; }}void fire_gun(){ Serial.println("Firing gun!"); trigger.write(108); retard (400); trigger.write(90); delay(2000);}void position_gun(){ float x, y; hyp_distance =ping(); hyp_distance /=100; while(!hyp_distance){ hyp_distance =ping(); hyp_distance /=100; }Série.println(hyp_distance); x =cos(current_angle) * hyp_distance; y =sin(current_angle) * hyp_distance; float target_angle =get_angle(x,y); angle_cible /=100; Serial.println(cible_angle); move_pitch(target_angle - current_angle); current_angle =target_angle;}void Acquisition_target(){ int x=0, y=0; long steps_taken=0 ; verrouillage bool =faux ; while(!lock){ pixy.ccc.getBlocks(); if(pixy.ccc.numBlocks){ x =pixy.ccc.blocks[0].m_x; y =pixy.ccc.blocks[0].m_y ; Serial.print("Cible vue à l'emplacement X:");Serial.print(x);Serial.print(", Y:");Serial.println(y); if(x <=(X_MID - DEADZONE)){ //Si trop à gauche, déplacer le pistolet vers la gauche move_yaw(1) ; } else if(x>=(X_MID + DEADZONE)){ move_yaw(-1); } else if(y <=(Y_MID - DEADZONE)){ //trop haut, déplacer le pistolet vers le haut pitch_stepper.move(33152) ; étapes_prises +=33152 ; } else if(y>=(Y_MID + DEADZONE)){ pitch_stepper.move(33152); étapes_prises +=33152 ; } else{ verrou =vrai; Serial.print("Cible verrouillée à l'emplacement X:");Serial.print(x);Serial.print(", Y:");Serial.println(y); Serial.print("Étapes prises : " );Serial.println(étapes_prises); } } } current_angle =steps_taken / STP_PER_DEG_PITCH; Serial.print("Angle actuel : ");Serial.println(current_angle);}void init_pins(){ pinMode(pins[2],OUTPUT); pinMode(broches[5],SORTIE); pinMode(limit_switch, INPUT_PULLUP); pinMode(laser_pin, SORTIE); pinMode(spool_pin, OUTPUT); pinMode(distance_echo, INPUT); pinMode(distance_trig, SORTIE); digitalWrite(broches[2],LOW); digitalWrite (broches[5], LOW); digitalWrite(laser_pin,LOW); digitalWrite(spool_pin,LOW); trigger.attach(servo_pin); pitch_stepper.begin(RPM, MICRO PAS); yaw_stepper.begin(5, MICRO PAS); trigger.write(90);}void move_yaw(float degrés){ yaw_stepper.move(degrés*STP_PER_DEG_YAW*32);}void move_pitch(float degrés){ current_angle +=degrés ; pitch_stepper.move(degrees*STP_PER_DEG_PITCH);}float get_angle(float distance, float hauteur){ float i =2 * height * 455.225; flotteur j =G * distance * distance; i +=j; j =9,8 * je; i =sqrt(pow(vitesse_carré,2) - j); return atan((velocity_squared-i) / (G * distance))*(180/PI);}float ping(){ Serial.println("Obtenir la distance..."); longue durée; digitalWrite(distance_trig, LOW); délaiMicrosecondes(5) ; digitalWrite(distance_trig, HAUT); délaiMicrosecondes(10) ; digitalWrite(distance_trig, LOW); durée =pulseIn(distance_echo, HIGH); durée de retour / 2 / 29,1 ; //distance en mètres}void home_pitch(){ Serial.println(digitalRead(limit_switch)); if(!digitalRead(limit_switch)){ //Si le commutateur est actif pitch_stepper.rotate (720); } while(digitalRead(limit_switch)){ //Serial.println(digitalRead(limit_switch)); pitch_stepper.move(-32); } pitch_stepper.rotate(2880*2);}

Pièces et boîtiers personnalisés

Référentiel Thingiverse
Fichier CAO sur thingverse.com

Schémas


Processus de fabrication

  1. Moteurs pas à pas
  2. Les pilotes intégrés facilitent la conception des moteurs pas à pas
  3. Prototype Raspoulette
  4. Robot Pi simple
  5. Bibliothèque de moteurs pas à pas bipolaires
  6. Swiper - Auto Tinder/Bumble Swiper
  7. La zone grise entre les servomoteurs et les moteurs pas à pas
  8. Qu'est-ce qu'un moteur linéaire ?
  9. Qu'est-ce qu'un servomoteur ?