22.11.2013 Aufrufe

Programmieren von LegoMindstorms-Robotern mit NQC

Programmieren von LegoMindstorms-Robotern mit NQC

Programmieren von LegoMindstorms-Robotern mit NQC

MEHR ANZEIGEN
WENIGER ANZEIGEN

Erfolgreiche ePaper selbst erstellen

Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.

11.1. Stoppen und erneutes Starten <strong>von</strong> Tasks<br />

<strong>Programmieren</strong> <strong>von</strong> LEGO-MindStorms- <strong>Robotern</strong> <strong>mit</strong> <strong>NQC</strong><br />

Eine Möglichkeit der Problemlösung ist sicherzustellen, dass immer nur eine Task den Roboter steuert. Das haben wir in<br />

Kapitel 7.1 getan. Wir wollen uns das Programm nochmals anschauen:<br />

task main()<br />

{<br />

SetSensor(SENSOR_1,SENSOR_TOUCH);<br />

start check_sensors;<br />

start move_square;<br />

}<br />

task move_square()<br />

{<br />

while (true)<br />

{<br />

OnFwd(OUT_A+OUT_C); Wait(100);<br />

OnRev(OUT_C); Wait(85);<br />

}<br />

}<br />

task check_sensors()<br />

{<br />

while (true)<br />

{<br />

if (SENSOR_1 == 1)<br />

{<br />

stop move_square;<br />

OnRev(OUT_A+OUT_C); Wait(100);<br />

OnFwd(OUT_A); Wait(160);<br />

start move_square;<br />

}<br />

}<br />

}<br />

Der springende Punkt ist, dass die task check_sensors() die Motoren erst ansteuert, nachdem sie die task<br />

move_square gestoppt hat. So kann diese die Bewegung vom Hindernis weg nicht behindern. Sobald das Ausweichmanöver<br />

beendet ist, startet sie move_square wieder. Obwohl dieses für das oben genannte Problem eine gute Lösung<br />

ist, gibt es ein weiteres Problem. Wenn wir move_square wieder starten, beginnt es wieder am Anfang und nicht an der<br />

Stelle an der es zuvor unterbrochen wurde. Dieses ist für unsere kleinen Tasks ohne große Bedeutung. Aber oft entspricht<br />

dies nicht dem <strong>von</strong> uns gewünschten Verhalten. Oftmals wäre es besser eine Task dort zu stoppen, wo sie sich gerade<br />

befindet, und später genau an dieser Stelle wieder fortzusetzen. Leider ist dies nicht möglich.<br />

11.2. Standardtechnik der Semaphore<br />

Eine häufig verwendete Möglichkeit zur Lösung dieses Problems besteht darin, eine Variable sozusagen als Signal zu verwenden.<br />

Diese soll anzuzeigen, welche Task gerade die Steuerung der Motoren ausübt. Die anderen Tasks dürfen die<br />

Steuerung der Motoren so lange nicht aufnehmen, bis die erste Task <strong>mit</strong> der Variablen anzeigt, dass sie fertig ist und da<strong>mit</strong><br />

die Steuerung erlaubt. Solch eine Variable wird häufig ein Semaphor genannt. „sem“ soll solch ein Semaphor sein. Wir<br />

nehmen an, dass ein Wert <strong>von</strong> 0 anzeigt, dass keine Task die Motoren steuert. Wann immer eine Task etwas <strong>mit</strong> den<br />

Motoren tun möchte, führt sie die folgenden Befehle durch:<br />

until (sem == 0);<br />

sem = 1;<br />

// die Motoren führen gerade Befehle aus<br />

sem = 0;<br />

Da<strong>mit</strong> warten wir zuerst, bis keine andere Task die Motoren mehr benötigt (sem = 0). Dann übernehmen wir die Steuerung,<br />

indem wir sem = 1 setzen. Da<strong>mit</strong> signalisieren wir den anderen Tasks, dass wir die Motoren gerade steuern. Wenn wir da<strong>mit</strong><br />

fertig sind, stellen wir sem zurück auf 0. Daran erkennen die anderen Tasks, dass wir die Motoren nicht mehr benötigen.<br />

Hier ist das Programm <strong>von</strong> oben, dieses Mal <strong>mit</strong> einem Semaphor. Wenn der Berührungs- Sensor etwas berührt, ist das<br />

Semaphor gesetzt und das Ausweichmanöver wird durchgeführt. Während dieser Prozedur läuft, muß die Task<br />

move_square() warten. Im dem Moment, wo das Ausweichmanöver beendet ist, wird das Semaphor = 0 gesetzt und<br />

move_square() kann fortfahren.<br />

- 31 -

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!