Trois robots de grande taille à construire et à programmer : Troisième robot "Spider" (Deuxième partie)

Nous terminons cette fois la description du troisième et dernier de nos robots : Spider, l’araignée à 6 pattes ! Dans cette dernière partie, nous analyserons ensemble tous les secrets des logiciels lui permettant de se déplacer et de reconnaître les obstacles.


Dans cette dernière partie nous étudierons ensemble les programmes logiciels gouvernant les périphériques et les dispositifs montés sur Spider et permettant au robot de se déplacer, de reconnaître la présence d’éventuels obstacles et de réagir correctement aux événements extérieurs.
Nous analyserons deux exemples de “listings”, toujours écrits en Basic : tous deux permettent à Spider de se déplacer dans son environnement, mais le premier utilise des “antennes” (ou “moustaches”, les insectes ayant plutôt des antennes, non ?) reliées à des micro-interrupteurs pour détecter les obstacles, alors que le second a recours aux détecteurs à infrarouges (lire la chronique Robotique dans les articles du blog) pour identifier d’éventuels empêchements à la progression du robot. Comme pour les articles consacrés aux logiciels des deux autres robots, pour Spider aussi le but du présent article est moins de vous montrer tout ce que notre robot est capable de faire que d’expliquer simplement quels sont les concepts de base qui sous-tendent sa programmation : ainsi, vous pourrez, quand vous le souhaiterez, réaliser la programmation de vos propres applications ou développer de nouvelles fonctionnalités, même si vous vous êtes contentés, dans un premier temps, de nos exemples.
Rappelons à ce propos que la carte-mère située sur le robot est munie de deux connecteurs d’extension (le premier, SV1, constitué de vingt broches, amène à l’extérieur les dix-neuf ports d’I/O plus la masse, le second, JP11, JP14, JP15, constitué de huit broches, met à disposition trois masses, trois niveaux +5 V et deux niveaux de tension provenant directement des batteries d’alimentation), de façon à pouvoir superposer une platine supplémentaire sur laquelle ajouter d’autres composants ou circuits (par exemple, des détecteurs, des mini-caméras vidéo ou des afficheurs LCD, etc.).
Avant d’entrer dans le vif des logiciels, revoyons rapidement quelques caractéristiques matérielles de Spider : toute la mécanique et l’électronique sont gérées par la carte-mère où trône le microcontrôleur PIC16F876 fonctionnant à la fréquence d’horloge de 20 MHz.
Le PIC dispose de trois ports d’I/O A, B et C, pour un total de vingt-deux broches.
Certaines de ces dernières sont utilisées chez Spider pour commander les dispositifs externes : par exemple, à la broche 1 du port A est relié le “speaker” (buzzer), aux broches 2, 1 et 0 du port B sont reliés les servomoteurs, respectivement de droite, de gauche et central, aux broches 4 et 5 du port A sont reliées les antennes, respectivement de gauche et de droite, etc. Pour une liste complète et détaillée, voyez les figures 1 et 2.
Nous pouvons maintenant analyser la génération du mouvement de Spider.
Il est obtenu au moyen de trois servomoteurs : le premier commande la marche en avant ou en arrière des pattes antérieures et postérieures droites, le deuxième gère la marche en avant ou en arrière des pattes antérieures et postérieures gauches, enfin la troisième commande l’abaissement ou le soulèvement d’une des deux pattes centrales tour à tour. Pour ces dernières, notez que les deux pattes centrales bougent en opposition mutuelle ou, si vous préférez, de façon différentielle : elles sont reliées par deux axes de renvoi de telle façon que, lorsqu’une patte se soulève (par exemple la gauche), l’autre s’abaisse (celle de droite) et vice versa. La marche en avant est donc obtenue ainsi :
- la patte centrale gauche s’abaisse, de telle façon que les deux autres pattes gauches se soulèvent,
- les pattes avant et arrière gauches avancent, tandis que les pattes avant et arrière droites reculent,
- la patte centrale droite s’abaisse, de telle façon que les deux autres pattes droites se soulèvent,
- les pattes avant et arrière droites avancent, tandis que les pattes avant et arrière gauches reculent.

En exécutant cycliquement ces quatre opérations, on obtient le mouvement en avant désiré. Si l’on veut en revanche faire reculer Spider, les opérations sont substantiellement les mêmes : une fois soulevées ou abaissées les pattes centrales, il faut alors bouger inversement, par rapport au cas précédent, les pattes avant et arrière. Pour faire varier la direction de son mouvement, Spider est en outre capable d’exécuter des rotations autour de son axe vertical : par exemple, pour tourner à gauche il est nécessaire de faire les pas suivants :
- abaisser la patte centrale gauche, de façon à soulever les deux autres pattes gauches,
- reculer les pattes avant et arrière droites ou gauches,
- abaisser la patte centrale droite, de façon à soulever les deux autres pattes droites,
- avancer les pattes avant et arrière droites ou gauches.
Si, en revanche, on veut que Spider tourne à droite, les premier et troisième points restent les mêmes, mais il faut inverser l’ordre d’exécution des deuxième et quatrième points.
Pour Spider aussi, les servomoteurs utilisés sont des Futuba S3003. Ils sont commandés par des trains d’impulsions dont la durée détermine le positionnement de l’axe. Rappelons que pour une durée de 1,5 ms l’axe se met en position centrale, pour 1,2 ou 1,8 ms il se met complètement dans une direction ou dans la direction opposée.
Comme pour les logiciels des deux autres robots, dans les programmes que nous allons analyser ici, la production des impulsions se fait par l’instruction PulseOut Pin,Period produisant sur la broche spéciale Pin une impulsion de durée égale à 2.10_6.Period. On l’a dit en introduction, le second logiciel utilise les émetteurs et le récepteur à infrarouges pour détecter la présence des obstacles. Rappelons brièvement leur logique de fonctionnement :
- on habilite l’émission sur le seul Emetteur à infrarouges IR1 (Emetteur droit), - si un obstacle est présent, il réfléchit la lumière émise vers le récepteur à infrarouges qui en identifie donc la présence,
- on habilite l’émission sur le seul Emetteur à infrarouges IR2 (Emetteur gauche),
- dans ce cas aussi, si un obstacle est présent, il réfléchit la lumière émise vers le récepteur à infrarouges qui en identifie donc la présence.

