Agent 00L – Liebesgrüße aus Helsinki
Linux Robotics
Im Vorwärtsmarsch zurück
Nachdem ich mein Programm vor_u_zurueck.nqc in den Spybot geladen und gestartet hatte fuhr dieser zunächst einmal rückwärts (statt vorwärts) und änderte dann nach drei Sekunden seine Richtung. Dieses ist kein Fehler im Programm, sondern einfach konstruktionsbedingt. Das Zahnrad setzt direkt am Motor einmal um auf die großen Zahnräder meines Gigamesh G60 (Agentenfoto 6), weswegen in allen Programmen vorwärts und rückwärts vertauscht programmiert werden müssten, wenn NQC dafür nicht den Befehl SetGlobalDirection() hätte. Mit dem Parameter OUT_REV werden alle Kommandos umgekehrt. Weitere Bewegungsbefehle für den Spybot finden Sie in Kasten 2.
Kasten 2: NQC-Bewegungsbefehle
OUT_A // rechter Motor
OUT_B // linker Motor
OUT_V // Laser
outputs // ein +
-Kombination aus
// OUT_A, OUT_B und OUT_C (soweit sinnvoll)
On(outputs) // An
Off(outputs) // Aus
Fload(outputs) // Auslaufen lassen
Fwd(outputs) // Vorwärts
Rev(outputs) // Rückwärts
Toggle(outputs) // Richtungswechsel
OnFwd(outputs) // = On()+Fwd()
OnRev(outputs) // = On()+Rev()
OnFor(outputs, time) // 100time = 1Sekunde
SetOutput(outputs, mode)
// mode aus OUT_OFF, OUT_ON, OUT_FLOAT
SetDirection(outputs, direction)
// direction aus OUT_FWD, OUT_REV, OUT_TOGGLE
SetPower(outputs, power)
// power aus 0 bis 7 setzt die Geschwindigkeit
x=OutputStatus(n)
// gibt den Status zurück
SetGlobalOutput(outputs, mode)
// mode aus OUT_ON, OUT_OFF Schaltet die generelle
// Kontrollmöglichkeit von Befehlen der Ausgänge ein oder aus.
SetGlobalDirection(outputs, direction)
// direction aus OUT_FWD, OUT_REV, OUT_TOGGLE
// Kehrt alle Befehle um oder setzt wieder auf norm oder wechselt
// Wichtiger Befehl für den Gigamesh G60
SetMaxPower(outputs, max_power)
// max_power aus OUT_LOW, OUT_HALF, OUT_FULL
// Setzt die generelle Höchstgeschwindigkeit der Motoren
x=GlobalOutputStatus(n)
// gibt generellen Status zurück
Hierarchie
Neben den Tasks gibt es noch Unterprogramme (sub()) und Inline-Funktionen (void()). Der Vorteil von Inline-Funktionen ist, dass man ihnen Parameter übergeben kann – sowohl über call by value als auch über call by reference. NQC-Programme kennen nur integer-Variablen. Agenten-Listing 2 zeigt eine typische Inline-Funktion: Sie wird mit ihrem Namen aufgerufen (zwei_drei();) und darf mit dem Befehl return; vorzeitig beendet und wieder verlassen werden. Als Alternative bietet NQC Unterprogramme, von denen insgesamt 32 pro Programm definiert werden dürfen. Auch wenn an diese keine Parameter übergeben werden können, haben sie den Vorteil, dass sie nur einmal im Speicher vorhanden sind und von mehreren Aufrufern geteilt werden dürfen. Unterprogramme können keine weiteren Unterprogramme aufrufen.
Es dürfen 32 globale und vier lokale Variablen deklariert werden, weshalb diese so lokal wie möglich deklariert werden sollten. Variablen können mit den gleichen Operatoren verknüpft werden, wie man dies von integer-Variablen aus C-Programmen kennt: +, -, *, /, % (mod), abs(), sign(), ++, --, ~ (bitweise Negation), ! (Negation), >>, <<, ==, !=, & (bitweises und), ^ (bitweises XOR), (bitweises oder), && (AND), (OR), >, <, >= und <=.
Die Anzahl der Tasks ist bei einem Spybotics-Programm auf acht begrenzt. Die Tasks laufen parallel, d. h. im Gegensatz zum Aufruf eines Unterprogramms wartet der Aufrufer nicht bis auf dessen Ende, sondern läuft weiter. Auf diese Weise lassen sich mit NQC echte Multitasking-Programme schreiben. Kasten 3 zeigt die einzelnen Task-Befehle.
Agenten-
: Eine NQC-Inline-Funktion
void zwei_drei(int value_var, int &reference_var)
{
value_var=2; // value_var behält ihren Wert nur bis zum Ende
reference_var=3; // der Wert 3 ist auch nach Aufruf noch vorhanden
}
Kasten 3: Task-Befehle
start taskname; // startet einen Task stop taskname; // stop einen Task StopAllTasks(); // stoppt alle Tasks
Für meinen Auftrag mit dem Spybot ist natürlich besonders interessant, dass er mit Sensoren ausgestattet ist. Mein Agentenprogramm soll je nach Status des Sensors bestimmte Aktionen koordinieren. Da ist zunächst einmal der Drucksensor, der in NQC über SENSOR_1 angesprochen wird. er Drucksensor wird normalerweise so eingestellt, dass er boolsche Werte, also 0 (Zustand "nicht gedrückt" und 1 (Zustand "gedrückt"), zurückgibt. NQC bezeichnet dies als SENSOR_MODE_BOOL. Ein Lichtsensor () SENSOR_2 gibt prozentuale Werte zurück (0 bis 100) und wird in NQC als SENSOR_MODE_PERCENT beschrieben. Außerdem kennt NQC noch SENSOR_MODE_RAW für den Spybot – es handelt sich um die interne Darstellung im Robotor für den Sensor (zurückgegeben wird ein Wert zwischen 0 und 1024). Die Statusabfrage eines Sensors erfolgt über eine Variablenzuweisung, z. B. x=SENSOR_1, aber auch eine Abfrage, wie z. B. if(SENSOR_1==1), gibt Auskunft darüber, ob der Sensor gedrückt ist. Kasten 4 enthält eine Liste aller Sensorbefehle.
Kasten 4: Sensorbefehle
sensor // SENSOR_1 oder SENSOR_2n // 0,1 für SENSOR_1 oder SENSOR_2mode // SENSOR_MODE_BOOL, SENSOR_MODE_PERCENT, SENSOR_MODE_RAW SetSensorMode(sensor,mode) // Setzt den Modus für Sensoren ClearSensor(sensor) // Nur sinnvoll bei Sensoren, die Impulse oder // Umdrehungen zählen und wieder zurückgesetzt werden sollen SensorValue(n) // x=SensorValue(0) entspricht x=SENSOR_1 SensorMode(n) // gibt den Modus zurück SensorValueRaw(n) // gibt den internen Sensorwert zurück



