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

Robot convivial de suivi des personnes omnidirectionnel

Composants et fournitures

Module de carte contrôleur de pilote de moteur pas à pas L298N
Conducteur de moteur double capable de jusqu'à 2A pour piloter les moteurs
× 2
Régulateur de tension abaisseur réglable à commutation CC CC LM2596
Pour réduire le 12V de la batterie à un rail 5V
× 1
Alarme Lipo embarquée Vérificateur de batterie Détecteur basse tension Avion RC Quadcopter
Utilisé pour sonner lorsque la tension de la lipo est faible pour s'assurer qu'elle n'est pas cassée pendant l'utilisation.
× 1
Moteur à engrenages 24 tr/min 12V 4mm arbre
Trois pour trois roues
× 3
Arduino Nano R3
Contrôleur de moteur
× 1
Caméra Web Microsoft LifeCam HD-3000
Pour détecter les visages des gens, vous pouvez utiliser un appareil photo moins cher mais c'est celui que j'avais au bureau .
× 1
Câbles de raccordement (générique)
Beaucoup de cavaliers pour la gestion de l'alimentation et l'utilisation du signal
× 10
Créateur Ci20
Comment oublier le cerveau de l'opération, le Ci20 !
× 1
Batterie Lipo 11.1V 3Cell
Exemple pour acheter sur ebay ci-joint.
× 1

Outils et machines nécessaires

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

Applications et services en ligne

OpenCV

À propos de ce projet

Soumission initiale

Ma première soumission au concours "Hackster Terminate the competition" était de créer un robot qui recherchait des humains, mais contrairement à ceux de l'univers Terminator, il ne tuait pas des gens, mais utilisait ses pouvoirs pour de bon.

Ce robot omnidirectionnel vous trouvera, vous détectera, vous repérera et vous complimentera !

Une exigence que je me suis spécifiée est que je m'assurerais que cela pourrait être fait sans avoir à construire l'électronique vous-même. Chaque pièce à l'intérieur de ce robot peut être achetée sur eBay, connectée à l'aide de didacticiels disponibles gratuitement et elle devrait fonctionner. Le boîtier sera alors imprimable en 3D, vous pourrez donc soit l'imprimer vous-même, soit le faire fabriquer sur des hubs 3D. Je pense que ce projet répond à cet objectif et je vais maintenant vous guider à travers les étapes de construction de votre propre Robot Hunter Flatterer

Comment tout fonctionne !

Commençons donc par un schéma du système qui montre toutes les parties du robot et comment elles s'assemblent. Nous ferons référence à cela tout au long de la construction et le vérifierons au fur et à mesure.

Ne soyez pas trop intimidé par ce schéma si vous n'avez jamais utilisé de moteurs auparavant. Cela se résume essentiellement à quatre parties principales :

  • Le côté gauche traite de la prise de la batterie et s'assure que les tensions sont correctes pour le système.
  • Le petit malin se fait sur le ci20
  • L'Arduino est utilisé pour dire aux moteurs quoi faire

Les quatre sections suivantes refléteront cette liste et vous guideront dans la configuration de chaque partie.

Faire face à l'électricité

Alors vous avez une batterie, et ensuite ?

Le schéma ci-dessus montre comment connecter tous les composants pour l'alimentation, si vous suivez le câblage dans le schéma, c'est la représentation réelle.

Connecter l'Arduino au L298N

Je pourrais expliquer cela, mais il vaut mieux suivre le tutoriel que j'ai fait :http://www.instructables.com/id/Arduino-Modules-L298N-Dual-H-Bridge-Motor-Controll.

Alors maintenant que vous avez tout câblé, vous avez des lumières bleues qui clignotent partout et aucune fumée bleue, donc vous êtes prêt à partir. Commençons à faire fonctionner ce mauvais garçon.

Imprimez vous-même une coque en 3D

Quand j'ai conçu cela, j'ai décidé que je voulais que deux choses se produisent, ça a l'air cool et ça montre le Ci20 aussi bien que possible. Je veux dire, c'est le but de la compétition, n'est-ce pas ?

J'ai conçu ce robot pour qu'il soit entièrement imprimable en 3D et les dessins sont tous disponibles ci-dessous. Fondamentalement, à ce stade, imprimez vous-même le haut, le bas et les roues. Si vous n'avez pas accès à une imprimante 3D, vous pouvez consulter www.3dhubs.com pour demander à quelqu'un de l'imprimer pour vous ! Vous pouvez consulter les conceptions ci-dessous

Voici un joli rendu que j'ai fait de la conception pour m'assurer que le ci20 allait s'adapter et être à la place d'honneur