En exécutant les contrôles logiciels voulus de l’état du récepteur à infrarouges, il est donc possible de vérifier la présence des obstacles à droite, à gauche ou des deux côtés (dans ce dernier cas l’obstacle est frontal).

Figure 1 : Connexion des dispositifs externes.
Table de vérité.

Pin            Port           Etat logique       Signification
IR_1 Port C.1 1 Aucun obstacle détecté
IR_1 Port C.1 0 Obstacle détecté
IFR_1 Port C.5 1 Active trx IR de dx
IFR_1 Port C.5 0 Désactive trx IR de dx
IFR_2 Port C.2 1 Active trx IR de sx
IFR_2 Port C.2 0 Désactive trx IR de sx
Speaker Port A.1 0 Aucun son émis
Speaker Port A.1 1 Emission d’un son
Servo1 Port B.2 - Servomoteur Droit
Servo2 Port B.1 - Servomoteur Gauche
Servo3 Port B.0 - Servomoteur Centre
Antenne_1 Port A.4 0 Obstacle détecté à sx
Antenne_1 Port A.4 1 Aucun obstacle à sx
Antenne_2 Port A.5 0 Obstacle détecté à dx
Antenne_2 Port A.5 1 Aucun obstacle à dx
LED_1 Port C.3 0 LED Gauche éteinte
LED_1 Port C.3 1 LED Gauche allumée
LED_2 Port C.4 0 LED Droite éteinte
LED_2 Port C.4 1 LED Droite allumée

Variable                  Valeur                   Opération exécutée
Servo1 600 Jambes Droites en arrière
Servo1 750 Jambes Droites centrées
Servo1 900 Jambes Droites en avant
Servo2 600 Jambes Gauches en avant
Servo2 750 Jambes Gauches centrées
Servo2 900 Jambes Gauches en arrière
Servo3 600 Lève Jambe centrale de sx
Servo3 750 Jambes centrales égales
Servo3 900 Lève Jambe centrale de dx


Figure 2 : Connecteurs d’extension.

Pour vous permettre d’étendre les fonctionnalités du robot, la carte-mère qui le constitue est munie de deux connecteurs d’extension (SV1 e JP13, JP14, JP15), dans les schémas publiés ici on en montre des détails.

Figure 3 : Emetteurs et récepteur à infrarouges.

La figure montre la logique de fonctionnement du détecteur à infrarouges.
Les deux émetteurs à infrarouges (droit et gauche) envoient alternativement le signal lumineux : si un obstacle est présent, le cône de lumière est réfléchi et donc détecté par le récepteur placé en position centrale.
En allant lire le récepteur, on peut donc savoir si des obstacles ont été détectés et s’ils sont sur le côté droit ou sur le côté gauche ou en face du robot.

