# Very High Speed Integrated Circuit Hardware Description Language/Commande de robot mobile et périphériques associés

Nous allons nous intéresser dans ce chapitre à la commande de robots différentiels mobiles par une carte FPGA. L’idée est naturellement d’utiliser un processeur pour les calculs mais aussi de développer des périphériques associés. La platine robotique utilisée est celle de Digilent car elle est adaptée pour une commande en 3,3 V.

## Introduction

La robotique mobile qui nous intéresse dans ce chapitre, est constitué par des petits robots propulsés en général à l'aide de deux roues. Ce type de robot est appelé "robot mobile différentiel", mais par souci de simplification, nous omettrons souvent le terme "différentiel". Voici quelques exemples de robots mobiles différentiels sur l'image ci-dessous.
Vous voyez sur cette image des robots mobiles plus ou moins sophistiqués qui sont en général commandés par un micro-contrôleur. Dans ce chapitre nous allons nous intéresser essentiellement à remplacer le micro-contrôleur de commande par un FPGA. Ce n’est pas le prix qui nous attire dans cette voie (les FPGA restent des circuits chers par rapport aux micro-contrôleurs). Ce qui nous intéresse est l'étude de périphériques conçus maison pour propulser un robot et l'aider à se repérer dans l'espace.
Le robot Asuro, à gauche dans la photo ci-dessus, a été étudié en détail dans le chapitre d'un autre livre : AVR et robotique : ASURO. La compréhension de l'odométrie du présent chapitre nécessitera la lecture de la section Étude de la cinématique d'un robot différentiel de cet autre projet.
Remplacer un micro-contrôleur par un FPGA ne pose en général que quelques problèmes sur les voltages. La famille Arduino par exemple gère des tensions de 5 V à part le "DUE". Par contre les FPGAs sont depuis longtemps déjà en 3,3 V. Pour éviter tout problème à ce niveau, nous avons choisi un Robot de chez Digilent car cette entreprise réalise à la fois des cartes FPGA et des cartes micro-contrôleur. On aura une compatibilité électrique entre les deux. Présentons maintenant cette base robotique.

## Présentation de la platine Digilent

La platine de robotique mobile de Digilent nous semple être un très bon point de départ pour un robot évolutif. Il est assez facile d'ajouter des modules extérieurs (et en particulier les fixer). La carte de commande originale utilise un PIC32 (CEREBOT MX4ck) mais nous avons retiré cette carte pour la remplacer par une carte FPGA. La Basys2 plus petite en taille que cette carte se fixe parfaitement sur le robot mais la Nexys3 peut certainement faire aussi l'affaire.
Nous avons à disposition Line-Following Motor Robot Kit mais il nous semble que MRK-BASIC moins chère peut suffire si vous n'avez pas l'intention de suivre des lignes.
Cette platine contient une partie mécanique évolutive, deux commandes de puissance pour deux moteurs à courant continu, et un éventuel détecteur infra-rouge capable de gérer 4 photo-transistors.
La carte de commande est architecturée autour d'un micro-contrôleur PIC32. Elle ne sera pas détaillée ici puisqu'elle sera remplacée de toute façon par une carte FPGA.
Depuis quelques années Digilent développe des modules d'interface aux capteurs appelés PMOD. L'intérêt de ceux-ci est qu’ils s'interfacent facilement aux cartes à micro-contrôleurs comme aux cartes FPGA. Ils sont décrits brièvement dans le chapitre Utiliser un processeur externe de manière pratique.

### La gestion de la détection infra-rouge

Il s'agit d'un module pouvant gérer 4 photo-transistors infrarouge avec le standard pmod de Digilent : module pmodLS1. L'intérêt de ces modules, comme déjà évoqué, est qu’ils se connectent sur les cartes micro-contrôleurs comme sur les cartes FPGA modernes (Basys2, Nexys2, Nexys3,... et bien d'autres encore). Ce module demande à être calibré à l'aide d'un réglage de potentiomètre.
Pour calibrer, nous vous conseillons d’utiliser un scotch noir sur un fond blanc (en bois) et de mettre le robot dans différentes positions par rapport au scotch. Des leds présentes sur le module doivent s'allumer et s'éteindre suivant la position.
Ces modules sont présentés plus loin.
Nous allons poursuivre par la présentation de la commande de puissance des deux moteurs.

