14 - Exercice : Startup_Manager

Introduction

Pour continuer à faire de l'Ada, mais en rentrant un peu plus dans le vif du sujet, on va s'occuper de la procédure de démarrage du robot. Lorsqu'on démarre le robot, le programme principale se lance automatiquement. Il attend que l'utilisateur suive une procédure bien précise avant de lancer le match, puis coupe tout 90s plus tard. L'objectif de cet exercice est d'écrire un package qui va gérer ça.

Comme entrées, on dispose de 2 boutons : le bouton rouge (power_switch) et le jack de démarrage (startup_switch). La procédure de demarrage consiste à enfoncer le bouton rouge, mettre le jack de démarrage, poser le robot sur la table, quand tout est prêt, on retire le bouton rouge, finalement, au top de l'arbitre, on retire le jack. Il y a donc 3 états importants : "en vrac", au début : on ne sais pas du tout où est le robot (en l'air, dans les mains du porteur, sur la table, ou n'importe où), "prêt à partir", et "en match".

Pour le programmeur qui va écrire une stratégie, il faut que notre package lui permette d'exécuter une fonction de son choix lorsque le robot est "prêt à partir" et une autre pour gérer le match.

L'ads de notre package va donc être le suivant:

package Startup_Manager is
  type Main_Function is access procedure;
  type Init_Function is access procedure;
 
  procedure Start_Match (Init : Init_Function; Main : Main_Function);
end Statup_Manager;

Squelette de base

Pour commencer, on va récupérer le squelette de base du programme : pour cela, entrer la commande suivante dans un terminal (pour des explications sur hg, c'est ici).

hg clone <a>
cd" title="http://bitbucket.org/telrob/startup<br />
cd">http://bitbucket.org/telrob/startup<br />
cd</a> startup
hg update -r 0

Voici la liste des fichiers important :

  • shix-switches.ad{s,b}: Ce fichier est un substitut de celui qu'on trouve dans le code du robot. L'ads est un sous-ensemble du vrai qui contient uniquement la définition de "Startup_Switch" et "Power_Switch" (dans le vrai robot, il y a beaucoup plus de "switches" qui sont tous définis dans le fichier shix-switches)
  • shix-switches-simu.ad{s,b}: Pour respecter ce qui se passe sur le vrai robot, il y a un deuxième fichier pour gérer les switches : shix-switches permet de lire la valeur des switches, valeurs mise à jour par l'appui sur les boutons physique de robot. Pour le test, il est agréable d'avoir un moyen de définir ses valeurs sans devoir avoir le robot sous la main et appuyer sur les boutons. C'est l'objectif de ce package : il permet de simuler l'appuie sur les boutons du robot.
  • startup_manager.ad{s,b}: Le package à completer
  • test_startup.ad{s,b}: un programme de test. Ce programme est une boucle qui lit une commande au clavier. Ces commandes sont au nombre de 2 : "STARTUP" et "POWER". Chaque commande change la valeur du switch correspondant. En parallèle, le programme de test lance un "match", c'est à dire qu'il appelle Start_Match avec une fonction d'initialisation qui affiche "init" en boule, et une fonction de match qui affiche "in match" en boucle.

Première version

Question 1: Ecrire un "protected" pour l'état du robot. L'état du robot est une variable qui va être manipulé par plusieurs threads. Il faut donc la proteger avec un protected. Ce protected contiendra une fonction pour obtenir l'état courante et une procédure pour le définir.

Question 2: Ecrire une tache qui met à jour l'état du robot en fonction des boutons

(ma solution: hg update -r 1)

Question 3:Ajouter une famille d'"entry" à notre protected qui attend d'être dans un état donné.

Ensuite, on peut écrire une 1ère version de Start_Match:

procedure Start_Match (Init : Init_Function; Main : Main_Function) is
begin
  State.Wait_For (Ready_For_Match);
  Init.all;
  State.Wait_For (In_Match);
  Main.all;
end Start_Match;

Deuxième version

Cette 1ère version est pas mal mais si jamais Clement est abscent, on risque de se retrouver avec une personne un peu a la rue devant le robot. Ce qui serait bien, c'est que

  • au bout de 90s, le robot s'arrete tout seul...
  • si on a merdé un truc on puisse recommencer simplement
  • si on a merdé grave, le robot part quand meme quand on tire sur le jack
  • en mode "simulateur", on puise lancer plein de match facilement

Question 4 : Changer la procedure "Start_Match" pour interrompre le travail en cours lors d'un changement d'état et lancer la nouvelle procédure.

Note : On appréciera la puissance du "select ... then abort ... end select" de l'Ada...

(ma solution: hg update -r 3)

Question 5 : Gérer la fin du match au bout de 30s.

Note: On pensera à stopper le timer si on change d'état avant la fin du match.