Premier logiciel : mouvement avec contrôle des obstacles au moyen des antennes
C’est celui de la figure 4. On l’a dit, ce programme permet à Spider de se déplacer et d’identifier les obstacles éventuels grâce à ses antennes (reliées à des micro-interrupteurs). Le cycle principal gère la marche en avant du robot et teste la présence d’un empêchement éventuel à cette progression : si un obstacle est détecté du côté droit, le robot recule de trois pas, tourne de 90° environ vers la gauche puis continue sa marche. Si à l’inverse l’obstacle est du côté gauche, Spider recule encore de trois pas, mais tourne vers la droite. Enfin, si l’obstacle est détecté par les deux antennes, après avoir reculé de trois pas, il tourne de 180° de façon à inverser la direction de sa marche.
Analysons maintenant le “listing” : le programme débute par la déclaration de certains paramètres de caractère général, du sens des ports (“input” ou “output”), des liaisons entre broches des ports et dispositifs externes et de certaines variables et constantes de commodité utilisées au sein du logiciel.
Ensuite commence l’exécution proprement dite : tout d’abord les trois servomoteurs sont réglés en position centrale, le positionnement est réalisé par la subroutine Mise à zéro utilisant les paramètres relatifs aux servomoteurs mémorisés dans les trois variables Pos_Servo1, Pos_Servo2 et Pos_Servo3.
On entre ensuite dans le cycle principal du programme : le premier mouvement du pas en avant est exécuté, on teste la présence des obstacles en appelant la subroutine Antennes, le pas en avant est complété, on teste à nouveau la présence des obstacles et enfin on revient au début du cycle principal, lequel se déroule indéfiniment.
La gestion du mouvement est exécutée par la subroutine Marche laquelle se contente de positionner les trois servomoteurs dans les positions qui lui sont indiquées par les trois variables Pos_Servo1, Pos_Servo2 et Pos_Servo3. A noter qu’à l’intérieur de cette subroutine la première opération consiste à positionner les pattes centrales, c’est seulement ensuite que les pattes avant et arrière bougent.
Si, au contraire, les trois servomoteurs étaient positionnés en même temps, on aurait un mouvement incorrect du robot.
Voyons à présent la subroutine Antennes : on le voit, à l’intérieur de celle-ci sont testés les états assumés par les deux micro-interrupteurs reliés aux deux antennes (rappelons que la condition Antenne=0 indique que le micro-interrupteur correspondant est fermé et que donc un obstacle est présent) et éventuellement les subroutines notées Gauche, Droite et Inverse sont appelées.
Dans le cas où c’est la première qui est appelée, cela implique la présence d’un obstacle à gauche : il faut alors reculer de quelques pas (trois dans notre exemple) et tourner à droite. Le premier point est exécuté en appelant la subroutine En arrière. La rotation est en revanche obtenue à l’intérieur d’un cycle “for” dans lequel sont paramétrées les positions des trois servomoteurs selon la logique expliquée en introduction de cet article.
La subroutine Droite travaille en symétrique de la Gauche vue ci-dessus : après avoir reculé de trois pas (géré encore par la subroutine En arrière) on exécute une rotation vers la gauche, rotation exécutée à l’intérieur d’un cycle “for” travaillant de façon absolument identique à la précédente.
Quant à la subroutine Inverse, elle gère la possibilité où seraient détectés des obstacles situés en même temps à droite et à gauche : là, après avoir reculé de trois pas (appel de En arrière), on tourne de 180°. La subroutine travaille comme la procédure Droite, dans ce cas cependant le cycle “for” est exécuté un nombre supérieur de fois, de façon à exécuter une rotation plus ample.
Avant de conclure l’analyse, notons deux choses. La première touche, à l’intérieur du “listing”, à la présence de deux variables, LED_1 et LED_2, utilisées pour allumer ou éteindre deux LED, montées respectivement sur les côtés gauche et droit, utilisées comme “yeux” du robot. La seconde concerne la subroutine Son et ses appels positionnés dans le “listing”.
Cette procédure, déjà amplement analysée à propos des logiciels pour CarBot et Filippo, fait émettre un signal sonore au “speaker” (buzzer) installé sur la carte-mère. L’émission du son est gérée par l’instruction Sound Speaker, [Note,Durée], produisant sur la broche indiquée Speaker une onde caractérisée par les niveaux de tension TTL. Le paramètre Note indique la fréquence du ton acoustique produit, Durée combien de temps cette émission doit se poursuivre (le paramètre Durée peut prendre des valeurs comprises entre 0 et 255, le temps de production est environ égal à Durée.12 millisecondes). Bien qu’à l’intérieur des “listings” cela ne soit pas nécessaire, nous vous précisons qu’il est possible de produire plusieurs notes en utilisant une seule instruction : par exemple, l’instruction Sound Speaker [Note1, Durée1, Note2, Durée2, …, NoteN, DuréeN] produit N signaux sonores de fréquence et durée spécifiées. Grâce à une seule instruction, il est donc possible de produire des signaux sonores multitons.
La subroutine Son se termine par l’instruction Low Speaker qui ne fait que mettre au niveau logique bas la broche du port spécifiée par le “speaker”.

Figure 4 : Listing “Mouvement avec contrôle des antennes”.
‘************************************************************************************
‘* Nom : Spider_Antennes *
‘* Notes : Mouvement avec contrôle des antennes *
‘************************************************************************************

‘-----[ Définitions ]----------------------------------------------------------------
DEFINE LOADER_USED 1 ‘Utilisé pour boot-loader
DEFINE OSC 20 ‘Paramètre Clock à 20 MHz
ADCON1 = 000111 ‘Port A = Numérique

‘-----[ Vers Port ]------------------------------------------------------------------
TRISA = 110000 ‘Paramètre pin Port A in Input et/ou Output
TRISB = 000000 ‘Paramètre pin Port B in Input et/ou Output
TRISC = 100100 ‘Paramètre pin Port C in Input et/ou Output

‘-----[ Définitions I/O ]------------------------------------------------------------
Servo1 VAR PORTB.2 ‘Port Servo 1 (Droite)
Servo2 VAR PORTB.1 ‘Port Servo 2 (Gauche)
Servo3 VAR PORTB.0 ‘Port Servo 3 (Centre)

Antenne_1 VAR PORTA.4 ‘Port Antenne 1 (Gauche)
Antenne_2 VAR PORTA.5 ‘Port Antenne 2 (Droite)

Speaker VAR PORTA.1 ‘Port Speaker

Led_1 VAR PORTC.3 ‘Port LED 1 (Gauche)
Led_2 VAR PORTC.4 ‘Port LED 2 (Droite)

‘-----[ Définitions Variables ]------------------------------------------------------
Pos_Servo1 VAR WORD ‘position servo1 Droite
Pos_Servo2 VAR WORD ‘position servo2 Gauche
Pos_Servo3 VAR WORD ‘position servo3 Centre

mcount VAR BYTE ‘loop pour subrout. marche
ncount VAR BYTE ‘loop pour les autres
Note VAR BYTE ‘note pour sound

‘-----[ Définitions Constantes ]-----------------------------------------------------
pos_max_3 CON 900 ‘Position Maximale Centre
pos_mid_3 CON 750 ‘Position Centrale Centre
pos_min_3 CON 600 ‘Position Minimale Centre
pos_max_1 CON 900 ‘Position Maximale Droite
pos_mid_1 CON 750 ‘Position Centrale Droite
pos_min_1 CON 600 ‘Position Minimale Droite
pos_max_2 CON 900 ‘Position Maximale Gauche
pos_mid_2 CON 750 ‘Position Centrale Gauche
pos_min_2 CON 600 ‘Position Minimale Gauche

Retard CON 20 ‘Pause pour Pulsout en μs
Pas CON 5 ‘Pas pour cycle Remise à zéro
Pas_1 CON 7 ‘Pas pour cycle Marche
Durée CON 50 ‘Durée note pour Sound

