Programmieren von LegoMindstorms-Robotern mit NQC
Programmieren von LegoMindstorms-Robotern mit NQC
Programmieren von LegoMindstorms-Robotern mit NQC
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 -