Crée un robot suiveur de ligne avec les états suivants :
- CALIBRATION : Le robot calibre ses capteurs de ligne
- SEARCHING : Le robot cherche la ligne
- FOLLOWING : Le robot suit la ligne
- LOST : Le robot a perdu la ligne, il la recherche
- FINISHED : Le robot a détecté la fin du parcours
Indices :
- Les capteurs infrarouges sous le châssis renvoient 0 si la ligne noire est détectée, 1 sinon. Tu trouveras l'API exacte en annexe.
- Utilise les capteurs infrarouges du Maqueen (sous le châssis)
- FOLLOWING → LOST si aucun capteur ne voit la ligne
- LOST → FOLLOWING si un capteur retrouve la ligne
- LOST → FINISHED après un timeout (ligne vraiment perdue)
Solution :
#include <stdio.h>
/* Stub for playground simulation */
typedef enum {
STATE_CALIBRATION,
STATE_SEARCHING,
STATE_FOLLOWING,
STATE_LOST,
STATE_FINISHED
} State;
static const char *state_names[] = {
"CALIBRATION", "SEARCHING", "FOLLOWING", "LOST", "FINISHED"
};
/* Simulated sensor values (0 = line detected, 1 = no line) */
static int sensor_left = 0;
static int sensor_right = 0;
static int sim_step = 0;
static int line_detected(void)
{
return (sensor_left == 0) || (sensor_right == 0);
}
static int lost_counter = 0;
static State current_state = STATE_CALIBRATION;
void on_enter(State state)
{
printf("[ENTER] %s\n", state_names[state]);
switch (state) {
case STATE_CALIBRATION:
printf(" Calibration des capteurs...\n");
break;
case STATE_SEARCHING:
printf(" Rotation pour chercher la ligne...\n");
break;
case STATE_FOLLOWING:
printf(" Suivi de ligne actif\n");
break;
case STATE_LOST:
printf(" Ligne perdue ! Recherche...\n");
lost_counter = 0;
break;
case STATE_FINISHED:
printf(" Parcours termine !\n");
break;
}
}
/* Mise à jour de chaque état (retourne le nouvel état) */
State on_update(State state)
{
switch (state) {
case STATE_CALIBRATION:
/* Après calibration, chercher la ligne */
return STATE_SEARCHING;
case STATE_SEARCHING:
if (line_detected()) {
return STATE_FOLLOWING;
}
return STATE_SEARCHING;
case STATE_FOLLOWING:
if (!line_detected()) {
return STATE_LOST;
}
/* Ajuster direction selon capteurs */
if (sensor_left) printf(" -> Tourner gauche\n");
else if (sensor_right) printf(" -> Tourner droite\n");
else printf(" -> Tout droit\n");
return STATE_FOLLOWING;
case STATE_LOST:
lost_counter++;
if (line_detected()) {
return STATE_FOLLOWING;
}
if (lost_counter > 5) {
/* Timeout : ligne vraiment perdue */
return STATE_FINISHED;
}
printf(" Recherche... (%d/5)\n", lost_counter);
return STATE_LOST;
case STATE_FINISHED:
return STATE_FINISHED;
}
return state;
}
/* Changer d'état avec gestion des transitions */
void change_state(State new_state)
{
if (new_state != current_state) {
printf("[EXIT] %s\n", state_names[current_state]);
current_state = new_state;
on_enter(current_state);
}
}
int main(void)
{
on_enter(current_state);
/* Scenario: calibration -> searching -> line found -> following
-> line lost -> 6 steps -> finished */
static const struct { int sl; int sr; } steps[] = {
{1, 1}, /* step 0: no line (searching) */
{0, 0}, /* step 1: line found (following) */
{0, 1}, /* step 2: line, turn left */
{1, 0}, /* step 3: line, turn right */
{1, 1}, /* step 4: line lost (LOST) */
{1, 1}, /* step 5: still lost */
{1, 1}, /* step 6: still lost */
{1, 1}, /* step 7: still lost */
{1, 1}, /* step 8: still lost */
{1, 1}, /* step 9: still lost -> finished */
};
int n = (int)(sizeof(steps) / sizeof(steps[0]));
for (int i = 0; i < n && current_state != STATE_FINISHED; i++) {
sensor_left = steps[i].sl;
sensor_right = steps[i].sr;
sim_step++;
printf("\n[step %d] sensors L=%d R=%d\n", sim_step,
sensor_left, sensor_right);
State next = on_update(current_state);
change_state(next);
}
return 0;
}
Solution copiée dans l'éditeur.