‘-----[ Initialisation ]-------------------------------------------------------------
PORTA =0
PORTB =0
PORTC =0

‘-----[ Début programme ]------------------------------------------------------------
ncount = 0
mcount = 0
Note = 0

GoSub Yeux ‘clignotement yeux

Note = 50
GoSub Son ‘Emets son
Pos_Servo1 = pos_mid_1 ‘position initiale...
Pos_Servo2 = pos_mid_2 ‘...des trois servomoteurs...
Pos_Servo3 = pos_mid_3 ‘...au centre
GoSub Remise à zéro

Début :
Pos_Servo1 = pos_min_1 ‘en arrière pattes Droites
Pos_Servo2 = pos_min_2 ‘en avant pattes Gauches
Pos_Servo3 = pos_max_3 ‘en bas centrale Gauches
GoSub Marche ‘-mouvement en avant

GoSub Antennes ‘test contact sur antennes

Pos_Servo1 = pos_max_1 ‘en avant pattes Droites
Pos_Servo2 = pos_max_2 ‘en arrière pattes Gauches
Pos_Servo3 = pos_min_3 ‘en bas centrale Droite
GoSub Marche ‘mouvement en avant

GoSub Antennes ‘test contact sur antennes

GoTo Début ‘répète cycle

‘-----[ Subroutine ]-----------------------------------------------------------------
Marche :

‘Positionne les pattes centrales
For mcount=1 to 100 step Pas_1
PulsOut Servo3,Pos_Servo3
Pause Retard
Next

‘Bouge les pattes Droites et Gauches
For mcount=1 to 100 step Pas_1
PulsOut Servo1,Pos_Servo1 ‘Droite
PulsOut Servo2,Pos_Servo2 ‘Gauche
PulsOut Servo3,Pos_Servo3 ‘Centre
Pause Retard
Next

Return

Antennes :
‘Teste présence d’obstacles sur antennes
IF Antenne_1 = 0 Then Gauche ‘contact sur antenne 1
IF Antenne_2 = 0 Then Droite ‘contact sur antenne 2
IF Antenne_1 AND Antenne_2 = 0 Then Inverse ‘contact sur les deux antennes
Return

Yeux :
LED_1 = 0 ‘Eteins les yeux
LED_2 = 0

For ncount=1 to 5 ‘5 Eclairs des yeux
Toggle LED_1
Toggle LED_2
Pause 100
Next
Return

Son :
Sound Speaker, [Note, Durée] ‘Emets son
Low Speaker ‘Eteins speaker
Return

Mise à zéro :
‘Positionne les trois servomoteurs en position centrale
For ncount = 1 to 100 step Pas
PulsOut Servo1,Pos_Servo1
PulsOut Servo2,Pos_Servo2
PulsOut Servo3,Pos_Servo3
Pause Retard
Next
Return

Gauche :
‘Il faut revenir en arrière de trois pas et tourner à droite...
‘...pour éviter l’obstacle détecté par antenne_1

Note = 10 ‘Emets son
GoSub Son

Led_1 = 0 ‘Eteins LED de Gauche
GoSub Arrière ‘Reviens en arrière de trois pas

For ncount=1 to 5 ‘Tourne à droite
Pos_Servo1 = pos_max_1 ‘av. pattes dx
Pos_Servo2 = pos_min_2 ‘av. pattes sx
Pos_Servo3 = pos_max_3 ‘en bas cent. sx
GoSub Marche

Pos_Servo1 = pos_min_1 ‘arr. pattes dx
Pos_Servo2 = pos_max_2 ‘arr. pattes sx
Pos_Servo3 = pos_min_3 ‘en bas cent. dx
GoSub Marche
Next

Led_1 = 1 ‘Rallume LED Gauche
Return

Droite :
‘Il faut revenir en arrière de trois pas et tourner à Gauche...
‘...pr éviter l’obstacle rencontré par antenne_2

Note = 100 ‘Emets son
GoSub Son

LED_2 = 0 ‘Eteins LED Droite
GoSub Arrière ‘Reviens en arrière de trois pas
For ncount=1 to 5 ‘Tourne à Gauche
Pos_Servo1 = pos_min_1 ‘arr. pattes dx
Pos_Servo2 = pos_max_2 ‘arr. pattes sx
Pos_Servo3 = pos_max_3 ‘en bas cent. sx
GoSub Marche

Pos_Servo1 = pos_max_1 ‘av. pattes dx
Pos_Servo2 = pos_min_2 ‘av. pattes sx
Pos_Servo3 = pos_min_3 ‘en bas cent. dx
GoSub Marche

Next

LED_2 = 1 ‘Rallume LED Droite
Return

Inverse :
‘Il faut revenir en arrière de trois pas et tourner de 180°...
‘...pour éviter l’obstacle rencontré par les deux antennes

Nota = 50 ‘Emets son
GoSub Son

Led_1 = 0 ‘Eteins les deux LED
Led_2 = 0
GoSub Arrière ‘Reviens en arrière de trois pas

For ncount=1 to 7 ‘Tourne à Gauche de180°
Pos_Servo1 = pos_min_1 ‘arr. pattes dx
Pos_Servo2 = pos_max_2 ‘arr. pattes sx
Pos_Servo3 = pos_max_3 ‘en bas cent. sx
GoSub Marche
Pos_Servo1 = pos_max_1 ‘av. pattes dx
Pos_Servo2 = pos_min_2 ‘av. pattes sx
Pos_Servo3 = pos_min_3 ‘en bas cent. dx
GoSub Marche

Next

Led_1 = 1 ‘Rallume les deux LED
Led_2 = 1
Return