### Les modules de commande de moteur : PmodHB5

Les moteurs à commander sont à courant continu (MT-MOTOR). Le module Pmod qui se charge de la commande en puissance s’appelle PmodHB5.
La description des PmodHB5 est disponible sur le site de Digilent et pour ceux qui sont allergiques à l'anglais, une description sommaire est disponible chez Lextronic.
Les moteurs ont deux codeurs incrémentaux à disposition. Le lien déjà présenté, (mais rappelé ici : MT-MOTOR), montre sur la photo à droite des codeurs incrémentaux. Nous allons les présenter brièvement maintenant.

### Les codeurs incrémentaux

La théorie de ces codeurs est représentée ci-contre. On vous représente deux signaux appelés phases qui sont déphasés. Ce qui caractérise ces signaux est que le déphasage dépend du sens de rotation. La figure représente ces deux signaux pour un sens de rotation dans le sens des aiguilles d'une montre. A est alors en retard de 90°.
Dans le cas d'une rotation dans l'autre sens, A sera en avance de 90° sur B. Ces informations conduisent à une description de suite d'états pour les deux sens de rotation.
Les deux diagramme d'états correspondant sont
Suite d'états pour rotation dans le sens des aiguilles d'une montre :
| Phase | A | B |
| 1 | 0 | 0 |
| 2 | 0 | 1 |
| 3 | 1 | 1 |
| 4 | 1 | 0 |
Suite d'états pour rotation dans le sens contraire des aiguilles d'une montre :
| Phase | A | B |
| 1 | 1 | 0 |
| 2 | 1 | 1 |
| 3 | 0 | 1 |
| 4 | 0 | 0 |
L'exploitation de ces codeurs en tant que périphérique fera appel à ces données et sera présentée plus loin dans ce chapitre.

### Interfacer le robot à la carte FPGA

Remplacer la platine de commande originale par un FPGA ne pose absolument aucun problème particulier. Pour éviter une trop longue description verbale, nous vous demandons de vous reporter aux quelques images du robot du chapitre.

## Commander les moteurs du robot avec notre FPGA

Nous allons utiliser un processeur pour prendre les décisions qui s'imposent en fonction des données des capteurs. Le processeur enfoui dans notre FPGA sera l'ATMega16 déjà décrit dans ce livre.
Vous pouvez remarquer sur la photo ci-dessus, que l’on à remplacé le support fixe par une bille permettant un roulement plus facile. Une roue castor libre pourrait tout aussi bien faire l'affaire.

### Les modules de commande de moteur : pmodHB5

Nous avons décidé d’utiliser le module HB5RefComp fourni par Digilent dont voici l'entité en VHDL :
Ce module s'occupe de générer "bitEnOut" et "bitDirout" nécessaires à la commande de l'électronique de puissance à partir d'une horloge (à 25 MHz pour nous) d'un bit de direction "bitDirIn" et d'un rapport cyclique "vecDfIn" sur 8 bits.
L'horloge de la Basys2 est à 50 MHz mais nous la divisons par deux pour notre processeur, c’est pour cela que l’on évoque 25 MHz dans le texte ci-dessus.

### Le module HB5RefComp

Comme nous avons changé quelques options par rapport au fichier original téléchargé, nous donnons sa version intégrale maintenant.
Comme nous avons deux moteurs à commander, il nous faudra utiliser ce module en double. Nous avons décidé d’utiliser PORTB pour le rapport cyclique du moteur gauche et PORTC pour celui du moteur droit. Les deux bits de direction seront ramenés sur DDRB :
* moteur droit est relié au bit b0 de DDRB
* moteur gauche est relié au bit b1 de DDRB
Avant de présenter le code source de io.vhd, nous présentons comme d'habitude le problème sous forme de schéma :

### Interface des pmodHB5 avec l'ATMega16

