Zum Inhalt springen

Mikrocontroller und der Raspberry Pi ​

Strido hat zwei Computer. Ein Raspberry Pi 5 läuft mit Linux und ROS 2 und entscheidet, wohin die Beine sollen. Ein Mikrocontroller Seeed XIAO ESP32-S3 führt ein kleines Programm aus, das diese Ziele alle 5 ms in Servopulse umsetzt und den Roboter sicher hält. Diese Seite erklärt, warum die Arbeit so aufgeteilt ist und wie die Daten zwischen beiden fließen.

In Strido

  • Raspberry Pi 5, 4 GB mit Active Cooler (pi5_4gb, pi5_cooler): ROS 2 Jazzy in Docker oder nativ, mit gait_node / policy_node, mcu_bridge, sllidar_ros2 und optional camera_ros (ros2/strido_control, ros2/strido_bringup).
  • Seeed XIAO ESP32-S3 (xiao_esp32s3): Firmware in firmware/strido_esp32s3 (PlatformIO, Arduino-ESP32 3.x). Die Pins stehen in src/board_config.h, gespiegelt in und geprüft gegen hardware/electronics.yaml.
  • PCA9685 16-Kanal-PWM-Treiber (pca9685, Adafruit-815-Layout) an I²C-Adresse 0x40: erzeugt die 12 Servopulse.
  • Verbindung: USB-CDC-Seriell, Pi USB-A → XIAO USB-C (W14), Gerätename /dev/strido_mcu aus ros2/strido_bringup/config/99-strido.rules.

Zwei Arten von Computer ​

Raspberry Pi 5XIAO ESP32-S3
ProzessorBroadcom BCM2712, 4 × Arm Cortex-A76 mit 2,4 GHzEspressif ESP32-S3, 2 × Xtensa LX7 mit bis zu 240 MHz
Speicher4 GB RAM, Betriebssystem auf einer 64-GB-microSD8 MB PSRAM, 8 MB Flash
BetriebssystemLinux (Ubuntu Server 24.04 oder Raspberry Pi OS)FreeRTOS unter dem Arduino-Core
Stärkegroße Software: ROS 2, Docker, Python, neuronale Policy, LiDAR- und Kameratreibervorhersagbares Timing, sofortiger Start, direkte Steuerung von Pins und Bussen
SchwächeTiming nicht garantiert; Booten dauert einige zehn Sekunden; SD-Karte kann durch Stromausfall beschädigt werdenwenig Speicher, keine Betriebssystemdienste, kein ROS
Leistungtypisch 5–7 W, Spitze 12 W mit Kühleretwa 1 W inklusive LCD, IMU und PCA9685-Logik

Ein Mikrocontroller (MCU) ist ein kompletter Computer auf einem Chip, gebaut, um dauerhaft ein Programm auszuführen und innerhalb von Mikrosekunden auf Hardware-Ereignisse zu reagieren. Ein Einplatinencomputer wie der Pi ist ein kleiner PC: Ein Allzweck-Betriebssystem teilt die CPU zwischen vielen Prozessen auf.

Echtzeit vs. „im Mittel schnell“ ​

Eine Regelschleife ist echtzeitfähig, wenn sie ihre Deadline in jedem Zyklus einhält, nicht nur im Mittel. Die Servoschleife in Strido hat eine Deadline von 5 ms (kControlPeriodUs = 5000): Periode und Schleifenrate sind Kehrwerte, T=1/f=1/200Hz=5ms. Warum die Periode für einen Controller wichtig ist, behandelt Regelung.

Linux ist schnell, aber nicht deterministisch. Der Scheduler, ein USB-Interrupt, ein Schreibvorgang auf die SD-Karte, Pythons Garbage Collector oder ein ausgelasteter ROS-Node können einen Prozess um mehrere Millisekunden verzögern. Ein verspätetes Servo-Update zeigt sich als Ruck im Bein. Ein eingefrorener Prozess auf dem Pi darf außerdem niemals zwölf Servos mit 3,43 N·m dauerhaft auf ihrem letzten Befehl halten lassen.

