Diagnostics =========== **S'applique à :** :bdg-info-line:`Simulation` :bdg-warning-line:`Robot réel` Le voyant et les sons disent **« regarde »**. Les diagnostics disent **quoi**. Ils décrivent en clair, chaque seconde, l'état de chaque partie du robot : les roues, les capteurs, la liaison avec le Raspberry Pi, la batterie, l'horloge… C'est **le premier endroit à regarder** quand quelque chose ne va pas. .. note:: Les diagnostics montrent **le présent**. Pour savoir ce qui s'est passé **avant** — pendant la nuit, pendant que vous n'étiez pas là, avant un redémarrage — c'est le journal de bord : voir :doc:`journal`. Les lire -------- Depuis le Raspberry Pi du robot, ou depuis n'importe quel ordinateur du même réseau configuré pour ROS : .. code-block:: bash ros2 topic echo /diagnostics Le défilement est rapide : chaque seconde, une vingtaine de **blocs** arrivent, un par partie du robot. Un bloc ressemble à ceci : .. code-block:: yaml - level: "\0" name: 'ratbot_1: emergency stop' message: contact released, robot armed hardware_id: ratbot_1 values: - key: latched value: '0' - key: trips value: '0' - key: rearms_local value: '0' .. list-table:: :header-rows: 1 :widths: 22 78 * - champ - ce qu'il dit * - ``level`` - **la gravité** — voir juste en dessous * - ``name`` - **qui parle** : le robot, puis la partie concernée * - ``message`` - **la phrase à lire** : ce que la partie constate, en une ligne * - ``values`` - **les compteurs et mesures** qui justifient le message. Utiles pour creuser, pas indispensables pour comprendre La gravité ~~~~~~~~~~ .. list-table:: :header-rows: 1 :widths: 22 18 60 * - vous lisez - niveau - signification * - ``level: "\0"`` - **OK** - tout va bien * - ``level: "\x01"`` - **avertissement** - quelque chose cloche, le robot continue * - ``level: "\x02"`` - **erreur** - une partie ne fonctionne pas, ou le robot s'est arrêté pour la sécurité .. tip:: **L'écriture est bizarre** — ``"\0"``, ``"\x01"`` — parce que ROS stocke la gravité comme un octet, et c'est ainsi qu'il l'affiche. Retenez simplement : **0 OK, 1 avertissement, 2 erreur**. Aller droit à ce qui ne va pas ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Plutôt que de tout lire, n'afficher **que les blocs qui ne sont pas OK** : .. code-block:: bash ros2 topic echo /diagnostics | grep -A2 'level: "\\x0[12]"' Chaque bloc en avertissement ou en erreur apparaît avec son nom et son message. **Si rien ne s'affiche au bout de quelques secondes, tout va bien.** Un seul bloc ~~~~~~~~~~~~ Chaque bloc porte le nom du robot devant : ``ratbot_1: traction``. On le retrouve donc directement, même quand plusieurs robots publient en même temps : .. code-block:: bash ros2 topic echo /diagnostics | grep -A30 "ratbot_1: emergency stop" Remplacez ``emergency stop`` par le nom d'un des blocs ci-dessous. En graphique ~~~~~~~~~~~~ ``rqt_robot_monitor`` affiche la même chose sous forme d'un arbre, avec des pastilles vertes, jaunes et rouges. Il demande un écran : lancez-le sur votre ordinateur, par exemple dans l'image Docker (voir :doc:`docker`), pas sur le Raspberry Pi du robot : .. code-block:: bash ros2 run rqt_robot_monitor rqt_robot_monitor Double-cliquez sur une ligne pour voir tous ses compteurs. Qui publie quoi --------------- Deux sources publient sur ``/diagnostics`` : - **la carte** (le *ratbot_controller*) : ses blocs commencent par ``ratbot_1:`` (le numéro du robot). C'est l'état du **matériel** ; - **le Raspberry Pi** : ses blocs commencent par ``ratbot:``. C'est l'état vu par les programmes : batterie en pourcentage, températures, état du voyant. D'autres programmes ajoutent leurs propres blocs, par exemple ``twist_mux`` ou ``ekf_filter_node`` : ils suivent le même format. .. important:: **Si aucun bloc** ``ratbot_1:`` **n'apparaît**, la carte ne parle pas au Raspberry Pi : programmes du robot arrêtés, câble débranché, ou carte éteinte. Le voyant respire alors en rouge. Voir :doc:`depannage`. Les blocs de la carte --------------------- Les messages sont en anglais. Pour chaque bloc : ce qu'il surveille, le message quand tout va bien, et les messages qui doivent faire réagir. La sécurité ~~~~~~~~~~~ .. list-table:: :header-rows: 1 :widths: 22 78 * - ``emergency stop`` - **Le bouton d'arrêt et la batterie critique.** Voir :doc:`arrets`. * - tout va bien - ``contact released, robot armed`` * - avertissement - ``EMERGENCY STOP ACTIVE -- release the contact, press SW1 5 times`` : l'arrêt est verrouillé. Relâchez le bouton, puis 5 appuis sur SW1. * - erreur - ``BATTERY CRITICAL -- power off and recharge`` : batterie sous 9,6 V. * - compteurs utiles - ``latched`` 1 si l'arrêt est verrouillé · ``contact_active`` 1 si le bouton est enfoncé en ce moment · ``trips`` nombre d'arrêts depuis le démarrage · ``rearms`` / ``rearms_local`` réarmements par commande / par SW1 · ``rearms_refused`` réarmements refusés (bouton encore enfoncé) L'arrêt automatique ~~~~~~~~~~~~~~~~~~~ .. list-table:: :header-rows: 1 :widths: 22 78 * - ``motion guard`` - **L'arrêt automatique** : robot renversé, roue bloquée, et le mode banc. Voir :doc:`arrets`. * - tout va bien - ``motion guard active`` * - avertissement - ``bench mode: motion guard disabled until reboot`` : le mode banc est actif, l'arrêt automatique est en pause * - erreur - ``TIPPED OVER -- set the robot upright, press SW1 5 times`` : le robot s'est coupé parce qu'il était renversé · ``WHEELS STALLED -- free the robot, press SW1 5 times`` : parce qu'une roue forçait sans tourner · ``WHEELS SLIPPING -- free the robot, press SW1 5 times`` : parce que ses roues patinaient · ``SHOCK -- check the robot, press SW1 5 times`` : parce qu'il a subi un choc * - compteurs utiles - ``tripped`` 0 rien, 1 renversé, 2 roue bloquée, 3 patinage, 4 choc · ``tilt_deg`` inclinaison actuelle en degrés (0 à plat, 180 à l'envers) · ``stalled_wheel`` la roue bloquée, 1 gauche, 2 droite, 3 les deux · ``bench_mode`` 1 si le mode banc est actif · ``tipped`` / ``stalled`` / ``slipping`` / ``shocks`` nombre d'arrêts depuis le démarrage · ``shock_peak_cms2`` le plus fort à-coup de la dernière seconde, en centièmes de m/s² (le robot se coupe à 500) · ``load_left_pct`` / ``load_right_pct`` la charge annoncée par chaque moteur, pour information : elle s'est révélée peu fiable, ne vous y fiez pas .. note:: ``tilt_deg`` cesse de bouger pendant que le robot est coupé : il garde l'inclinaison du moment où l'arrêt s'est produit. Les roues ~~~~~~~~~ .. list-table:: :header-rows: 1 :widths: 22 78 * - ``traction`` - **Les deux roues vues par la commande de mouvement.** * - tout va bien - ``traction nominal (AX-18A)``, ou ``(XL430)`` : les moteurs que la carte conduit (``wheel_servo_model``, voir :doc:`parametres`) * - avertissement - ``only one wheel answers`` : une roue ne répond plus * - erreur - ``no wheel detected (expects AX-18A, protocol 1.0)`` : aucune roue ne répond — alimentation des moteurs, câble du bus. La parenthèse dit quels moteurs la carte cherche (``wheel_servo_model``, voir :doc:`parametres`) : des XL430 sur un robot réglé pour des AX-18A ne répondent à rien, et inversement * - compteurs utiles - ``wheels_online`` **3** = les deux roues, 1 = la gauche seule, 2 = la droite seule, 0 = aucune · ``commands_received`` ordres de vitesse reçus · ``watchdog_stops`` arrêts faute d'ordre récent (normal quand on lâche la manette) .. list-table:: :header-rows: 1 :widths: 22 78 * - ``dynamixel bus`` - **Le câble qui relie la carte aux moteurs des roues.** * - tout va bien - ``bus nominal``, ou ``bus idle`` s'il n'a encore rien échangé * - avertissement - ``bus degraded: fewer than 80 % of exchanges succeed`` : faux contact probable · ``a servo reports an error (overload, overheat...)`` : un moteur force ou chauffe · ``wheels answer on connector 2, connector 1 expected`` : moteurs branchés sur le mauvais connecteur * - erreur - ``no servo answers`` : aucun moteur ne répond. Si aucune roue n'a répondu au démarrage, la carte a cherché partout, et le message dit ce qu'elle a trouvé : ``scan: conn2 id14 1000k conn2 id10 1000k`` (deux moteurs, connecteur 2, identifiants 14 et 10). ``p2`` signale un moteur en protocole 2.0, un XL430 * - compteurs utiles - ``exchanges`` / ``succeeded`` : les deux doivent rester égaux · ``timeouts`` réponses qui ne sont pas venues · ``refused`` ordres refusés par un moteur XL430 (toujours 0 avec des AX-18A) Le bloc ``wheel estimator`` ne contient que des compteurs internes, pour les développeurs ; il est toujours OK. Les capteurs ~~~~~~~~~~~~ .. list-table:: :header-rows: 1 :widths: 22 78 * - ``sensors`` - **La mesure de la batterie, de la température et la centrale inertielle.** * - tout va bien - ``sensor acquisition nominal`` * - avertissement - ``sensor acquisition not started yet`` : normal les premières secondes * - erreur - ``a sensor did not answer at boot`` : un capteur n'a pas répondu au démarrage — le code en bips (2 longs) dit lequel, voir :doc:`signaux` * - compteurs utiles - ``battery_mV`` tension de la batterie en millivolts (12344 = 12,3 V) · ``temperature_mC`` température de la carte en millièmes de degré (31687 = 31,7 °C) · ``temp_errors``, ``battery_errors`` lectures ratées .. list-table:: :header-rows: 1 :widths: 22 78 * - ``imu`` - **La centrale inertielle** (le gyroscope qui mesure les rotations). * - tout va bien - ``imu nominal`` * - avertissement - ``unstable I2C reads`` : lectures qui échouent, faux contact probable * - compteurs utiles - ``reads`` / ``errors`` · ``gyro_zero_updates`` nombre de fois où le zéro du gyroscope a été remesuré (chaque immobilité de plus de 2,5 s) · ``gyro_zero_z_urads`` la dérive de lacet retirée en ce moment, en millionièmes de rad/s (228 ≈ 0,8 °/min) : elle doit rester petite · ``gyro_scale_ppm`` l'échelle du gyroscope appliquée, en millionièmes (1007000 = 1,007 ; voir :doc:`gyroscope`) La liaison avec le Raspberry Pi ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :header-rows: 1 :widths: 22 78 * - ``micro-ROS link`` - **La conversation entre la carte et le Raspberry Pi.** * - tout va bien - ``micro-ROS session established`` * - avertissement - ``clock not synchronised: zero timestamps`` : la carte n'a pas encore reçu l'heure du Raspberry Pi. Normal quelques secondes au démarrage * - compteurs utiles - ``pings_lost`` messages de contrôle restés sans réponse · ``clock_synced`` 1 si l'heure est reçue .. list-table:: :header-rows: 1 :widths: 22 78 * - ``serial link`` - **Le câble lui-même** entre la carte et le Raspberry Pi. * - tout va bien - ``Pi link: no reception error`` * - avertissement ou erreur - ``Pi link: reception errors, reception restarted`` : des octets sont arrivés abîmés. Quelques-uns au démarrage du Raspberry Pi sont normaux ; s'ils montent en permanence, vérifiez le câble * - compteurs utiles - ``framing``, ``noise``, ``overrun``, ``parity`` : les types d'erreur · ``restarts`` relances de la réception La mémoire et l'horloge ~~~~~~~~~~~~~~~~~~~~~~~ .. list-table:: :header-rows: 1 :widths: 22 78 * - ``flash and settings`` - **Les réglages du robot**, gardés en mémoire (empattement, calibrage…). * - tout va bien - ``settings loaded from flash`` * - avertissement - ``defaults in use: blank flash or bad CRC`` : réglages illisibles, le robot tourne sur ses valeurs d'usine. Refaire le calibrage, voir :doc:`calibration` * - erreur - ``flash U7 missing: settings will not survive a reboot`` · ``flash write failed`` * - compteurs utiles - ``wheel_base_mm`` empattement en service · ``writes`` sauvegardes .. list-table:: :header-rows: 1 :widths: 22 78 * - ``clock`` - **L'horloge de la carte**, qui date le journal. Voir :doc:`heure`. * - tout va bien - ``RTC on time, synced with the agent`` : à l'heure, calée sur le Raspberry Pi. ``RTC on time, agent not seen yet`` juste après le démarrage * - avertissement - ``RTC not set yet`` : jamais mise à l'heure · ``backup domain blank at boot: the battery does not power the RTC`` : la pile de l'horloge est vide ou absente · ``the Pi is behind the RTC: it must pick up status/rtc`` : c'est le Raspberry Pi qui est en retard * - erreur - ``32 kHz crystal stopped: the RTC is not counting`` : le quartz de l'horloge ne bat plus .. list-table:: :header-rows: 1 :widths: 22 78 * - ``logbook`` - **Le journal de bord** lui-même. Voir :doc:`journal`. * - tout va bien - ``logbook active`` * - erreur - ``the logbook cannot write to flash`` * - compteurs utiles - ``boot`` numéro du démarrage en cours · ``lines`` lignes gardées · ``dropped`` lignes perdues (doit rester à 0) .. list-table:: :header-rows: 1 :widths: 22 78 * - ``black box`` - **La boîte noire** : la cause du dernier plantage. * - tout va bien - ``no crash recorded`` * - erreur - ``crash: stack overflow`` · ``crash: FreeRTOS heap exhausted`` · ``crash: core hardware fault`` · ``crash: Error_Handler, a peripheral refused`` : la carte s'est arrêtée sur une erreur **au tour précédent**, puis a redémarré. Le bloc reste en erreur jusqu'au prochain redémarrage, même si tout remarche : un plantage ne doit pas passer inaperçu. Notez le message et signalez-le aux développeurs. Le reste ~~~~~~~~ .. list-table:: :header-rows: 1 :widths: 22 78 * - ``buzzer`` - ``buzzer nominal``, ou ``a requested melody id does not exist`` si un programme a demandé un son qui n'existe pas (compteur ``unknown_ids``) * - ``screen`` - l'écran : ``idle animation (no heartbeat)`` quand il anime tout seul, ``screen driven by ROS`` quand un programme le pilote. ``a requested face is missing from the gallery`` : un programme a demandé un visage inconnu. Voir :doc:`ecran` * - ``log dump`` - le transfert du journal vers le Raspberry Pi pendant un ``ratbot log`` ; toujours OK * - ``loop profile`` - le temps pris par chaque étape de la boucle micro-ROS de la carte, en microsecondes par seconde ; toujours OK. Utile aux développeurs quand la carte ralentit * - ``tof`` - le capteur de distance avant (:doc:`tof`). ``tof nominal`` quand il mesure. ``no VL53L5CX at 0x29; I2C2 answers: …`` (WARN) : il ne répond pas, et la carte dit ce qu'elle a trouvé sur le bus ; voir « Dépanner » dans :doc:`tof`. ``i2c_last_error`` 4 = personne n'acquitte l'adresse. ``chip_temp_c`` est la température de la puce (environ 58 °C en service ; 85 °C est la limite de température ambiante). ``dma_fallbacks`` doit rester à 0. ``not_published`` compte les images produites mais jamais publiées Les blocs du Raspberry Pi ------------------------- .. list-table:: :header-rows: 1 :widths: 26 74 * - bloc - ce qu'il dit * - ``ratbot_N: status`` - l'état affiché par le voyant (``idle``, ``moving``…, voir :doc:`signaux`). **Erreur** pour ``emergency``, **avertissement** pour ``low_battery`` et ``overheat`` * - ``ratbot_N: battery`` - la charge en pourcentage. **Avertissement** sous 20 % * - ``ratbot_N: temp controleur`` - la température de la carte. **Avertissement** à partir de 75 °C * - ``ratbot_N: temp raspberry`` - la température du Raspberry Pi. **Avertissement** à partir de 80 °C Comme ceux de la carte, ces blocs portent le numéro du robot, dans leur nom et dans ``hardware_id`` : ``ratbot fleet diag`` (voir :doc:`flotte`) s'en sert pour attribuer chaque problème au bon robot. Un message ``aucune mesure`` veut dire que le Raspberry Pi ne reçoit pas la mesure de la carte : la liaison est à vérifier (bloc ``micro-ROS link``). Exemples -------- **Le robot ne bouge plus, voyant rouge rapide, alarme.** .. code-block:: bash ros2 topic echo /diagnostics | grep -A2 'level: "\\x0[12]"' .. code-block:: text - level: "\x01" name: 'ratbot_1: emergency stop' message: EMERGENCY STOP ACTIVE -- release the contact, press SW1 5 times Le bouton d'arrêt a été enfoncé : relâchez-le, puis 5 appuis sur SW1. **Voyant orange, un code « 1 long, 2 courts » au démarrage.** .. code-block:: text - level: "\x01" name: 'ratbot_1: traction' message: only one wheel answers La roue droite ne répond pas. Le compteur ``wheels_online`` vaut ``1`` : seule la gauche est là. Vérifiez le câble de la roue droite. Pour aller plus loin -------------------- La liste complète des compteurs de chaque bloc, et la façon d'ajouter un bloc, sont dans la documentation développeur.