Une fois que vous avez tout imprimé, vous pouvez coller toutes les pièces comme ci-dessus (ou utiliser du ruban adhésif si vous ne vous sentez pas à l'aise. Vous aurez besoin d'un boulon M4 pour maintenir les moteurs.

Faire de la magie du CI20

Le CI20 est le patron, le cerveau de l'opération. Sans cela, le robot pataugera. Alors qu'est-ce que ça fait ?

Eh bien, le ci20 va utiliser OpenCV pour détecter votre visage, puis envoyer les commandes appropriées en série à l'Arduino pour que les moteurs aillent dans la bonne direction.

Étape 1 :Installez OpenCV

Comme je l'ai dit tout au long de ce guide, je n'essayais pas de réinventer le panier à pommes. J'essaie de construire quelque chose que vous pouvez faire à la maison et étendre avec une relative facilité. Alors pour installer OpenCV allez et suivez ce tutoriel :

Il vous explique pas à pas comment faire fonctionner OpenCV.

Étape 2 :Exécutez le code

Le code Face Tracking devra être compilé et exécuté, exécutez cette commande sur le fichier sur le Ci20.

g++ -I/usr/local/include/opencv -I/usr/local/include/opencv2 -L/usr/local/lib/ -g -o binary main.cpp -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_ml -lopencv_video -lopencv_features2d -lopencv_calib3d -lopencv_objdetect -lopencv_contrib -lopencv_legacy -lopencv_stitching 

Le fichier binaire à créer :FaceTracking :main.cpp> ​​Fichier source :FaceTracking.cpp

Facile non ?

Ci20 et magie Arduino

Après avoir flashé l'Arduino avec le code dans les pièces jointes ci-dessous. Branchez l'Arduino sur le port USB du CI20 et exécutez votre FaceTracker récemment créé. Vous verrez apparaître un flux de caméra (Oh oui, branchez la webcam) et si vous collez votre visage au milieu, les roues du robot devraient commencer à le faire avancer !

Travail terminé ?

Maintenant, en raison de contraintes de temps, je n'ai pas réussi à faire autre chose, alors voici un défi pour tous ceux qui sont allés jusqu'ici. Il y a deux choses que vous pouvez ajouter pour rendre ce bot super génial :

Ajoutez un ensemble de haut-parleurs et des fichiers son afin que lorsque le visage est suffisamment grand sur l'écran, il diffuse un fichier son à la personne

  • Si le robot n'a pas détecté de visage en 1 à 2 minutes, faites-le tourner sur place. Vous pouvez le faire en envoyant la commande "R XX" à l'Arduino. Remplacez XX par la durée pendant laquelle vous souhaitez faire demi-tour.

Code

  • Arduino Sketch - Principal
  • Arduino Sketch - MotorControl
  • FaceTracking C++ pour Ci20
Arduino Sketch - PrincipalArduino
Ce code Arduino reçoit la commande d'entraînement du Ci20 via série et garantit que les moteurs sont entraînés correctement pour aller dans la bonne direction.

J'ai initialement écrit ceci pour un Raspberry Pi mais cela fonctionne aussi avec le Ci20
// Motor 1int dir1PinA =3;int dir2PinA =2;int speedPinA =9; // Doit être une broche PWM pour pouvoir contrôler la vitesse du moteur// Motor 2int dir1PinB =4;int dir2PinB =5;int speedPinB =8; // Doit être une broche PWM pour pouvoir contrôler la vitesse du moteur// Moteur 3int dir1PinC =6;int dir2PinC =7;int speedPinC =10; // Doit être une broche PWM pour pouvoir contrôler la vitesse du moteurint x =0;int y =0;int dominantUltrasonic =0;bool moveMotor =false;int startTime =0;void setup() { Serial.begin(9600); pinMode(dir1PinA,OUTPUT); pinMode(dir2PinA,OUTPUT); pinMode(speedPinA,OUTPUT); pinMode(dir1PinB,OUTPUT); pinMode(dir2PinB,OUTPUT); pinMode(speedPinB,OUTPUT); pinMode(dir1PinC,OUTPUT); pinMode(dir2PinC,OUTPUT); pinMode(speedPinC,OUTPUT); startTime =millis();}String rpiString;void loop() { readDataFromRPi(); // Ceci teste si nous avons reçu une valeur du RPi dans la dernière seconde. // Il agit effectivement comme un tampon afin qu'il ne s'arrête pas et ne démarre pas car la commande de déplacement n'est pas continue // Il permet également l'arrêt si rien ne vient du RPi // int elapsedTime =millis() - startTime; // if (elapsedTime> 1000)// {// x =0;// y =0;// dominantUltrasonic =0;// moveMotor =false;// startTime =millis();// // } // Envoyez les X &Y aux moteurs //if(moveMotor ==true &&(x !=0 &&y !=0)) //{ //Serial.println("MovingMotor"); // driveInDirection(x,y); //} //if(x ==0 &&y ==0) //{ //Serial.println("ZeroMMotor"); // driveInDirection(x,y); //} // Cela pourrait simplement être laissé par les ultrasons - hésitant à supprimer delay(30);}void readDataFromRPi(){ // Lire à partir de Rpi while (Serial.available()) { delay(3); //délai pour permettre au tampon de se remplir if (Serial.available()>0) { char c =Serial.read(); // obtient un octet du tampon série rpiString +=c; //rend la chaîne readString if(c =='n') { break; } } } // ENDWHILE // Si quelque chose a été lu depuis le RPi, placez-le dans x,y &domniantUltrasonic if (rpiString.length()>0) { Serial.println(rpiString); // voir ce qui a été reçu String isRotate =getValue(rpiString, ' ', 0); Chaîne xval =getValue(rpiString, ' ', 1); Chaîne yval =getValue(rpiString, ' ', 2); x =xval.toInt(); y =yval.toInt(); startTime =millis(); if (isRotate =="r") { rotate(x); } else { driveInDirection(x,y); } rpiString=""; } //ENDIF} String getValue(String data, char separator, int index){ int found =0; int strIndex[] ={0, -1 } ; int maxIndex =data.length()-1; for(int i=0; i<=maxIndex &&found<=index; i++){ if(data.charAt(i)==separator || i==maxIndex){ found++; strIndex[0] =strIndex[1]+1; strIndex[1] =(i ==maxIndex) ? i+1 :je; } } return found>index ? data.substring(strIndex[0], strIndex[1]) :"";}
Arduino Sketch - MotorControlArduino
Cela va avec le fichier ino principal et doit être inclus dans le même fichier de projet
/* * Code de contrôle du moteur * * Cette classe inclura le code pour faire aller le robot dans n'importe quelle direction * et tourner autour du point central. */void driveInDirection(float newX, float newY){ delay(20); flottant x =nouveauX ; float y =newY; flottant thêta =atan2(y,x); float mag =sqrt((x*x) + (y*y)); float vx =mag * cos (thêta); float vy =mag * sin(theta); flottant w1 =-vx; float w2 =0.5 * vx - sqrt(3)/2 * vy; float w3 =0.5 * vx + sqrt(3)/2 * vy; // Récupère la plus grande valeur w float wSet[] ={w1, w2, w3}; float la plus grandeValue =0,0 ; for (int i =0; i <3; i++) { if(abs(wSet[i])> plus grandeValue) { plus grande =abs(wSet[i]); } } float speedCoef =(float)147.0 /largeValue; w1 =w1 * speedCoef ; w2 =w2 * speedCoef ; w3 =w3 * speedCoef ; if (x ==0 &&y ==0) { w1 =0; w2 =0 ; w3 =0 ; } Serial.println(w1) ; Serial.println(w2); Serial.println(w3) ; w1 =contraindre (w1, -150, 150); w2 =contraindre (w2, -150, 150); w3 =contraindre (w3, -150, 150); booléen w1_ccw =w1 <0 ? vrai faux; booléen w2_ccw =w2 <0 ? vrai faux; booléen w3_ccw =w3 <0 ? vrai faux; octet w1_speed =(octet) map(abs(w1), 0, 150, 0, 255); octet w2_speed =(octet) map(abs(w2), 0, 150, 0, 255); octet w3_speed =(octet) map(abs(w3), 0, 150, 0, 255); printMotorSpeed ​​(w1_speed, 1); printMotorSpeed ​​(w2_speed, 2); printMotorSpeed ​​(w3_speed, 3); analogWrite(speedPinA, w1_speed);//Définit la variable de vitesse via PWM analogWrite(speedPinB, w2_speed); analogWrite(speedPinC, w3_speed);//Définit la variable de vitesse via PWM digitalWrite(dir1PinA, !w1_ccw); digitalWrite(dir2PinA, w1_ccw); digitalWrite(dir1PinB, !w2_ccw); digitalWrite(dir2PinB, w2_ccw); digitalWrite(dir1PinC, w3_ccw); digitalWrite(dir2PinC, !w3_ccw);}void rotate(float milliseconds){ float w1 =255; flottant w2 =255 ; flottant w3 =255 ; booléen w1_ccw =w1 <0 ? vrai faux; booléen w2_ccw =w2 <0 ? vrai faux; booléen w3_ccw =w3 <0 ? vrai faux; octet w1_speed =(octet) map(abs(w1), 0, 150, 0, 255); octet w2_speed =(octet) map(abs(w2), 0, 150, 0, 255); octet w3_speed =(octet) map(abs(w3), 0, 150, 0, 255); printMotorSpeed ​​(w1_speed, 1); printMotorSpeed ​​(w2_speed, 2); printMotorSpeed ​​(w3_speed, 3); analogWrite(speedPinA, w1_speed);//Définit la variable de vitesse via PWM analogWrite(speedPinB, w2_speed); analogWrite(speedPinC, w3_speed);//Définit la variable de vitesse via PWM digitalWrite(dir1PinA, !w1_ccw); digitalWrite(dir2PinA, w1_ccw); digitalWrite(dir1PinB, !w2_ccw); digitalWrite(dir2PinB, w2_ccw); digitalWrite(dir1PinC, w3_ccw); digitalWrite(dir2PinC, !w3_ccw); délai (millisecondes); analogWrite(speedPinA, 0);//Définit la variable de vitesse via PWM analogWrite(speedPinB, 0); analogWrite(speedPinC, 0);//Définit la variable de vitesse via PWM }void printMotorSpeed(byte motorSpeed, int motor){ Serial.print("Motor"); Serial.print(moteur); Serial.print(":"); Serial.println(motorSpeed); }
FaceTracking C++ pour Ci20C/C++
Suivez le guide dans Story
#include "opencv2/objdetect/objdetect.hpp"#include "opencv2/highgui/highgui.hpp"#include "opencv2/imgproc/imgproc.hpp"#include #include en utilisant l'espace de noms std;en utilisant l'espace de noms cv;CascadeClassifier face_cascade, eyes_cascade;String window_name ="Face Detection";#include #include #include #include #include #include #include #include int sendSerial(char* message){int fd =open("/ dev/ttyUSB0", O_RDWR);if (fd ==-1){ perror("dev/ttyUSB0"); return 1;}struct termios tios;tcgetattr(fd, &tios);tios.c_iflag =IGNBRK | IGNPAR;tios.c_oflag =0;tios.c_lflag =0;cfsetspeed(&tios, B96000);tcsetattr(fd, TCSAFLUSH,&tios);usleep(1000);//char msg[] ="50 50";write(fd , message, strlen(message));return 0;}/** * Détecte les visages et dessine une ellipse autour d'eux */void detectFaces(Mat frame) { std::vector faces; Tapis frame_gray; // Convertir en échelle de gris cvtColor(frame, frame_gray, COLOR_BGR2GRAY); // Égaliser l'histogramme equalizeHist(frame_gray, frame_gray); // Détecte les visages face_cascade.detectMultiScale(frame_gray, faces, 1.1, 3, 0|CASCADE_SCALE_IMAGE, Size(30,30)); // Itérer sur toutes les faces for(size_t i =0; i  yeux ; // Essayez de détecter les yeux, à l'intérieur de chaque visage // eyes_cascade.detectMultiScale(face, eyes, 1.1, 2, // 0 |CASCADE_SCALE_IMAGE, Size(50, 50) ); // if(eyes.size()> 0) // Dessine une ellipse autour du visage ellipse(frame, center, Size(faces[i].width/2, faces[i].height/2), 0, 0, 360 , Scalaire( 255, 0, 255 ), 4, 8, 0 ); if(center.x> frame.cols/3 &¢er.x =0) // pause break; } renvoie 0 ;}

Pièces et boîtiers personnalisés

C'est la base du robot omnidirectionnel, conçu par moi pour s'adapter à toutes les pièces et avoir un couvercle attachéC'est le couvercle qui montre le Ci20 dans toute sa splendeur.
Roues omnidirectionnelles
C'est la conception originale des roues omnidirectionnelles. J'en ai utilisé la moitié avec les jantes, puis je l'ai édité pour inclure le fichier CAO de l'arbre du moteur sur thingverse.com Une roue remixée du lien thingverse

Schémas

Voir une meilleure description dans la section histoire

Processus de fabrication

  1. Suivi de la boule Raspberry Pi
  2. Prototype Raspoulette
  3. Robot boîtier CD Raspberry Pi
  4. Robot d'alarme roulante
  5. Open CV Robot
  6. Robot ROS
  7. Robot Pi simple
  8. Robot pour une navigation intérieure super cool
  9. Qu'est-ce qu'un moteur linéaire ?