Roboterprojekt Bluetooth RC Car 1. Projektidee 1.1 Aufgabe des Roboters Unser Roboter ist ein Auto, das via Bluetooth ferngesteuert wird. Dabei werden 2 NXT s verwendet; einer auf dem Auto und einer dient als Fernbedienung. Die NXT sind fähig, die Umdrehung der Servos in Grad als Wert aufzuzeichnen und via Bluetooth weiter zu senden. In unserem Fall bedeutet das, dass wenn ein Servo der Fernbedienung gedreht wird, der Servo am Auto diesen Wert empfängt und weiterverarbeitet. Unser Auto soll gelenkt werden können und vorwärts und rückwärts fahren (mit Geschwindigkeitsregelung). 1.2 Motivation Als Inspirationsquelle auf der Ideensuche durchstöberten wir Lego-NXT Foren und YouTube. Wir trafen wiederholt Autos an, die ferngesteuert werden. Sie waren teilweise jedoch kabelgesteuert. Unser Ziel war kabellos. Ausserdem wollten wir die Möglichkeiten des NXT ein bisschen ausreizen, sehen was alles möglich ist mit Bluetooth. So fassten wir den Entschluss, ein über Bluetooth ferngesteuertes Auto zu bauen. 2. Projektumsetzung 2.1 Aufbau des Roboters Abb. 1: Das ganze Setup 1
2.1.1 Fernbedienung Die Fernbedienung ist ein NXT, mit 2 Servos bestückt. Links betätigt man eine Art Gashebel mit dem Finger (Hebel nach vorne rückwärts; Hebel nach hinten vorwärts) und rechts ist ein Lego-Rad als Steuerrad angebracht. 2.1.2 Auto Im Auto dienen Zwei Servos über eine Übersetzung als Antrieb für die Hinterräder. Ausserdem wurde ein Differential eingebaut. Im vorderen Teil befindet sich die Servolenkung. Möglichst zentral ist ein NXT als Empfänger und zur Verarbeitung des Signals von der Fernbedienung eingebaut. 2
2.2 Vollständige Quellcodes (siehe nächste Seite) Zusätzlich besteht die Software noch aus einer BTcom.java, welche wir heruntergeladen und für unsere Zwecke erweitert haben. Über diese wird die Kommunikation gesteuert. 3. Reflexion Am Anfang fingen wir relativ unorganisiert an, zu bauen. Der erste Auto-Prototyp wurde viel zu lang und unbrauchbar. Dann teilten wir auf; Severin widmete sich dem Programmcode und Ich baute das Auto nochmal neu. Es funktionierte besser. Unser erster Erfolg war die gelungene Verbindung zwischen den NXT s via Bluetooth und dass der Befehl zum Fahren via Bluetooth schon mal funktionierte. Wir machten einige Testfahrten und stellten fest, dass die Reichweite bis über 40 Meter weit ging. Doch die zeitliche Verzögerung war noch ein Punkt, den es zu optimieren gab. Das nächste Problem war die Programmierung der Lenkung. Es brauchte etwa doppelt so viel Zeit für die Lenkung als für den Antrieb. Anfangs blockierte wegen einem Fehler der Servo, und zeitweise wussten wir selber nicht warum es nicht funktionierte. Doch schlussendlich erreichten wir unsere Zielsetzung: Das Auto konnte vorwärts und rückwärts fahren, und gesteuert werden. Doch ein grosses Problem war immer noch die verzögerte Reaktion des Empfänger-NXT s auf die Signale der Fernbedienung. 3
2.3 Vollständige Quellcodes 2.3.1 Control package rc_car; import lejos.nxt.lcd; import lejos.nxt.motor; import lejos.nxt.nxtregulatedmotor; import lejos.nxt.sensorport; import lejos.nxt.touchsensor; import rc_car.btcom; public class Control { static NXTRegulatedMotor steermotor = Motor.A; static NXTRegulatedMotor drivemotor = Motor.B; public static TouchSensor touchsensor = new TouchSensor(SensorPort.S1); public static void main(string[] args) throws InterruptedException { BTcom.connect("nxt_ref"); //verbinden mit Slave-NXT steermotor.setspeed(450); int anglemax = 100; //max. Auslesewinkel Steuerrad while (true) { int speed = drivemotor.gettachocount(); //Winkel von Steuerrad und int angle = steermotor.gettachocount(); //Gashebel auslesen if (angle > anglemax) { steermotor.rotateto(anglemax); //mechanische Begrenzung steermotor.flt(); //der Steuerung bei if (angle < -anglemax) { //+ und - anglemax steermotor.rotateto(-anglemax); steermotor.flt(); if (touchsensor.ispressed()) { angle = 0; speed = 0; steermotor.rotateto(0); drivemotor.rotateto(0); Thread.sleep(1); steermotor.flt(); drivemotor.flt(); BTcom.sendangle(angle+10000); BTcom.sendspeed(speed-10000); Thread.sleep(10); LCD.clear(); LCD.drawInt(-speed, 0, 0); LCD.drawInt(angle, 10, 0); //bei gedrücktem Touchsensor wird //der Wagen gestoppt und die //Steuerung zurückgesetzt //Veränderung der Variabelnwerte //zur Erkennung beim Slave //Verzögerung, da es sonst zur //Überlastung beim Slave kommt //Geschwindigkeit und Steuerungs- //werte werden auf den Bild- //schirm geschrieben 4
2.3.2 Car package rc_car; import lejos.nxt.motor; import lejos.nxt.nxtregulatedmotor; import rc_car.btcom; import lejos.nxt.lcd; public class Car { static NXTRegulatedMotor leftmotor = Motor.A; static NXTRegulatedMotor rightmotor = Motor.B; static NXTRegulatedMotor steermotor = Motor.C; public static void main(string[] args) throws InterruptedException { BTcom.connect(); //verbinden mit Master-NXT int speed = 0; int angle = 0; int anglemax = 100; //max. Auslesewinkel Steuerrad Master int steermax = 45; //max. Auslenkung Steuermotor int speedmax = 45; //max. Auslesewinkel Gashebel Master steermotor.setspeed(450); while (true) { String strspeedorangle = BTcom.receivespeedorangle(); int speedorangle = Integer.parseInt(strspeedorangle); //Empfangen von //speed,angle if (speedorangle == 0) { speed = 0; angle = 0; else { if (speedorangle > 5000) { //Wert steht für angle, wenn angle = speedorangle-10000; //Wert>5000 else { //Wert steht für speed, wenn speed = speedorangle+10000; //Wert <=5000 LCD.clear(); LCD.drawInt(speed, 0, 0); LCD.drawInt(angle, 6, 0); //Geschwindigkeit und Steuerungs- //werte werden auf den Bild- //schirm geschrieben if (speed!= 0) { drive(speed*900/speedmax); //Geschwindigkeit festlegen (900 max) else { leftmotor.stop(); rightmotor.stop(); //Motoren stoppen, wenn speed=0 int angleto = (int) Math.round(angle*steermax/anglemax); //Steuerung LCD.drawInt(angleto, 12, 0); //... auslenken (max. steermax) steermotor.rotateto(angleto,true); Thread.sleep(1); 5
lasse public static void drive(int speed) { //Motoren vorwärts und rückwärts drehen leftmotor.setspeed(speed); rightmotor.setspeed(speed); if (speed < 0) { leftmotor.forward(); rightmotor.forward(); else { leftmotor.backward(); rightmotor.backward(); 6