Der PiBot ist ein einfacher Roboter mit Zweiradantrieb. Die Motoren sind mit Positionsmelder (Quadrature Encoder) ausgestattet. Jedes Rad kann bis auf 1° genau positioniert werden kann. Als Chassis kommt das Magician Chassis von Dagu zum Einsatz.
Die Stromversorgung und der Motorentreiber ist auf dessen Unterdeck untergebracht. Wichtig ist, dass die Motoren genügend elektrische Leistung zur Verfügung haben. Es empfiehlt sich dazu eine Powerbank mit zwei Ausgängen, 1A und 2.1A zu verwenden, oder die Motoren separat mit Batterien zu speisen.
Motoren Ansteuern
Mit dem folgenden Programm können die Motoren des PiBot angesteuert werden.
import time import pigpio DUTY_MAX=150 pi=pigpio.pi() motorA=(24,23) motorB=(8,25) # Setze den Duty Cycle def setMotorDuty(pins,duty): if duty < 0: duty = max(duty, -DUTY_MAX) + pi.get_PWM_range(pins[0]) pi.set_PWM_dutycycle(pins[0], duty) pi.write(pins[1], True) else: duty = min(duty, DUTY_MAX) pi.set_PWM_dutycycle(pins[0], duty) pi.write(pins[1], False) try: for i in range(0,150,5): setMotorDuty(motorA,i) setMotorDuty(motorB,i) time.sleep(0.2) # stop motors setMotorDuty(motorA,0) setMotorDuty(motorB,0) # catch ctrl-c except KeyboardInterrupt: setMotorDuty(motorA,0) setMotorDuty(motorB,0)
Aufgaben
- Erstelle auf einem anderen Raspberry Pi ein Programm, mit welchem man den Roboter fernsteuern kann. Verwende dazu die Bibliothek pygame um einen Tastendruck zu registrieren. Die Motoren sollen dabei nicht auf volle Leistung gestellt werden.
Motorposition ermitteln
An jedem Motor ist ein Quadratur-Encoder angebracht. Dieser erzeugt an seinen beiden Ausgängen ein spezielles Muster.
Dieses Muster erlaubt es, die Drehrichtung und die Position des Motors zu bestimmen. Pro Motorumdrehung werden 12 Impulse generiert. Das bedeutet, dass man die Motorposition bis auf 30° Grad genau messen kann. Zwischen Motor und Rad gibt es eine Untersetzung im Verhältnis 1:48. Somit lässt sich die Position eines Rades mit einer Genaugikeit von ca. 30°/48 = 0.6° bestimmen. Mit dem folgenden Code können die Positionen ausgelesen werden.
import time import pigpio DUTY_MAX=150 pi=pigpio.pi() # Motoren Pins motorA=(24,23) motorB=(8,25) # Encoder Pins encA = (7,11) encB = (9,10) # Registriere die Encoderpins encA1 = pi.callback(encA[0],pigpio.EITHER_EDGE) encA2 = pi.callback(encA[1],pigpio.EITHER_EDGE) encB1 = pi.callback(encB[0],pigpio.EITHER_EDGE) encB2 = pi.callback(encB[1],pigpio.EITHER_EDGE) # Setze den Duty Cycle def setMotorDuty(pins,duty): if duty < 0: duty = max(duty, -DUTY_MAX) + pi.get_PWM_range(pins[0]) pi.set_PWM_dutycycle(pins[0], duty) pi.write(pins[1], True) else: duty = min(duty, DUTY_MAX) pi.set_PWM_dutycycle(pins[0], duty) pi.write(pins[1], False) # Stoppe die Motoren und warte def stopMotors(): setMotorDuty(motorA,0) setMotorDuty(motorB,0) time.sleep(1) encA1.reset_tally() encA2.reset_tally() encB1.reset_tally() encB2.reset_tally() # Schreibe die Werte der Encoder def printTally(): print(encA1.tally()," ",encA2.tally()," ",encB1.tally()," ",encB2.tally()) try: # Teste Motor A stopMotors() for i in range(0,150,5): setMotorDuty(motorA,i) printTally() time.sleep(0.2) # Teste Motor B stopMotors() for i in range(0,150,5): setMotorDuty(motorB,i) printTally() time.sleep(0.2) # Teste beide Motoren stopMotors() for i in range(0,150,5): setMotorDuty(motorA,i) setMotorDuty(motorB,i) printTally() time.sleep(0.2) setMotorDuty(motorA,0) setMotorDuty(motorB,0) # catch ctrl-c except KeyboardInterrupt: setMotorDuty(motorA,0) setMotorDuty(motorB,0)
Aufgaben
- Schreibe eine Funktion, welche die Radposition in Grad ermittelt.
- Lass den Roboter genau einen Meter weit fahren.
- Schreibe eine Funktion, welche die Winkelgeschwindigkeit der Räder ermittelt.
- Lass den Roboter mit einer Geschwindigkeit von genau 10cm/s fahren.
- Schreibe eine Funktion, welche die beiden Motoren mit genau der gleichen Winkelgeschwindigkeit drehen lässt.
- Schreibe eine Funktion, welche die Räder blockiert.
- Lass den Roboter eine 90° Drehung machen. Die beiden Räder sollen sich dabei synchron und gegenläufig bewegen.
Stückliste
1 x Dagu Magician Chassis, Fr. 26.-
1 x mechadroid.aaac.ch, Pololu Magnetic Encoder Pair Kit, Fr. 9.50
1 x conrad.ch, Lochstreifen Platine, Fr. 3.50
2 x aliexpress.com, Biaxial Motoren, Fr. 2.-
1 x ebay.ch, L9110 Motoren Treiber, Fr. 2.-
2 x conrad.ch, Kondensator 0.47 μF, Fr. 1.50
2 x conrad.ch, Buchsenleiste 2×3 Pin, Fr. 1.50
2 x conrad.ch, Wannensteckerleiste 2×3 Pin, Fr. 0.70
1 x conrad.ch, Stiftleiste 1×36, Fr. 0.60
4 x aliexpress.com, M1 Kreuzschrauben, Fr. 0.05
Total: Fr. 47.95