Instructions Difficile
Gestion d'erreurs
Machine à états · Exercice 3
Ajoute la gestion des erreurs à la machine à états du robot :
- Si le LIDAR ne répond pas pendant le scan, passe en ERROR
- Si les moteurs sont bloqués (encodeurs immobiles), passe en ERROR
- En ERROR, affiche un message et clignote la LED rouge
- Le bouton A permet de revenir à IDLE pour réessayer
Indices :
Solution :
#include <stdio.h>
/* États principaux (avec gestion d'erreur) */
enum robot_state { IDLE, EXPLORING, PAUSED, ERROR };
/* Sous-états d'EXPLORING */
enum explore_substate { FORWARD, TURNING, BACKING_UP };
static enum robot_state etat = IDLE;
static enum explore_substate sous_etat = FORWARD;
/* Simule les conditions du robot */
int lidar_ok = 1;
int moteurs_ok = 1;
int bouton_A_sim = 0;
int obstacle_sim = 0;
static void update_exploring(void)
{
/* Vérifie les erreurs matérielles */
if (!lidar_ok) {
printf("[ERROR] LIDAR ne répond pas — passage en ERROR\n");
etat = ERROR;
return;
}
if (!moteurs_ok) {
printf("[ERROR] Moteurs bloqués — passage en ERROR\n");
etat = ERROR;
return;
}
switch (sous_etat) {
case FORWARD:
printf("[EXPLORING/FORWARD] Avance...\n");
if (obstacle_sim) {
printf(" Obstacle détecté !\n");
sous_etat = BACKING_UP;
}
break;
case BACKING_UP:
printf("[EXPLORING/BACKING_UP] Recule...\n");
/* attente 500 ms (simulée) */
sous_etat = TURNING;
break;
case TURNING:
printf("[EXPLORING/TURNING] Tourne...\n");
sous_etat = FORWARD;
break;
}
}
void update(void)
{
switch (etat) {
case IDLE:
printf("[IDLE] En attente. Bouton A pour démarrer.\n");
if (bouton_A_sim) {
etat = EXPLORING;
}
break;
case EXPLORING:
update_exploring();
if (bouton_A_sim && etat == EXPLORING) {
etat = PAUSED;
}
break;
case PAUSED:
printf("[PAUSED] Pause. Bouton A pour reprendre.\n");
if (bouton_A_sim) {
etat = EXPLORING;
}
break;
case ERROR:
printf("[ERROR] LED rouge clignotante. Bouton A pour réessayer.\n");
/* attente 500 ms clignotement (simulée) */
if (bouton_A_sim) {
etat = IDLE;
}
break;
}
}
/* Un événement à injecter dans la machine : un libellé pour
l'affichage, et les entrées passées aux globaux avant update(). */
struct evenement {
const char *label;
int bouton_A;
int lidar_ok_val;
};
int main(void)
{
const struct evenement scenario[] = {
{ "Démarre l'exploration", 1, 1 },
{ "Cycle normal", 0, 1 },
{ "LIDAR tombe en panne", 0, 0 },
{ "Réinitialisation", 1, 0 },
};
const int n = sizeof(scenario) / sizeof(scenario[0]);
printf("=== Simulation machine à états avec gestion d'erreurs ===\n");
for (int i = 0; i < n; i++) {
printf("\n--- Etape %d : %s (bouton_A=%d, lidar_ok=%d) ---\n",
i + 1, scenario[i].label,
scenario[i].bouton_A, scenario[i].lidar_ok_val);
bouton_A_sim = scenario[i].bouton_A;
lidar_ok = scenario[i].lidar_ok_val;
update();
}
printf("\n=== Robot réinitialisé en IDLE. ===\n");
return 0;
} Solution copiée dans l'éditeur.
ÉDITEUR | GCC 14.2 -Wall -Wextra -std=c17
Snippets :
SORTIE
Appuie sur Ctrl+Entrée pour compiler et exécuter.