5.9 20 Hz 폐루프 추론

20 Hz 폐루프와 비동기 추론

그림 5-3. sensor/control loop와 policy worker를 분리하고 action queue, safety filter, watchdog을 거치는 폐루프.

5.9.1 주기와 deadline

20 Hz의 period는 50 ms다. 한 cycle의 예산은 capture, preprocessing, inference/queue, safety filter, communication을 포함한다.

Tcapture+Tpre+Tinfer+Tsafety+Tcomm≤50 ms T_{capture}+T_{pre}+T_{infer}+T_{safety}+T_{comm} \le 50\text{ ms}

VLA inference가 50 ms를 넘으면 매 cycle 동기 추론은 deadline을 놓친다. 대안은 다음과 같다.

  • action chunk를 queue에 넣고 control loop가 소비한다.
  • policy worker를 별 thread/process/machine에 둔다.
  • execution horizon이 소진되기 전에 다음 chunk를 요청한다.
  • inference가 늦으면 이전 안전 action을 유지하거나 정지한다.

LeRobot은 Asynchronous Inference와 RTC 방식 안내를 제공한다. 사용 API는 버전에 따라 달라질 수 있으므로 개념과 실제 CLI를 구분한다.

5.9.2 receding horizon

chunk 전체를 끝까지 open-loop로 실행하지 않고 첫 hh개만 실행한 뒤 새 관측으로 재계획한다. h=1h=1이면 가장 폐루프적이지만 inference rate가 높다. latency와 환경 변화 속도에 맞춰 execution horizon을 정한다.

5.9.3 temporal ensembling

시점 t−jt-j에서 예측한 chunk가 현재 step tt의 action도 포함할 수 있다. 여러 예측을 가중 평균한다.

aˉt=∑jwja^t(t−j)∑jwj,wj=exp⁡(−λj) \bar a_t = \frac{\sum_j w_j \hat a_t^{(t-j)}}{\sum_j w_j}, \qquad w_j=\exp(-\lambda j)

code/temporal_ensemble.py가 이를 구현한다. 평균은 discontinuity를 줄일 수 있지만 multimodal 행동의 서로 다른 mode를 섞으면 위험한 중간 행동을 만들 수 있다. grasp 전환점처럼 mode switch가 있는 구간은 history를 reset하거나 phase-aware ensemble을 사용한다.

후보를 무조건 평균하지 않는다. 각 proposal에 schema, unit, finite, source timestamp, task/phase, 기본 hard limit 검사를 먼저 적용하고 stale/invalid proposal을 버린다. 유효 후보만 ensemble/filter한 뒤 최종 결과에 rate, joint/workspace, collision 검사를 다시 적용한다.

5.9.4 safety filter와 watchdog

모델 출력은 곧바로 motor command가 아니다. 최소한 다음 단계를 거친다.

  1. inverse normalization
  2. NaN/Inf 검사
  3. joint/workspace limit clamp 또는 reject
  4. velocity/acceleration/jerk limit
  5. self/environment collision check
  6. timestamp freshness 확인
  7. watchdog heartbeat
  8. command 전송

code/closed_loop_20hz.py는 hardware-free mock loop로 joint limit과 per-cycle delta limit을 보여 준다. 실제 안전 정지는 software exception 하나에 의존하지 않고 hardware E-stop과 독립 watchdog을 둔다.

잠깐 점검 — 부드러운 출력과 안전한 출력은 같은가

  1. Temporal ensembling으로 행동이 매끄러워졌다면 관절 한계 검사를 생략해도 되는가?
  2. 값과 단위가 올바른 action이라도 source timestamp가 오래되었다면 왜 실행하면 안 되는가?

확인 포인트: 평균화는 불연속을 줄일 뿐 물리 한계를 보장하지 않는다. 오래된 action은 현재 관측과 상태를 반영하지 않으므로 폐기하거나 HOLD로 전환해야 한다.

5.9.5 최신 LeRobot 배포 backend

2026년 공식 LeRobot 배포 인터페이스는 동기 실행, local RTC(Real-Time Chunking), remote inference를 구분한다.

  • Sync: control tick마다 policy call을 기다린다.
  • Local RTC: rollout process의 background thread가 다음 chunk를 만들며 현재 trajectory와 이어지는 action을 준비한다.
  • Remote inference: 별 process/host의 policy server와 통신하고 robot client가 bounded action buffer를 소비한다.

RTC의 execution_horizon, observation age, action/startup timeout, starvation grace는 실측 latency와 usable chunk horizon 안에서 정한다. queue가 비었다고 마지막 action을 무기한 유지하지 않는다. task instruction이 바뀌면 이전 instruction의 queued/in-flight action을 폐기하고 fresh observation으로 재계획한다. 최신 flag와 지원 checkpoint 계약은 Policy Deployment, Real-Time Chunking, Remote Inference를 따른다. 이전 async server/client tutorial의 actions_per_chunk, chunk_size_threshold와 최신 local RTC flag를 섞지 않는다.

이 장의 예제 코드·설정 파일 (5)

이 장의 자가 점검·가상실습