Voici le fichier "io.vhd" modifié pour prendre en compte deux moteurs. Bien sûr les sorties LeftEnOut, LeftDirOut, RightEnOut, RightDirOut sont à prolonger jusqu'à la sortie du processeur et donc à gérer correctement dans l'ucf. Voici les parties du fichier ucf concernées :
où l’on voit que le moteur droit est relié au connecteur JC tandis que le moteur gauche est relié au connecteur JD.
Et voici donc le fichier io.vhd comme promis :

### Programmation des pmodHB5 avec l'ATMega16

Voici un exemple de programme qui utilise cette interface.
Que fait ce programme ?
Arrivé à ce point, il serait probablement très utile de réaliser des sous-programmes permettant d'aller en ligne droite pendant un certain temps et de tourner de 90° ou mieux encore de tourner d'un angle fourni en paramètre. Pour le moment nous laissons le soin de réaliser ce travail au lecteur. Mais d'autres sous-programmes (intéressants ?) sont présentés un peu plus loin...
Vous allez vite remarquer à l'aide de vos essais que les deux moteurs ne sont pas symétriques. C'est normal quand en y pense : pour une marche avant l'un doit aller en avant mais l'autre en arrière.
Maintenant que nous sommes capables de faire bouger notre robot, le problème de savoir où l’on est à tout moment se pose sérieusement.

## Se repérer dans l'espace

Dans cette section, nous allons examiner comment se repérer dans l'espace à l'aide de compteurs (un par roues, donc deux compteurs). Ces compteurs devront mémoriser la distance de déplacement effectuée par chacune des roues. Mais expliquons d’abord comment ceci va être réalisé en pratique.
La commande des moteurs par les modules PModHB5 nous a pris seulement deux fils plus l'alimentation comme on peut facilement le voir dans le schéma qui explicite l'interface de cette commande. Pourtant une autre information est disponible, comme déjà évoqué. Il s'agit de codeurs incrémentaux à effet Hall. Nous désirons les mettre en œuvre dans cette section.
Nous allons d’abord tenter de répondre à la question de la difficulté du problème.

### Pourquoi le problème est difficile

