Communication avec la carte STM32 ================================= Principe -------- La carte STM32 exécute un **client micro-ROS** (voir le chapitre :doc:`../firmware/MicroRosandFreeRtos_config`). Elle ne parle pas DDS directement : ses nœuds, publications et abonnements sont *proxifiés* par l'**agent micro-ROS** qui tourne sur la Raspberry Pi. Vu du graphe ROS 2, les topics du firmware sont des topics ordinaires. :: ┌─────────────┐ XRCE-DDS sur série ┌──────────────────┐ │ STM32 │◄───────────────────────►│ Raspberry Pi 4 │ │ micro-ROS │ (1 Mbaud) │ agent micro-ROS │──► graphe │ client │ │ │ ROS 2 └─────────────┘ └──────────────────┘ Transport --------- Deux transports sont possibles avec ``micro_ros_stm32cubemx_utils`` : .. list-table:: :header-rows: 1 :widths: 25 40 35 * - Transport - Usage - Périphérique côté Pi * - USB CDC (port série virtuel) - Développement : c'est le transport décrit dans le guide firmware actuel. Le débit annoncé est virtuel. - ``/dev/ttyACM0`` * - UART + DMA (``dma_transport.c``) - Fonctionnement nominal sur le robot : liaison série dédiée à **1 Mbaud** entre la Pi et la carte. - ``/dev/ttyAMA0`` ou ``/dev/serial0`` (TODO : à confirmer) TODO : documenter la bascule du firmware vers le transport UART/DMA (sélection dans le Makefile, UART retenu, brochage). Pourquoi la cinématique est dans le firmware (et pas ros2_control) ------------------------------------------------------------------ Décision (2026-07) : c'est le **firmware qui convertit** ``cmd_vel`` en vitesses de roues (cinématique inverse) et les encodeurs en ``odom`` (cinématique directe). L'alternative envisagée était le ``diff_drive_controller`` de **ros2_control** sur la Raspberry Pi, la carte ne recevant que des consignes de vitesses de roues. Arguments de la décision : - **Sécurité au bon endroit** : le watchdog (silence de ``cmd_vel`` > ~500 ms → arrêt) vit dans la carte, au plus près des moteurs, et fonctionne même si la Pi ou le WiFi est hors service. - **Les dynamixels asservissent déjà la vitesse** : il ne reste au firmware que les deux formules de la cinématique différentielle (~30 lignes). - **Le passage à des moteurs CC ne change pas la donne** (la carte le prévoit) : la boucle d'asservissement PID (~1 kHz) devrait tourner dans le STM32 *dans les deux options* — ros2_control envoie des consignes de roues et suppose que quelqu'un les réalise en dessous. Le travail firmware serait le même. - **La mutualisation avec l'URDF est un faux avantage** : ``diff_drive_controller`` lit ``wheel_separation``/``wheel_radius`` dans son YAML, pas dans l'URDF — il y aurait deux sources dans les deux cas. Le vrai avantage (régler sans reflasher) est conservé : les paramètres de roues du firmware seront **configurables depuis la Pi** (paramètres micro-ROS, TODO). - **Moins de trafic et de fragilité** : pas de boucle de commande à 50–100 Hz qui traverse la liaison série, pas de *hardware interface* micro-ROS à écrire ni de ``controller_manager`` à configurer. Cette décision est **réversible et invisible de l'extérieur** : le contrat public reste ``base/cmd_vel``/``base/odom``. Si un besoin réel de ros2_control apparaît (bras manipulateur, contrôleurs avancés…), le pont pourra être écrit sans rien changer pour les projets hôtes. Messages échangés ----------------- Le firmware est organisé en threads FreeRTOS, chacun responsable d'un sous-système. Le tableau donne la correspondance entre les threads et les topics du contrat (:doc:`topics`) : .. list-table:: :header-rows: 1 :widths: 30 40 30 * - Thread FreeRTOS - Topics - Remarques * - Moteurs de traction - ``base/cmd_vel_safe`` (⬇), ``base/odom`` (⬆), ``base/joint_states`` (⬆) - Le firmware s'abonne à ``base/cmd_vel_safe``, la sortie du garde-barrière ``cmd_vel_gate`` (voir :doc:`topics`, arrêt global). Watchdog : arrêt si silence > ~500 ms. * - IMU (I2C) - ``imu/data_raw`` (⬆) - Données brutes ; la fusion se fait sur la Pi. * - Température carte (TMP102) - ``health/temperature`` (⬆) - Capteur entre les deux régulateurs de courant. * - Écran + 6 boutons de navigation - *(aucun)* - Menu local du robot, interne au firmware. * - 4 boutons + 4 LEDs utilisateur - ``ui/buttons`` (⬆), ``ui/leds`` (⬇) - * - Buzzer actif - *(aucun — reflet dans* ``health/diagnostics`` *)* - Alertes de sécurité autonomes (température, batterie, danger), indépendantes de ROS. * - Buzzer passif - ``ui/buzzer/play`` (⬇) - Mélodies et alertes sonores commandées depuis ROS. * - Capteurs additionnels - TODO - Prévu pour des extensions futures. TODO : ``health/battery`` (quel thread ?), ``ui/display/text``, service ``reset_odometry``, et la politique QoS de chaque topic (*best effort* pour les flux périodiques, *reliable* pour les événements). Dimensionnement de la liaison ----------------------------- Une liaison série à 1 Mbaud (8N1) transporte au mieux ~100 ko/s. Budget estimé si tous les topics du contrat sortent du firmware : - ``base/odom`` à 50 Hz : ~38 ko/s (message d'environ 750 octets, dominé par les deux matrices de covariance) ; - ``imu/data_raw`` à 100 Hz : ~32 ko/s ; - ``base/joint_states`` à 10 Hz + ``health/*`` à 1 Hz + événements : ~5 ko/s. Soit **~75 ko/s, environ trois quarts du lien** : ça passe, mais sans grande marge. Leviers si besoin : réduire la cadence de ``odom``, ou faire publier au firmware des messages compacts recomposés par un nœud sur la Pi (à ne faire qu'en cas de besoin avéré). Limites du client micro-ROS --------------------------- Le nombre d'entités micro-ROS est fixé à la compilation de la bibliothèque statique (``colcon.meta``, section ``rmw_microxrcedds``). Le contrat demande environ 7 publishers, 4 subscriptions et 1 service : la configuration actuelle (``MAX_PUBLISHERS=10``, ``MAX_SUBSCRIPTIONS=5``, ``MAX_SERVICES=1``, ``MAX_NODES=1``) convient, avec peu de marge — à ajuster si le contrat s'étend.