5.9 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을 포함한다.
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로 실행하지 않고 첫 개만 실행한 뒤 새 관측으로 재계획한다. 이면 가장 폐루프적이지만 inference rate가 높다. latency와 환경 변화 속도에 맞춰 execution horizon을 정한다.
5.9.3 temporal ensembling
시점 에서 예측한 chunk가 현재 step 의 action도 포함할 수 있다. 여러 예측을 가중 평균한다.
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가 아니다. 최소한 다음 단계를 거친다.
- inverse normalization
- NaN/Inf 검사
- joint/workspace limit clamp 또는 reject
- velocity/acceleration/jerk limit
- self/environment collision check
- timestamp freshness 확인
- watchdog heartbeat
- command 전송
code/closed_loop_20hz.py는 hardware-free mock loop로 joint limit과 per-cycle delta limit을 보여 준다. 실제 안전 정지는 software exception 하나에 의존하지 않고 hardware E-stop과 독립 watchdog을 둔다.
잠깐 점검 — 부드러운 출력과 안전한 출력은 같은가
- Temporal ensembling으로 행동이 매끄러워졌다면 관절 한계 검사를 생략해도 되는가?
- 값과 단위가 올바른 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를 섞지 않는다.