RL ํ•™์Šต โ€” Isaac Lab์—์„œ mechadog ์ •์ฑ… ๋งŒ๋“ค๊ธฐ

PC(x86_64, NVIDIA RTX 3070+ ๊ถŒ์žฅ)์—์„œ ์‹œ๋ฎฌ๋ ˆ์ด์…˜์œผ๋กœ PPO ์ •์ฑ…์„ ํ•™์Šตํ•œ ๋’ค ONNX๋กœ exportํ•ฉ๋‹ˆ๋‹ค. ํ•™์Šต๋œ ์ •์ฑ…์€ Rock 5C์˜ RKNN/CPU์—์„œ ์ง์ ‘ ๋ฐฐํฌ๋ฉ๋‹ˆ๋‹ค.

ํŠœํ† ๋ฆฌ์–ผ ๊ถŒ์žฅ ๊ฒฝ๋กœ โ€” ๊ณต์‹ Isaac Lab ์ง„์ž…์  [isaac-sim/IsaacLab GitHub](https://github.com/isaac-sim/IsaacLab)์™€ [Lab-of-AI-and-Robotics/IsaacLab-Tutorial](https://github.com/Lab-of-AI-and-Robotics/IsaacLab-Tutorial)๋ฅผ ๋จผ์ € ํ•œ๋ฒˆ ํ†ต๊ณผํ•œ ๋‹ค์Œ, ๋ณธ mechadog URDF๋กœ ๊ต์ฒดํ•˜๋Š” ์ˆœ์„œ๊ฐ€ ๊ฐ€์žฅ ๋น ๋ฆ…๋‹ˆ๋‹ค.

1. PC ํ™˜๊ฒฝ ์ค€๋น„

์š”๊ตฌ ์‚ฌ์–‘

ํ•ญ๋ชฉ๊ถŒ์žฅ์ตœ์†Œ
GPUNVIDIA RTX 4080 (16 GB VRAM)RTX 3070 (8GB ยท ๊ถŒ์žฅ์น˜ ๋ฏธ๋งŒ)
RAM64 GB32 GB
๋””์Šคํฌ500 GB NVMe SSD200 GB
OSUbuntu 22.04 LTSWSL2 Ubuntu 22.04 (์„ฑ๋Šฅ โ†“50%)

์„ค์น˜

# 1. CUDA(๋“œ๋ผ์ด๋ฒ„ยทtoolkit) โ€” host system์— ๋งž๊ฒŒ ์„ค์น˜ ํ›„
# 2. Isaac Sim 5.x via Omniverse Launcher (https://docs.isaacsim.omniverse.nvidia.com/5.1.0/installation/requirements.html)
# 3. Isaac Lab Git Clone
git clone https://github.com/isaac-sim/IsaacLab.git
cd IsaacLab
./docker/container.sh  # ๋˜๋Š” ์ง์ ‘ install
pip install -e .
pip install rsl-rl-lib==2.3.0  # PPO + Student-Teacher Distillation

2. mechadog์šฉ 12 DOF URDF ์ค€๋น„

๊ธฐ๋ณธ์ ์œผ๋กœ ODRI Solo12 12dof v1์˜ URDF๋ฅผ ์ถœ๋ฐœ์ ์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. URDF๋Š” ๋‹ค์Œ์„ ๋งŒ์กฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:

# Solo12 12dof URDF ๋ณต์‚ฌ ํ›„ ์ˆ˜์ •
mkdir -p mechadog_description/urdf
cp /path/to/solo_12dof_v1.urdf mechadog_description/urdf/mechadog.urdf

# effort limit ๋ณ€๊ฒฝ (ํ…์ŠคํŠธ ํ•œ ์ค„ sed)
sed -i 's/effort="[0-9]\+\.[0-9]\+"/effort="0.180"/g' mechadog_description/urdf/mechadog.urdf
sed -i 's/effort="[0-9]\+\.[0-9]\+"/effort="0.180"/g' mechadog.urdf

3. Isaac Lab ํ™˜๊ฒฝ ์ •์˜

๋ณธ mechadog ํ”„๋กœ์ ํŠธ๋Š” ๋ชจ๋“  ํ™˜๊ฒฝ ์ •์˜ setup์—์„œ leggedrobotics/legged_gym ํŒจํ„ด์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

# file: mechadog_lab/envs/mechadog/mechadog_env_cfg.py
from isaaclab.envs import ManagerBasedRLEnvCfg
from isaaclab.managers import ObservationGroupCfg, ObservationTermCfg
from isaaclab.assets import ArticulationCfg
from isaaclab.utils.assets import ISAACLAB_NUCLEUS_DIR
import isaaclab.sim as sim_utils
from isaaclab_tasks.manager_based.locomotion.velocity import mdp
from dataclasses import MISSING

MECHADOG_USD = "mechadog/usd/mechadog.usd"   # URDF โ†’ Isaac Sim Import ์ถœ์ฒ˜

@configclass
class MechadogRoughEnvCfg(ManagerBasedRLEnvCfg):
    scene = SceneCfg(num_envs=4096, env_spacing=2.5)
    robot = ArticulationCfg(
        prim_path="{ENV_REGEX_NS}/Robot",
        spawn=sim_utils.UsdFileCfg(usd_path=MECHADOG_USD),
        actuators={leg_joint: ImplicitActuatorCfg(joint_names_expr=[...], effort_limit=0.18, stiffness=20.0, damping=0.5)},
    )
    commands = UniformVelocityCommandCfg(sampling_range=(-1.0,1.0), rel_standing_envs=0.1)
    rewards = RewardsCfg()    # r_track_lin, r_track_ang, r_torque, r_action_rate, r_orientation, r_alive
    observations = ObservationsCfg()  # 48-dim obs: base state (9) + cmd (3) + joint pos (12) + joint vel (12) + last action (12)
    terminations = TerminationsCfg()  # base contact terminate, time out 20s

    decimation = 4   # 200 Hz decision, 50 Hz control
    sim_dt = 0.005

4. PPO ํ•™์Šต launch (rsl_rl)

python scripts/reinforcement_learning/rsl_rl/train.py \
    --task Isaac-Mechadog-Velocity-Rough-v0 \
    --num_envs 4096 \
    --headless \
    --max_iterations 2000 \
    --run_name mechadog_walk_v26p06

RTX 4080 ๊ธฐ์ค€ ~15-25๋ถ„(iter 1000ํšŒ) ๋‚ด์™ธ. ๋„๋ฉ”์ธ ๋žœ๋คํ™” ๊ฐ•๋„์— ๋”ฐ๋ผ 1k~3k iter ํ•„์š”.

5. ๋ณด์ƒ ํ•จ์ˆ˜ (์š”์ง€)

r_total = w_lin ยท r_track_lin + w_ang ยท r_track_ang - w_tau ยท ฮฃ โ€–ฯ„โ€–ยฒ - w_acc ยท ฮฃ โ€–qฬˆโ€–ยฒ - w_orient ยท โ€–g_xyโ€–ยฒ + w_alive ยท alive_bonus - w_foot ยท โ€–a_foot_xyโ€–ยฒ - w_action_rate ยท โ€–ฮ”aโ€–ยฒ

์ƒ์ˆ˜ ๊ถŒ์žฅ๊ฐ’:

๊ฐ€์ค‘์น˜๊ฐ’ํšจ๊ณผ
w_lin (vx, vy ํŠธ๋ž˜ํ‚น)2.0์ง€์‹œ ์†๋„ ์ถ”์ข…
w_ang (yaw ํŠธ๋ž˜ํ‚น)1.0ํšŒ์ „ ๋ช…๋ น ์ถ”์ข…
w_tau0.0001ํ† ํฌ ์ตœ์†Œํ™”
w_joint_acc0.01๊ด€์ ˆ ๊ฐ€์† ํŽ˜๋„ํ‹ฐ
w_orient0.5์ˆ˜ํ‰ ์ž์„ธ ์œ ์ง€
w_alive0.1์‚ด์•„์žˆ์Œ ๋ณด๋„ˆ์Šค
w_foot0.001๋ฐœ ์Šฌ๋ฆฝยท์ถฉ๊ฒฉ ํก์ˆ˜

6. ๋„๋ฉ”์ธ ๋žœ๋คํ™” (์™ธ๋ถ€ ์ถฉ๊ฒฉ ์ €ํ•ญ ์ž์„ธ ๋ณด์ • ํ•™์Šต)

# file: mechadog_lab/envs/mechadog/randomizers.py
from isaaclab.managers import RandomizationTermCfg as RandTerm
import isaaclab.sim as sim_utils

# ๋ณธ์ฒด์— ๊ฐ€ํ•ด์ง€๋Š” ์ž„ํŽ„์Šค (์™ธ๋ถ€ ์ถฉ๊ฒฉ ๋ชจ์‚ฌ)
@torch.no_grad()
def push_impulse(env, env_ids):
    env_origins = env.scene.env_origins[env_ids]
    # ํž˜ / ํ† ํฌ random per env, ์ ์šฉ 0.5s ๋™์•ˆ 1ํšŒ
    for i, env_id in enumerate(env_ids):
        # base link apply force/torque
        force = torch.tensor(np.random.uniform(-30, 30, 3))
        torque = torch.tensor(np.random.uniform(-5, 5, 3))
        env.robot.set_external_force_and_torque(force, torque, env_id)

# ๋‹ค์Œ reset๋งˆ๋‹ค ๋ณธ์ฒด ์งˆ๋Ÿ‰ ยฑ10%, ๋งˆ์ฐฐ ยฑ25%
@torch.no_grad()
def randomize_mass(env, env_ids):
    rng = np.random.uniform(0.9, 1.1, len(env_ids))
    env.robot.root_physx_view.set_masses(env_ids, env.base_mass * rng)

7. ONNX export & ๊ฒ€์ฆ

python scripts/reinforcement_learning/rsl_rl/play.py \
    --task Isaac-Mechadog-Velocity-Rough-v0 \
    --num_envs 1 \
    --checkpoint /logs/mechadog_walk_v26p06/model_2000.pt \
    --export_onnx /out/policy.onnx

์ƒ์„ฑ๋œ policy.onnx(~90 KB)๋Š” Rock 5C์— ๋ณต์‚ฌ. CPU 50 Hz ์ถ”๋ก  ์‹œ ํ•œ inference ~ 3 ms.

8. ์นด๋ฉ”๋ผ ์ธ์ง€ โ€” ์˜ต์…˜: YOLO-Nano depth ์‚ฌ์ „ ํ•™์Šต

๋ณธ ๊ฒฉ์ฐจ๋Š” ํ•™์Šต ์‹œ๋ฎฌ์˜ ์นด๋ฉ”๋ผ ์ž…๋ ฅ์„ 0์ฑ„๋„ placeholder๋กœ ๋‘๋ฉด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋ณธ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ์‹œ๋ฎฌ์—์„œ ํ•ฉ์„ฑ depth map (4์ฑ„๋„)์„ ์ •์ฑ… obs ๋์— ํ•ฉ์นฉ๋‹ˆ๋‹ค:

# ํ•ฉ์„ฑ ์นด๋ฉ”๋ผ ์ž…๋ ฅ (4 depth bins ร— 16ร—16 sectors = 1024 dim)์œผ๋กœ obs ํ™•์žฅ
cam_feature = simulate_lidar_4bin(env)    # Isaac Lab ray cast
obs = torch.cat([base_state, joint_state, last_action, cam_feature], dim=-1)
# obs ์ฐจ์›: 48 + 1024 = 1072 โ†’ RoboStudio์—์„œ ์‹ค์ œ๋กœ๋Š” 256-512๋กœ ์ฐจ์› ์ถ•์†Œ

9. ํ•™์ƒ์šฉ ์‹œ์ž‘ ๋ฃจํŠธ ์ •๋ฆฌ

  1. Isaac Lab ์„ค์น˜ (RTX 3070+ ๊ถŒ์žฅ, ์œ„ step 1)
  2. Solo 12dof URDF ๋ณต์ œ + effort limit 0.18 Nยทm ์ ์šฉ
  3. leggedrobotics/legged_gym์˜ anymal_c_flat ํ™˜๊ฒฝ์„ ๊ทธ๋Œ€๋กœ ๋ณต๋ถ™ํ•ด mechadog_flat์œผ๋กœ rename
  4. 50 iter ์งง๊ฒŒ ํ•™์Šต โ€” ์ž˜ ๋„๋Š”์ง€ 5๋ถ„ ๋งŒ์— ํ™•์ธ
  5. ์ž˜ ๋™์ž‘ํ•˜๋ฉด 1000~3000 iter ๋ณธ๊ฒฉ ํ•™์Šต
  6. ONNX export โ†’ Rock 5C์— ๋ณต์‚ฌ
  7. ์ œ์–ด ํŽ˜์ด์ง€์˜ ROS2 ๋…ธ๋“œ + CRSF ํŒŒ์„œ๋กœ ๋ฐฐํฌ

10. ํ•™์Šต ๋น„์šฉ ์ถ”์ • (ํ•™์ƒ 1์ธ ๊ธฐ์ค€)

ํ•ญ๋ชฉ๊ฐ’
GPU ์‹œ๊ฐ„ (1000 iter, RTX 4080)~25 ๋ถ„ (~$0.5 / GG ๊ฐ€๊ฒฉ ํ™˜์‚ฐ ์‹œ)
๊ฐœ๋ฐœ ์‹œ๊ฐ„ (URDF + env cfg)6~10 ์‹œ๊ฐ„
๋””๋ฒ„๊น…+ํŠœ๋‹ (๋„๋ฉ”์ธ ๋žœ๋คํ™” iteration)10~30 ์‹œ๊ฐ„ ์ถ”๊ฐ€

๋‹ค์Œ ๋‹จ๊ณ„