Unitree Go2: Low-Level-Steuerung

Die Low-Level-Steuerung steuert die 12 Gelenkmotoren des Go2 direkt an – mit voller Kontrolle, aber auch deutlich höherem Risiko. Sie richtet sich an erfahrene Entwickler. Dieser Walkthrough erklärt das Regelprinzip und zeigt den Aufbau einer Steuerschleife.

Achtung: Fehlerhafte Werte können zu ruckartigen, gefährlichen Bewegungen führen. Testen Sie ausschließlich mit aufgebocktem bzw. sicher fixiertem Roboter.

Hinweis: Beispielcode ist illustrativ; exakte Feld-/Topic-Namen und die CRC-Berechnung entnehmen Sie dem README des SDK.

Konzept

Der Go2 hat 12 Motoren: vier Beine mit je drei Gelenken (Hüfte, Oberschenkel, Knie). Pro Motor geben Sie Sollwerte vor, die der Motorcontroller per PD-Regelung umsetzt:

  • q – Zielposition (rad)
  • dq – Zielgeschwindigkeit (rad/s)
  • kp – Steifigkeit (Positionsverstärkung)
  • kd – Dämpfung (Geschwindigkeitsverstärkung)
  • tau – Vorsteuer-Drehmoment (Nm)

Das resultierende Drehmoment ergibt sich näherungsweise als: tau_out = kp * (q - q_ist) + kd * (dq - dq_ist) + tau. Kleine kp/kd ergeben weiche, große kp/kd steife Gelenke.

Datenfluss

  • Befehle: Publisher auf Topic rt/lowcmd (Nachricht LowCmd)
  • Zustand: Subscriber auf Topic rt/lowstate (Nachricht LowState mit Ist-Werten je Motor, IMU usw.)

Ablauf der Steuerschleife

  1. DDS-Kanal mit der Netzwerkschnittstelle initialisieren.
  2. Publisher (rt/lowcmd) und Subscriber (rt/lowstate) anlegen.
  3. Aktuellen Zustand aus LowState lesen.
  4. Pro Motor Modus und Sollwerte (q, dq, kp, kd, tau) setzen.
  5. CRC berechnen und Befehl senden – mit fester, hoher Frequenz (z. B. alle 2 ms, also 500 Hz).

Beispiel: Gelenke auf Position halten (C++, Auszug)

// cmd: LowCmd, state: zuletzt empfangener LowState
for (int i = 0; i < 12; ++i) {
    cmd.motor_cmd()[i].mode() = 0x01;          // Servo-/Steuermodus
    cmd.motor_cmd()[i].q()    = target_q[i];   // Zielposition
    cmd.motor_cmd()[i].dq()   = 0.0;
    cmd.motor_cmd()[i].kp()   = 5.0;           // klein beginnen
    cmd.motor_cmd()[i].kd()   = 1.0;
    cmd.motor_cmd()[i].tau()  = 0.0;
}
cmd.crc() = calc_crc(&cmd);   // CRC setzen (Helfer aus dem SDK)
publisher->Write(cmd);        // an rt/lowcmd senden

Eine sinnvolle Startroutine: zunächst die aktuellen Ist-Positionen aus LowState als target_q übernehmen und mit kleinen kp/kd halten – so „klebt“ der Roboter sanft in seiner Pose, bevor Sie Trajektorien fahren.

Praxis-Tipps

  • kp/kd immer klein starten und schrittweise erhöhen.
  • Vor dem ersten Senden den realen Zustand aus LowState einlesen, nie „blind“ befehlen.
  • CRC nicht vergessen – ohne gültige CRC wird der Befehl verworfen.
  • Konstante Schleifenfrequenz einhalten (Echtzeit-nähe), Aussetzer vermeiden.

Weiterführend

Exakte Nachrichtenfelder, Motor-Indizes und CRC-Helfer: offizielle Unitree-Doku und das unitree_sdk2-Repository (Ordner mit Low-Level-Beispielen).