Arrière :
For ncount=1 to 4 ‘Reviens en arrière de trois pas
Pos_Servo1 = pos_max_1 ‘av. pattes dx
Pos_Servo2 = pos_max_2 ‘arr. pattes sx
Pos_Servo3 = pos_max_3 ‘en bas cent. sx
GoSub Marche
Pos_Servo1 = pos_min_1 ‘arr. pattes dx
Pos_Servo2 = pos_min_2 ‘av. pattes sx
Pos_Servo3 = pos_min_3 ‘en bas cent. dx
GoSub Marche

Next
Return

End

Figure 5 : Le “bootloader”.
Pour faire fonctionner toute la série de nos robots, il est nécessaire d’écrire un programme qui fasse faire au robot ce que nous voulons, dans la limite des ressources disponibles. Ce programme peut être écrit en n’importe quel langage, du Basic au C en passant par l’Assembleur, etc. Il doit être ensuite compilé de manière à obtenir le fichier .HEX adapté à la mémorisation par le microcontrôleur. Nous expliquons ici comment ce fichier peut être chargé dans le microcontrôleur.
Normalement, cette opération s’effectue en utilisant un programmateur matériel adapté dans lequel le microcontrôleur est physiquement inséré. Toutefois, pour rendre plus facile cette opération, notre carte-mère prévoit un système de programmation “in-circuit” permettant de ne pas déposer le microcontrôleur de sa platine. En fait, la programmation se fait directement à partir du PC par l’intermédiaire du port sériel connecté à la prise DB9 de la carte-mère du robot.
Pour ce faire, il est nécessaire d’utiliser un système spécial de programmation appelé “bootloader”.
Ce système prévoit l’utilisation d’un logiciel spécifique (PICdownloader.exe) permettant de charger dans le microcontrôleur les programmes que nous avons développés (au format .HEX) par l’intermédiaire du port sériel. Cela est possible uniquement si on a préalablement chargé dans le microcontrôleur un bref programme de support (bootldr20Mhz-19200bps.hex) logé dans les premières cellules de mémoire : ce logiciel, bien sûr, doit être chargé avec un programmateur normal. Cependant, le microcontrôleur contenant déjà ce mini programme (“firmware”) est disponible.
Voyons donc comment utiliser le “bootloader” : avant tout, il est nécessaire de charger le programme PICdownloader.exe sur le site de la revue, ensuite ce programme doit être installé sur votre PC. Alors, par l’intermédiaire d’un compilateur adéquat, vous devez produire un fichier au format .HEX de votre programme et, grâce au PICdownloader, le charger dans l’EEPROM du PIC présent sur la carte-mère.
Pour de plus amples informations sur les opérations à exécuter, nous vous renvoyons aux précédents articles sur les robots, rubrique “ Comment charger les programmes” : vous y trouverez des détails sur les étapes nécessaires à l’installation du programme sur PC et le chargement des fichiers .HEX à l’intérieur du microcontrôleur.

Figure 6 : Utilisation pratique.
On l’a vu dans l’article, les trois servomoteurs sont commandés par le paramètre “Period” de la fonction “PulsOut”. Nous avons déjà expliqué que pour des valeurs de “Period” de 900 ou 600 l’axe se place complètement dans un sens ou complètement dans l’autre, alors que pour une “Period” de 750, l’axe se place au centre. Ces valeurs ont été calculées théoriquement en partant de la formule T = 2.10-6.Period : si l’on remplace T par les durées désirées, on obtient les valeurs correspondantes de “Period”. En réalité, dans l’utilisation pratique, les tolérances interviennent. Par exemple, au cours de nos tests, il nous est arrivé que pour une “Period” de 750 les trois servomoteurs ne fussent pas en position centrale, mais celui des pattes de gauche était décalé d’un angle minimum. Nous avons donc dû centrer les deux servomoteurs (au moyen du “listing” de la figure 7), en trouvant que le moteur des pattes de droite était centré pour une “Period” de 750 et celui des pattes de gauche de 749. On le voit, ces variations sont minimes, elles relèvent des tolérances habituelles en électronique et, dans ce cas, elles ont pu être résolues par un procédé logiciel.

Figure 7 : Listing “Centrage des servomoteurs”.
‘************************************************************************************
‘* Nom : Centre Servomoteurs *
‘* Proces.: PIC16F876 *
‘* Notes : Permet de centrer les trois servomoteurs *
‘************************************************************************************
‘------[ Définitions ]---------------------------------------------------------------
DEFINE LOADER_USED 1 ‘Utilisé pour boot-loader
DEFINE OSC 20 ‘Paramètre Clock à 20MHz
ADCON1 = 000111 ‘Port A = Numérique
‘------[ Vers Port ]-----------------------------------------------------------------
TRISB = 000000
‘-----[ Définitions I/O ]------------------------------------------------------------
Servo1 VAR PORTB.2 ‘Port Servo 1
Servo2 VAR PORTB.1 ‘Port Servo 2
Servo2 VAR PORTB.0 ‘Port Servo 3

‘------[ Initialisation ]------------------------------------------------------------
PORTB = 0

‘------[ Début programme ]-----------------------------------------------------------
Début :
PulsOut Servo1, 750 ‘Centre le Servo 1 avec 1500 μs
PulsOut Servo2, 749 ‘Centre le Servo 2 avec 1498 μs
PulsOut Servo3, 750 ‘Centre le Servo 2 avec 1500 μs
Pause 20 ‘Attends 20 ms
GoTo Début
End

