Um sich im Labyrinth zurechtzufinden, haben wir einen kleinen Automaten gebaut. Der Roboter versucht den Turm zu finden. Ist er erfolgreich, so fährt er darauf zu, bis er ein Hindernis (=Wand) oder die Zielfläche findet. Bei erreichen einer Wand folgt er dieser bis eine Ecke erkannt wird oder eine zufällige Zeit verstrichen ist (deadlock vermeiden). Um die erkannten Ecken fährt er selbständig herum, um einer eventuell vorhandenen Falle zu entgehen. Danach sucht er wieder den Turm:
Diese Prozedur wird bei erreichen der Zielfläche abgebrochen und das Erreichen des Turms signalisiert (durch ein langsames zurück- und wieder vorfahren).
Mit einer genügend langen/tiefen Falle (so daß der Roboter nach dem Timeout noch nicht wieder heraus ist) ist zwar auch diese Strategie auszuhebeln, aber innerhalb des Spielfeldes ( ) müsste es schon speziell dafür aufgebaut werden. Dagegen würde eine längeres Timeouteinstellung helfen, jedoch würde dies wieder zu ungünstigen Ergebnissen bei den 'kleinen' Fallen führen.
z = FINDE_TURM; /* z = GERADEAUS; timertjp = 0u; to = 30000u; */ /*z = WAND_LANG; timertjp = 0u; to = 30000u; */ while(1) { switch(z) { /* Per hin und her drehen den Turm Finden */ case FINDE_TURM : printf("FINDE_TURM\n"); finde_turm(); /* timeout fuers wand- und geradeausfahren finden */ to = 15000u + (((unsigned int)TCNT) % 15000u); /* zaehler zuruecksetzen (wird sonst nur in finde_turm verwendet) */ timertjp = 0u; z = GERADEAUS; DEBSTOP; break; /* Geradeaus (auf den Turm zu, bis zur Zielflaeche oder einer Wand */ case GERADEAUS : printf("GERADEAUS\n"); geradeaus_bis_wand(); if(BODEN<BODEN_THRESHOLD) z = AM_ZIEL; /* zielflaeche */ else if((RIGHT_IR>=MIN_IR) || (LEFT_IR>=MIN_IR)) z = WAND_LANG; /* wand */ else z = FINDE_TURM; /* timeout */ DEBSTOP; break; /* Auf Zielflaeche Gestossen? */ case AM_ZIEL : printf("AM_ZIEL\n"); /* Langsam Rueckwaerts, als Zeichen */ stop(); wait(2000); motorv(LEFT_MOTOR, LOW_BW); motorv(RIGHT_MOTOR, LOW_BW); wait(2000); motorv(LEFT_MOTOR, LOW_FW); motorv(RIGHT_MOTOR, LOW_FW); wait(2000); stop(); DSTART; /* und von Vorne beginnen */ z = FINDE_TURM; break; /* je nachdem, welche wand naeher ist rechts oder links lang */ case WAND_LANG : printf("WAND_LANG\n"); if(LEFT_IR>RIGHT_IR) p = LEFT_WALL; else p = RIGHT_WALL; an_der_wand_lang(p); if(BODEN<BODEN_THRESHOLD) z = AM_ZIEL; /* zielflaeche */ else if(timertjp>=to) z = FINDE_TURM; /* timeout */ else z = KORREKTUR; /* aussenecke oder wandende */ DEBSTOP; break; /* Richtungskorrektur nachdem eine Wand scheinbar zuende ist; */ /* Danach ggf. weiter an der Wand entlang oder Turm finden. */ /* p muss angeben, welch die Verfolgte Wand war */ case KORREKTUR : printf("KORREKTUR\n"); if(p==LEFT_WALL) { motorv(LEFT_MOTOR, 0); motorv(RIGHT_MOTOR, -30); wait(300); motorv(LEFT_MOTOR, 50); motorv(RIGHT_MOTOR, 50); wait(900); motorv(LEFT_MOTOR, 0); motorv(RIGHT_MOTOR, 50); wait(600); } else { /* p==RIGHT_WALL */ motorv(LEFT_MOTOR, -30); motorv(RIGHT_MOTOR, 0); wait(300); motorv(LEFT_MOTOR, 50); motorv(RIGHT_MOTOR, 50); wait(900); motorv(LEFT_MOTOR, 50); motorv(RIGHT_MOTOR, 0); wait(600); } if((RIGHT_IR>=MIN_IR) || (LEFT_IR>=MIN_IR)) z = WAND_LANG; else z = UM_ECKE; /* p = p */ DEBSTOP; break; /* falls es ein echtes wandende war, um die Ecke */ /* herumfahren (Fallen vermeiden) */ case UM_ECKE : printf("UM_ECKE\n"); if(p==LEFT_WALL) { motorv(LEFT_MOTOR, 50); motorv(RIGHT_MOTOR, 50); wait(300); motorv(LEFT_MOTOR, 0); motorv(RIGHT_MOTOR, 50); wait(800); } else { motorv(LEFT_MOTOR, 50); motorv(RIGHT_MOTOR, 50); wait(300); motorv(LEFT_MOTOR, 50); motorv(RIGHT_MOTOR, 0); wait(800); } if((RIGHT_IR>=MIN_IR) || (LEFT_IR>=MIN_IR)) z = WAND_LANG; else z = FINDE_TURM; DEBSTOP; break; } /* switch */ } /* while(1) */ }