Microduck RL
[IMG:N]
Microduck — 약 800g, 높이 약 25cm의 이족 보행 로봇에 대한 RL(강화학습) 훈련 환경입니다. 본 시스템은 mjlab (MuJoCo Warp)을 기반으로 PPO를 사용하여 구축되었습니다. 정책(Policies)은 여기서 50 Hz로 훈련되어 ONNX로 내보내진 후, pollen-robotics/microduck의 런타임에 실제 로봇에 배포됩니다.
<!-- HERO VIDEO — real robot montage: walking, standup, roulade, roller skating.
Keep it short (~30 s) and real-robot-first: this is the "why should I care" shot. -->
이 저장소는 전체 sim2real 레시피를 인코딩합니다: BAM 액추에이터 물리, 도메인 무작위화(domain randomization), 백래시 시뮬레이션, 그리고 작동하게 만든 보상 설계 교훈들입니다 (정제된 플레이북은 AGENTS.md를 참조하세요).
빠른 시작하기 (Quickstart)
CUDA GPU와 uv가 필요합니다. (훈련은 MuJoCo Warp를 통해 실행됩니다.)
ARM 장치(DGX Spark / GB10, Jetson)의 경우: uv sync는 첫 실행 시 약 2GB의 CUDA wheels를 다운로드하며, uv의 기본 30초 HTTP 타임아웃이 중간에 중단될 수 있습니다. 첫 동기화 시에는 UV_HTTP_TIMEOUT=600을 내보내주세요.
git clone https://github.com/pollen-robotics/microduck_rl
cd microduck_rl
...
체크포인트에서 재개하기:
uv run train Mjlab-Velocity-Flat-MicroDuck --env.scene.num-envs 4096 \
--agent.run-name resume --agent.load-checkpoint model_29999.pt --agent.resume True
GPU가 없나요? 모든 train 명령어에 --hf-jobs를 추가하여 로컬 대신 Hugging Face Jobs에서 실행할 수 있습니다 (참고: scripts/hf/README.md).
작업 목록 (Tasks)
uv run list-envs는 라이브 레지스트리를 출력합니다. 명시된 곳에는 Flat/Rough 변형이 존재합니다.
<!-- SHOWCASE GRID — 작업군별 짧은 GIF 하나씩 (시뮬레이션 또는 실제), 행당 3개. 기록할 수 있는 우선순위 순서: Velocity, VelStand(낙하+회복), Roulade, SitStand, Rollers/Swizzle, BallKick. -->
| Task id | Terrain | Description |
|---|
Mjlab-Velocity-{Flat,Rough}-MicroDuck | flat/rough | 주요 작업: 속도 명령 + 머리 자세(head-pose) 명령을 이용한 걷기 |
| ... | | |
배포 시 런타임은 이러한 정책들(walk / recover / trick)을 공유된 61차원 관측 계약(observation contract) 뒤에서 실시간으로 교체(hot-swaps)할 수 있으므로, 어느 것이든 언제든지 로봇을 제어할 수 있습니다. scripts/infer_policy.py는 정확히 이를 연습합니다:
uv run scripts/infer_policy.py --walking walk.onnx --standing stand.onnx \
--sitstand sitstand.onnx --roulade roulade.onnx --new-cmd-obs
키보드 기반(속도 명령, G 지면 집기(ground pick), Y 앉기/서기(sit/stand), R 룰라드(roulade), K/L 발차기(kicks)); --debug, --save-csv, --record는 sim2real 비교를 지원합니다.
서보 모터는 정책이 학습된 것과 동일한 BAM M6 XL330 모델을 사용하여 시뮬레이션됩니다(전압 제어 + 부하 의존성 마찰, bam.mujoco.MujocoController를 통해). --vin / --vin-drop-gain / --kp-fw는 학습 DR 범위를 하나의 값으로 고정하며, --no-bam은 XML PD 액추에이터로 폴백(fallback)합니다.
백래시 변형 (Backlash variants)
모든 주요 작업에는 14개 서보 관절 각각에 ±1°의 기어 유격(gear play) (총 2°)을 가진 모델에서 학습하는 백래시 쌍둥이(twin)가 있습니다. 작업 ID에서 MicroDuck 앞에 -Backlash를 삽입하면 됩니다. 예: Mjlab-Velocity-Flat-Backlash-MicroDuck.
백래시는 sim2real 환경에 맞게 적절하게 모델링되었습니다: 각 서보에는 구동되지 않는 passive_<joint>_backlash 힌지가 부착되며, 실제 인코더가 백래시(play)의 출력 측에 위치하기 때문에, 펌웨어 PD 에뮬레이션(BacklashEncoderBamActuator)과 joint_pos/joint_vel 관측값 모두 백래시를 '통해' 읽힙니다 (qpos[servo] + qpos[backlash]). 관측 및 액션 차원(Observation and action dims)은 변경되지 않으므로, ONNX 내보내기(export)와 런타임에 수정할 필요가 없습니다. 자세한 내용은 src/mjlab_microduck/tasks/backlash.py를 참조하십시오.
액추에이터 모델 (Actuator model)
모든 태스크는 Dynamixel XL330의 BAM M6 액추에이터 모델을 사용합니다 (전압 제어 법칙(voltage control law), 역기전력(back-EMF), 쿨롱/스트라이벡/부하 의존 마찰(Coulomb/Stribeck/load-dependent friction)). 이 모델은 배터리 전압, 부하 상태에서의 전압 강하(voltage sag under load), 명령 지연(command delay), 그리고 마찰 크기(friction magnitude)에 대한 환경별 도메인 무작위화(domain randomization)를 포함합니다 (src/mjlab_microduck/actuator/의 FrictionDRBamActuator).
이 규모에서 — 약 800g의 이족 보행 로봇을 구동하는 작은 서보들 — 액추에이터 충실도(fidelity)가 sim2real 격차의 가장 큰 원인이므로, 액추에이터는 이상적인 PD 제어기가 아닌 전압 제어 법칙까지 모델링되었습니다.
로봇 모델 (Robot models)
MJCF 모델은 src/mjlab_microduck/robot/microduck/에 위치하며, onshape-to-robot을 사용하여 Onshape에서 내보내집니다. 모델당 하나의 config_mjcf_*.json 파일이 존재합니다:
| XML | 사용처 |
|---|
robot_walk.xml | 속도(Velocity) (몸통/머리 접촉 제거 — 넘어지는 것이 저렴함) |
| ... | |
scene*.xml 파일은 로봇들을 바닥과 키프레임(STAND/SIT/FOLD)으로 감싸서 빠르고 쉽게 확인하거나 infer_policy.py에서 사용합니다.
<!-- IMAGE — side-by-side render: walk model vs rollers model (or a collision-geom visualization). One image here makes the model-variant story instant. -->
프로젝트 구조 (Project structure)
src/mjlab_microduck/
├── robot/
│ ├── microduck/ # MJCF 내보내기, 내보내기 설정 파일, 장면(scenes), add_backlash.py
...
알아두면 좋은 규칙들:
- 관측치 레이아웃은 모든 정책에서 공유됩니다 (61차원 액터 obs: 48개 고유감각 정보(proprioception) + 명령어
[twist(3), head_pose(4), body_pose(6)]). 이것이 런타임 정책의 핫 스와핑(hot-swapping)을 가능하게 하는 요소입니다. 명령어 슬롯을 사용하지 않는 환경(Envs)은 해당 값을 제거하는 대신 제로 패딩(zero-pad)합니다.
- 구동되지 않는 관절(Unactuated joints)은 모두
passive_*로 명명됩니다 (롤러 휠, 백래시 힌지 등). 액추에이터(actuators), 관절 관측치 및 자세 보상(pose rewards)은 ^(?!passive_).*를 가진 서보 관절을 선택합니다.
- 도메인 무작위화(Domain-randomization) 토글은 각 환경 설정 파일(env cfg file) 상단에 있는
ENABLE_* 부울 값입니다.
- 관절 레이아웃 (14개의 서보): 0–4 왼쪽 다리(hip_yaw, hip_roll, hip_pitch, knee, ankle), 5–8 목/머리(neck/head)(neck_pitch, head_pitch, head_yaw, head_roll), 9–13 오른쪽 다리.
- 익스포터는 관측치 정규화기(observation normalizer)를 ONNX 그래프에 내장합니다. 항상
scripts/export.py로 생성된 ONNX를 배포해야 하며, 수동으로 변환된 체크포인트(checkpoint)를 사용해서는 안 됩니다. 그렇지 않으면 정책이 런타임 시 정규화되지 않은 관측치를 보게 됩니다.
AGENTS.md는 환경 구축 워크플로우와 프로젝트 전반에 걸쳐 학습된 보상 설계 규칙을 문서화합니다 (이 저장소에서 작업하는 AI 코딩 에이전트도 목표로 합니다).
정책 게시(Publishing a policy)
uv run publish는 로봇의 데몬이 로드하는 형태(observation normalizer가 내장된 하나의 policy.onnx, microduck policy manifest의 스키마 2를 따르는 manifest.json, 그리고 실행 방법을 설명하는 README)로 정책을 Hugging Face Hub에 올립니다. 이후 microduck을 가진 누구나 단 하나의 명령어로 설치할 수 있으며, 데몬 배포가 필요하지 않습니다.
uv run publish --task Mjlab-PoliteBow-Flat-MicroDuck \
--wandb-run-path <entity/project/run_id> --checkpoint 3000 \
...
이후 로봇에서:`
sudo robotctl policy add polite-bow <user>/microduck-polite-bow
sudo robotctl policy add flamingo <user>/microduck-flamingo --hold 5
sudo robotctl policy load walk <user>/microduck-my-walk
...
--kind가 의미하는 바와 각 종류별 요구 사항:
- 에피소드형(episodic) —
--duration-s 동안 실행되며 스스로 서 있는 자세로 돌아옵니다 (발차기, 굴림, 인사하기 등). 버튼을 누르고 있을 때 반복해야 하는 경우 --chain을 추가합니다.
- 영속형(perpetual) — 달리 지시가 내려질 때까지 실행됩니다. 두 가지 형태가 있습니다:
- 보행 패턴(gait) (새로운 걷기 또는 서기):
--slot walk (또는 stand)만 추가하고 다른 것은 아무것도 추가하지 않습니다. 소유자가 robotctl policy load walk <repo>로 설치합니다.
- 유지 자세(held pose) (플라밍고): 데몬이 보행 패턴으로 제어권을 넘기기 전에 유휴 비틀림(
--idle, 기본값 0)을 얼마나 오래 구동할지 --unwind-s를 지정하여, 로봇이 한 발로 놓치지 않도록 합니다. 소유자는 policy add ... --hold <초>로 일회성으로 실행합니다.
무언가를 업로드하기 전에, publish는 그래프가 [1,61] -> [1,14]인지 확인합니다 (51-D 레거시 정책은 메시지와 함께 거부됨). 이는 그럴듯한 입력으로 실행하고 NaN 또는 상수 출력을 거부하며, git과 wandb에서 training 블록(작업, 커밋, 브랜치, 변경 플래그, 실행, 체크포인트)을 채우고, --force 없이 레포지토리의 기존 .onnx를 덮어쓰는 것을 거부합니다. 레포지토리는 비공개로 생성되며, 공개용은 --no-private를 사용하고, 리비전을 태그하려면 --tag v1을 사용합니다.
오직 상수 명령 정책만이 이 방식으로 게시될 수 있습니다. 위상 기반 동작(바닥 집기)과 자세 플래그 앉기↔서기는 데몬 자체에 의해 구동되며, 공식 세트인 pollen-robotics/microduck-policies에 존재합니다.
테스트
uv run --with pytest pytest tests/
CPU 전용 설정 불변 및 보상 함수 회귀 테스트 — 이들은 관절 인덱스 매핑, 보상 부호 규칙, NaN 가드를 고정합니다.
관련 프로젝트
- microduck — Microduck 프로젝트의 홈이며, 내보낸 정책(exported policies)을 실행하는 온보드 런타임(onboard runtime)이 포함되어 있습니다.
- mjlab — 학습 프레임워크입니다 (MuJoCo Warp + rsl_rl).
- BAM — Rhoban에서 제공하는 개선된 액추에이터 모델(actuator models)입니다.
라이선스 (License)
본 저장소의 코드는 Apache License 2.0 하에 라이선스가 부여됩니다. 자세한 내용은 [LICENSE] 파일을 참조하십시오.
3D 모델 파일(src/mjlab_microduck/robot/microduck/assets/ 및 src/mjlab_microduck/robot/xl330_test_bench/assets/의 .stl 메시)은 Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) 하에 라이선스가 부여됩니다. 정확한 범위와 출처 표기(attribution)는 [LICENSE-MODELS.md]를 참조하십시오.