
:MAIN
    SET:walk:0              // Noch nicht loslaufen
    SET:rest:0              // Ausruhen noch nicht nötig
    SET:Wait:0              // Anzahl gleichzeitig laufender Aktionen zurücksetzen
    SET:Clock:0             // Interne Uhr zurücksetzen
    SET:Back_ON:0           // Rückensensor nicht berührt (210/220)
    SET:Tail_U_ON:0         // Schwänzchen nicht nach oben bewegt (31x)
    CALL:STARTUP_STAND      // Aufstehen (siehe unten)
    SET:actions:1           // Es wird mindestens eine Aktion laufen

:SEARCH_BALL
    SET:Eye_L2:0            // Linkes  grünes Auge aus (RCodePlus 210)
    SET:Eye_R2:0            // Rechtes grünes Auge aus (RCodePlus 210)
    SET:pan:Head_Pan        // Waagerechten Kopfwinkel ermitteln
    RND:Context:1:2         // Links oder rechts nach Zufall
    CSET:pan:>:+15:1        // Zeigt Kopf mehr als 15 Grad nach links?  Dann doch links
    CSET:pan:<:-15:2        // Zeigt Kopf mehr als 15 Grad nach rechts? Dann doch rechts
    SET:leftright:Context   // Richtung setzen (nach links oder rechts)

:SEARCH_BALL_HEAD
    SWITCH:leftright                            // Richtung prüfen
    CASE:1:PLAY:ACTION:MOVE.HEAD.SLOW:+60:0     // Nach links?  Dann Kopf nach links  bewegen
    CASE:2:PLAY:ACTION:MOVE.HEAD.SLOW:-60:0     // Nach rechts? Dann Kopf nach rechts bewegen

    // Aibo bewegt seinen Kopf in die entsprechende Richtung.
    // Das Programm läuft währenddessen weiter!

    // Solange Aibo seinen Kopf bewegt ist die Variable "Wait" um 1 erhöht.

:SEARCH_BALL_LOOP
    CALL:ATTENTION                              // Sinnesorgane prüfen
    IF:rest:<>:0:SHUTDOWN                       // Schwach? Dann schlafen gehen
    IF:Pink_Ball:<>:0:SEARCH_BALL_TRACK         // Ball in Sichtweite? Dann dem Ball nachsehen
    IF:Wait:>=:actions:SEARCH_BALL_LOOP         // Falls sich der Kopf noch bewegt 
                                                // oder eine andere Aktion läuft, 
                                                // die Prüfungen wiederholen

    // Aibo bewegt seinen Kopf jetzt nicht mehr.

    SWITCH:leftright                            // Letzte Richtung prüfen
    CASE:1:SET:leftright:2                      // Links?  Dann jetzt rechts
    CASE:2:SET:leftright:1                      // Rechts? Dann jetzt links
    GO:SEARCH_BALL_HEAD                         // Kopf in die neue Richtung drehen


:SEARCH_BALL_TRACK
    PLAY:ACTION:MOVE.HEAD.NORMAL:Head_Pan:Head_Tilt  // Kopf anhalten
    WAIT:MOTION_HEAD                            // Warten bis der Kopf angehalten ist
    GO:TRACK_BALL                               // Dem Ball nachsehen

////////////////////////////////////////////////////////

:TRACK_BALL
    PLAY:ACTION:TRACK_HEAD:PINK_BALL            // Dem rosaroten Ball nachsehen

    // Aibo sieht seinem rosaroten Ball nach.
    // Das Programm läuft währenddessen weiter!

    // Solange Aibo seinem Ball nachsieht ist die Variable "Wait" um 1 erhöht.
    // Falls Aibo seinen Ball aus dem Auge verliert, hört er von alleine auf, seinem Ball nachzusehen.

    SET:Eye_L2:1                                // Linkes  grünes Auge ein (RCodePlus 210)
    SET:Eye_R2:1                                // Rechtes grünes Auge ein (RCodePlus 210)

:TRACK_BALL_LOOP
    CALL:ATTENTION                              // Sinnesorgane prüfen
    CALL:TRACK_BALL_HANDLER                     // Weitere Prüfungen (siehe unten)
    IF:rest:<>:0:SHUTDOWN                       // Schwach? Dann schlafen gehen
    IF:Wait:>=:actions:TRACK_BALL_LOOP          // Falls Aibo noch dem Ball nachsieht 
                                                // oder eine andere Aktion läuft, 
                                                // Prüfungen wiederholen

    // Aibo sieht seinem Ball jetzt nicht mehr nach.

    GO:SEARCH_BALL                              // Wieder den Ball suchen

