Communication avec la carte STM32

Principe

La carte STM32 exécute un client micro-ROS (voir le chapitre FreeRTOS and MicroROS environment guide). 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 :

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 (Les topics du robot) :

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 Les topics du robot, 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.