이번 단계 목표: 12번에서 남긴 두 오차를 청소합니다 — 회전 추종 20% 저하 (대칭 벌점과 회전의 충돌)와 발 들림 4cm(알고 보니 우리 명세의 계산 실수).
발견 1: 발 들림 4cm는 정책 탓이 아니었다
10번부터 스윙 발 목표를 8cm로 줬는데 실측은 늘 4cm 언저리였습니다. 정책이 게으른 걸까요? 서 있는 로봇의 발목 링크 높이를 재 보니 답이 나왔습니다: 0.039m.
우리 보상은 스윙 발의 ‘링크 절대 높이’가 0.08m가 되도록 채점합니다. 그런데 발목 링크는 서 있어도 이미 0.039m에 있으니, 실제 발 들림 목표는 0.08 − 0.039 = 4.1cm였던 겁니다. 실측 3.5~4.4cm — 정책은 우리가 준 목표를 정확히 달성하고 있었습니다. 잘못된 건 명세를 쓴 우리 쪽이었죠. R01의 교훈에 한 항목을 추가해야 합니다: 보상이 이상하게 달성될 때, 정책을 의심하기 전에 명세의 산수부터 검산하라.
교정: 목표를 0.039 + 0.08 ≈ 0.12로 상향.
발견 2의 처방: 회전할 때는 대칭을 묻지 않는다
12번의 회전 저하는 대칭 벌점이 회전(본질적 비대칭 동작)까지 벌줬기 때문이었습니다. 처방은 명령 조건부 대칭(command-gated symmetry): 회전 명령이 클수록 대칭 벌점을 줄입니다.
turn_gate = clamp(1 - |회전 명령| / 0.5, min=0) # 직진이면 1, 0.5rad/s 회전이면 0
대칭_벌점 *= turn_gate
“직진할 땐 절뚝이지 마라, 돌 때는 다리를 다르게 써도 된다” — 채점 항목에 조건을 달아 두 요구가 싸우지 않게 하는 겁니다.
cd scripts/train
python g1_train.py --task sym -e g1-sym2 --max_iterations 3000
결과
| 지표 | 12 sym | 13 sym2 | 목표 |
|---|---|---|---|
| 발 들림 (왼/오른) | 3.5 / 4.4cm | 7.9 / 8.0cm | 8cm 정확 달성 |
| 회전 추종 (좌/우) | +92° / −97° | +102° / −99° | ±115° 부분 개선 |
| 무릎 대칭 | −5~40° / −5~39° | −6~52° / −6~53° | 유지 (발을 더 드니 가동범위도 커짐) |
| 걸음 빈도/보폭/발 간격 | 1.25Hz / 30cm / 16cm | 1.25Hz / 29cm / 13cm | 유지 |
| 밀치기 4회 | 4/4 | 4/4 (기울기 6~19°) | 유지 |
- 발 들림은 명세를 고치자 한 번에 풀렸습니다. 목표를 0.12(실제 들림 8cm)로 바꾸니 실측 7.9~8.1cm — 오차 1mm. 역시 정책은 늘 시키는 것을 정확히 하고 있었습니다.
- 회전은 절반쯤 회복됐습니다(저하 20%→12%). 게이트가 열리는 회전 구간에도 ‘직진 구간과 이어지는 관성’이 있는 데다, 스윙 발을 8cm씩 드는 더 조심스러운 걸음이 회전을 둔하게 만드는 면도 있습니다. gaitpush 수준(오차 3°)까지 되돌리려면 게이트를 더 일찍(0.3rad/s부터) 열거나 회전 추종 보상을 키워 한 번 더 학습을 돌려야 합니다 — 남은 오차는 기록하고 여기서 멈춥니다.

전체 영상:
회고
- 명세의 산수를 검산하라. 발 들림 4cm를 두 단계 동안 ‘정책의 한계’로 여겼는데, 실은 좌표 기준(링크 절대 높이 vs 실제 들림)을 헷갈린 우리 계산 실수였습니다. 보상이 이상하게 달성되면 정책보다 명세부터 의심할 것.
- 조건부 채점은 통하지만 공짜는 아니다. 회전 게이트로 두 항목의 충돌은 줄였지만 완전히 없애지는 못했습니다. 채점 항목이 16개쯤 되면 항목 간 상호작용 자체가 튜닝 대상이 됩니다 — 모방학습(R01의 대응책 ③)이 왜 매력적인지 체감하게 되는 대목입니다.
다음: 14. 팔 스윙 — 상체를 정책에게 넘긴다.
이 시리즈의 전체 글 목록 → 시리즈 목차