Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Manufacturing Technology >> Herstellungsprozess

Omnidirektionale Personen, die freundlichen Roboter verfolgen

Komponenten und Verbrauchsmaterialien

L298N Dual-Schrittmotortreiber-Steuerplatinenmodul
Dual-Motortreiber mit bis zu 2A zum Antrieb der Motoren
× 2
LM2596 DC DC Switching Einstellbarer Abwärtsspannungsregler
Um die 12V von der Batterie auf eine 5V Schiene zu reduzieren
× 1
Onboard Lipo Alarm Battery Checker Niederspannungsdetektor RC Flugzeug Quadcopter
Wird verwendet, um zu ertönen, wenn die Spannung des Lipo zu niedrig wird, um sicherzustellen, dass er während des Gebrauchs nicht zerbricht.
× 1
24RPM DC 12V 4mm Wellengetriebemotor
Drei für drei Räder
× 3
Arduino Nano R3
Motorsteuerung
× 1
Microsoft LifeCam HD-3000-Webkamera
Um Gesichter zu erkennen, können Sie eine billigere Kamera verwenden, aber diese hatte ich im Büro .
× 1
Jumper (generisch)
Viele Steckbrücken für Energieverwaltung und Signalnutzung
× 10
Creator Ci20
Wie konnten wir das Gehirn der Operation, den Ci20, vergessen!
× 1
3 Zellen Lipo-Akku 11,1 V
Beispiel zum Kauf bei ebay im Anhang.
× 1

Notwendige Werkzeuge und Maschinen

3D-Drucker (generisch)
Lötkolben (generisch)

Apps und Onlinedienste

OpenCV

Über dieses Projekt

Ersteinreichung

Meine ursprüngliche Einreichung beim Wettbewerb "Hackster Terminate the competition" bestand darin, einen Roboter zu entwickeln, der Menschen sucht, aber im Gegensatz zu denen im Terminator-Universum nicht herumläuft, Menschen tötet, sondern seine Kräfte für immer nutzt.

Dieser omnidirektionale Roboter wird Sie finden, erkennen, auf Sie zielen und Ihnen Komplimente machen!

Eine Anforderung, die ich mir selbst gestellt habe, ist, dass ich sicherstellen würde, dass es hergestellt werden kann, ohne dass die Elektronik selbst gebaut werden muss. Jedes Teil in diesem Roboter kann bei eBay gekauft, mit frei verfügbaren Tutorials zusammengesteckt werden und sie sollten funktionieren. Das Gehäuse ist dann 3D-druckbar, sodass Sie es entweder selbst drucken oder auf 3D-Hubs herstellen lassen können. Ich denke, dieses Projekt erfüllt dieses Ziel und ich werde Sie jetzt durch die Schritte zum Bau Ihres eigenen Hunter Flatterer Robot führen

So funktioniert alles!

Beginnen wir also mit einem Systemdiagramm, das alle Teile des Roboters zeigt und wie sie zusammengesteckt werden. Wir werden während des gesamten Builds darauf verweisen und es im Laufe der Zeit überprüfen.

Lassen Sie sich von diesem Diagramm nicht zu sehr einschüchtern, wenn Sie noch nie zuvor Motoren verwendet haben. Es läuft im Wesentlichen auf vier Hauptteile hinaus:

  • Die linke Seite befasst sich damit, die Batterie zu entnehmen und sicherzustellen, dass die Spannungen für das System korrekt sind.
  • Der clevere Teil ist auf dem ci20 gemacht
  • Der Arduino wird verwendet, um den Motoren zu sagen, was sie tun sollen

Die nächsten vier Abschnitte spiegeln diese Liste wider und führen Sie durch die Einrichtung jedes Teils.

Umgang mit Elektrik

Du hast dir also eine Batterie besorgt, was nun?

Das obige Diagramm zeigt, wie Sie alle Komponenten für die Stromversorgung anschließen. Wenn Sie der Verdrahtung im Schaltplan folgen, ist dies die reale Darstellung.

Anschließen des Arduino an den L298N

Ich könnte das erklären, aber es ist besser, einfach dem Tutorial zu folgen, das ich gemacht habe:http://www.instructables.com/id/Arduino-Modules-L298N-Dual-H-Bridge-Motor-Controll.

Jetzt haben Sie alles verkabelt, überall blinken blaue Lichter und kein blauer Rauch, also können Sie loslegen. Lass uns diesen bösen Jungen zum Laufen bringen.

3D-Druck selbst eine Hülle

