L'heure du robot ================ **S'applique à :** :bdg-warning-line:`Robot réel` Le robot connaît l'heure, et il sait la retrouver seul après une coupure. Cette page explique comment, parce que deux ou trois comportements surprennent quand on ne les connaît pas. Pourquoi le robot a besoin de l'heure ------------------------------------- **Pour que ses mesures soient comparables.** Chaque message publié porte la date de la **mesure**, et le journal de bord garde 256 événements datés (:doc:`journal`). Une heure fausse rend tout cela illisible le lendemain. **Pour que plusieurs robots s'accordent.** Si vous faites travailler plusieurs robots ensemble, ou un robot avec des caméras fixes, ce qui compte n'est pas d'avoir l'heure juste dans l'absolu : c'est que **toutes les machines aient la même**. Elles comparent leurs horodatages pour savoir quelle observation est la plus récente. C'est pourquoi le robot ne vise qu'**un seul serveur de temps**, celui du réseau local, et pas les serveurs publics d'Internet. Un robot mieux réglé que ses voisins serait plus juste et **en désaccord avec eux** — le pire des deux mondes. La Raspberry n'a pas d'horloge ------------------------------ .. important:: **La Raspberry Pi n'a aucune horloge à pile.** Hors tension, elle oublie l'heure et repart, au démarrage, de la date de son dernier arrêt. Elle est donc toujours **en retard** — parfois de plusieurs semaines. La carte du robot, elle, a une horloge sur pile. C'est le seul élément qui garde l'heure éteint. D'où l'inversion qui surprend : **c'est la carte qui remet la Raspberry à l'heure**, et pas l'inverse. Ce qui se passe au démarrage ---------------------------- .. graphviz:: :caption: La décision, au démarrage. Chaque losange est une question ; le robot finit toujours par avoir une heure. digraph demarrage { bgcolor="transparent"; node [fontname="sans-serif", fontsize=10]; edge [fontname="sans-serif", fontsize=9]; depart [shape=box, style="rounded,filled", fillcolor="#f5f5f5", color="#999999", label="La Pi démarre\nsans heure juste"]; q_res [shape=diamond, style=filled, fillcolor="#fff2cc", color="#d6b656", label="Le serveur de\ntemps répond ?"]; ntp [shape=box, style="rounded,filled", fillcolor="#d5e8d4", color="#82b366", label="Tout le monde est à l'heure"]; attente [shape=box, style="rounded,filled", fillcolor="#f5f5f5", color="#999999", label="Elle attend 12 s au plus,\npuis continue quand même"]; q_qui [shape=diamond, style=filled, fillcolor="#fff2cc", color="#d6b656", label="Qui est le plus\nen avance ?"]; vers_pi [shape=box, style="rounded,filled", fillcolor="#dae8fc", color="#6c8ebf", label="La carte s'aligne\nsur la Pi"]; vers_c [shape=box, style="rounded,filled", fillcolor="#ffe6cc", color="#d79b00", label="La Pi prend l'heure de la carte\net AVANCE son horloge"]; depart -> q_res; q_res -> ntp [label=" oui"]; q_res -> attente [label=" non"]; attente -> q_qui; q_qui -> vers_pi [label=" la Pi"]; q_qui -> vers_c [label=" la carte"]; } Le robot démarre donc **même sans réseau**, avec l'heure de sa carte. En mode dégradé mais utilisable, et sans intervention. .. note:: La carte **refuse** une heure invraisemblable : toute date **antérieure à celle de son propre firmware**, puisqu'elle ne peut pas exister avant lui. Une Pi revenue à 1970, ou à la date de son dernier arrêt, ne peut donc pas écraser l'horloge de la carte : ce serait détruire la seule heure juste qui reste. C'est arrivé le 26 septembre 2026 : sans serveur de temps, la Pi se croyait en juillet, et la carte, qui n'acceptait alors que les dates postérieures à 2025, l'avait crue. Vérifier -------- .. code-block:: bash chronyc tracking # la Pi est-elle synchronisée, et sur quoi ? Ligne à regarder : ``Leap status : Normal`` veut dire que la synchronisation tient. ``Not synchronised`` veut dire que le serveur de temps n'a pas répondu — le robot tourne alors sur l'heure de sa carte. Pour tout le parc d'un coup, depuis le PC : .. code-block:: bash ./scripts/ratbot fleet time # l'écart de chaque robot au PC, et des cartes Le PC doit lui aussi suivre le serveur de temps. S'il utilise systemd-timesyncd plutôt que chrony, ``timedatectl timesync-status`` le vérifie : ``Packet count: 0`` veut dire qu'il n'a jamais obtenu de réponse. Le plus souvent, c'est que le serveur de temps n'est pas démarré. L'état de l'horloge de la carte est dans ses diagnostics : .. code-block:: bash ros2 topic echo --once /diagnostics | grep -A12 "clock" Trois témoins comptent : .. list-table:: :header-rows: 1 :widths: 32 68 * - Témoin - Ce qu'il dit * - ``boot_backup_blank: 0`` - la pile a tenu pendant la coupure. **À 1, changez la pile** : l'horloge repart de zéro à chaque extinction * - ``boot_lse_ready: 1`` - le quartz de l'horloge a démarré * - ``writes`` - combien de fois l'horloge de la carte a été recalée En cas de souci --------------- **Les dates du journal sont aberrantes.** Le robot a tourné sans heure juste. Une ligne datée ``boot+12.3s`` au lieu d'une date a été écrite **avant** qu'il ne connaisse l'heure — voir :doc:`journal`. **``apt`` ou ``git`` échouent en parlant de certificat.** C'est presque toujours l'horloge, pas le certificat : une machine qui se croit dans le passé juge tous les certificats « pas encore valides ». Réglez l'heure d'abord, l'erreur disparaît. **Le robot met douze secondes de plus à démarrer.** Il attend le serveur de temps. C'est le comportement prévu quand le réseau manque ; il part ensuite sans lui. .. seealso:: Le détail du mécanisme — règles de décision, ordre des services, pièges d'ordonnancement systemd — est dans la documentation développeur : `L'heure : une chaîne à trois maillons `_.