On va donc un petit peu étudier ce capteur ultrasonique, voir comment
ce programme simple a été écrit, pourquoi on l'a pas suffisamment testé
et ce qu'il a fallu faire pour le dépanner, et réfléchir un
petit peu ensuite pour des programmes
plus complexes, par interruption, utilisant d'autres capteurs.
Le capteur ultrasonique est bien connu, on l'a déjà présenté
dans une leçon précédente. Il est très simple à utiliser, puisqu'il
suffit d'envoyer une impulsion de démarrage,
et ensuite, mesurer la durée de l'écho.
À l'oscilloscope, et bien on voit qu'on a des signaux tout à fait parfaits et
utilisables. Et le programme est aussi simple à écrire.
Il faut naturellement définir les unités, donner les bonnes directions.
Et au niveau de la boucle de mesure, que l'on va,
naturellement, commencer par tester, dans le programme le plus simple possible, on
active la sortie Trig, on fait un petit delay, de plus 10 microsecondes,
on désactive, et puis on a une facilité Arduino, qui attend
l'impulsion et mesure sa durée.
Donc, il suffit ensuite d'imprimer la valeur
que l'on a mesurée, et puis recommencer toutes les secondes,
par exemple, pour ne pas remplir trop vite l'écran pendant qu'on bouge le capteur.
Alors, il y deux problèmes avec cette routine.
C'est qu'ici, elle attend
l'Echo, donc, c'est une instruction qui
est bloquante, pendant toute la lecture, le
processeur ne fera rien d'autre, et, les
deux autres problèmes qui peuvent être embêtants
assez souvent, c'est si le capteur ne donne pas de signal, et bien
la routine va rester bloquée en attente, et si le capteur donne un signal
trop long, parce que, par exemple, il n'y a pas eu de retour de l'information
sonore, et bien le programme va aussi attendre, cette fois, sur l'état en un.
Donc, la durée de l'Echo que l'on espère avoir pour un mètre
cinquante, c'est typiquement 10ms, vous n'avez qu'à calculer la vitesse du son.
Avec le capteur qui
a quatre pin, on peut avoir jusqu'à 200ms pendant lesquelles
le circuit, voyant qu'il n'y a pas d'Echo, attend encore.
Alors que le SR05 avec cinq pattes, lui attend maximum 20 ms et
vous pouvez recommencer, toutes les 40 ms, à faire une lecture.
Alors, 200 ms, évidemment, ça peut être assez gênant pusique votre
bord, s'il se déplace pendant ce temps, tout va
être bloqué pour prendre des décisions concernant ce capteur.
Alors, les problèmes qu'on a avec ces capteurs sonores, et j'étais pas conscient
qu'il y en avait autant que ça, vous avez des possibilités de réflexion du sol.
Si c'est du tapis, et bien, vous allez avoir une réflexion non-négligeable,
qui risque de fausser les distances. Vous posez le moindre petit
objet sur la scène, un crayon, et bien, tout de suite il va faire des
réflexions. Un problème qui est facile à comprendre,
c'est que si la surface, dont on doit mesurer la
distance, est inclinée par rapport à un trajet sonore
émis, et bien, vous allez avoir une réflexion, réflexion au sens d'un
miroir, et aucune onde sonore ne va revenir vers le capteur, donc
si l'objet est proche, et bien il sera vu comme étant à
l'infini, et vous aurez cette attente, qui peut être abusive dans certains cas.
Donc, une matière lisse réfléchit, une matière poreuse absorbe complètement.
Donc, si vous mettez de la mousse très proche du robot,
et bien vous aurez de nouveau l'impression que l'obstacle est à l'infini.
Une autre expérience, c'est que du carton
ondulé est relativement favorable, même si sa longueur
d'onde semble un petit peu courte par
rapport à la longueur d'onde des ondes lumineuses.
Alors, le problème, c'est qu'il y un cône d'émission, qui est
documenté comme étant 15 degrés. Notre expérience est que ce cône est en
fait beaucoup plus large, et évidemment, vous devinez que dès que
ce cône touche le bord de l'obstacle, et bien,
il va y avoir réflexion, et puis vous n'aurez plus du tout la distance infinie.
Alors, ça c'est naturellement quelque chose qu'il faut expérimenter,
qu'on aurait dû expérimenter tout de suite, je n'aurais
peut-être pas proposé ce projet si j'avais fait cette expérience.
Et, le résultat, c'est que l'angle est plus proche et
60 degrés si on est relativement proche du sol, et apparemment,
ça diminue un petit peu, si on surélève le capteur,
mais ça ne semble quand même pas être la solution miracle.
Donc, la conclusion, et c'est vrai pour tous
les projets robotiques, analysez soigneusement les capteurs avant de
programmer l'application. C'est ce qu'on n'a pas fait.
Donc, Raphaël a suivi les indications que je lui avais donné.
On va définir un certain nombre
de positions angulaires pour faire des mesures.
On peut les représenter sous forme d'un diagramme horizontal.
En face, et bien, on espère avoir une distance très grande.
Dès qu'on touche l'obstacle, et bien il va y avoir une distance qui diminue, et puis
qui, tout à coup, peut brusquement augmenter à cause de la réflexion.
Donc ça, on l'observe facilement, et graphiquement, et bien,
vous voyez qu'ici, la distance est grande, et puis elle a diminué, ce qui
nous intéresse c'est de reconnaître cette zone de mesure, dont on va reparler.
Alors, faire bouger le robot, et bien on va faire des impulsions.
L'idée, c'est de faire des impulsions de 10 ms
et puis de l'arrêter 10 ms, et de faire la
mesure de distance après cette distance, pour être sûr que le robot soit stable.
C'est peut-être pas essentiel, de nouveau, c'est des
choses qui méritent d'être analysées, le plus précisément possible,
et si vous avez un oscilloscope, évidement, ça
vous vous permet d'avoir une meilleure compréhension des phénomènes.
Alors, on doit tourner. Donc, là,
j'ai utilisé des définitions qui modifient
les quatre bytes des deux moteurs simultanément.
C'est beaucoup plus compact que d'aligner des digitalWrite.
On définit la durée du pas, et puis, on définit les
fonctions Step à droite, Step à gauche, Avance, pas nécessairement de retard
après avoir fait le Stop pour Step Avance,
si on veut aller plus vite en ligne droite.
Donc là, il n'y a pas de problème maintenant pour faire
mon Step de 10 ms et il nous faut faire des mesures.
Alors, la proposition pour faire les mesures, c'est de dire, on va
déplacer le robot qui est, plus ou moins, en direction de l'obstacle,
en lui faisant faire 5 pas à gauche.
Ensuite, on va faire 10 pas à droite, en faisant les
mesures, et, attention, il y a le fameux problème des poteaux et des intervalles,
il faudra décider si on fait d'abord la mesure et ensuite le pas, ou, et
dans ces cas-là il faut rajouter la dernière mesure, ou bien
le pas et la mesure ensuite, et dans ce cas-là il fallait,
on aurait oublié la première mesure, si on n'y a pas pensé.
Une fois qu'on a fini les mesures, on va remettre le
robot en position centrale, pour analyser les données qu'on a accumulées.
Raphaël, il a préféré, tout de suite, revenir du bon pas pour se mettre dans la
direction souhaitée.
Euh, si on fait comme je l'ai dit, de rassembler
toutes ces données dans une table, on a une plus
grande flexibilité de pouvoir ensuite tranquillement analyser la table, montrer
son contenu, dépanner, afficher euh, sur le, sur le terminal naturellement.
Donc on définit une table de 11. La première
boucle for positionne à gauche, on fait ces, les cinq pas à gauche.
Ensuite on fait la mesure en remplissant la table.
Et puis on se repositionne, on rajoute la dernière valeur ici.
Et puis on se repositionne au centre.
Donc voilà la programmation est, est tout à fait naturelle.
Et le programme qui en découle et bien, il ne pose pas trop de problèmes
puisqu'on n'a pas d'interruptions, que les choses peuvent se faire
l'une après l'autre en ayant tout le temps nécessaire à disposition.
On fait la mesure en balayant, comme on vient de le voir.
On calcule l'angle et là, le raisonnement qu'il faut faire c'est là que, il
peut y avoir plusieurs algorithmes et des
algorithmes qui sont plus fiables que d'autres.
Euh, on doit travailler ici sur une différence,
sur la dérivée, dans le fond, du signal.
Alors cette différence elle augmente brusquement quand on passe de la distance
ici, relativement courte, 50 cm, 1 mètre, à une distance maximale de
3 mètres qui risque d'être affichée par une valeur limitée par le capteur.
Donc on peut avoir une très grande différence
de, de variations.
On attend un son positif ici d'une amplitude suffisante.
On attend ensuite un son négatif d'une amplitude suffisante.
Il ne faut pas être troublé par le fait qu'on a eu des
passages en réflexion au début et éventuellement à la fin.
Donc c'est là qu'il faut bien tester l'algorithme pour être
sûr qu'on repère les flancs correctement. Si vous multipliez le nombre
de pas, Raphaël en a utilisé 20, là j'en ai dessiné 10,
vous diminuez l'amplitude des pas et il faudrait être sûr
que le bruit inévitable que vous avez ne devient pas
du même ordre de grandeur que les pas. Et évidemment, quand le robot
se rapproche, et bien, tous ces paramètres changent,
donc c'est là que c'est nécessaire de faire une
étude très systématique, en déplaçant le robot à
la main, en observant sur le terminal les valeurs.
Une fois que vous avez confiance que vous avez ici échantillonné ces deux
paramètres, les numéraux, dans le fond, angulaires, vous faites la moyenne pour
savoir quelle direction euh, vous avez, dans le fond, la position
idéale par rapport à ces deux mesures mais ces deux mesures
sont décallées par rapport à la courbe en fait hein puisqu'il
y a un échantillonnage qui se fait avec un certain retard.
Donc dans le cas particulier de ce dessin, ben vous voyez qu'on partirait euh,
pile contre le mur, ce qui n'est pas tout à fait ce qu'on souhaite.
Donc là évidemment on pourrait réfléchir à des corrections ou
simplement ce qu'on a fait, ben c'est de, plus on se
rapproche de, de l'obstacle, et bien, plus l'erreur, dans le fond,
sera euh, sera diminuée par rapport à la largeur de l'obstacle.
Donc voilà, alors la programmation euh, peut se
faire, dans le fond, sans contraintes mais maintenant,
si vous voulez rajouter des moustaches et puis au moment où vous avez, par exemple,
un choc contre l'obstacle euh, réagir correctement, ce qui serait, par exemple,
de reculer un bout et de recalibrer la position du trou, et bien
cette détection de moustaches, doit être intégrée dans
la procédure avancer, ce qui n'est peut-être pas très difficile
parce que, de nouveau, on peut laisser l'avance sous contrôle, dans
le fond, d'un PWM et d'un retard mais on ne va
en tout cas pas faire un délai simple, il faudra faire
un, des petits délais et, dans chaque délai, tester les moustaches.
Alors, plus on complique évidemment la fontionnalité, plus
ça devient indispensable, dans le fond, de travailler
par interruptions. Alors est-ce qu'on peut mesurer la
distance par interruptions? Euh, oui, on va voir rapidement comment.
Est-ce que faire les pas pour le balayage peut se faire par interruptions?
On peut tout faire par interruptions mais est-ce que ça vaut la peine?
L'avance, ben là on sait bien qu'avec le PWM
ou le PFM, c'est facile à gérer par euh,
l'interruption.
Et puis maintenant les décisions, les algorithmes de correction
d'angle, ça naturellement qu'on les laisse en général au
programme principal qui appelle les fonctions adéquates et on
corrige les fonctions jusqu'à ce que le comportement soit bon.
Alors une approche quand on veut travailler par interruptions c'est
de dire : ben, pour chaque opération, on va susciter
une interruption spécifique. Et, c'est souvent documenté comme ça,
avec des librairies qui, mystérieusement, vous gèrent ça par interruptions.
Et puis si vous voulez garder le contrôle, ben,
une approche que j'ai souvent utilisée, c'est de dire
: toutes les 100 microsecondes, on va faire une
interruption et puis toutes les 100 microsecondes, je vais passer
par une machine d'état qui va me, me construire la distance.
Et puis ensuite, on va refaire un petit diviseur pour
dire : mais toutes les 20 millisecondes, j'aimerais faire autre
chose, par exemple faire avancer mon moteur, et puis on
peut encore imaginer d'autres choses qui se font plus lentement.
Alors là, on a, on sait exactement ce qui se passe, chaque fois, et combien
de temps ça va mettre.
Pour mesurer la distance avec les capteurs ultrasonores, là
je ne vais pas rentrer dans le détail mais il
y a, hein puisqu'on a quelque chose d'assez gênant puisque
le programme qu'on a vu tout à l'heure est bloquant.
Une solution non bloquante, ben c'est soit d'utiliser un timer et puis de repérer
le front montant, démarrer le timer, repérer le front descendant
donc ça ça se fait par des interruptions, le timer a la logique nécessaire
pour faire ça, et puis ensuite, on lit le timer pour avoir la valeur.
On peut aussi, comme je viens de l'évoquer, faire une interruption toutes
les 100 microsecondes et puis passer à travers une machine d'état qui va
générer l'impulsion 100 microsecondes, ben ça sera juste d'un cycle au suivant,
et puis ensuite qui va compter pour être sûr que le capteur répond dans moins de
20 millisecondes, on a vu que s'il est là, il doit répondre dans les 5 millisecondes.
On peut faire un timeout pour que, signaler que ça ne sert à rien de faire
démarrer le moteur s'il n'y a pas de
capteur connecté ou que le capteur est défectueux.
Et puis
maintenant, on passe dans la mesure. Et, là aussi,
on a un capteur qui va mesurer la durée de l'impulsion
avec aussi un timeout puisque ça ne sert à rien
de mesurer des distances qui, théoriquement, auraient plus de 3 mètres.
Alors évidemment le capteur, l'électronique du
capteur n'est pas nécessairement retombée sur ses pieds
mais si le fabricant garantit qu'il y a un
cycle de 20 millisecondes, et bien on peut
tout de suite recommencer au bout de 20 millisecondes.
Ça serait dangereux de recommencer tout de suite dès que Echo passe à 0 puisqu'on
n'est pas sûr que l'électronique interne du capteur est bien
retombée sur ses pattes.
Bien, d'autres solutions pour résoudre ce problème, ben naturellement,
on pourrait mettre un servo pour orienter le capteur, ça permettrait un déplacement
continu puisque pendant que le robot avance et bien on pourrait basculer le,
le capteur de part et d'autre et corriger la trajectoire.
Mais évidemment
ça, ça suppose hein, qu'on voit parfaitement bien les ouvertures donc
c'est là qu'on a vu que cette application pose un problème majeur.
Alors par interruptions, ben là on commanderait les,
on commanderait les moteurs et puis la position
du servo permettrait de mesurer où est la
distance maximale et puis de corriger les vitesses
des deux moteurs.
Est-ce qu'on devrait utiliser un autre capteur?
Alors oui puisqu'on, je prétends qu'on ne peut pas
tellement utiliser ces capteurs bon marché pour faire cette application.
Un capteur ultrason à champ étroit, je
ne sais pas s'ils existent mais probablement que
industriellement ça existe mais à des prix qui
sont dix fois supérieurs si c'est pas plus.
Un capteur qui conviendrait bien, c'est le PSD de Sharp
dont on a euh, dont on a parlé, qu'on a mentionné,
qui est un petit peu cher mais qui envoie un spot
lumineux et sa réflexion permet de savoir quelle est la distance.
Donc là, il n'y a aucun problème de largeur.
de l’obstacle, puisque même si on est suffisamment précis dans
le déplacement angulaire, une fente de quelques centimètres, même pas 1
centimètre, pourrait être vue mais, de nouveau, à expérimenter en détail.
C’est rare que les spécifications des fabricants
soient suffisamment précises pour éclairer votre application précise.
Les capteurs infrarouges qui sont utilisés pour mesurer la distance,
c’est en général, au maximum, 5 à 10
centimètres et ils sont assez sensibles à l’ambiance lumineuse.
Les photorésistances, qui sont très bon marché, ça va bien
pour faire un suivi de lumière, un suivi de piste, ce
qui est une des applications traditionnelles des robots mobiles que
je ne voulais justement pas vous expliquer aujourd’hui puisque vous avez
des tas de sites qui vous expliquent ça et vous l’avez peut-être fait, déjà, en LEGO!
Les moustaches, on en a dit deux mots, elles sont
faciles à gérer mais évidemment c’est toujours une tâche un
petit peu supplémentaire à faire en parallèle avec les autres tâches, et une
gestion par interruption est tout à fait souhaitée.
Ensuite, un concept important, qu’on n'a
pas le temps de bien développer dans ce cours, c’est la notion de « timeout ».
Vous avez une application, cette application, elle
peut très bien se produire que les
capteurs ne répondent pas, que le robot,
dans notre cas simple, le robot est bloqué.
Bon ça ne gêne pas d’aller le déplacer à la
main mais si on fait les choses sérieusement, ça serait bien
de dire, si le robot reste bloqué pendant 3 secondes, et bien c’est pas normal,
on va, par exemple, reculer un peu, lui faire chercher ailleurs et cetera.
Alors on avait parlé du « watchdog »
qui est à l’intérieur du processeur, pour surveiller
en fait le fonctionnement global du processeur, on
peut appliquer la même chose, dans le fond,
avec des compteurs. On réinitialise régulièrement un compteur
mais ce compteur décompte par interruption chaque seconde, par exemple.
S’il arrive à 0, c’est qu’on n’a pas
réinitialisé régulièrement, et puis on va exécuter une tâche.
Donc, typiquement, quand on teste les moustaches et puis
qu’on voit que les moustaches n’ont pas été activées,
et bien on remet le compteur à une certaine
valeur, et puis si, tout à coup, les moustaches sont
bloquées, le compteur décompte, et bien au bout de quelques
secondes, et bien on va faire cette opération de recul.
Bien, voilà, il y aurait encore beaucoup
de choses à dire pour comprendre les capteurs.
Des documents sont proposés
en annexe, avec ces leçons, pour aller un petit peu plus dans
le détail et puis vous expliquer des choses un peu plus spécialisées.
Naturellement, si vous êtes un chercheur et puis
que vous voulez faire une application de robot mobile
pour comprendre l’intelligence ou pour avoir une application industrielle,
là, il y a énormément de choses à comprendre.
Les logiciels s’appuient sur des noyaux temps
réel et vous facilitent la gestion, dans
le fond, des tâches simultanées sur des
processeurs naturellement qui doivent devenir beaucoup plus performants.
Alors, avec ce cours, on espère vous avoir
donné envie de continuer, de progresser vers la complexité
par petits pas. Et, en faisant suffisamment de petits pas,
et bien vous savez que on a marché sur la Lune!