Description du robot
Le paquet ratbot_description (dans ros2_ws/src/) contient la
description URDF du robot, écrite en xacro :
urdf/ratbot.urdf.xacro.
Contenu du modèle
Le modèle décrit une base différentielle :
base_footprint: projection du robot au sol (racine du modèle) ;base_link: le châssis ;left_wheel_link/right_wheel_link: les roues motrices (articulationscontinuous) ;caster_link: le point d’appui.
S’ajoutent une frame imu_link, un lidar RPLidar optionnel
(laser_link, activable par use_lidar:=true|false) et un capteur de
distance multizone VL53L5CX optionnel à l’avant (tof_link et
tof_optical_link, activable par use_tof:=true|false).
Où est l’origine
base_link est sur l’axe des roues, à mi-chemin entre elles (REP-105
pour une base différentielle) : c’est le point autour duquel le robot tourne,
et celui que l’odométrie intègre. Le reste est placé par rapport à lui, d’après
le plan du châssis :
pièce |
x |
remarque |
|---|---|---|
roues |
0 |
à ±70 mm |
centrale ( |
−45 mm |
montée à l’envers et tournée : X vers la droite, Y vers
l’arrière, Z vers le bas, soit |
lidar ( |
−45 mm |
à l’aplomb de la centrale, tourné d’un demi-tour : |
capteur ToF ( |
+35 mm |
collé à l’avant de la plaque, au centre, à 10 cm du sol, pointé
droit devant. Position prévue, pas encore mesurée (2026-10-14) :
à reprendre une fois le capteur monté, l’inclinaison surtout — un
degré d’erreur de tangage déplace le sol vu à 1 m de 1,7 cm, assez pour
en faire un obstacle. |
centre de la plaque |
−50 mm |
plaque de 158 mm |
bille ( |
−101,34 mm |
Warning
Jusqu’au 2026-09-27, ``base_link`` était au centre de la plaque, 50 mm derrière l’axe. L’odométrie déplaçait l’axe et l’appelait centre de la plaque : pendant une rotation sur place, chaque scan était replacé jusqu’à 10 cm à côté de sa vraie position — de quoi dédoubler les murs d’une carte. Et la centrale était déclarée à l’endroit : l’EKF fusionnait un lacet de signe inverse. Les deux sont corrigés ; une carte faite avant est à refaire.
L’empreinte Nav2 suit. Un rectangle exact (3 cm devant l’axe à 13 cm
derrière, sur ±8 cm), en place du 2026-09-27 au 2026-10-18, laissait Nav2
approcher une planche puis faire demi-tour dessus : Regulated Pure Pursuit
ne vérifie pas le balayage d’une rotation sur place, et le coin arrière
décrit un cercle de 15,3 cm. Contact sur le robot réel le 2026-10-16.
Depuis, l’empreinte est un disque de 16 cm centré sur l’axe des roues
(robot_radius: 0.16 dans ratbot_nav/config/nav2.yaml) : le robot
garde toujours la place de tourner. Au banc, la marge pendant un demi-tour
près d’une planche passe de 5 à 16 cm ; un but à moins de 16 cm d’un
obstacle est ramené par le planificateur (tolerance: 0.25) au point sûr
le plus proche, et Nav2 l’annonce atteint. Le labyrinthe (ouvertures de
38 cm) devient presque impossible.
Les dimensions (châssis, rayon et entraxe des roues, positions) sont
définies comme propriétés xacro en tête de fichier, d’après le plan
mécanique (Châssis et mécanique). Les visuels utilisent les
maillages DAE (voir ci-dessous) ; les collisions restent des primitives
(boîte/cylindre), et use_mesh:=false bascule aussi les visuels en
primitives. Exception : les roues de collision sont des sphères, pas des
cylindres — un cylindre couché touche le sol par ses deux bords, et Gazebo
voyait un entraxe de 16 cm au lieu de 14 (+14 % de rotation comptée par les
roues). Seul Gazebo lit les collisions : sans effet sur le vrai robot.
TODO :
ajouter la frame du marqueur ArUco (surface supérieure du robot), utile à tout système de localisation externe ;
renseigner les inerties réelles (actuellement estimées).
Maillages 3D : où mettre quoi
Les formats CAO (STEP) ne sont pas lisibles par RViz/Gazebo : il faut distinguer la source de conception des maillages exportés.
Fichier |
Emplacement |
Rôle |
|---|---|---|
|
|
La source CAO, éditable — jamais référencée par l’URDF. |
|
|
Les exports pour l’URDF : DAE pour le visuel (couleurs), STL simplifié pour la collision. |
L’URDF les référence ainsi :
<mesh filename="package://ratbot_description/meshes/chassis.dae"/>
Règles d’export (depuis FreeCAD, Fusion 360…) :
unités : mètres — les CAO travaillent en millimètres, un maillage exporté en mm apparaîtra 1000 fois trop grand (sinon,
scale="0.001 0.001 0.001"dans la balise<mesh>) ;origine et orientation du maillage cohérentes avec la frame du link ;
pour la collision, préférer une version simplifiée (voire garder les primitives boîte/cylindre actuelles) : Gazebo calcule les contacts dessus, la finesse ne sert à rien.
Placement d’un maillage
Les maillages CAO ont souvent leur origine sur un coin (ou sur la
carte) et un axe vertical Y_UP. Le placement se règle sans toucher au
fichier, via des propriétés en tête de l’URDF :
struct_mesh_xyz/struct_mesh_rpy: position et orientation de la structure dans la framebase_link;wheel_mesh_rpy: orientation de la roue (son axe de rotation doit suivre l’axeYdu joint) ;mesh_scale: facteur d’échelle (voir le piège des unités ci-dessous).
L’interrupteur use_mesh:=false revient aux primitives boîte/cylindre —
pratique pour vérifier un problème d’alignement.
Gazebo reçoit toujours les primitives. spawn_robot.launch.py pose le
modèle avec use_mesh:=false (create -string), alors que
robot_description, donc RViz, garde les maillages. Le lidar simulé
(gpu_lidar) est un capteur de rendu : il mesure les visuels, pas les
collisions. Or le haut de ratbot_struct_asembly.dae monte à ~0,204 m dans
base_link, au-dessus du plan de balayage (~0,202 m). Avec le maillage, les
rayons partaient de l’intérieur de la structure, et le lidar devenait aveugle
selon l’orientation du robot, jusqu’à 0 rayon sur 360 : cartographie figée,
exploration en boucle (mesuré le 2026-10-11). Avec les primitives : 360 sur
360 à toute orientation.
Nettoyage des exports DAE (fix_dae.py)
Les DAE issus de la CAO ou de MeshLab tombent régulièrement sur trois
pièges qui cassent le rendu dans RViz et/ou Gazebo. Le script
meshes/fix_dae.py les corrige en une passe (idempotent, valide le XML
avant d’écrire) ; à relancer après chaque ré-export.
Piège |
Symptôme / cause |
Correctif |
|---|---|---|
Balise |
Double mise à l’échelle : le loader applique l’unité et le
|
|
|
Les exports CAO écrivent |
|
Aucun matériau |
MeshLab strippe les matériaux → la pièce apparaît blanche dans Gazebo (RViz est plus tolérant). |
Matériau uniforme injecté et lié (couleur configurable). |
cd ros2_ws/src/ratbot_description/meshes
python3 fix_dae.py ratbot_struct_asembly.dae # nettoie + injecte le gris
python3 fix_dae.py wheel.dae --no-material # nettoie sans toucher au bleu du DAE
python3 fix_dae.py ratbot_struct_asembly.dae --color 0.5 0.55 0.6 # couleur personnalisée
Note
MeshLab ne conserve pas les matériaux : un ré-export redonne une
belle géométrie mais sans couleur, et fix_dae.py réinjecte un gris
uniforme. Pour un vrai rendu multi-couleurs, passer plutôt par
Blender (import DAE → Decimate → export DAE), qui préserve les
matériaux.
Ne committer (et donc n’installer via colcon) que les maillages
réellement référencés par l’URDF : supprimer les copies de sauvegarde
ou de travail qui traînent dans meshes/.
Visualisation
Le launch display.launch.py permet de visualiser le modèle :
source ros2_ws/install/local_setup.bash
ros2 launch ratbot_description display.launch.py
Il démarre robot_state_publisher, joint_state_publisher_gui et
RViz. L’argument gui:=false ne lance que robot_state_publisher
(utile sur le robot, sans écran).
Dans RViz, ajouter un affichage RobotModel (topic
/robot_description) et choisir base_footprint comme Fixed Frame.
Dépendances : xacro, robot_state_publisher, et pour la
visualisation joint_state_publisher_gui et rviz2.