Hallo

Zitat aus Kapitel 4.6.9 (Seite 101) der Anleitung:
Der letzte Parameter der Funktion, „blocking“ ist eine kleine Besonderheit, die wir etwas
genauer erklären müssen.
Die Funktion setzt normalerweise nur ein paar Variablen und es würde dann sofort mit
dem normalen Programmablauf weitergemacht. Die Fahrt würde „im Hintergrund“ automatisch
von der motionControl Funktion gesteuert. Das ist sinnvoll, wenn der Roboter
nebenbei noch andere Dinge tun muss, wie z.B. auf Hindernisse reagieren.
Das Task-System des RP6 verwaltet im Hintergrund mit einer Mischung aus Polling (regelmässiges Aufrufen aus dem Hauptprogramm) und Interupts (unterbrechen des Hauptprogramms) die Funktionen des Roboters. Mit den Funktionen der Bibliothek steuert man quasi nicht selbst den Roboter, man übergibt dem Task-System den Befehl und dieses organisiert dann das Zusammenspiel der einzelnen Funktionen. Dabei unterscheiden sich zwei Möglichkeiten:

- Es muss schnell auf ein Ereigniss reagieren (z.B. auf einen Feldwechsel der Odometry-Sensoren) oder periodisch immer wiederkehrend auf ein Ereigniss reagieren (z.B. Stopwatches oder Rampen bei setMotorPower). Dann verwendet das Task-System einen Interrupt und unterbricht für seine Aufgaben das Hauptprogramm (um z.B. den Impulszähler des Antriebs oder die Werte der Stopuhren zu akualisieren). Diese Unterbrechungen sind sehr kurz, weil sie nur aus ein paar Befehlen bestehen und nur das nötigste erledigen. Das Hauptprogramm wird dadurch fast nicht gebremst. (Tiefer mag ich an dieser Stelle nicht auf die Interupts eingehen)

- Es muss regelmässig umfangreiche Berechnungen anstellen (Fahrwege überwachen, Geschwindigkeiten regeln, IR und ACS-Signale auswerten..), die analogen Eingänge einlesen (Bumper, LDRs, Motorströme...) und andere, weniger zeitkritische Dinge erledigen. Es reicht vollkommen, wenn man dazu das Hauptprogramm an einer Stelle unterbricht und diese Tätigkeiten durch den Aufruf der jeweiligen Task-Funktion ausführen läßt. Im Gegensatz zum Interrupt, der ja für das Hauptprogramm zu einem willkührlichen Zeitpunkt auftreten kann, spricht man hier vom Polling. Allerdings werden nicht alle Aktionen bei nur einem Aufruf erledigt, es dauert einige Aufrufe, bis alle arbeiten erledigt sind und die Abarbeitung erneut startet. In der Anleitung steht dazu:

Ständig aus dem Hauptprogramm
aufrufen heisst hier nichts anderes, als dass man diese Funktion in der
Hauptschleife des Programms bei jedem Schleifendurchlauf einmal aufrufen muss. Es
reicht, wenn die Funktion alle 10 bis 50 Millisekunden einmal aufgerufen wird. Besser
ist es allerdings, die Funktion noch sehr viel öfter aufzurufen. Es schadet nicht, wenn
man die Funktion noch schneller aufruft, denn das Timing wird von einem der Hardwaretimer
gesteuert. Daher ist es auch egal ob man die Funktion in gleichbleibenden
Intervallen aufruft, oder ob man mal 1ms und mal 10ms zwischen den einzelnen Aufrufen
benötigt. Es kostet auch nur unwesentlich mehr Rechenzeit, die Funktion oft
aufzurufen. Sie wird nur komplett ausgeführt, wenn auch etwas zu tun ist.
"Blockierend" bedeutet nun, das Hauptprogramm pollt nicht (oder zu langsam). Ursachen sind z.B. zu lange Schleifen ohne Task-Aufruf, mSleep()s oder das Senden von vielen Zeichen. Und beim blockierenden Move() werden alle Tasks außer dem motionControll blockiert.

Nach soviel Text und Erklärungen bleibt mir leider nur noch zu sagen, dass dies alles nichts mit der Fehlfunktion deines Programms zu tun hat. Das ist mir zwar peinlich, aber es fehlt wohl nur der setMotorDir(FWD,FWD); vor dem moveAtSpeed(100,100); deshalb drehen die Motoren mit den Richtungen weiter, die sie beim Rotate() hatten.

Gruß

mic