Als ich dies entwarf, entschied ich, dass zwei Dinge passieren sollten, es sieht cool aus und es zeigt den Ci20 so gut wie möglich. Ich meine, das ist der Sinn des Wettbewerbs, richtig?

Ich habe diesen Roboter so entworfen, dass er vollständig 3D-druckbar ist und die Designs sind alle unten verfügbar. Im Grunde gehen Sie an dieser Stelle und drucken Sie sich die Oberseite, die Unterseite und die Räder aus. Wenn Sie keinen Zugang zu einem 3D-Drucker haben, können Sie www.3dhubs.com besuchen, um jemanden zu finden, der ihn für Sie druckt! Sie können sich die Designs unten ansehen

Hier ist ein hübsches Rendering, das ich vom Design gemacht habe, um sicherzustellen, dass das ci20 passt und einen Ehrenplatz hat

Sobald Sie alles gedruckt haben, können Sie alle Teile wie oben beschrieben einkleben (oder verwenden Sie Klebeband, wenn Sie sich nicht sicher sind. Sie benötigen eine M4-Schraube, um die Motoren zu halten.

Lassen Sie den CI20 etwas zaubern

Der CI20 ist der Boss, das Gehirn des Unternehmens. Ohne sie wird der Roboter ins Stocken geraten. Was macht es also?

Nun, das ci20 wird OpenCV verwenden, um Ihr Gesicht zu erkennen, und dann die entsprechenden Befehle seriell an den Arduino senden, um die Motoren in die richtige Richtung zu bringen.

Schritt 1:OpenCV installieren

Wie ich in diesem Handbuch gesagt habe, habe ich nicht versucht, den Apfelwagen neu zu erfinden. Ich versuche, etwas aufzubauen, das Sie zu Hause tun und mit relativer Leichtigkeit erweitern können. Um OpenCV zu installieren, gehen Sie und folgen Sie diesem Tutorial:

Es führt Sie Schritt für Schritt durch, wie Sie OpenCV zum Laufen bringen.

Schritt 2:Code ausführen

Der Face Tracking-Code muss kompiliert und ausgeführt werden. Führen Sie diesen Befehl für die Datei auf dem Ci20 aus.

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 

Die zu erstellende Binärdatei:FaceTracking:main.cpp> ​​Quelldatei:FaceTracking.cpp

Einfach oder?

Ci20 &Arduino Magic

Nach dem Flashen des Arduino mit dem Code in den Anhängen unten. Stecken Sie den Arduino in den USB-Port des CI20 und führen Sie Ihren kürzlich erstellten FaceTracker aus. Sie werden sehen, wie ein Kamera-Feed auftaucht (Oh ja, schließen Sie die Webcam an) und wenn Sie Ihr Gesicht in die Mitte halten, sollten die Räder des Roboters beginnen, ihn vorwärts zu fahren!

Job erledigt?

Jetzt habe ich es aus Zeitgründen nicht ganz geschafft, etwas anderes zu tun, also ist hier eine Herausforderung für jeden, der so weit gekommen ist. Es gibt zwei Dinge, die Sie hinzufügen können, um diesen Bot super toll zu machen:

Fügen Sie eine Reihe von Lautsprechern und einige Tondateien hinzu, damit das Gesicht, wenn es groß genug auf dem Bildschirm ist, der Person eine Tondatei vorgespielt wird

  • Wenn der Roboter innerhalb von 1-2 Minuten kein Gesicht erkannt hat, drehen Sie ihn auf der Stelle herum. Sie können dies tun, indem Sie den Befehl "R XX" an den Arduino senden. Ersetzen Sie XX durch die Zeit, für die Sie sich umdrehen möchten.

Code

  • Arduino-Skizze - Haupt
  • Arduino-Skizze - MotorControl
  • FaceTracking C++ für Ci20
Arduino-Skizze - HauptArduino
Dieser Arduino-Code empfängt den Antriebsbefehl vom Ci20 über seriell und stellt sicher, dass die Motoren in der richtigen Weise angetrieben werden, um in die richtige Richtung zu gehen.

Ich habe dies ursprünglich für einen Raspberry Pi geschrieben, aber es funktioniert auch mit dem Ci20
// Motor 1int dir1PinA =3;int dir2PinA =2;int speedPinA =9; // Muss ein PWM-Pin sein, um die Motordrehzahl steuern zu können // Motor 2int dir1PinB =4;int dir2PinB =5;int speedPinB =8; // Muss ein PWM-Pin sein, um die Motordrehzahl steuern zu können // Motor 3int dir1PinC =6;int dir2PinC =7;int speedPinC =10; // Muss ein PWM-Pin sein, um die Motordrehzahl steuern zu könnenint 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 (GeschwindigkeitPinA, AUSGANG); pinMode (dir1PinB,OUTPUT); pinMode (dir2PinB,OUTPUT); PinMode (GeschwindigkeitPinB, AUSGANG); pinMode (dir1PinC, AUSGANG); pinMode (dir2PinC, AUSGANG); pinMode (speedPinC, AUSGANG); startTime =millis();}String rpiString;void loop() { readDataFromRPi(); // Dies testet, ob wir in der letzten Sekunde einen Wert vom RPi erhalten haben. // Es fungiert effektiv als Puffer, so dass es nicht ständig stoppt und startet, da der Bewegungsbefehl nicht kontinuierlich ist // Es ermöglicht auch das Anhalten, wenn nichts vom RPi eingeht // int elapsedTime =millis() - startTime; // if (elapsedTime> 1000) // {// x =0; // y =0; // dominantUltrasonic =0; // moveMotor =false; // startTime =millis (); // // } // Senden Sie die X &Y an die Motoren //if (moveMotor ==true &&(x !=0 &&y !=0)) //{ //Serial.println("MovingMotor"); // driveInDirection(x,y); //} //if(x ==0 &&y ==0) //{ //Serial.println("ZeroMMotor"); // driveInDirection(x,y); //} // Dies könnte nur vom Ultraschall übrig bleiben - zögerlich zu entfernen delay (30);}void readDataFromRPi(){ // Von Rpi lesen while (Serial.available()) { delay(3); // Verzögerung, damit der Puffer gefüllt werden kann, wenn (Serial.available ()> 0) { char c =Serial.read (); // holt ein Byte aus dem seriellen Puffer rpiString +=c; // macht den String readString if(c =='n') { break; aufrechtzuerhalten. //sehen, was empfangen wurde String isRotate =getValue(rpiString, ' ',0); String xval =getValue(rpiString, ' ', 1); String yval =getValue(rpiString, ' ', 2); x =xval.toInt(); y =yval.toInt(); startTime =millis(); if (isRotate =="r") { rotieren (x); aufrechtzuerhalten. Sonst { 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 :ich; } } Rückgabe gefunden>index ? data.substring(strIndex[0], strIndex[1]) :"";}
Arduino-Skizze - MotorControlArduino
Dies gehört zur Haupt-Ino-Datei und muss in dieselbe Projektdatei
/* * Motorsteuerungscode * * Diese Klasse enthalten Code, um den Roboter in jede Richtung * zu bewegen und um den Mittelpunkt zu drehen. */void driveInDirection(float newX, float newY){ delay(20); Float x =newX; float y =newY; Float theta =atan2(y,x); float mag =sqrt((x*x) + (y*y)); float vx =mag * cos(theta); float vy =mag * sin(theta); Schwimmer w1 =-vx; float w2 =0,5 * vx - sqrt(3)/2 * vy; float w3 =0,5 * vx + sqrt(3)/2 * vy; // Größten w-Wert ermitteln float wSet[] ={w1, w2, w3}; float größterWert =0,0; for (int i =0; i <3; i++) { if (abs (wSet [i])> größterWert) { größter Wert =abs (wSet [i]); } } float speedCoef =(float)147,0 / größterWert; w1 =w1 * GeschwindigkeitKoef; w2 =w2 * GeschwindigkeitKoef; w3 =w3 * GeschwindigkeitKoef; wenn (x ==0 &&y ==0) {w1 =0; w2 =0; w3 =0; } Serial.println (w1); Serial.println (w2); Serial.println (w3); w1 =einschränken(w1, -150, 150); w2 =einschränken(w2, -150, 150); w3 =einschränken(w3, -150, 150); boolesch w1_ccw =w1 <0 ? wahr falsch; boolesch w2_ccw =w2 <0 ? wahr falsch; boolesch w3_ccw =w3 <0 ? wahr falsch; byte w1_speed =(byte) map(abs(w1), 0, 150, 0, 255); byte w2_speed =(byte) map(abs(w2), 0, 150, 0, 255); byte w3_speed =(byte) map(abs(w3), 0, 150, 0, 255); printMotorSpeed ​​(w1_speed, 1); printMotorSpeed ​​(w2_speed, 2); printMotorSpeed ​​(w3_speed, 3); analogWrite (speedPinA, w1_speed); // Setzt die Geschwindigkeitsvariable über PWM analogWrite (speedPinB, w2_speed); analogWrite (speedPinC, w3_speed); // Setzt die Geschwindigkeitsvariable über 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 rotieren(float Millisekunden){ float w1 =255; Schwimmer w2 =255; Schwimmer w3 =255; boolesch w1_ccw =w1 <0 ? wahr falsch; boolesch w2_ccw =w2 <0 ? wahr falsch; boolesch w3_ccw =w3 <0 ? wahr falsch; byte w1_speed =(byte) map(abs(w1), 0, 150, 0, 255); byte w2_speed =(byte) map(abs(w2), 0, 150, 0, 255); byte w3_speed =(byte) map(abs(w3), 0, 150, 0, 255); printMotorSpeed ​​(w1_speed, 1); printMotorSpeed ​​(w2_speed, 2); printMotorSpeed ​​(w3_speed, 3); analogWrite (speedPinA, w1_speed); // Setzt die Geschwindigkeitsvariable über PWM analogWrite (speedPinB, w2_speed); analogWrite (speedPinC, w3_speed); // Setzt die Geschwindigkeitsvariable über 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); Verzögerung (Millisekunden); analogWrite (speedPinA, 0); // Setzt die Geschwindigkeitsvariable über PWM analogWrite (speedPinB, 0); analogWrite (speedPinC, 0); // Setzt die Geschwindigkeitsvariable über PWM}void printMotorSpeed ​​(byte motorSpeed, int motor) {Serial.print ("Motor"); Serial.print (Motor); Serial.print (:"); Serial.println (motorSpeed); }
FaceTracking C++ für Ci20C/C++
Folgen Sie der Anleitung in Story
#include "opencv2/objdetect/objdetect.hpp"#include "opencv2/highgui/highgui.hpp"#include "opencv2/imgproc/imgproc.hpp"#include #include Namespace std verwenden;Namespace cv verwenden;CascadeClassifier face_cascade, eyes_cascade;String window_name ="Gesichtserkennung";#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, B9600);tcsetattr(fd, TCSAFLUSH,&tios);usleep(1000);//char msg[] ="50 50";write(fd , message, strlen(message));return 0;}/** * Erkennt Gesichter und zeichnet eine Ellipse um sie herum */voidDetectFaces(Mat frame) { std::vectorfaces; Mattrahmen_grau; // In Graustufen konvertieren cvtColor(frame, frame_gray, COLOR_BGR2GRAY); // Histogramm entzerren equalizeHist(frame_gray, frame_gray); // Gesichter erkennen face_cascade.detectMultiScale(frame_gray, faces, 1.1, 3, 0|CASCADE_SCALE_IMAGE, Size(30,30)); // Iteriere über alle Gesichter for(size_t i =0; i  Augen; // Versuche Augen in jedem Gesicht zu erkennen // eyes_cascade.detectMultiScale(face, eyes, 1.1, 2, // 0 |CASCADE_SCALE_IMAGE, Size(50, 50) ); // if(eyes.size()> 0) // Ellipse um Gesicht zeichnen Ellipse(frame, center, Size(faces[i].width/2, faces[i].height/2), 0, 0, 360 , Skalar (255, 0, 255), 4, 8, 0); if(center.x> frame.cols/3 &¢er.x =0) // Pause break; } Rückgabe 0;}

Kundenspezifische Teile und Gehäuse

Dies ist die Basis des omnidirektionalen Roboters, der von mir entworfen wurde, um alle Teile hineinzupassen und einen Deckel angebracht zu haben. Dies ist der Deckel, der den Ci20 in seiner ganzen Pracht zeigt.
Omni-Richtungsräder
Dies ist das ursprüngliche Design der omnidirektionalen Räder. Ich habe eine Hälfte davon mit den Felgen verwendet und sie dann bearbeitet, um die Motorwellen-CAD-Datei auf thingiverse.com . einzubinden Ein remixtes Rad aus dem Dingiverse-Link

Schaltpläne

Siehe bessere Beschreibung im Story-Abschnitt

Herstellungsprozess

  1. Himbeer-Pi-Ball-Tracking
  2. Raspoulette-Prototyp
  3. Raspberry Pi CD-Box-Roboter
  4. Rollender Alarmroboter
  5. Offener CV-Roboter
  6. ROS-Roboter
  7. Einfacher Pi-Roboter
  8. Roboter für supercoole Indoor-Navigation
  9. Was ist ein Linearmotor?
  10. Was ist ein Getränkeroboter?