Bonjour. Pour cette dernière leçon, on va analyser une application robotique simple. Raphaël a programmé son robot, Zébulon, pour passer entre deux briques. Sur le rebord, un capteur ultrasonique permet de mesurer la distance. Donc, l'algorithme, naturellement, est de balayer l'espace pour mesurer les distances, et puis ensuite, de partir dans la bonne direction. Comme le robot ne va pas parfaitement droit, la solution prudente est de recalibrer, après avoir parcouru une certaine distance. Alors Raphaël est très déçu, ça marchait bien chez lui, mais là, catastrophe, il n'a pas pris la bonne direction. On va comprendre un peu pourquoi. 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!