์๋ฎฌํ PARTS: ์ฐํํ์ ํ ์ธ์ฐ๊ธฐ ์์ฐจ ์กํฐ(MuJoCo)
OpenArm SciEdu ์ฐํํ์ ์คํ์์, ์ค๋ฅธ์์ ์ฅ ์ฒ ํ์ ๋น์ปค์ ๋ฃ๊ธฐ ์ ์ ์์ง์ผ๋ก ์ธ์ฐ๋ ํ ๋จ๊ณ๋ฅผ MuJoCo(๋ฒค์น 2ํ props-4 ์ฅ๋ฉด)์์ ๋ฐฐ์ด ์์ ์์ฐจ ์กํฐ๋ค. ๋ฐํ์ ์ผ๋ฆฐ ์ฝ๋ ๋ฃฐ("๋ณด์ง ์๊ณ ์ธ์ฐ๊ธฐ": ํ์ด ๋ ๊ฐ์ ๊ฐ์ผ๋ก ๋งค๋ฌ๋ฆฐ๋ค๊ณ ๋๊ณ ํ ์๋ ๋์ ์ถ์ผ๋ก ์์ 10ยฐ/s ๋๋ฆผ)์ด๊ณ , ์กํฐ๋ ๊ทธ ์์ ์ค๋ฅธ์ ๊ธฐ์ธ๊ธฐ ๋ ์ถ(์ธ๊ณ xยทy ๋๋ ๋๋ฆผ, ํ ์๋ ๋์ด ์ถ)๋ง ์ถ๋ง๋ค ยฑ5ยฐ ์์์ ๋ํ๋ค. PARTS(Su ์ธ, arXiv 2609.21788)์ ๋ณ๋ชฉ ์์ฐจ RL์ ์ด ํ ๋จ๊ณ๋ก ์ฎ๊ธด ๊ฒ์ด๋ค. ํ์ต์ ์ฒญํฌ ๋จ์ TD3 + BC(์ฐธ์กฐ ๋๋กญ์์ 50%, ์ฐธ์กฐ ์ชฝ ฮฒ, ์ฑ๊ณต ํ ๋ฐ๋ผํ๊ธฐ, ์คํจ ํ 0์ผ๋ก), 50ํ๋ง๋ค ์ฑ๊ณต ๊ฐ์ค ์ฌํ์ต, ์ฒ์ 20ํ์ ๋ฐํ๋ง, ๋ณด์์ ์ฅ๋ฉด ํ์ ์ ํฌ์ 1/0์ด๋ค. ๋ก๋ดยท์ค๋ฌผ ๋ฐ์ดํฐ๋ ์ฐ์ง ์์๋ค.
์๋ฎฌ ์ ์ฉ. sim_* ํ์ ์๋ฎฌ์ ํ ์์ธ(ํ ๊ธด ์ถ์ ์ธ๊ณ xยทy)๋ฅผ ๊ด์ธก์ผ๋ก ์ฝ๋๋ค. ์ค๋ฌผ์๋ ํ ์์ธ ์ผ์๊ฐ ์์ด ๊ทธ๋๋ก ์ฎ๊ธฐ์ง ๋ชปํ๋ค.
proprio_* ํ์ ์ค๋ฌผ ์๋น์์๋ ์ป๋ ๊ฐ(์ค๋ฅธํ ๊ด์ 7, ์ ๋ช
๋ น โ ์ฝ๊ธฐ 7, ๋ฐํ์ด ๋จ๊ธด ๋๋ฆผ 3, ์ง๊ธ ์์ฐจ 2, ๋จ๊ณ ์๊ฐ 1)๋ง ์ฝ๋๋ค.
๊ฒฐ๊ณผ(ํ๊ฐ ์์ 20๊ฐ, ์กํฐ ํ๊ท ํ๋, 2026-11-06)
๊ฐ์ ํ๊ฐ ์์ 20๊ฐ(์์ ํ์ผ redox_dipยทredox_put_left๋ง๋ค ์ฒ์ 10)์์ ์์ฐจ ๋ 20ํยท์ผฌ 20ํ. ํ์ ์ ํ ๊ธด ์ถ 2ยฐ ์, ์ฅ , ํ ์๋ ๋ 2 cm ์ยทํ
๋๋ฆฌ ์,
๋น์ปค ๊ท์น, ํ ๋ฉ์ถค์ด 0.5์ด(์ํ 6์ด). ๋๊ดํธ๋ Wilson 95% ๊ตฌ๊ฐ(%).
| ํ | ์์ฐจ ๋(๋ฐํ ๋ฃฐ) | ์์ฐจ ์ผฌ | ํ์ต ํ | ์๋ฎฌ ํฑ(30 Hz) | ๋ฒฝ์๊ณ ๋ถ(CPU ๋ ์ค๋ ๋) |
|---|---|---|---|---|---|
proprio_s0 |
2/20 [3, 30] | 3/20 [5, 36] | 820 | 142,711 | 23.2 |
proprio_s1 |
2/20 [3, 30] | 7/20 [18, 57] | 420 | 72,893 | 11.4 |
proprio_s2 |
2/20 [3, 30] | 8/20 [22, 61] | 420 | 72,852 | 12.0 |
sim_s0 |
2/20 [3, 30] | 19/20 [76, 99] | 820 | 129,589 | 20.7 |
sim_s1 |
2/20 [3, 30] | 19/20 [76, 99] | 820 | 132,095 | 20.9 |
sim_s2 |
2/20 [3, 30] | 16/20 [58, 92] | 820 | 128,786 | 19.7 |
sim์จ์ 3๊ฐ ํฉ: ์์ฐจ ์ผฌ 54/60 [80, 95] (์จ์๋ณ [19, 19, 16]/20)proprio์จ์ 3๊ฐ ํฉ: ์์ฐจ ์ผฌ 18/60 [20, 43] (์จ์๋ณ [3, 7, 8]/20)
ํ์ต ํ ์๋ ๋ฐํ๋ง 20ํ์ ๋ฃ์ ์๋ค. ๊ด์ ๋ง ๋ณด๋ ๋ง์ ์จ์ 1ยท2๋ 400ํ(+20)์ผ๋ก ์ค์๋ค: ์จ์ 0์ 800ํ ๊ณก์ ์ด 400ํ ๋ค์๋ 2~5/20์์
ํํํ๊ธฐ ๋๋ฌธ์ด๋ค(์ฝ๋๋ค์ดํฐ ํ๋ฝ, 2026-11-06). sim_s0_400ep๋ ๊ฐ์ ์จ์ 0์ 400ํ์์ ๋ฉ์ถ ์ ํ์ผ๋ก, 800ํ ํ์ ๊ณก์ ๊ณผ 420ํ๊น์ง ๊ฐ๋ค(๊ฒฐ์ ์ ์ฌํ ํ์ธ).
๊ฐ์ ์์์ ๋ฃฐ: ๋ณด์ง ์๊ณ ์ธ์ฐ๊ธฐ 2/20 [3, 30], ํ์ ํ ๋ฒ ๋ณด๊ณ 11/20 [34, 74], ํ์ ๋ค์ ๋ณด๋ฉฐ ๊ณ ์น๊ธฐ 20/20 [84, 100] (๋ค ๋์ ์๋ฎฌ ํ ์์ธ๋ฅผ ์ฝ๋ ์์ ).
์ฐ๋ ๋ฒ
from huggingface_hub import hf_hub_download
import json, numpy as np
from safetensors.numpy import load_file
d = "sim_s0"
w = load_file(hf_hub_download("leapshared/sciedu_sim_parts_redox_upright", f"{d}/actor.safetensors"))
cfg = json.load(open(hf_hub_download("leapshared/sciedu_sim_parts_redox_upright", f"{d}/config.json")))
layers = [(w[f"actor.{i}.weight"], w[f"actor.{i}.bias"]) for i in (0, 2, 4)]
def act(obs): # obs: cfg["obs_dim"] floats (code/parts_upright.py features)
x = np.asarray(obs, np.float64)
for j, (W, b) in enumerate(layers):
x = W @ x + b
x = np.maximum(x, 0) if j < 2 else x
return np.tanh(x) * cfg["limit_deg"] # degrees about world x and world y, cut to +-5
๊ด์ธก์ ๊ผดยท์์ฐจ๋ฅผ ์๋ ๋ชฉํ์ ๋ํ๋ ๋ฒยทํ์ ์ code/parts_upright.py์ code/upright_bench.py(์ ์ฅ์ scripts/sim/, ์ปค๋ฐ 7b190796)์ ์๋ค.
๋ฐ์ ์์์ code/accepted.json, ๋ฐํ ๋ฃฐ์ด ์ฐ๋ ์ ์ ํ ์์ธ๋ code/taught.json์ด๋ค. ํ๋ง๋ค log.jsonl(ํ์ต ํ๋ง๋ค์ ๊ฒฐ๊ณผ์ ํ์ต ๊ณก์ ),
eval.jsonl(ํ๊ฐ 40ํ)์ด ์๋ค.
ํ๊ณ
- ์๋ฎฌ(MuJoCo props-4)์์๋ง ๋ฐฐ์ฐ๊ณ ์๋ค. ํ ์์ธ ๊ด์ธก(
sim_*), ์ ์์์ ํ์ด ๋งค๋ฌ๋ฆฌ๊ณ ๋ฏธ๋๋ฌ์ง๋ ๋ชจ์, ํ๋ก์ ๋ชจํ์ ์ค๋ฌผ๊ณผ ๋ค๋ฅผ ์ ์๋ค. - ๋ฐํ์ ์ฝ๋ ๋ฃฐ์ด๋ค. ์ค๊ธฐ ์๋น์ ๋ฐํ(pi0.5) ์์ ํ์ ์์ง ์๋ค.
- ์ค๋ฌผ์ ์ฐ๋ ค๋ฉด ์ค๊ธฐ ์์ ๊ฒํ ์ ํ ์ถ์ ์ฌ๋ ์ธ์์ด ๋จผ์ ๋ค.