Mandar un objetivo a 29 motores es fácil; lo difícil es lo que pasa cuando el objetivo está lejos, fuera del límite o deja de llegar. En esta lección comandas el G1 suspendido con tres protecciones (límite del MJCF, rampa y watchdog) y ves, en el mismo script, cómo el escalón pide más torque del que tiene el motor.
3Watchdog: un comando viejo se vuelve amortiguación
4CRC y mode_machine, que el robot real exige
Objetivo: comandar las 29 articulaciones del G1 con límite, rampa y watchdog, y ver cómo el comando en escalón pide torque por encima del límite.
01 · Tres protecciones entre la policy y el motor
Haz clic en cada bloque.
Haz clic en cada bloque del diagrama para ver qué hace.
El watchdog del kit es tuyo, en tu controlador. Lo que el firmware del robot hace sin comando no está documentado en el SDK: no cuentes con eso. Y corre en el mismo proceso del envío: si el proceso muere, lo que sostiene al robot es la parada de emergencia física y el pórtico.
02 · Qué lleva un comando
Haz clic en cada parte.
1. MotorCmd_
mode (1 habilita, 0 deshabilita), q (objetivo), dq (velocidad objetivo), tau (torque sumado), kp y kd. No hay Ki ni un modo global de "posición" o "torque".
Rígido = kp alto; solo torque = kp y kd en cero y tau completado; amortiguación = kp en cero y kd pequeño.
Ganancias del ejemplo oficialPiernas 60/60/60/100/40/40, cintura 60/40/40, brazos 40; kd 1 (rodilla 2). Punto de partida del ejemplo, no "estándar del robot".
2. Encabezado
mode_pr = 0 (PR: pitch/roll en serie), mode_machine copiado del primer LowState_, y crc = CRC().Crc(cmd) antes de publicar.
El simulador Python no verifica el CRC y envía mode_machine = 0; el kit completa ambos de todos modos, como el ejemplo oficial, para que el código sea igual al del robot.
3. Lazo de 2 ms
El ejemplo oficial del G1 envía cada 2 ms (control_dt_ = 0,002). La política puede ser más lenta (50 Hz): el lazo rápido reenvía el último objetivo con los límites.
En ese lazo vive el watchdog: ve cuándo el objetivo envejece.
03 · Rampa, límites y watchdog en el G1 suspendido
6 s de comando: rampa de 3 s hasta la pose de trabajo (rodillas y codos doblados), se mantiene, y en t = 4,5 s la "política" se traba a propósito.
idade = t_ciclo - comp["carimbo"]
if not amortecendo and idade > IDADE_MAX:
amortecendo = True
print(f"política sem resposta desde t = {a.trava_em:.1f} s")
print(f"watchdog: comando velho há mais de {IDADE_MAX * 1000:.0f} ms → amortecimento ativado (kp=0, kd={KD_AMORTECER:g})")
cmd.mode_pr, cmd.mode_machine = 0, modo
for i in range(op.N):
m_ = cmd.motor_cmd[i]
m_.mode, m_.dq, m_.tau = 1, 0.0, 0.0
if amortecendo:
m_.q, m_.kp, m_.kd = 0.0, 0.0, KD_AMORTECER
else:
m_.q, m_.kp, m_.kd = comp["alvo"][i], op.KP[i], op.KD[i]
simulador: G1 29 motores · DDS domínio 1 em lo · 9 s · suspenso: sim
estado recebido: 29 juntas · pose inicial lida · mode_machine = 0
limites: 29/29 alvos já dentro da faixa do MJCF (margem 0.05 rad), 0 recortados
política sem resposta desde t = 4.5 s
watchdog: comando velho há mais de 100 ms → amortecimento ativado (kp=0, kd=2)
rampa de 3 s · todas as juntas pediram menos de 50 % do torque máximo
juntas que pediram acima do limite: 0
ciclo de envio: 2 ms · watchdog: amortecimento ativado
saída: 0
simulador: fim em t = 9.0 s · robô suspenso (pés fora do chão)
Con rampa, todas las articulaciones quedan por debajo de la mitad del tope. La política se traba, el watchdog ve envejecer el comando y amortigua.
simulador: G1 29 motores · DDS domínio 1 em lo · 9 s · suspenso: sim
estado recebido: 29 juntas · pose inicial lida · mode_machine = 0
limites: 29/29 alvos já dentro da faixa do MJCF (margem 0.05 rad), 0 recortados
política sem resposta desde t = 4.5 s
watchdog: comando velho há mais de 100 ms → amortecimento ativado (kp=0, kd=2)
degrau · junta mais perto do limite: left_wrist_pitch (9 de 5 N·m, ≈ 170 %)
juntas que pediram acima do limite: 4
ciclo de envio: 2 ms · watchdog: amortecimento ativado
saída: 1
simulador: fim em t = 9.0 s · robô suspenso (pés fora do chão)
El mismo objetivo de golpe: cuatro articulaciones piden por encima del tope, y la muñeca pide casi el doble de lo que tiene. En el robot real eso es un tirón y un motor saturado; el script sale con código 1.
04 · Práctica
Las tres protecciones, medidas.
E1 · Rampa con watchdog
5 min
Ejecuta el bloque de la rampa y ubica en la salida el momento en que actúa el watchdog.
Listo cuando:python3 kit/rampa.py; echo "saída: $?" → juntas que pediram acima do limite: 0, watchdog: amortecimento ativado y saída: 0.
E2 · Ver cómo falla el escalón
5 min
Ejecuta el bloque del error común y di qué articulación pasó más el límite y por qué justo esa.
Listo cuando:python3 kit/rampa.py --sem-rampa; echo "saída: $?" → juntas que pediram acima do limite: 4 y saída: 1.
E3 · Leer el límite en el MJCF
5 min
Encuentra en el MJCF del simulador el tope de torque de la muñeca que se pasó en el escalón.
Listo cuando:grep -c 'ctrlrange="-5 5"' ~/fth/unitree_mujoco/unitree_robots/g1/g1_29dof.xml → 4 (pitch y yaw de las dos muñecas, tope de 5 N·m).
05 · Prueba de la clase
La explicación aparece después de tu respuesta.
Pregunta 1 de 4
¿Qué campo NO existe en un MotorCmd_ del G1?competencia
Correcto
El comando tiene mode, q, dq, tau, kp y kd. No hay término integral: el PID con Ki del curso antiguo no corresponde al SDK.
No es esa
El comando tiene mode, q, dq, tau, kp y kd. No hay término integral: el PID con Ki del curso antiguo no corresponde al SDK.Repasar: Qué lleva un comando
Pregunta 2 de 4
La política dejó de mandar objetivos. ¿Qué hace el watchdog del kit?
Correcto
Un comando viejo es señal de que algo se trabó. Amortiguar es el modo seguro; volver solo escondería la falla.
El simulador no verifica el CRC. ¿Por qué el kit lo rellena igual?
Correcto
El ejemplo oficial calcula CRC().Crc(cmd) y copia el mode_machine. El ensayo en el simulador vale más cuando el código es el mismo que el del robot real.
No es esa
El ejemplo oficial calcula CRC().Crc(cmd) y copia el mode_machine. El ensayo en el simulador vale más cuando el código es el mismo que el del robot real.Repasar: Qué lleva un comando
Prueba completada
Acertaste {a} de {n}. Si aciertas todas, la clase se marca como completada.
Elige una alternativa. La explicación aparece después de tu intento.
06 · En tres frases
LímiteObjetivo recortado al rango del MJCF; torque con tope en el ctrlrange.
RampaDel punto actual al objetivo en segundos, nunca de golpe.
WatchdogUn comando viejo se convierte en amortiguación y no se reactiva solo.