Le banc de test sur PC
firmware/ratbot_firmware_card/test/ compile les vrais fichiers de la
carte — pas une copie, pas une réécriture — avec du faux matériel, et les fait
tourner sur le PC de développement.
cd firmware/ratbot_firmware_card/test
make
=== traction ===
un tour complet rend bien 2*pi radians (1229 pas, pas 1024)
en marche avant, la vitesse mesuree ne passe jamais negative
...
=== traction, XL430 ===
XL430 : trois tours rendent 6*pi, sans secteur aveugle ni credit
...
67 verifications, 0 echec(s)
Pourquoi il existe
L’estimateur de roue (Traction : estimateur de roue et odométrie) est du calcul pur : des comptes entrent, des radians sortent. Rien n’oblige à le déboguer sur le robot, où chaque essai coûte un flash, une batterie et un mètre ruban.
Surtout, ses défauts sont difficiles à provoquer à la demande : il faut que la roue s’arrête pile dans le secteur aveugle, ou qu’un fantôme apparaisse au bon moment. Sur le banc, on les écrit en trois lignes et ils se rejouent à chaque compilation.
Ce qu’il ne fait pas : il ne teste ni FreeRTOS, ni le DMA, ni le bus Dynamixel réel, ni micro-ROS. Il teste la logique. Pour le XL430 en particulier, l’échange réel sur le fil (délais, réception bourrée) reste à essayer avec les moteurs.
Le modèle du capteur
capteur(angle_rad) reproduit l’AX-18A : 1024 pas sur 300 degrés, puis 60
degrés où le registre colle à 1023 en entrant et à 0 en sortant.
Deux détails qui ont chacun coûté une séance :
Le signe du servo. L’angle reçu est celui de la roue dans le repère du
robot ; le servo tourne dans le sens que lui impose son montage. Le modèle
applique donc wheel[0].sign, le même signe que le firmware. Sans cette
ligne, le banc simulait encore les moteurs du banc d’essai et plus ceux du robot
monté — cinq tests échouaient pour une mauvaise raison.
L’angle zéro est au milieu de la course visible, pas à son bord. Partir du bord mettait la roue simulée dans le secteur aveugle dès le premier échantillon, à vitesse nulle, et les scénarios de secteur aveugle passaient sans rien prouver — un robot à l’arrêt ne traverse jamais ce trou, il y reste.
Les cas
Cas |
Ce qu’il empêche de revenir |
|---|---|
un tour vaut 1229 pas |
perdre un sixième de tour à chaque passage |
la vitesse ne passe jamais négative en marche avant |
la boucle qui pousse à fond en voyant une roue reculer |
un fantôme ne crédite rien |
le saut de −2 rad pris pour une sortie de trou |
une roue débranchée puis rebranchée ne crédite rien |
78 mm de déplacement fantôme à la reconnexion |
l’intégrale s’arrête au plafond de sortie |
la roue qui pousse 1,5 s après l’ordre de ralentir |
une roue arrêtée dans le trou ne fait pas dériver l’odométrie |
les 600 rad en cinq minutes, robot à l’arrêt |
freinage actif puis coupure |
les virages qui dépassent de 13 à 22 degrés |
un fantôme au redémarrage n’est pas une sortie |
les sauts de 3,4 rad au départ des virages |
l’estime s’arrête avec la roue |
107 plafonnements en un seul arrêt |
remise à zéro roue garée dans le trou |
les +6,9 degrés de cap du troisième carré UMBmark |
chaque roue prend son propre rayon |
qu’un des quatre usages du rayon reste sur l’autre roue |
Chaque ligne de la colonne de droite est un défaut qui s’est réellement produit, avec sa mesure. C’est la règle du banc : on n’y ajoute pas de cas spéculatif, on y ajoute le cas qui vient de coûter une séance.
Vérifier qu’un test a des dents
Un test qui passe ne prouve rien tant qu’on n’a pas vu qu’il pouvait échouer. La pratique retenue est le test par mutation : on casse volontairement la ligne visée, on vérifie que le banc proteste, puis on restaure.
# Exemple : la roue droite emprunte le rayon de la gauche
sed -i 's|/ cfg->wheel_radius_right|/ cfg->wheel_radius_left|' ../App/traction.c
make # doit afficher « 1 echec(s) »
git checkout ../App/traction.c
make # doit repasser au vert
Sans cette vérification, un test peut être vide de sens et rassurer pour rien.
Ajouter un cas
static void cas_mon_scenario(void)
{
CAS("ce que le cas demontre, en une phrase");
roue_neuve();
commande(4.6); /* consigne suivie, rad/s */
lire(capteur(angle), 20u); /* un pas de 20 ms */
PROCHE(wheel[0].position_rad, attendu, 0.01, "pourquoi c'est ca");
}
Puis l’appeler depuis main(). Les helpers disponibles :
roue_neuve()— remet la roue, le faux bus et les compteurs à zéro ;commande(omega)— pose la consigne, queblind_estimate()consulte ;lire(compte, dt_ms)— avance le temps, pose la réponse du capteur, appellewheel_read_position();capteur(angle_rad)— le modèle du capteur ;faux_config_radii(gauche, droite)— les deux rayons de roue.
Voir aussi
Traction : estimateur de roue et odométrie — ce que ces cas protègent.
Comment il est bâti
Fichier
Rôle
faux/main.h,faux/cmsis_os.hde quoi satisfaire les
#includedu firmware sans HAL ni FreeRTOSfaux_materiel.cle bus Dynamixel simulé,
HAL_GetTick(), la configuration, l’arrêt d’urgencecadre.ctrois macros :
CAS,VERIFIE,PROCHE. Rien de plustest_traction.cles cas, et le modèle du capteur AX-18A ; depuis le 2026-10-19, ceux du XL430 : odométrie sur trois tours, repli de la position à 2³¹, servo qui redémarre (remis en service), consigne écrêtée et jamais répétée, arrêt d’urgence, mise en service (EEPROM écrite une fois, couple coupé), modèle refusé
test_dxl_frame2.cles trames du protocole 2.0 : les exemples du manuel ROBOTIS à l’octet près (CRC compris), les trames abîmées, et le bourrage dans les deux sens — une position de −32 tours s’écrit
FF FF FD FF—, et la recherche de la réponse derrière l’écho, même décalée d’un parasitetest_tof.cla tâche ToF avec un faux capteur : démarrage (8 × 8, 15 Hz, cible la plus proche), capteur absent puis branché, image convertie (colonnes retournées), panne puis redémarrage, image corrompue, température transmise, et la place laissée dans le diagnostic à
ros_toftest_config.cla configuration en flash, avec une fausse flash : une version 4 (la calibration de ratbot-1) est relue et convertie, une v4 abîmée retombe sur les défauts
test_rearm_gesture.cle geste de réarmement local — 5 appuis sur SW1 : fronts montants, fenêtre de 4 s, pas de second déclenchement, débordement de l’horloge
traction.cest inclus dans la compilation du test, ce qui donne accès à ses statiques. Les options y sont plus sévères que sur la carte —-Wextraet-Wconversion— parce que ces fichiers-là sont du calcul et qu’autant en profiter.Warning
traction.cdoit figurer dans les dépendances de la cible, et pas seulement dans la ligne de compilation. Sans cela, une modification du firmware ne reconstruit rien et le banc rejoue l’ancienne version.C’est arrivé : il a annoncé « 0 échec » sur un correctif qu’il n’avait pas compilé.