Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
| lehrkraefte:blc:informatik:glf20:robotik:motorenkontrolle [2021/04/28 06:53] – [Intervall umrechnen, ein für alle mal] Ivo Blöchliger | lehrkraefte:blc:informatik:glf20:robotik:motorenkontrolle [2021/05/03 07:15] (current) – [Steuerung der Motoren] Ivo Blöchliger | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== Steuerung der Motoren ====== | ||
| + | Wir werden alle Längenangaben in cm vornehmen (das ist auch die Masseinheit für den Distanzsensor). | ||
| + | Die Motoren haben einen Winkelsensor, | ||
| + | |||
| + | <WRAP todo> | ||
| + | Messen Sie den Roboter aus und notieren Sie sich folgende Grössen (in cm): | ||
| + | * Raddurchmesser. | ||
| + | * Abstand der Räder (für die Berechnung von Kurven). | ||
| + | Berechnen Sie daraus folgende Grössen: | ||
| + | * Radumfang. | ||
| + | * Distanz in cm, die das Rad mit 1° Rotation zurücklegt. | ||
| + | * Anzahl Grad Rotation, die ein Rad zurücklegen muss, um den Roboter um 90° zu drehen (angenommen das andere Rad steht still). | ||
| + | |||
| + | <code python viertelkreis.py> | ||
| + | from ev3robot import * | ||
| + | |||
| + | # Roboter initialisieren | ||
| + | |||
| + | robot = LegoRobot() | ||
| + | links = Motor(MotorPort.A) | ||
| + | robot.addPart(links) | ||
| + | links.rotateTo(100, | ||
| + | |||
| + | robot.exit() | ||
| + | </ | ||
| + | {{: | ||
| + | </ | ||
| + | |||
| + | |||
| + | ==== Wichtigste Gear-Funktionen ==== | ||
| + | <WRAP info> | ||
| + | * Voraussetzung ist, dass die Variable '' | ||
| + | * **Nicht-blockierend** heisst, das Programm läuft sofort weiter. Die Motoren drehen einfach weiter in dieser Einstellung, | ||
| + | * **Blockierend** heisst, das Programm wartet an dieser Stelle die gegebene Anzahl **Millisekunden** und kann während dieser Zeit nicht auf Sensoreingaben reagieren. Die Motoren **stoppen nach** einen blockierenden Befehl wieder. | ||
| + | |||
| + | ^ nicht-blockierend ^ blockierend ^ Beschreibung ^ | ||
| + | | gear.backward() | gear.backward(ms) | fährt rückwärts | | ||
| + | | gear.forward() | ||
| + | | gear.left() | gear.left(ms) | dreht links | | ||
| + | | gear.right() | gear.right(ms) | dreht rechts | ||
| + | | gear.leftArc(radius) | gear.leftArc(radius , ms) | fährt auf einem Linksbogen (negative Radien bewirken eine Rückwärtsbewegung) | | ||
| + | | gear.rightArc(radius) | gear.rightArc(radius , ms) | Rechtsbogen | | ||
| + | | gear.setSpeed(speed) | | setzt die Geschwindigkeit (Werte zwischen 0 und ungefähr 70 sind überhaupt sinnvoll.) | | ||
| + | | gear.stop() | | stoppt das Fahrwerk (nötig nach nicht-blockierenden Befehlen | | ||
| + | | getLeftMotorCount() | | Gibt die Position des linken Motors in Grad zurück | | ||
| + | | resetLeftMotorCount() | | Setzt den Gradzähler des linken Motors auf 0° zurück | | ||
| + | |||
| + | Vollständige Dokumentation der Funktionen: http:// | ||
| + | </ | ||
| + | |||
| + | |||
| + | <WRAP todo> | ||
| + | * Der Wert '' | ||
| + | * Testen Sie dazu das folgende Programm '' | ||
| + | * Ermitteln Sie den Umrechnungsfaktor. | ||
| + | |||
| + | |||
| + | <code python speedtest.py> | ||
| + | from ev3robot import * | ||
| + | |||
| + | ###################### | ||
| + | ## Initialisierung ## | ||
| + | ###################### | ||
| + | |||
| + | # Roboter initialisieren | ||
| + | robot = LegoRobot() | ||
| + | |||
| + | # Raeder hinzufuegen | ||
| + | gear = Gear() | ||
| + | robot.addPart(gear) | ||
| + | |||
| + | ########################################### | ||
| + | ## B E G I N D E S P R O G R A M M S ## | ||
| + | ########################################### | ||
| + | v = 40 # Werte bis ca. 70 sind sinnvoll | ||
| + | t = 2 # Zeit, während der gemessen wird. | ||
| + | print(" | ||
| + | gear.setSpeed(v) | ||
| + | gear.forward() | ||
| + | Tools.delay(1000) | ||
| + | start = gear.getLeftMotorCount() | ||
| + | Tools.delay(t*1000) | ||
| + | distanz = gear.getLeftMotorCount()-start | ||
| + | print(" | ||
| + | gear.stop() | ||
| + | robot.exit() | ||
| + | </ | ||
| + | |||
| + | </ | ||
| + | |||
| + | === Zusatzaufgabe für Musiker (und alle Ton-Begeisterte) === | ||
| + | Testen Sie folgendes Program (drehen Sie dazu den Roboter auf den Kopf, damit die Räder frei drehen können. Was hören Sie und warum? | ||
| + | <code python speedtest.py> | ||
| + | from ev3robot import * | ||
| + | |||
| + | ###################### | ||
| + | ## Initialisierung ## | ||
| + | ###################### | ||
| + | |||
| + | # Roboter initialisieren | ||
| + | robot = LegoRobot() | ||
| + | |||
| + | # Raeder hinzufuegen | ||
| + | gear = Gear() | ||
| + | robot.addPart(gear) | ||
| + | |||
| + | ########################################### | ||
| + | ## B E G I N D E S P R O G R A M M S ## | ||
| + | ########################################### | ||
| + | |||
| + | for v in range(10, | ||
| + | print(" | ||
| + | gear.setSpeed(v) | ||
| + | gear.forward() | ||
| + | Tools.delay(2000) | ||
| + | |||
| + | gear.stop() | ||
| + | robot.exit() | ||
| + | </ | ||
| + | ===== Sauber anfahren und bremsen ===== | ||
| + | <WRAP todo> | ||
| + | * Schreiben Sie ein Programm, das den Roboter mit einer gegebenen Geschwindigkeit '' | ||
| + | * Berechnen Sie dazu aus der Geschwindigkeit die benötigte Zeit. | ||
| + | * Wie genau fährt der Roboter (Richtung und Distanz)? | ||
| + | <code python> | ||
| + | # INITIALISIERUNG FEHLT HIER NOCH | ||
| + | v = 50 # Geschwindkeit in setSpeed | ||
| + | d = 100 # Distanz | ||
| + | zeit = ???? # Aus v und d die benötigte Zeit berechnen | ||
| + | |||
| + | gear.setSpeed(v) | ||
| + | gear.forward(int(zeit*1000)) | ||
| + | |||
| + | gear.stop() | ||
| + | |||
| + | robot.exit() | ||
| + | </ | ||
| + | * Schreiben Sie das Programm wie folgt um: | ||
| + | <code python> | ||
| + | # INITIALISIERUNG FEHLT HIER NOCH | ||
| + | einMeter = 1234 # Die korrekte Anzahl Grad für 1 m ausrechnen und eintragen! | ||
| + | gear.resetLeftMotorCount() | ||
| + | mySpeed = 60 # Egal welche Geschwindigkeit | ||
| + | gear.setSpeed(mySpeed) | ||
| + | gear.forward() | ||
| + | while gear.getLeftMotorCount()< | ||
| + | pass # Tu einfach nix | ||
| + | gear.stop() | ||
| + | robot.exit() | ||
| + | </ | ||
| + | * Die Geschwindgkeit vor der while-Schlaufe soll auf 5 gesetzt werden. | ||
| + | * Die Geschwindigkeit soll auf den ersten 10cm langsam auf '' | ||
| + | * Finden Sie dazu eine lineare Funktion $v(d)=m \cdot d + q$, die zur Distanz $d$ (in Grad = '' | ||
| + | * Setzen mit dieser Funktion in der while-Schlaufe die Geschwindigkeit, | ||
| + | * Testen Sie Ihren Code. | ||
| + | * Machen Sie das umgekehrt Gleiche am Ende auf den letzten 40 cm | ||
| + | |||
| + | **Zusatz für Mathematik-Begeisterte**: | ||
| + | <hidden Lösungsansatz> | ||
| + | Bei konstanter Beschleunigung $a$ sehen ist $v(t)=a\cdot t$ und $s(t) = \frac{1}{2}a\cdot t^2$. Wir nehmen der Einfachheit halber an, dass $v(0)=0$ und $s(0)=0$. Ansonsten verkomplizieren sich die Formeln etwas, das Ergebnis ist aber qualitativ das gleiche. | ||
| + | |||
| + | Aus $s(t)=\frac{1}{2}a\cdot t^2$ erhält man $t=\sqrt{\frac{2s}{a}}$, | ||
| + | |||
| + | D.h. $v(s)$ müsste eine Wurzelfunktion sein (und nicht eine lineare Funktion). | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | ==== Intervall umrechnen, ein für alle mal ==== | ||
| + | <WRAP todo> | ||
| + | Wir suchen die lineare Funktion $f$, die das Intervall $[a,b]$ auf das Intervall $[c,d]$ abbildet, d.h. $f(a)=c$ und $f(b)=d$. | ||
| + | |||
| + | Gehen Sie dazu wie folgt vor: | ||
| + | * Intervall verschieben: | ||
| + | * Intervall skalieren auf $[0,1]$: Bestimmen Sie eine Multiplikation (Funktion $(f_2(x)$) so, $f_2(f_1(b)) = 1$ (und damit natürlich weiterhin $f_2(f_1(a))=0$). | ||
| + | * Intervall skalieren auf die Länge von $[c,d]$: Bestimmen Sie eine Multiplikation (Funktion $(f_3(x)$) so, $f_3(1) = $ Länge von $[c,d]$. | ||
| + | * Intervall verschieben: | ||
| + | * Die gesuchte Funktion ist $f(x) = f_4(f_3(f_2(f_1(x))))$. | ||
| + | |||
| + | {{lehrkraefte: | ||
| + | |||
| + | {{lehrkraefte: | ||
| + | |||
| + | Programmieren Sie diese Funktion nun in Python: | ||
| + | <code python> | ||
| + | # Bildet x mit lineare Funktion ab, so dass das Intervall [a,b] auf [c,d] abgebildet wird | ||
| + | def linear(a, | ||
| + | # Obige Funktionen auf x anwenden | ||
| + | # Resultat zurückgeben | ||
| + | return x | ||
| + | </ | ||
| + | Diese Funktion kann dann im Programm verwendet werden, z.B. | ||
| + | <code python> | ||
| + | if gear.getLeftMotorCount()< | ||
| + | gear.setSpeed(int(linear(0, | ||
| + | </ | ||
| + | |||
| + | <hidden Lösungsvorschlag> | ||
| + | <code python> | ||
| + | def linear(a, | ||
| + | return (x-a)/ | ||
| + | |||
| + | |||
| + | einMeter = 100/ | ||
| + | anfahren = 0.4*einMeter | ||
| + | bremsen = 0.6*einMeter | ||
| + | gear.resetLeftMotorCount() | ||
| + | mySpeed = 60 # Egal welche Geschwindigkeit | ||
| + | |||
| + | while gear.getLeftMotorCount()< | ||
| + | if gear.getLeftMotorCount()< | ||
| + | v = linear(0, | ||
| + | print(int(v)) | ||
| + | gear.setSpeed(int(v)) | ||
| + | gear.forward() | ||
| + | |||
| + | </ | ||
| + | </ | ||
| + | * Bauen Sie die Funktion '' | ||
| + | * Programieren Sie eine Funktion '' | ||
| + | <code python> | ||
| + | def fahrgut(distanz): | ||
| + | global gear # Sonst ist die Variable gear in der Funktion nicht zugänglich | ||
| + | # Hier den Programmteil einfügen | ||
| + | |||
| + | # Benutzung der Funktion | ||
| + | fahrgut(50) | ||
| + | </ | ||
| + | |||
| + | **Zusatz für Mathematik-Begeisterte** | ||
| + | * Bestimmen Sie $v(s)$ für die gleichmässig beschleunigte Bewegung mit $v(t)=at+v_0$ ($v_0>0$ ist die Anfangsgeschwindigkeit) und $s(t)=\frac{1}{2}at^2+v_0t$, | ||
| + | |||
| + | <hidden Lösung> | ||
| + | $$ | ||
| + | s(t)=\frac{1}{2}at^2+v_0t \quad \Leftrightarrow \quad t = \frac{-v_0 + \sqrt{v_0^2+2as}}{a} | ||
| + | $$ | ||
| + | Die negative Lösung wird hier verworfen, weil wir nur an der positiven Zeit interessiert sind. | ||
| + | Eingesetzt in $v(t)$ erhält man | ||
| + | $$ | ||
| + | v(s) = \sqrt{v_0^2+2as} | ||
| + | $$ | ||
| + | Löst man $v(s_1)=v_1$ nach $a$ auf erhält man | ||
| + | $$ | ||
| + | a = \frac{v_1^2-v_0^2}{2s_1} | ||
| + | $$ | ||
| + | und damit die gesuchte Funktion | ||
| + | $$ | ||
| + | v(s) = \sqrt{v_0^2 + \frac{v_1^2-v_0^2}{s_1} \cdot s} | ||
| + | $$ | ||
| + | |||
| + | Diese kann nun in Python programmiert werden: | ||
| + | <code python> | ||
| + | # Anfangsgeschwindigkeit, | ||
| + | def vs(v0, v1, s1, s): | ||
| + | return (v0*v0 + (v1*v1-v0*v0)/ | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||