이번 단계 목표: 학습 버튼을 누르기 전에, 내장 환경
Isaac-Velocity-Flat-G1-v0가 정확히 뭘로 이루어져 있는지 해부해서 시즌 1에서 우리가 손으로 짰던 환경과 항목별로 대조합니다. 그리고 이 표만 보고 학습 결과를 미리 예측해 둡니다. 맞는지는 05~06편에서 확인합니다.
해부 도구
Isaac Lab의 manager는 print(env.reward_manager)만 해도 표를 그려 줍니다. 이걸 이용해 환경을 실제로 띄우고 구성 전체를 덤프하는 스크립트를 만들었습니다.
python -u scripts/04_dissect_env.py --headless # flat
python -u scripts/04_dissect_env.py --headless --task Isaac-Velocity-Rough-G1-v0 # rough
전체 덤프는 outputs/04_env_anatomy_*.txt에 남습니다. 아래는 그 요약이에요.
한눈 비교 — 시즌 1의 손코딩 vs 내장 환경
| 항목 | 시즌 1 (Genesis) | Isaac flat G1 | 메모 |
|---|---|---|---|
| 제어 주기 | 50Hz | 50Hz (dt 0.005 × decimation 4) | 동일 — 비교하기 좋습니다 |
| 에피소드 | 20초 | 20초 | 동일 (우연이 아니라 이 분야 표준) |
| 관측 차원 | 45 | 123 | 아래 상세 |
| 액션 차원 | 12 (다리만) | 37 (전 관절, 손가락 포함) | 가장 큰 철학 차이 |
| 명령 재샘플 | 4초 | 10초 | |
| 관측 노이즈 | 없음 | 내장 (항목별 균일 노이즈) | 시즌 1 로드맵의 숙제가 여기선 기본값 |
| 학습 알고리즘 | RSL-RL PPO | RSL-RL PPO | 같은 계열 — 공정 비교 가능 |
관측 대조 — 123차원의 정체
| 항목 | 시즌 1 | Isaac | 메모 |
|---|---|---|---|
| 몸통 선속도 | 없음 | 3 | 시즌 1은 일부러 뺐던 항목 (실기에서 추정이 어려움) |
| 몸통 각속도 | 3 | 3 | |
| 중력 투영(기울기) | 3 | 3 | |
| 명령 (vx·vy·ωz) | 3 | 3 | |
| 관절 위치/속도 | 12+12 | 37+37 | 관절 수 차이 그대로 |
| 직전 액션 | 12 | 37 | |
| 위상 클록 (sin/cos) | 2 | 없음 | 내장 환경엔 걸음 박자 개념이 없습니다 |
| 합계 | 45(+2) | 123 | rough판은 높이맵 187을 더해 310 |
관전 포인트가 둘입니다. 첫째, Isaac은 모든 관측에 노이즈를 섞습니다(관절속도 ±1.5 같은 식). 시즌 1에서 “sim-to-real 준비물”로 미뤄 뒀던 것이 여기서는 기본값이에요.
둘째, 위상 클록이 없습니다. 시즌 1의 10편에서 셔플 걸음을 고치는 열쇠였던 그 장치가 내장 환경에는 없습니다. 그럼 걸음 품질은 뭐가 지킬까요? 보상에서 확인합니다.
보상 대조 — 16개 항목
| # | 항목 | 가중치 | 시즌 1의 대응물 |
|---|---|---|---|
| 0 | track_lin_vel_xy_exp | 1.0 | tracking_lin_vel 1.0 — 같은 지수형, 같은 가중치 |
| 1 | track_ang_vel_z_exp | 1.0 | tracking_ang_vel 0.5 |
| 2 | lin_vel_z_l2 | −0.2 | lin_vel_z −1.0 |
| 3 | ang_vel_xy_l2 | −0.05 | ang_vel_xy −0.05 — 동일 |
| 4 | dof_torques_l2 | −2e-6 | 토크 벌점 (우리는 −2e-4·다리만) |
| 5 | dof_acc_l2 | −1e-7 | 없음 |
| 6 | action_rate_l2 | −0.005 | action_rate −0.005 — 동일 |
| 7 | feet_air_time | +0.75 | 걸음 채점과 같은 목적, 다른 수단 |
| 8 | flat_orientation_l2 | −1.0 | orientation −2.0 |
| 9 | dof_pos_limits (발목) | −1.0 | 없음 |
| 10 | termination_penalty | −200 | 없음 — 넘어지면 그냥 리셋이었음 |
| 11 | feet_slide | −0.1 | 미끄럼 금지 채점과 동일 목적 |
| 12~15 | joint_deviation (엉덩이·팔·손가락·허리) | −0.1/−0.05 | similar_to_default −0.1 |
읽어낼 것 네 가지입니다.
- 시즌 1에서 우리가 ‘발명’했던 걸음 채점이 여기 이미 있습니다.
feet_air_time(공중 체류 보상)과feet_slide(접지 미끄럼 벌점)이 그것이죠. 다만 우리의 위상 클록 (박자 강제) 방식과 달리, 여기는 “체공 시간이 0.4초에 가깝게”라는 통계적 방식입니다. - termination_penalty −200. 넘어짐 자체에 큰 벌점입니다. 시즌 1은 에피소드가 끊기는 것 자체가 벌이었는데(보상 흐름 중단) 여기는 명시적이에요. “일찍 죽어서 벌점을 피하는” 구멍을 막는 표준 처방입니다.
- 몸통 높이 벌점이 없습니다. 시즌 1은 −30으로 키를 강제했는데, 여기는 lin_vel_z + flat_orientation으로 간접 유지합니다.
- 대칭 보상에 해당하는 것도 없습니다. 절뚝임을 막는 장치가 없다는 뜻이죠.
학습 전에 적어 두는 예측
위 두 표에서 비어 있는 칸만 모으면 그게 곧 예상 병리 목록이 됩니다. 05~06편에서 대조할 수 있게 지금 적어 둡니다.
- 박자(빈도)를 채점하는 항목이 없다 → 빈도가 극단으로 갈 것 (잰걸음 또는 셔플)
- 좌우 대칭을 채점하는 항목이 없다 → 절뚝임이 나올 것
- 발 들림 목표가 없다 → 좌우 들림이 들쭉날쭉할 것
시즌 1의 뼈아픈 교훈이 “채점 안 하는 자유도는 최적화가 마음대로 쓴다”였으니, 그 교훈을 이번엔 학습 전에 적용해 보는 겁니다.
이벤트(랜덤화)와 종료
| 구분 | 시즌 1 | Isaac flat G1 |
|---|---|---|
| 스폰 랜덤화 | 위치·자세 | 위치 ±0.5m·방향 ±180° (관절은 기본자세 고정) |
| 마찰 랜덤화 | 없음 | 정지 0.8 / 동 0.6 고정값 배정 |
| 밀치기 | 4초마다 | 꺼져 있음 (베이스엔 있으나 G1 설정이 비활성화) |
| 질량 랜덤화 | 없음 | 꺼져 있음 |
| 종료 조건 | 기울기 40° 또는 키 0.5m 미만 | 몸통 접촉 + 20초 타임아웃 |
흥미로운 발견입니다. 4족(Anymal 등) 베이스 환경에는 밀치기·질량 랜덤화가 켜져 있는데, G1 설정은 이것들을 명시적으로 꺼 뒀습니다. 휴머노이드는 그만큼 학습이 예민하다는 방증이고, 시즌 1의 외란 회복이 여기서는 아직 숙제라는 뜻이기도 합니다.
종료도 철학이 다릅니다. 시즌 1은 “자세가 무너지면”, 여기는 “몸통이 땅에 닿으면”입니다. 접촉 판정은 넘어지기 직전까지 회복 기회를 주는, 더 관대한 기준이에요.
PPO 하이퍼파라미터 — 거의 같은 값
| 항목 | 시즌 1 | Isaac flat G1 |
|---|---|---|
| clip / desired_kl / γ / λ | 0.2 / 0.01 / 0.99 / 0.95 | 동일 |
| learning rate | 1e-3 (adaptive) | 동일 |
| entropy | 0.01 | 0.008 |
| 네트워크 | MLP [512,256,128] | MLP [256,128,128] |
| rollout 길이 | 24 | 24 |
PPO는 사실상 같은 물건입니다. 그러니 05편에서 학습 결과가 다르다면 그건 알고리즘이 아니라 환경 설계(관측·보상·랜덤화)와 엔진의 차이예요. 이 시리즈가 보고 싶은 게 바로 그겁니다.
개념 박스 — 37관절 전부를 정책에게 시즌 1은 다리 12관절로 시작해 14편에서야 팔 6관절을 조심스럽게 열었고, 그때 “상체를 열면 다리 학습이 무너질 수 있다”는 걱정을 했습니다. 내장 환경은 처음부터 손가락까지 37관절 전부를 정책에 줍니다. 대신 joint_deviation 벌점으로 “쓸 필요 없는 관절은 기본자세 근처에”라는 압력을 걸어 둬요. 이 벌점이 팔 스윙(시즌 1이 공짜로 받은 선물)을 죽이는지 살리는지도 관전 포인트입니다.
다음 단계
해부는 끝났습니다. 이제 진짜로 학습 버튼을 누릅니다 → 05. 평지 보행 학습