Der XIAO führt nur seine eigene Firmware aus, aufgeteilt in zwei FreeRTOS-Tasks auf getrennten Kernen (src/main.cpp):

TaskKernPrioritätPeriodeAufgabe
controlTask13 (höher)5 msIMU lesen, Orientierung aktualisieren, INA260 alle 100 ms lesen, Sicherheits-Zustandsautomat ausführen, 12 Servopulse berechnen und schreiben
commsTask02~1 ms Pollingeingehende Frames parsen, alle 10 ms einen STATE-Frame senden (100 Hz), LCD-Gesicht alle 50 ms aktualisieren

Durch die Aufteilung auf die Kerne kann ein Schwall serieller Daten das Servo-Update nie verzögern.

Warum beide und nicht nur einer ​

  • Nur der Pi? Der Pi müsste Pulse erzeugen und die Sicherheit aus Linux heraus gewährleisten, ohne Timing-Garantie. Ein Absturz oder Neustart des Pi würde die Servos in einem unbekannten Zustand lassen.
  • Nur der ESP32? Er kann weder ROS 2, Nav2, den LiDAR-Treiber, den Kamera-Stack noch die gelernte Policy mit ihrer numpy-Laufzeit ausführen.
  • Beide: Jeder macht, was er gut kann. Der Pi plant mit 100 Hz (gait_node, rate_hz: 100) oder 50 Hz (policy_node). Der XIAO führt mit 200 Hz aus und verantwortet alles Sicherheitskritische.

Was der XIAO selbstständig garantiert ​

Dies gilt unabhängig davon, was der Pi gerade tut (docs/software.md, safety.h):

  • Watchdog: 200 ms kein Gelenkbefehl → Pose halten; weitere 2 s → kraftlos (Ausgänge aus). Nur Gelenkbefehle speisen den Watchdog; stirbt also der Gait-Node, hält der Roboter zuerst und wird dann kraftlos.
  • Verriegelter Not-Halt: /strido/estop zieht den Output-Enable-Pin des PCA9685 auf High. Alle Pulse stoppen sofort, und der Halt bleibt verriegelt, bis er freigegeben wird.
  • Akkuabschaltung: Warnung bei 6,8 V; nach 5 Messwerten unter 6,4 V kraftlos schalten und Fahren verweigern.
  • Grenzen: Jedes Ziel wird auf 6 rad/s ratenbegrenzt und auf die Gelenk- und Kniekurbelgrenzen aus dem CAD-Bewegungsbereich-Sweep begrenzt. Nicht-endliche Werte (NaN) werden verworfen.
  • Kein INA260, kein Fahren: Ohne Power-Monitor gibt es keine Abschaltung.

Der PWM-Treiber PCA9685 ​

Warum erzeugt der ESP32 die zwölf Pulse nicht direkt?

  1. Pins. Der XIAO bietet 11 Pads (D0–D10). Neun sind bereits belegt, für das LCD (6), I²C (2) und die Output-Enable-Leitung (1). Zwölf weitere Pulsausgänge sind nicht verfügbar.
  2. Entlastung. Der PCA9685 hält pro Kanal einen 12-Bit-Ein/Aus-Zählwert und wiederholt die Pulse selbstständig mit 200 Hz. Die Firmware schreibt nur dann einen neuen Wert, wenn sich ein Ziel ändert.
  3. Eine Abschaltleitung. Sein Low-aktiver OE-Pin (Output Enable) schaltet alle 16 Ausgänge auf einmal ab, in Hardware.
  4. Kontinuität mit Upstream. Strido behält die Kanalbelegung des Upstream-Yertle bei (Kanäle 4–15), sodass Verkabelungswissen übertragbar bleibt.

Der OE-Pull-up