////////////////////////////////////////////////////////

:TRACK_BALL_HANDLER
    SET:pan:Head_Pan                            // Waagerechten Kopfwinkel ermitteln
    IF:pan:>:+30:TURN_LEFT_TRACK                // Kopf mehr als 30 Grad nach links?  Dann nach links drehen
    IF:pan:<:-30:TURN_RIGHT_TRACK               // Kopf mehr als 30 Grad nach rechts? Dann nach rechts drehen
    IF:walk:<>:0:THEN                           // Falls laufen erlaubt:
        IF:Distance:>:200:WALK_FORWARD_TRACK    // Abstand mehr als 200? Dann vorwärts laufen
        IF:Pink_Ball:<>:0:TRACK_BALL_FOUND      // Falls Ball in Sichtweite? Dann Ziel erreicht!
    ENDIF
    RETURN

////////////////////////////////////////////////////////

:TRACK_BALL_FOUND                               // Ziel erreicht:
    SET:walk:0                                  // Loslaufen nicht mehr erlaubt
    RETURN

////////////////////////////////////////////////////////

:TURN_LEFT_TRACK
    ADD:actions:1                               // Eine Aktion mehr ist am Laufen
    PLAY:ACTION:TURN:pan                        // Nach links drehen (um den Winkel "pan")

    // Aibo dreht sich.
    // Das Programm läuft währenddessen weiter!
    // Solange Aibo sich dreht ist die Variable "Wait" um 1 erhöht.

:TURN_LEFT_TRACK_LOOP
    CALL:ATTENTION                              // Sinnesorgane prüfen
    IF:stop:<>:0:TURN_STOP                      // Bewegung stoppen?
    IF:Wait:<:actions:TURN_STOP                 // Zu wenige Aktionen am Laufen?
    IF:Pink_Ball:==:0:TURN_STOP                 // Ball nicht in Sichtweite?
    IF:Head_Pan:<=:0:TURN_STOP                  // Zeigt Kopf nach rechts?
    GO:TURN_LEFT_TRACK_LOOP                     // Erneut prüfen

////////////////////////////////////////////////////////

:TURN_RIGHT_TRACK
    ADD:actions:1                               // Eine Aktion mehr ist am Laufen
    PLAY:ACTION:TURN:pan                        // Nach rechts drehen (um den Winkel "pan")

    // Aibo dreht sich.
    // Das Programm läuft währenddessen weiter!
    // Solange Aibo sich dreht ist die Variable "Wait" um 1 erhöht.

:TURN_RIGHT_TRACK_LOOP
    CALL:ATTENTION                              // Sinnesorgane prüfen
    IF:stop:<>:0:TURN_STOP                      // Bewegung stoppen?
    IF:Wait:<:actions:TURN_STOP                 // Zu wenige Aktionen am Laufen?
    IF:Pink_Ball:==:0:TURN_STOP                 // Ball nicht in Sichtweite?
    IF:Head_Pan:>=:0:TURN_STOP                  // Zeigt Kopf nach links?
    GO:TURN_RIGHT_TRACK_LOOP                    // Erneut prüfen

////////////////////////////////////////////////////////

:TURN_STOP
    SUB:actions:1                               // Eine Aktion weniger ist am Laufen
    PLAY:ACTION:TURN:0                          // Drehen stoppen
    WAIT:MOTION_LEG                             // Warten bis Drehen gestoppt
                                                // Aibo dreht sich jetzt nicht mehr.
    RETURN

////////////////////////////////////////////////////////

:WALK_FORWARD_TRACK
    ADD:actions:1                               // Eine Aktion mehr ist am Laufen
    RND:Context:1:2                             // Spurt oder normal laufen zur Auswahl
    CSET:Distance:<:300:2                       // Abstand kleiner als 300? Dann normal laufen
    CSET:Distance:>:900:2                       // Abstand größer  als 900? Dann normal laufen
    CASE:1:PLAY:ACTION:WALK.STYLE3:pan:300      // 300 mm Spurt (im Winkel "pan") (RCodePlus 210/220/31x)
    CASE:ELSE:PLAY:ACTION:WALK:pan:300          // 300 mm normal laufen (im Winkel "pan")

    // Aibo läuft.
    // Das Programm läuft währenddessen weiter!
    // Solange Aibo läuft ist die Variable "Wait" um 1 erhöht.