Second logiciel : mouvement avec contrôle des obstacles par infrarouges
C’est celui de la figure 8. Ce programme permet aussi à Spider de se déplacer à l’intérieur d’un espace, d’avancer, de reculer ou de tourner.
La différence avec le logiciel précédent est qu’ici la détection des obstacles se fait par les deux émetteurs et le récepteur à infrarouges (comme pour Filippo, voir l'article : "Deuxième robot "Filippo" (Première partie)").
Analysons donc pas à pas (c’est bien le cas de le dire !) le “listing” : comme d’habitude le programme débute par la déclaration de certains paramètres de caractère général, du sens des ports (“input” ou “output”), des liaisons entre broches des ports et dispositifs externes (servomoteurs, “speaker”, émetteurs et récepteurs à infrarouges, etc.). Ensuite sont définies et initialisées certaines variables et constantes utilisées dans le programme.
On entre alors dans le cycle principal : tous les servomoteurs se centrent (subroutine Mise à zéro), puis les tests du récepteur à infrarouges ont lieu.
Le fonctionnement est le même que pour le logiciel de Filippo : on active l’émetteur de gauche et on mémorise au sein de la variable Gau_IR_det l’état du récepteur à infrarouges. L’émetteur droit s’active ensuite et on mémorise dans Drt_IR_det l’état du récepteur (rappelons que la présence des obstacles d’un seul côté est indiquée avec Gau_IR_det ou Drt_IR_det égale 0).
Alors, en fonction de l’état des deux variables, on détermine quelle subroutine exécuter (la sélection est écrite dans la variable Action). Si aucun obstacle n’est présent Action est égale à 0, si au contraire il y a un obstacle à gauche, elle est égale à 1, si l’obstacle est à droite, elle est égale à 2 et enfin si l’obstacle est frontal, elle est égale à 3.
Les deux bits les moins significatifs d’Action sont alors écrits dans la variable VarAnd (utilisant une opération de And, représentée par le symbole &).
Nous avions déjà rencontré dans le logiciel de Filippo l’instruction déterminant le passage à la subroutine correcte et à la Branch VarAnd, [En avant, Droite, Gauche, Inverse]. Pour résumer un peu, nous pouvons dire que si VarAnd=0 on saute à En avant, si VarAnd=1 on exécute la subroutine Droite et ainsi de suite. A noter que les sauts sont équivalents à des instructions GoTo (et non Gosub) : c’est pourquoi les quatre subroutines En avant, Droite, Gauche et Inverse reviennent au cycle principal (étiqueté avec le “label” Début) au moyen de l’instruction GoTo Début et non avec une Return.
En ce qui concerne ces quatre subroutines, disons que ce sont pratiquement les mêmes que pour le premier logiciel de la figure 4 : En avant gère la marche en avant pour un pas (réclamant la Marche), c’est-à-dire des pattes droites et gauches. La subroutine Gauche est réclamée quand un obstacle est présent à droite. Au moyen de Arrière on recule de trois pas et au moyen du cycle “for” on tourne à droite. La subroutine Droite est symétrique de la Gauche : après avoir reculé on tourne à gauche. Enfin, Inverse réclame Arrière pour reculer de trois pas et inverse le sens de la marche en tournant de 180° à gauche.

Figure 8 : Listing “Mouvement avec contrôle des obstacles à infrarouges”.
‘************************************************************************************
‘* Nom : Spider_IR *
‘* Notes : Mouvements avec contrôle des détecteurs à IR *
‘************************************************************************************

‘-----[ Définitions ]----------------------------------------------------------------
DEFINE LOADER_USED 1 ‘Utilisé pour boot-loader
DEFINE OSC 20 ‘Paramètre Clock à 20MHz
ADCON1 = 000111 ‘Port A = Numérique

‘-----[ Vers Port ]------------------------------------------------------------------
TRISA = 110000 ‘Paramètre pin Port A en Input et/ou Output
TRISB = 000000 ‘Paramètre pin Port B en Input et/ou Output
TRISC = 000011 ‘Paramètre pin Port C en Input et/ou Output

‘-----[ Définitions I/O ]------------------------------------------------------------
Servo1 VAR PORTB.2 ‘Port Servo 1 (Droite)
Servo2 VAR PORTB.1 ‘Port Servo 2 (Gauche)
Servo3 VAR PORTB.0 ‘Port Servo 3 (Centre)

Speaker VAR PORTA.1 ‘Port Speaker

IR_1 VAR PORTC.1 ‘Port Récepteur à infrarouges

IFR_1 VAR PORTC.5 ‘Port Trx. infrarouges Droit
IFR_2 VAR PORTC.2 ‘Port Trx. infrarouges Gauche

‘-----[ Définitions Variables ]------------------------------------------------------
Pos_Servo1 VAR WORD ‘position servo1 Droite
Pos_Servo2 VAR WORD ‘position servo2 Gauche
Pos_Servo3 VAR WORD ‘position servo3 Centre

mcount VAR BYTE ‘loop pour subrout. marche
ncount VAR BYTE ‘loop pour les autres
Note VAR BYTE ‘note pour sound

action VAR BYTE
VarAnd VAR BYTE ‘variable pour and logique
Sinist_IR_det VAR BIT ‘variables pour sauvegarder...
Destr_IR_det VAR BIT ‘...l’état du récepteur IR

‘-----[ Définitions Constantes ]-----------------------------------------------------
pos_max_3 CON 900 ‘Position Maximale Centre
pos_mid_3 CON 750 ‘Position Centrale Centre
pos_min_3 CON 600 ‘Position Minimale Centre
pos_max_1 CON 900 ‘Position Maximale Droite
pos_mid_1 CON 750 ‘Position Centrale Droite
pos_min_1 CON 600 ‘Position Minimale Droite
pos_max_2 CON 900 ‘Position Maximale Gauche
pos_mid_2 CON 750 ‘Position Centrale Gauche
pos_min_2 CON 600 ‘Position Minimale Gauche

Retard CON 20 ‘Pause pour Pulsout en μs
Pas CON 5 ‘Pas pour cycle Mise à zéro
Pas_1 CON 7 ‘Pas pour cycle Marche
Durée CON 50 ‘Durée note pour Sound

‘-----[ Initialisation ]-------------------------------------------------------------
PORTA =0
PORTB =0
PORTC =0
Gau_IR_det = 0
Drt_IR_det = 0
ncount = 0
mcount = 0
Note = 0
VarAnd = 0

‘-----[ Début programme ]------------------------------------------------------------
Note = 50
GoSub Son ‘émets son

Pos_Servo1 = pos_mid_1 ‘position initiale...
Pos_Servo2 = pos_mid_2 ‘...des trois servomoteurs...
Pos_Servo3 = pos_mid_3 ‘...au centre
GoSub Mise à zéro

Début :
‘Vérification présence obstacle à Gauche
High IFR_2 ‘Active Trx. IR Gauche
Pause 1
Sinist_IR_det = IR_1 ‘Lis état Rx. IR
Low IFR_2 ‘Désactive Trx. IR
Pause 1

IF Gau_IR_det = 0 Then ‘Si obstacle présent...
Note = 10 ‘...émets son
GoSub Son
EndIF
‘Vérifie présence obstacle à Droite.
High IFR_1 ‘Active Trx. IR Droite
Pause 1
Destr_IR_det = IR_1 ‘Lis état Rx. IR
Low IFR_1 ‘Désactive Trx. IR
Pause 1
IF Destr_IR_det = 0 Then ‘Si obstacle présent...
Nota = 100 ‘...émets son
GoSub Son
EndIF
‘Détermine quelle action exécuter
action = 0
‘si 1 (obstacle non présent) ne rien faire
IF Sinist_IR_det = 1 Then cont1
action = action +1
cont1:
‘si 1 (obstacle non présent) ne rien faire
IF Destr_IR_det = 1 Then cont2
action = action +2
cont2:
‘Action = 0, aucun obstacle
‘Action = 1, obstacle à Gauche
‘Action = 2, obstacle à Droite
‘Action = 3, obstacle frontal
‘Exécute l’action indiquée par Action
VarAnd = action & 000011
Branch VarAnd, [Avance, Droite, Gauche, Inverse]

‘-----[ Subroutine ]-----------------------------------------------------------------
En avant :
Pos_Servo1 = pos_min_1 ‘en arrière pattes Droite
Pos_Servo2 = pos_min_2 ‘en avant pattes Gauche
Pos_Servo3 = pos_max_3 ‘en bas centrale Gauche
GoSub Marche

Pos_Servo1 = pos_max_1 ‘en avant pattes Droite
Pos_Servo2 = pos_max_2 ‘en arrière pattes Gauche
Pos_Servo3 = pos_min_3 ‘en bas centrale Droite
GoSub Marche

GoTo Inizio ‘Retourne au cycle main

Marche :
‘Positionne les pattes centrales
For mcount=1 to 100 step Pas_1
PulsOut Servo3,Pos_Servo3
Pause Retard
Next
‘Bouge les pattes Droites et Gauches
For mcount=1 to 100 step Pas_1
PulsOut Servo1,Pos_Servo1 ‘Droite
PulsOut Servo2,Pos_Servo2 ‘Gauche
PulsOut Servo3,Pos_Servo3 ‘Centre
Pause Retard
Next
Return

Son :
Sound Speaker, [Note,Durée] ‘Emets son
Low Speaker ‘Eteins speaker
Return

Mise à zéro :
‘Positionne les trois servomoteurs...
‘...en position centrale
For ncount = 1 to 100 step Pas
PulsOut Servo1,Pos_Servo1
PulsOut Servo2,Pos_Servo2
PulsOut Servo3,Pos_Servo3
Pause Retard
Next
Return

Gauche :
‘Il faut revenir en arrière...
‘...de trois pas et tourner à Droite...
‘...pour éviter l’obstacle rencontré...
‘...par antenne_1
Note = 10 ‘Emets son
GoSub Son

GoSub Arrière ‘Reviens en arrière de trois pas

For ncount=1 to 5 ‘Tourne à Droite
Pos_Servo1 = pos_max_1 ‘av. pattes dx
Pos_Servo2 = pos_min_2 ‘av. pattes sx
Pos_Servo3 = pos_max_3 ‘en bas cent. sx
GoSub Marche

Pos_Servo1 = pos_min_1 ‘arr. pattes dx
Pos_Servo2 = pos_max_2 ‘arr. pattes sx
Pos_Servo3 = pos_min_3 ‘en bas cent. dx
GoSub Marche
Next
Goto Début

Droite :
‘Il faut revenir en arrière...
‘...de trois pas et tourner à Gauche...
‘...pour éviter l’obstacle rencontré...
‘...par antenne_2

Note = 100 ‘Emets son
GoSub Son

GoSub Arrière ‘Reviens en arrière de trois pas
For ncount=1 to 5 ‘Tourne à Gauche
Pos_Servo1 = pos_min_1 ‘arr. pattes dx
Pos_Servo2 = pos_max_2 ‘arr. pattes sx
Pos_Servo3 = pos_max_3 ‘en bas cent. sx
GoSub Marche

Pos_Servo1 = pos_max_1 ‘av. pattes dx
Pos_Servo2 = pos_min_2 ‘av. pattes sx
Pos_Servo3 = pos_min_3 ‘en bas cent. dx
GoSub Marche
Next
GoTo Début

Inverse :
‘Il faut revenir en arrière...
‘...de trois pas et tourner de 180°...
‘...pour éviter l’obstacle rencontré...
‘...par les deux antennes

Note = 50 ‘Emets son
GoSub Son

GoSub Arrière ‘Reviens en arrière de trois pas

For ncount=1 to 7 ‘Tourne à Gauche de 180°
Pos_Servo1 = pos_min_1 ‘arr. pattes dx
Pos_Servo2 = pos_max_2 ‘arr. pattes sx
Pos_Servo3 = pos_max_3 ‘en bas cent. sx
GoSub Marche

Pos_Servo1 = pos_max_1 ‘av. pattes dx
Pos_Servo2 = pos_min_2 ‘av. pattes sx
Pos_Servo3 = pos_min_3 ‘en bas cent. dx
GoSub Marche
Next
GoTo Début

En arrière :
For ncount=1 to 4 ‘Reviens en arrière de trois pas
Pos_Servo1 = pos_max_1 ‘av. pattes dx
Pos_Servo2 = pos_max_2 ‘arr. pattes sx
Pos_Servo3 = pos_max_3 ‘en bas cent. sx
GoSub Marche

Pos_Servo1 = pos_min_1 ‘arr. pattes dx
Pos_Servo2 = pos_min_2 ‘av. pattes sx
Pos_Servo3 = pos_min_3 ‘en bas cent. dx
GoSub Marche
Next
Return
End

Figure 9 : Le compilateur Basic pour PIC.
Pour pouvoir faire fonctionner chacun des trois robots disponibles, il est nécessaire d’écrire un programme qui leur fasse faire ce que nous voulons. Le programme peut être écrit en n’importe quel langage, mais pour pouvoir être transféré au PIC16F876, il est nécessaire qu’il soit compilé au format .HEX, compréhensible par le microcontrôleur. Nous avons utilisé le Basic et avons donc dû nous munir d’un compilateur Basic pour PIC capable de convertir les “listings” écrits en Basic en instructions de code machine.
Dans l’article, nous avons déjà fait référence au “bootloader” et au transfert à partir du PC des fichiers .HEX. Notre conseil est d’utiliser le “pack” PicBasic Compiler de μEngineerig Laboratoires. Avec ce logiciel, il est possible d’écrire un programme directement en Basic : ce sera ensuite au compilateur de le transformer en un fichier écrit en code machine, pouvant être mémorisé dans le microcontrôleur par l’intermédiaire du “bootloader”. L’utilisation de ce logiciel rend la programmation beaucoup plus simple et rapide, ce qui permet de réaliser en peu de lignes de Basic ce qui en demanderait beaucoup plus en Assembleur.
Deux versions du logiciel sont disponibles : une de base permettant d’utiliser des fonctions avancées de programmation, commandes de saut, d’interaction, etc., et une pro permettant en plus la gestion des “Interrupts”, la possibilité d’utiliser “array”, une meilleure gestion des sérielles au niveau matériel comme au niveau logiciel, etc. Quant à nous, nous nous sommes servis de la version de base du compilateur, suffisante pour cette application robotique.

Figure 9a : Ecran de PicBasic Compiler : il est possible d’écrire directement dans la fenêtre le listing en Basic. Avec un clic, on obtient le code compilé au format .Hex.

Figure 9b : Fenêtre de paramétrage de PicBasic Compiler : il est possible de spécifier si l’on veut utiliser la version de base ou pro, ainsi que le registre où se trouve le compilateur.

Conclusion
Cet article, le septième, achève notre chronique dédiée à la Robotique. Si vous nous avez suivi avec attention (ce dont votre abondant courrier nous interdit de douter) une bonne partie de cette année, vous êtes maintenant certainement capables de continuer par vous-mêmes à développer les ressources (matérielles et logicielles) caractérisant nos trois robots.
Il nous semble en effet que nous vous avons donné toutes les informations nécessaires pour vous permettre de réaliser ce qui, à notre avis, constitue la partie la plus intéressante, divertissante et passionnante de la robotique de loisir : étendre à de nouvelles fonctionnalités nos trois réalisations de telle façon que chacun de vous puisse personnaliser selon son goût et ses préférences son propre robot. En quelque sorte ces sept chroniques auront constitué un Cours de robotique par la pratique !
Désormais vous devriez avoir une connaissance approfondie de tous les concepts fondamentaux concernant la mécanique, l’électronique et l’informatique sous-tendant la réalisation de chaque robot présenté et, par exemple, il ne vous sera pas difficile de modifier légèrement l’électronique de manière à ajouter de nouveaux périphériques ou dispositifs.
Une idée, entre autres, nous vient à l’esprit : vous pourriez monter un second système émetteurs et récepteurs à infrarouges à l’arrière du robot et, au lieu de l’utiliser comme détecteur d’obstacles, vous pourriez réaliser un système permettant de “voir” et contourner d’éventuels trous ou marches.
Ou alors vous pourriez relier la carte-mère des trois robots à un module récepteur, de façon à réaliser une sorte de télécommande sans fil.
Si vous avez compris le fonctionnement des “listings” Basic que nous vous avons montrés et décrits ces derniers mois, vous devriez à présent être capables de les modifier pour les adapter à ces (ou à d’autres) nouvelles fonctions, comme par exemple la commande des périphériques ajoutés.
Prochainement, une nouvelle chronique remplacera celle qui s’achève : elle sera consacrée à la programmation des microcontrôleurs ST7LITE09. Merci pour votre fidélité.

Fin.

Trois robots de grande taille à construire et à programmer
Premier robot "CarBot" (Première partie)
Premier robot "CarBot" (Deuxième partie)
Deuxième robot "Filippo" (Première partie)
Deuxième robot "Filippo" (Deuxième partie)
Troisième robot "Spider" (Première partie)

0 commentaires:

Enregistrer un commentaire

Related Posts Plugin for WordPress, Blogger...