Die PCA9685-Platine zieht OE auf Low, was „Ausgänge an“ bedeutet. Während der XIAO zurückgesetzt wird oder im Bootloader steht, ist sein Pin D3 offen, und die Servos würden dem folgen, was der PCA9685 zuletzt hielt. Ein 2,2-kΩ-Widerstand von OE nach VCC hält die Ausgänge aus, bis die Firmware sie aktiv freigibt. Der Smoke-Test prüft das: Im Bootloader muss OE ≥ 2,4 V messen (docs/electronics.md, Kabelbaum-Schritt 8).

Datenfluss ​

Diagramm wird gezeichnet…

Ein Zyklus, von Anfang bis Ende:

  1. Planen. gait_node wandelt den Geschwindigkeitsbefehl in 12 Gelenkwinkel in Radiant um, Go2-Reihenfolge FL, FR, RL, RR × Hüfte, Oberschenkel, Unterschenkel.
  2. Senden. mcu_bridge packt sie in einen JOINT_COMMAND-Frame: Sequenznummer, Modus, 12 × float32. Er fügt eine CRC16-Prüfsumme hinzu, COBS-kodiert den Frame und schreibt ihn nach /dev/strido_mcu.
  3. Ausführen. Bei seinem nächsten 5-ms-Takt:
    • begrenzt der XIAO die Änderungsrate der Ziele;
    • rechnet er den Unterschenkelwinkel über das Koppelgetriebemodell in den Kniekurbelwinkel um (jointsToActuators);
    • begrenzt er auf die Gelenkgrenzen;
    • rechnet er jeden Winkel mit der Kalibrierung pro Gelenk in einen Puls um;
    • schreibt er die Pulse in den PCA9685.
  4. Melden. Alle 10 ms sendet der XIAO eine 103 Byte große STATE-Payload: die angewendeten Gelenkwinkel, das Orientierungsquaternion, Gyroskop- und Beschleunigungsmesswerte, Busspannung, Strom und Status-Flags. mcu_bridge veröffentlicht sie als ROS-Topics.

Da beide Seiten eine gemeinsame Protokolldefinition nutzen (packages/strido-core/src/strido/protocol.py ⇄ firmware/.../protocol.h), funktionieren dieselben Frames aus ROS, aus strido-cli auf einem Laptop und aus dem NT-X-Adapter.

Selbsttest ​

  1. Was passiert mit den Servos 200 ms und 2,2 s nach einem Absturz von gait_node?
  2. Nennen Sie zwei Gründe, warum die Servopulse von einem PCA9685 statt direkt vom XIAO kommen.
  3. Warum läuft der Regel-Task auf einem eigenen Kern mit höherer Priorität als der Kommunikations-Task?
  4. Was verhindert der 2,2-kΩ-Widerstand am OE-Pin des PCA9685?
  5. Welche Komponente rechnet den Unterschenkelwinkel in einen Kniekurbelwinkel um, und warum geschieht das nicht auf dem Pi?
Antworten
  1. Nach 200 ms ohne Befehle halten die Servos die letzte Pose. Nach weiteren 2 s (insgesamt 2,2 s) werden sie kraftlos, die Ausgänge sind aus.
  2. Zwei beliebige von: Der XIAO hat zu wenige freie Pins; der PCA9685 wiederholt die Pulse in Hardware; sein OE-Pin schaltet alle Ausgänge auf einmal ab; er behält die Upstream-Kanalbelegung bei.
  3. Damit serieller Datenverkehr und LCD-Updates die 5-ms-Servo-Deadline nie verzögern können.
  4. Dass Servos angesteuert werden, während der XIAO zurückgesetzt wird oder im Bootloader steht, wenn sein Pin D3 OE nicht aktiv auf High hält.
  5. Die XIAO-Firmware (jointsToActuators in servo_map.cpp). Geschieht dies direkt neben Begrenzung und Pulserzeugung, kann die MCU die Kniekurbelgrenzen selbst durchsetzen, egal was der Pi sendet. Dieselbe Mathematik existiert auch in strido-core für die Simulation.

Weiterführende Literatur ​

MIT-Lizenz. Mechanik abgeleitet von Yertle (Jerome Graves). CAD, Simulation und native Tests sind kein Hardware-Nachweis – siehe Verifikation.