dimanche 22 mars 2020

Chapitre 84 : assembleur ARM64 : système multi-agents : application à un banc de poisson


Pour ce chapitre je repars encore du livre de Virginie MATHIVET « l’intelligence Artificielle pour les développeurs en Java ».
L’adaptation en assembleur ARM pose quelques problèmes intéressants puisqu’il faut adapter toute la partie graphique pour la porter sous X11. De plus, il faut aussi réaliser une animation pour déplacer le banc de poisson dans son océan.
Source du programme mAgent3.s 

Les calculs de vitesse suivant les axes X et Y font intervenir des cosinus et sinus et une racine carrée, ce qui nous oblige à trouver et à écrire les algorithmes nécessaires.
En ce qui concerne la partie graphique, je suis reparti du programme écrit au chapitre XX pour l’afficheur des images PNG. Je ne garde que les routines de connexion, de  chargement des couleurs, polices et la création de la fenêtre principale, des contextes graphiques et de la gestion des événements.

Pour le calcul du cosinus et sinus, je trouve l’algorithme CORDIC que j’adapte pour l’assembleur ARM 64 bits. Cela nécessite l’utilisation des instructions de traitement des nombres en virgule flottante et la création dans la .data d’une table de valeurs servant au calcul.
Pour la racine carré, le calcul s’effectue en nombre entier avec un algorithme que j’avais déjà écrit pour le 32 bits.

Ah oui, vous remarquerez que chaque routine comporte le commentaire INFO : avec le nom de la routine. J’ai besoin de cela car j’utilise un plugin de notepad++ qui me permet pour les gros programmes d’avoir une liste des routines dans une fenêtre séparée, ce qui facilite le déplacement d’une routine à l’autre.

Après ces routines de base, nous trouvons les routines d’affichage d’un poisson et d’un obstacle. Comme le poisson se déplace il faut aussi écrire une routine identique pour effacer son ancienne position en le redessinant mais avec la même couleur que le fond bleu, ce qui le fait disparaitre. Son dessin ne consiste qu’en une simple ligne blanche.
Pour les obstacles, le dessin est un cercle mais curieusement X11 ne propose pas de routine de dessin d’un cercle complet mais seulement des arcs. Pour avoir un cercle complet il faut indiquer le même rayon sur l’axe des X et des Y puis indiquer l’angle de départ et celui d’arrivée en degré multiplié par 64.
Dans l’appel à XDrawArc, il est nécessaire de passer 8 paramètres et donc la nome d’appel nous oblige à passer ce 8ième paramètre sur la pile (et toujours alignée sur 16 octets). Et dans ce cas, il ne faut pas oublier de réaligner la pile après l’appel.

Pour les routines de calcul d’évitement des murs, des poissons des obstacles etc. j’adapte celles données dans le livre.  Il faut faire attention aux instructions car les vitesses peuvent être négatives ou positives. En particulier si on utilise l'instruction lsr pour diviser par une puissance de 2 il faut la remplacer par l'instruction asr qui gérera correctement la division pour des valeurs négatives.
L’autre difficulté est de bien gérer l’utilisation des registres en n’oubliant pas de les sauvegarder.
J’ai galéré un moment avec les nombres float car pour vérifier les calculs j’utilisai l’instruction printf du C et celle ci utilise des registres utilisés dans mes routines sans les sauvegarder, ce qui engendrait de nouvelles erreurs.

Enfin l’animation est effectuée dans la routine gestionAttenteEvenements qui utilise l’appel système select pour attendre soit un évènement qui survient sur la connexion X11 soit un top du timer. La valeur d’attente est passée en paramètre sous la forme d’une structure contenant le délai en secondes et macro secondes. Puis nous appelons la fonction de gestion des évènements pour gérer la fermeture de la fenêtre et les clics de la souris pour créer les obstacles à la position du clic.
Il y a là aussi une curiosité : nous récupérons le FD de la connexion mais au lieu de stocker sa valeur dans la zone réservée, il faut mettre à jour le bit correspondant au FD. Par exemple si le FD est égal à 3, il faut mettre le bit en position 4 à 1 (les positions commençant à 0). Et passer la valeur 4 dans le premier paramètre d’appel à Select.

Après les tests et les corrections des erreurs, le programme fonctionne mais les poissons ont un comportement bizarre. Au bout d’un moment, ils se rassemblent presque tout dans le coin inférieur droit puis se déplacent à nouveau dans tout l’aquarium : la réserve de nourriture peut être !!!!. Certains poissons restent aussi collés aux parois pendant un certain temps puis repartent !!!
Je ne suis pas arrivé à trouver une erreur dans la programmation et j’en suis arrivé à penser que le comportement des  agents peut aboutir à des effets non prévus.
Attention : le spectacle du mouvement des poissons est hypnotique !!!

Aucun commentaire:

Enregistrer un commentaire