:WALK_FORWARD_TRACK_LOOP
    CALL:ATTENTION                              // Sinnesorgane prüfen
    IF:stop:<>:0:WALK_STOP                      // Bewegung stoppen?
    IF:Wait:<:actions:WALK_STOP                 // Zu wenige Aktionen am Laufen?
    IF:Pink_Ball:==:0:WALK_STOP                 // Ball nicht in Sichtweite?
    IF:Distance:<:200:WALK_STOP                 // Abstand kleiner als 200?
    IF:Head_Pan:>:+45:WALK_STOP                 // Zeigt Kopf mehr als 45 Grad nach links?
    IF:Head_Pan:<:-45:WALK_STOP                 // Zeigt Kopf mehr als 45 Grad nach rechts?
//  IF:Head_Tilt:>:+10:WALK_STOP                // Zeigt Kopf mehr als 10 Grad nach oben?
    IF:Head_Tilt:<:-65:WALK_STOP                // Zeigt Kopf mehr als 65 Grad nach unten?
    GO:WALK_FORWARD_TRACK_LOOP                  // Erneut prüfen

////////////////////////////////////////////////////////

:WALK_STOP
    SUB:actions:1                               // Eine Aktion weniger ist am Laufen
    PLAY:ACTION:WALK:0:0                        // Laufen stoppen
    WAIT:MOTION_LEG                             // Warten bis Laufen gestoppt
                                                // Aibo läuft jetzt nicht mehr.
    RETURN

////////////////////////////////////////////////////////

:ATTENTION
    SET:stop:0                                  // Bewegungen sollen nicht gestoppt werden
    CALL:SENSOR                                 // Sensoren prüfen
    CALL:REST_CHECK                             // Akku und Temperaturen prüfen
    RETURN

////////////////////////////////////////////////////////

:SENSOR
    IF:Back_ON:<>:0:SENSOR_Back_ON              // Rückensensor berührt? (210/220)
    IF:Tail_U_ON:<>:0:SENSOR_Tail_U_ON          // Schwänzchen nach oben bewegt? (31x)
    RETURN

:SENSOR_Back_ON
    SET:Back_ON:0                               // Rückensensor zurücksetzen (210/220)
    GO:SENSOR_WALK                              // Loslaufen erlauben

:SENSOR_Tail_U_ON
    SET:Tail_U_ON:0                             // Schwänzchen nach oben zurücksetzen (31x)
    GO:SENSOR_WALK                              // Loslaufen erlauben

:SENSOR_WALK
    SET:walk:1                                  // Loslaufen erlauben
    RETURN

////////////////////////////////////////////////////////

:REST_CHECK
    IF:Batt_Rest:<:25:REST_CHECK_STOP           // Akku weniger als 25%
    IF:Batt_Temp:>:45:REST_CHECK_STOP           // Akkutemperatur über 45°C
    IF:Body_Temp:>:45:REST_CHECK_STOP           // Körpertemperatur über 45°C
    RETURN

:REST_CHECK_STOP
    SET:stop:1                                  // Bewegungen sollen gestoppt werden
    SET:rest:1                                  // Ausruhen erforderlich
    RETURN

////////////////////////////////////////////////////////

:WAIT_ACTIONS
:WAIT_ACTIONS_LOOP
    CALL:ATTENTION                              // Sinnesorgane prüfen
    IF:Wait:>:0:WAIT_ACTIONS_LOOP               // Solange mindestens 1 Aktion läuft
    RETURN

////////////////////////////////////////////////////////

:STARTUP_STAND
    IF:Status:==:0:THEN                         // Falls nicht umgefallen:
        PLAY:ACTION:LIE                         // Hinlegen
        CALL:WAIT_ACTIONS                       // Warten bis Hinlegen beendet
    ENDIF
                                                // Immer:
    PLAY:ACTION:STAND                           // Aufstehen
    CALL:WAIT_ACTIONS                           // Warten bis Aufstehen beendet
    RETURN

////////////////////////////////////////////////////////

:SHUTDOWN
    RND:pan:-25:25                              // Zufallswinkel zwischen 25 Grad rechts und links
    PLAY:ACTION:LIE                             // Hinlegen
    CALL:WAIT_ACTIONS                           // Warten bis Hinlegen beendet
    PLAY:ACTION:MOVE.HEAD.NORMAL:pan:-90        // Kopf auf Zufallswinkel rechts/links (siehe oben) 
                                                // und 90 Grad nach unten bewegen
    CALL:WAIT_ACTIONS                           // Warten bis Kopf bewegt
    HALT                                        // Einschlafen

////////////////////////////////////////////////////////
//  Copyright © Jürgen Reule 2008  MADE IN GERMANY


