Nachdem ich etwas mit der Pixy CMUCam5 rumgespielt habe, wollte ich das auch als ein Sensor für einen Roboter ausprobieren. Das Pan-Tilt Modul habe ich ich weggelassen. D.h. die Kamera kann sich nur vor, zurück, links und rechts bewegen, was für meinen Test vollkommen ausreicht.
Mechanik
Das Fahrgestell besteht aus folgenden Tamiya Teilen:
- Tamiya 70157 Universal Plate Set (2 Stk)
- Tamiya Kettensatz
- Tamiya 70168 Double Motor Getriebebox
Auf den Aufbau des Chassis möchte ich nicht näher eingehen. Die Anleitung liegt den Sets bei. Es hat allerdings etwas gedauert, bis ich eine Idee hatte, wie man die zweite Platte am Chassis befestigen kann.
Elektronik
Versorgt wird der Roboter mit 5x AA Eneloop Akkus. Es ist auch empfehlenswert Akkus statt Batterien zu nehmen. Allein die Kamera kann schon gut über 200mA ziehen + die Motoren ziehen auch einiges an Strom. Mit Akkus wird man länger Spaß haben. Als Mikrocontroller (-Board) wird ein Arduino UNO eingesetzt und als Treiber der DRV8835. Die Verbindung zwischen Treiber und Arduino erfolgt auf einem Steckbrett. Ich wollte hier nichts fest verlöten, da der Roboter einfach nur ein Testaufbau ist. Wenn ich damit genug rumgespielt habe, wird das Fahrgestell für andere Sachen als Testplattform verwendet.
Die Verdrahtung auf dem Steckbrett ist ist dieselbe, wie in diesem Artikel, wo ich die Ansteuerung des Treibers kurz erklärt habe. Trotzdem hier nochmal die Fritzing-Grafik.
Programmierung
Nachdem man eine Signatur angelernt hat (siehe dazu: https://5volt-junkie.net/pixy-arduino/), kann man die Position des Objektes im Programm auswerten und dementsprechend die Motoren ansteuern.
Der Roboter versucht das Objekt in der Mitte der x-Achse zu behalten und einen bestimmten Abstand zum Objekt zu halten. Ist das Objekt zu nah, währt der Roboter rückwärts und wenn es zu weit weg ist, fährt er näher ran. Für die Größe des Objektes wird seine Fläche mit einer einfachen Formel ausgerechnet: Breite x Höhe = Fläche.
Die Soll-Fläche (area), die man selber vergeben muss, wird mit der Ist-Fläche verglichen. Dabei muss die Differenz größer als 200px sein. Das ist dafür da, damit der Roboter nicht ständig hin und her zuckt und sich erst in Bewegung setzt, wenn das Objekt erheblich weit/nah ist.
Ähnlich ist es auch bei der x-Achse gelöst. D.h. wenn das Objekt nur um 1px nach links oder rechts verschoben wurde, macht der Roboter erstmal nichts.
Variablen anpassen
In dem Programm gibt es mehrere Variablen, die an eigene Bedürfnisse angepasst werden sollen/können. U.A. maxArea und minArea. Diese Werte werden durch die Größe des Objektes beeinflusst und welchen Abstand der Roboter zu diesem Objekt halten soll.
Je nach gewünschter Geschwindigkeit, kann auch der Wert speed angepasst werden.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
//Pixy arduino robot //Arduino IDE 1.0.6 #include <SPI.h> #include <Pixy.h> Pixy pixy; int signature = 0; int x = 0; //positon x axis int y = 0; //position y axis int width = 0; //object's width int height = 0; //object's height int area = 0; int maxArea = 1000; //max object area int minArea = 800; //min object area int Xmin = 140; //min x position int Xmax = 180; //max x position int aPhase = 2; //aPhase on Pin D2 int aEnable = 3; //aEnable on Pin D3 int bPhase = 4; //bPhase on Pin D4 int bEnable = 5; //bEnable on Pin D5 int Speed = 50; //motor speed //drive forward void forward(){ digitalWrite(aPhase, LOW); digitalWrite(bPhase, LOW); analogWrite(aEnable, Speed); analogWrite(bEnable, Speed); } //drive backward void backward(){ digitalWrite(aPhase, HIGH); digitalWrite(bPhase, HIGH); analogWrite(aEnable, Speed); analogWrite(bEnable, Speed); } //rotate right void turnRight(){ digitalWrite(aPhase, HIGH); digitalWrite(bPhase, LOW); analogWrite(aEnable, Speed); analogWrite(bEnable, Speed); } //rotate left void turnLeft(){ digitalWrite(aPhase, LOW); digitalWrite(bPhase, HIGH); analogWrite(aEnable, Speed); analogWrite(bEnable, Speed); } //brake void brake(){ digitalWrite(aEnable, LOW); digitalWrite(bEnable, LOW); } void setup() { //D2 - D5 as output pinMode(aPhase, OUTPUT); pinMode(aEnable, OUTPUT); pinMode(bPhase, OUTPUT); pinMode(bEnable, OUTPUT); brake(); Serial.begin(9600); Serial.print("Starting...\n"); pixy.init(); //start direction test - can be deleted forward(); delay(1000); brake(); backward(); delay(1000); brake(); turnLeft(); delay(1000); brake(); turnRight(); delay(1000); brake(); delay(1000); //end direction test } //infinity loop void loop() { static int i = 0; uint16_t blocks; blocks = pixy.getBlocks(); //receive data from pixy signature = pixy.blocks[i].signature; //get object's signature x = pixy.blocks[i].x; //get x position y = pixy.blocks[i].y; //get y position width = pixy.blocks[i].width; //get width height = pixy.blocks[i].height; //get height //looking for signature 1 if(signature == 1){ area = width * height; //calculate the object area //rotate left if x position < max x position if (x < Xmin){ turnLeft(); } //rotate right if x position > max x position else if (x > Xmax){ turnRight(); } //drive forward if object too small else if(area < minArea){ forward(); } //drive backward if object too big else if(area > maxArea){ backward(); } //else brake else if(area > minArea && area < maxArea && x > Xmin && x < Xmax){ brake(); } } else{ brake(); } } //end |
Mein Robot fährt nur vorwärts und folgt nur im Zick-Zack Kurs.
Was mache ich falsch ?
Hi,
überprüfe mal die Verkabelung. Ansonsten kann es sein, dass sich an der Firmware oder Bibliotheken von Pixy was geändert hat. Da ich den Roboter aus dieser Anleitung nicht mehr habe, kann ich leider schlecht prüfen, was nicht stimmt.