Ceci est une ancienne révision du document !
L'Hokuyo c'est cool, mais l'Hokuyo c'est quoi ?
L'Hokuyo est un télémètre laser, un LiDar. Il faut imaginer un capteur qui crée une “nappe laser” autour de lui et qui renvoi la position des objets dans ce plan.
Plus précisément, nous possédons un modèle URG-04LX-UG01 de la marque Hokuyo (d’où le nom).
Vous pouvez trouver les caractéristiques techniques ici : https://www.hokuyo-aut.jp/search/single.php?serial=166
Comme je l'ai expliqué plus haut, un télémètre laser balaye un plan à l'aide d'un laser rotatif, créant une “nappe laser”. Tout objet dans ce plan va renvoyer le laser et permettre au télémètre d'en connaitre la distance. Notre Hokuyo par exemple, balaye sur 240° avec une résolution de 1024 points par tour, soit environ 700 points sur 240°.
On se doit d'évoquer deux points problématiques de ces télémètres (ils sont magiques, mais pas trop) :
Parlons de l'Hokuyo en particulier, et plus précisément de notre modèle. Comment communique-t-on avec lui et sous quelle forme ?
L'hokuyo est relié à un ordinateur par câble USB. Il va créer une interface serial dans les périphériques (/dev/ttyACMx
). Nous communiquons avec l'hokuyo à l'aide d'une librairie C : v0.8.18. Nous avons utilisé la version 1.0.4 auparavant mais elle beugue avec deux Hokuyo.
Toute la documentation est disponible sur le site. La documentation est plutôt faible et incomplète. Je vais donc essayer de fournir les informations essentielles à l'utilisation de l'hokuyo et les quelques pièges dans lesquels il ne faut pas tomber.
L'hokuyo renvoit simplement un tableau de long. Cela correspond à la distance des points. Nous avons donc des distance associées à des index. Il est facile de transformer index en angle à l'aide d'une fonction présente dans la librairie. On peut donc conclure que l'hokuyo nous renvoi des coordonnées radiales. Un simple cosinus/sinus les transformera en coordonnées cartésiennes. Je ne m'étend pas sur le sujet, les exemples de la documentation sont facile à comprendre.
Voici une liste de ce que l'on peut faire :
Angle, Index, Step : Il existe trois manière de représenter l'angle d'une mesure : son angle (ce que l'on utilise), son index (son numéro de mesure) et sa step (son angle en représentation interne). Petit détail au passage : 0° est le point “en face” de l'hokuyo.
En pratique voila ce qu'il faut retenir :
Données max :
Un point bien angigu qui m'a vallu de bonnes prises de tête. Une fonction est disponibles pour connaitre le nombre maximal de points que renverra l'hokuyo. Cette fonction renvoit une donnée liée au matériel et non à la configuation de celui-ci.
Ce qu'il faut comprendre est :
Multi-echo / Intensité :
Je me répète ici, mais inutile de chercher à récupérer les données de multi-echo et d'intensité. Bien que les fonction existent, le matériel ne le supporte pas.
Quelques précision sur des points importants liés au matériel.
Bien que la consommation de l'hokuyo soit de 2.5W (0.5A à 5V), il est nécessaire d'utiliser le câble double, ou une alimentation externe. Si une alimentation externe est utilisée, attention tout de même aux raccordement, l'expérience m'a appris que si vous branchez cela n'importe comment, les données seront corrompues et il sera impossible d'utiliser l'hokuyo ! Si on utilise un long câble pour les données ou l'alimentation, attention à la résistance interne du câble, qui est loin d'être négligeable au delà de quelques dizaine de cm !
L'hokuyo scanne dans un plan, il est donc important que celui-ci soit bien droit lors des matchs. S'il est de travers, la précision sera moins bonne, et on risque même de ne plus détecter les robots !
Pendant un moment, nous avons monté les Hokuyos sur une base avec une articulation permettant de modifier l'horizontalité et le cap du capteur. En réalité, les plateformes des tables à la coupe sont suffisamment horizontale mais leur cap et leur hauteur ne sont pas forcément très précis.
Attention au temps de mise en place ! A la coupe, on (2 personnes max.) ne dispose que de 3 minutes pour que les robots et les tourelles soient prêts. Avant 2017, les Hokuyos occupaient 2 des 3 tourelles et étaient reliés par câble USB à la Raspberry Pi de la troisième tourelle. Il fallait au moins 3 minutes pour tout mettre en place. En 2017, la sortie de la Raspberry Zero nous a permis de l'intégrer directement à la balise.
L'hokuyo renvoi une liste d'entiers, chacun étant la distance de l’écho à un certain angle. Il faut alors traiter ces données. La première étape est de grouper ces points en cluster.
Voici l'algo utilisé :
tab[] tableau des distance culsters[] tableau des clusters nb_clusters = 0 found_cluster = false Pour i de 0 à size(tab): found_cluster = false Pour j de i-1 à max(0, i - search_size): //parcours inverse Si distance(tab[i], tab[j]) < distance_max: clusters[i] = clusters[j] found_cluster = true break Si found_cluster == false : clusters[i] = nb_clusters nb_cluster += 1
On note les variables de réglage search_size
et distance_max
:
search_size
est un entier désignant le nombre points précédents parmi lesquels chercher un cluster existantdistance_max
désigne la distance en dessous de laquelle un point est rattaché à un cluster existantCet algorithme se base sur le fait que les liste renvoyées par l'hokuyo sont triées par angle.
Suite à cela, on dispose de groupes (clusters) de points. Le groupe point
étant stocké dans le tableau cluster[]
. On peut alors filtrer les groupes ne comporte qu'un faible nombre de points, qui ont de fortes chances d'être des parasites.
Il faut ensuite convertir les coordonnées du repère polaire au repère cartésien. Chaque index correspond à un angle, que l'on peut récupérer par une fonction de la librairie. Selon la manière dont seront traités les points et les groupes, il peut être intéressant de précalculer les sinus/cosinus en fonction de l'angle. En effet, a chaque scan de l'hokuyo, un même index correspondra toujours au même angle. Ainsi il suffira d'initialiser l'hokuyo puis de calculer les tableaux d'équivalence index↔sin et index↔cosinus.
Il suffira alors pour convertir les points dans le repère cartésien d'effectuer :
x[i] = tab[i]*sin_tab[i] y[i] = tab[i]*cos_tab[i]
au lieu d’appeler pour chaque point, à chaque scan, les fonction sinus et cosinus.
Dans l'absolu, l'hokuyo devrait renvoyer un nombre de cluster égal au nombre de robots sur la carte. Or il peut arriver que l'on détecte un objet en trop (un arbitre qui passerait sa main au dessus de l'aire de jeu par exemple). On se propose donc de filtrer les cluster de la manière suivante :
Calculer la taille de chaque cluster (en millimètres, pas en nombre de points) Trier les cluster par taille décroissante Garder les X premiers (X étant le nombre de robots attendus)
Un autre avantage de ce tri est qu'il peut permettre de différencier les deux robots adverses en fonction de la taille de la balise. Par exemple, on peut mettre une balise plus petite sur le petit robot adverse afin de le reconnaitre. Le gros robot sera donc toujours avant le petit dans la liste des robots détectés.
On peut difficilement différencier les balises car elles ne représentent en pratique que quelques points, qu'une balise trop petite peut passer entre les mailles du filet et parce que le bruit et la précision ne permettent pas de différencier le diamètre de la balise.
En 2017, on a donc calculé le diamètre des clusters et on a supprimé ceux qui étaient trop grands (main, bras) ou trop petits (bruit). On a conservé tous les groupes restants.