On va ici utiliser les potentialités offertes par legOS, afin de tenter d'augmenter la
réactivité de notre robot par une gestion plus fine de l'execution des tâches. On va ainsi modifier
notre code, jusqu'alors séquentiel, pour obtenir un certain nombre de threads
s'exécutant en parallèle, et
permettant a priori une plus grande finesse dans l'exécution. Par exemple, une tâche peut en permanence s'occuper
d'affecter aux moteurs les données qu'elle reçoit, même lorsque les autres tâches sont
occupées.
On peut aussi a priori disposer de davantage de temps et de ressources matérielles pour
échantilloner les valeurs
lues sur les capteurs. On peut dédier une täche à la lecture d'un capteur, lui faire fournir en sortie une valeur
résultant d'une moyenne effectuée sur un certain nombre de mesures, ceci afin de gagner en robustesse et afin de
limiter les erreurs de lecture.
Sur le papier, ceci semble bien prometteur.
On a donc obtenu un code decoupé en petites entités dediées a une tâche spécifique, ces threads communiquent entre elles
et échangent des données par le biais de variables globales, dont l'accès sera protegé
par des sémaphores aux moyens des instructions suivantes :
sem_wait(&semspeed); ... /* process speed */ ... sem_post(&semspeed);
Le lancement des différents threads se fait au moyen de la fonction execi dont voici un exemple :
int task_manager() { pid3=execi(&catchBright,0,NULL,1,DEFAULT_STACK_SIZE); pid4=execi(&catchBlanc,0,NULL,1,DEFAULT_STACK_SIZE); pid5=execi(&catchNoir,0,NULL,1,DEFAULT_STACK_SIZE); pid6=execi(&tuning,0,NULL,1,DEFAULT_STACK_SIZE); pid7=execi(&vitesseGrad,0,NULL,1,DEFAULT_STACK_SIZE); return 0; }
Ceci étant, il semblerait que la présence de nombreuses tâches augmente de façon sensible la charge du microprocesseur.
On peut s'en convaincre en jouant une melodie dans les parties critiques du code, son
exécution sera parfois
ralentie dramatiquement et la gestion des temporisations approchera de l'aléatoire... À
moins qu'il ne s'agisse d'un bug encore inexpliqué. (cf task bigBrother() dans les sources en annexe)
Qui plus est, il semblerait que l'utilisation de fonctions
wait_event à outrance
produise une certaine lenteur dans l'exécution du code. En effet, les interruptions
liées à des évènements ne se produisent apparemment que toutes les 20 millisecondes, ce qui est bien
plus important que la fréquence d'échantillonage des capteurs (officiellement annoncée à
1 ms). L'emploi de threads pour la surveillance des capteurs n'est donc pas une bonne
idée, et il faudra plutôt utiliser les threads avec parcimonie, n'en gardant qu'un
nombre limité et en conservant dans ceux-ci une certaine approche
séquentielle à base de if...then...else.