Avant de se poser des questions il faut essayer de bien comprendre ce que veut dire connaître exactement l'état du robot. Celui-ci est donné par trois paramètres même si l’on est en deux dimensions : $(x,y,\theta )$. x et y sont naturellement le repérage de la position sur les deux axes x et y et $\theta$ est l'orientation du robot par rapport à l'axe des x. Regardez la figure ci-contre pour vous convaincre de la pertinence de ces trois données.
Imaginons que vous ayez fait déplacer votre robot pendant un temps T quelconque. Vous relevez les compteurs de chacune des roues et convertissez en centimètres parcourus et trouvez deux nombres A et B. Est-il possible d’en déduire la nouvelle position (et orientation) sachant que l’on connaît exactement la position de départ ? Autre manière de poser le problème : je connais parfaitement $(x_{d},y_{d},\theta _{d})$ ainsi que la distance parcourue par chacune des roues est-il possible d’en déduire $(x_{f},y_{f},\theta _{f})$ ? Malheureusement la réponse à cette question est partiellement négative ! Il n'est possible que d’avoir $\theta _{f}$ mais pas le reste.
Tout cela est résumé simplement par la figure ci-contre. Dans cette figure, les deux longueurs (en pointillés) rouges sont identiques (et égales à A) et les deux longueurs (en pointillés) bleues sont elles aussi identiques (et égales à B) et pourtant on obtient deux points d'arrivées différents. Seule l'orientation finale est identique. Cela montre qu'aucune formule ne permet le calcul de xf à partir de xd, A et B.
Doit-on abandonner l’idée de trouver le point final à partir du point de départ ? Non, heureusement. En fait le problème présenté devient possible si les deux distances parcourues A et B deviennent différentielles (c'est-à-dire toutes petites). C'est quand même une mauvaise nouvelle malgré tout. Cela veut dire qu’il nous faut mémoriser les distances parcourues par chacune des roues à des instants précis et assez fréquemment pour se rapprocher de l’idée mathématique de différentielle. Nous essaierons dans un premier temps dix mesures par seconde. Nous utiliserons des compteurs sur 8 bits en complément à deux... et dix fois par seconde nous mémoriserons donc les valeurs des deux compteurs (droit et gauche) dans une mémoire.
Le problème de la gestion de la mémoire sera examiné plus loin. Pour ce qui est de la taille, une mémoire de 2 ko permet de mémoriser 1024 valeurs de 16 bits correspondant aux deux compteurs (roue droite et roue gauche). 1024 valeurs correspondent à 100 s (car 10 enregistrements par seconde) soit une minute et demi. Pas grandiose ! mais suffisant pour examiner quelques problèmes intéressants avec des étudiants.
Une autre solution qui sera examinée dans un futur projet (voir en fin de chapitre) sera de calculer au fur et à mesure les valeurs de x et y.
Pour l'instant nous allons présenter le module fourni par Digilent qui est destiné à mesurer la vitesse angulaire d'une roue.

### Présentation du module de mesure de vitesse de Digilent

Mesurer la vitesse à l'aide des modules PModHB5 est une opération qui est proposée par Digilent à l'aide d'un module VHDL appelé "HallTradSpeedDecoder" dont voici l'entité :
On voit apparaître une horloge "ck" qui est supposée être à 100 MHz (puisque ce module est destiné à la Nexys3), deux entrées "pinSA" et "pinSB" supposées être en provenance du codeur incrémental et une vitesse de sortie sur 12 bits. La vitesse est directement exprimée en tours par minute et codée en BCD.
Le travail de repérage développé dans cette section nécessite de prendre comme hypothèse que les roues ne glissent pas sur le sol. Dans le cas contraire, il faut développer une autre technique. Ces techniques sont par exemple :
* une roue passive (non motrice) qui roule et ne glisse pas couplée à un codeur incrémental. Ici il en faudrait deux pour avoir une information de direction.
* utilisation d'un accéléromètre.
Nous allons essayer de modifier ce module pour tenter de réaliser un périphérique capable de mémoriser les positions.

#### Bien comprendre la base de temps

Dans le module original apparaît une base de temps. Nous allons la changer.
La base de temps est (100 000 000 x 60) /(12 x 19) = 26315789. Cette valeur est entièrement liée au fait que l’on a 12 fronts sur les deux entrées pour un tour de l'axe moteur associé à un facteur de réduction de 19. Ainsi, si l’on compte pendant ce temps on aura directement la vitesse en tour par minute.
On veut une mise à jour d'une dizaine de fois par seconde.

#### Supprimer la gestion BCD

La gestion du BCD était utile dans le module original dans la mesure où la vitesse devait être affichée sur des afficheurs sept segments. En ce qui nous concerne l'information sera donnée au processeur qui pourra faire toutes les conversions imaginables par programme.
Cette suppression de la gestion du BCD est simple à réaliser : il suffit de repérer les commentaires d'incrémentation et de décrémentations et de les réaliser en binaire. C'est beaucoup plus simple et l’on peut espérer n'avoir qu'un octet pour mémoriser ce nombre (au lieu de trois).

#### Utiliser le timer de l'AVR embarqué comme base de temps

La base de temps du module original est réalisée par :
Nous allons supprimer ce timer pour le remplacer par celui de l'AVR décrit dans un chapitre précédent. L'intérêt est que celui de l'AVR est capable de déclencher une interruption. Ainsi à chaque interruption les deux compteurs du côté droit et du côté gauche seront sauvés en mémoire par l'AVR.
Le pseudo-timer de l'AVR ne présente pas de préscalaire. Il est sur 20 bits et déborde avec une fréquence de 95 Hz sur la Nexys3 qui sera d'environ 43 Hz sur la Basys2. Il faut donc la diviser par 4 pour avoir environ 10 mises à jour par seconde. Cela revient tout simplement à ajouter deux bits au timer.

### Décodeur incrémental simple

Nous avons fini par abandonner l’utilisation du code de Digilent pour utiliser une variation beaucoup plus simple. Il s'agit d'un code proposé par Ken Chapman (le concepteur du picoBlaze) pour décoder un bouton incrémental. Voici donc ce code modifié pour nos besoins :
Ce code fonctionne correctement à priori même sans gestion des rebonds. C'est une particularité des signaux incrémentaux de ne pas nécessiter toujours d'une gestion d'anti-rebonds. Cela reste vrai pour un affichage (qui est une fonction lente) mais si l’on échantillonne le compteur pendant des rebonds, il y aura une erreur qui finira par s'accumuler. Tout ceci nécessite donc une vérification minutieuse.

#### Interfacer ce module à l'ATMega16

Comme d'habitude nous présentons l'interface avec l'ATMega16 sous forme de schéma :
Cette figure présente une version provisoire de l'interface. Nous avons connecté l'entrée "reset" de notre module à l'entrée "I_CLR" du module io.vhd (même si ce n’est pas visible sur le dessin) et ceci ne peut rester comme cela. La raison ? Rappelons qu’il nous faut :
* mémoriser les valeurs de la sortie "position" dans une mémoire au fur et à mesure que le temps s'écoule. Cela signifie en particulier qu'une fois la valeur lue, il faut remettre à 0 le compteur position par programme. Ceci est impossible si l'AVR n'a pas accès au "reset".
* mémoriser peut-être les valeurs dans un grand compteur (au moins 16 bits) ce qui éviterait de perdre des données lors des lectures intermédiaires. En effet un reset en même temps qu'une incrémentation ou décrémentation fera perdre une donnée
Tout ceci est susceptible d'encore évoluer... mais sera certainement stable lorsque nous présenterons le cahier des charges du projet 2014

#### Réaliser un programme pour les tests

Pour tester ce module sur une seule roue, nous avons réalisé le programme suivant :
La compréhension de ce code nécessite de lire la section sur la manette Nunchuk un peu plus loin.
L'idée de ce code est d’utiliser la manette Nunchuk pour déplacer le robot et sans arrêt lire la valeur d'un compteur de position sur 8 bits et de l'afficher directement sur des leds.

### Réaliser un programme de traitement de données pour trouver la trajectoire

Nous allons essayer de retrouver la trajectoire de notre robot mobile à partir des données fournies par l'AVR. L’idée générale est que l'AVR mémorise les valeurs de ses compteurs régulièrement et qu'une fois terminé ces valeur sont transmise à un PC en vue d'un calcul. Le calcul se faisant sur un PC on peut utiliser les librairies standard du C, en particulier les cosinus et sinus.

## Autre moyen de se repérer : le module infrarouge PmodLS1

Le module infrarouge permet de se repérer mais pas en absolu. Il permet en effet de suivre une ligne, par exemple mais cela nécessite naturellement que cette ligne soit dessinée. Une autre possibilité est de réaliser un quadrillage et espérer repérer les lignes horizontales et verticales quand on les franchit. Mais réaliser un programme qui réalise cela doit être assez complexe : Nous n'avons jamais rencontré d'exemple sur Internet !
Avant de se lancer dans une programmation compliquée, revenons sur terre pour examiner le PmodLS1. Ce module est branché directement sur le connecteur JA de la Basys2. Mais il demande à être calibré à l'aide d'un réglage de potentiomètre. Le réglage peut se faire facilement à l'aide d'un programme tout simple :
si l’on a pris soin de sortir le PORTD sur les LEDs (ceci se fait dans l'ucf) et de mettre les entrées du connecteur JA sur PINB. Voici l'extrait de l'ucf correspondant :
Si vous prenez une surface blanche sur laquelle vous avez collé du scotch noir vous devez voir les différentes leds s'allumer et s'éteindre en fonction de leur positions par rapport à la ligne noir.
Pour information nous avons eu l’idée de remplacer le module pmodLS1 par un Arduino micro en 3,3 V pour utiliser ses convertisseurs analogiques numériques et ainsi pouvoir régler les seuils (blanc/noir) de manière indépendante. Mais les étudiants chargés de ce projet en 2014/2015 n'ont pas abouti. Il a été présenté dans ce livre comme un projet autour d'un MSP430 mais nous avons changé au dernier moment de processeur pour des questions de réalisation de circuit imprimé. Mais sans carte digne de remplacer les pmodLS1, nous abandonnons l'infra-rouge pour le moment.
Le gros problème du module PModLS1 est qu'il n'y qu'un potentiomètre pour régler le seuil de chacun des capteurs infrarouges. Un collègue s'est lancé dans une réalisation avec un potentiomètre par capteur. Espérons qu'elle aboutira bientôt.
Cet abandon nous a amené à étudier un autre domaine que nous allons présenter maintenant.

## Contrôle du robot par une manette Nunchuk

Nous avons déjà utilisé la manette Nunchuk pour contrôler un jeu vidéo dans un autre chapitre. Nous avons donc décidé d’utiliser le travail déjà fait pour notre robot.
Visualisez Using an Arduino and Wii Nunchuck to Control a Robot (Youtube). Vous y verrez un exemple de ce que l’on cherche à faire mais avec un autre robot.

### Interfacer la manette Nunchuk

Pour ceux qui ont lu ce livre en entier cette section paraîtra comme du déjà vue. C'est normal on reprend ici le travail fait dans ce domaine pour le pacman.
Un module capable de gérer TOUTES les données de la Nunchuk est disponible dans un autre chapitre. C'est lui que vous allez utiliser et interfacer dans "io2.vhd". Vous utiliserez deux registres réservés à l’i2c dans l'ATMega16 :
* TWDR en adresse 0x23 pour les données
* TWCR en adresse 0x56 pour les commandes et états commande TWEN est en bit b2 (écriture) et l'état TWINT = data présent en bit b7 (lecture)
Voici un condensé sous forme de schéma de ce qu’il y a à faire :
Même si cette figure ne représente pas tous les registres et PORTs que nous utilisons dans le projet pacman complet elle nous montre l'essentiel. L'ensemble du travail consiste donc à câbler et ajouter des lignes dans les deux "case" des deux process de lecture et d'écriture. Ce qui est peut être un peu délicat à comprendre est la réalisation du signal "s_readFIFO" tout en haut de la figure. Ce signal est là pour vider le FIFO au fur et à mesure de ses lectures par le processeur. Il sera relié à l'entrée readFIFO du module NunchukTop.
Nous avons utilisé les registres TWXX pour interfacer notre module gérant la liaison i2c avec la manette. Ces registres sont destinés dans l'ATMega original à effectivement gérer l'i2c. La gestion reste cependant complètement différente ici. Pour construire un module aussi générique que l'ATMega du commerce il y aurait beaucoup de changements à réaliser qui ne sont pas prévus pour le moment.

### Réaliser un programme pour utiliser la manette Nunchuk

Nous allons vous donner deux sous-programmes pour vous aider à démarrer votre projet.

#### Lecture du FIFO et demande de données

Le sous-programme présenté ci-dessous est appelé avec un nom très long qui, nous l'espérons, sera assez évocateur. Il fait deux choses :
* lecture du FIFO qui a été rempli par la manette
* départ d'une nouvelle demande d'information à la Nunchuk
Il devra être inséré dans un boucle (éventuellement infinie) pas trop rapide pour que la fois suiivante le FIFO soit correctement rempli.
Voici le code source correspondant :

#### Attente d'un départ

Il est naturellement possible de bloquer le robot en attendant un événement sur la Nunchuk.
Voici comment on peut bloquer tout en attendant un appui sur le bouton Z :
On rappelle pour comprendre le code, que les deux boutons sont peésents dans le 6° octet retourné par la Nunchuk (donc la case 5 de notre tableau) que les deux boutons sont les deux poids faibles et qu’ils sont à 1 lorsqu’ils ne sont pas appuyés.

#### Programme Joystick

Calibrage Joystick analogique :
* gauche à fond : 0x20
* droite à fond : 0xE1
* repos 7F
* avant à fond : 0xE0
* arrière à fond : 0x25
* repos 0x80

## Mise en pratique du repérage dans l'espace avec des codeurs de roues

Nous avons présenté de manière théorique le repérage dans l'espace à l'aide de codeurs de roues. Nous allons tenter maintenant de mettre cela en pratique avec notre robot.

### Calcul des coordonnées x et y du robot

L'objectif est de coupler le module de repérage de position au coprocesseur CORDIC. L'intérêt de ce projet est d’éviter la mémorisation continue des compteurs de roue en calculant au fur et à mesure l'état $\left(x(t_{i}),y(t_{i}),\theta (t_{i})\right)$. La formule de calcul faisant intervenir un cosinus et un sinus, nous allons coupler les compteurs avec le coprocesseur CORDIC du précédent chapitre.

#### Ajouter un décodeur incrémental

Nous allons vous donner une version corrigée du projet de l'année passée. Cette version possède un seul décodeur incrémental pour la roue gauche. On vous demande à partir de ce code :
* de gérer le reset de manière automatique lors de la lecture de la position
* d'ajouter un décodeur incrémental pour l'autre roue en le gérant de la même manière. Par exemple la position peut être reliée à PINC (adresse 0x33)
* ajouter la gestion des afficheurs sept segments (les 4) pour faciliter les tests.
Un programme d'affichage automatique des valeurs de position gauche et droite sera alors, par exemple :
Les sous-programmes manquants ont déjà été publiés dans cette page.
L'idée de ce programme est d'ajouter au fur et à mesure les valeurs des positions droites et gauches de les mettre dans une seule et même variable ("toPrint") qui sera affichée par l'interruption sur les 4 afficheurs 7 segments de la carte Basys 2.
Vous allez vite remarquer à l'aide de vos essais que les deux moteurs ne sont pas symétriques comme nous l'avons déjà évoqué. Pour une marche avant l'un doit aller en avant mais l'autre en arrière et vous allez facilement le constater sur vos afficheurs 7 segments. Il suffit de remplacer une addition par une soustraction pour gérer ce problème !

#### Adapter CORDIC à notre problème

Nous allons nous poser la question de savoir comment adapter l'algorithme CORDIC à ce problème. En fait une question nous taraude depuis quelques temps. Nous la posons et tenterons de la résoudre plus tard (Lecteurs revenez de temps en temps voir où l’on en est ?).
Le radian comme le degré ne sont pas des bonnes unités d'angle pour nous. Elles nécessitent, en effet, toutes les deux des calculs arithmétiques compliqués (divisions). Notre unité sera plutôt un nombre de ticks sur une roue (pour parcourir une distance). Par exemple tourner de 90° nécessitera d'exécuter un certain nombre de ticks et c’est ce nombre qui doit devenir notre unité d'angle. Pas besoin de le diviser par l'entre-axe des roues (avantage sur le radian). La question est donc : Comment adapter la partie correspondante au calcul d'angle dans CORDIC à cette nouvelle unité ? et sa question corollaire Quelles sont les valeurs pré-calculées que l’on devra mettre en mémoire ? Si nous répondons correctement à ces deux questions, chacun d'entre-vous pourra l'adapter à son propre robot.
Prenons des exemples concrets
* pour le robot ASURO décrit dans un autre projet la rotation sur place de 90° se fait avec 27 ticks. Cette valeur nécessite 5 bits seulement, on est très loin des 16 bits du format Q3.13 ! Comment se traduira l'équation de récurrence sur les angles dans ce contexte ?
* pour le robot Digilent de ce chapitre, ce nombre de ticks est évalué à 114 (si rapport de réduction 1:19 [soit 1,5 tour x 19 x 4]). Un essai direct a donné entre 69 et 74, et on sera encore loin des 16 bits puisque 7 bits suffisent. Ici encore comment cela interviendra-t-il sur l'équation de récurrence des angles ?
Nous avons eu l'intuition par une nuit d'insomnie, qu’il fallait certainement reporter les 7 bits dans la partie haute (disons b13-b7) du format Q3.13 et compléter par des zéros sur les poids faibles (b6-b0). Tout cela en complément à deux. Si l’on s'arrête aux 6 bits initiaux on n'aura jamais assez d'itérations pour le calcul. Ceci ne reste qu'une intuition pour le moment et demande à être expérimenté.