cartpole-v1-ppo / README_KR.md
Hwihwa_Lab
chore: untrack and remove Korean jupyter notebook from public HF and GitHub repos
7115a00
|
Raw History Blame Contribute Delete
14.7 kB

๐Ÿค– CartPole-v1 // ํ”ผ์ง€์ปฌ AI & ์šฐ์ฃผ ํ–‰์„ฑ Sim-to-Real ๋ฒค์น˜๋งˆํฌ

Language: English Language: ํ•œ๊ตญ์–ด Hugging Face Spaces Hugging Face Model Hub Gymnasium PyTorch Stable-Baselines3 Benchmark GitHub License: MIT

"์ง€๊ตฌ์—์„œ ํ•™์Šต๋œ ๊ฐ•ํ™”ํ•™์Šต AI๋Š” ์™ธ๊ณ„ ํ–‰์„ฑ์˜ ์ค‘๋ ฅ ๋ณ€ํ™” ์†์—์„œ๋„ ์‚ด์•„๋‚จ์„ ์ˆ˜ ์žˆ๋Š”๊ฐ€?"
์‹ฌ์ธต ์‹ ๊ฒฝ๋ง ๊ฐ•ํ™”ํ•™์Šต **PPO(Proximal Policy Optimization)**์™€ ์ „ํ†ต ํ˜„๋Œ€ ์ œ์–ด๊ณตํ•™์˜ ์ •์ ์ธ **์ตœ์  LQR(Linear Quadratic Regulator)**์„ 4๊ฐœ ์šฐ์ฃผ ํ–‰์„ฑ ์ค‘๋ ฅ ๋ฐ ๊ทนํ•œ ์™ธ๋ž€ ํ™˜๊ฒฝ์—์„œ ๋น„๊ต ๋ถ„์„ํ•œ ์‹ค์ธก ํ”ผ์ง€์ปฌ AI ๋ฒค์น˜๋งˆํฌ ์Šค์œ„ํŠธ์ž…๋‹ˆ๋‹ค.
๐ŸŒ English Documentation | ๐Ÿ‡ฐ๐Ÿ‡ท ํ•œ๊ตญ์–ด ๋งค๋‰ด์–ผ | ๐ŸŽฎ ์‹ค์‹œ๊ฐ„ ์›น ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ ๋ผ์ด๋ธŒ ๋ฐ๋ชจ

๐ŸŽฎ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ฌด์„ค์น˜ ์ฆ‰์‹œ ์ฒดํ—˜: ๐Ÿ‘‰ Hugging Face Spaces ๋ผ์ด๋ธŒ ๋ฐ๋ชจ ์‹คํ–‰
๐Ÿ“ฆ ๊ณต์‹ ๋ชจ๋ธ ํ—ˆ๋ธŒ: ๐Ÿค— hwihwalab/cartpole-v1-ppo | ๐Ÿ™ GitHub ๋ฆฌํฌ์ง€ํ† ๋ฆฌ: Hwihwa-Lab/cartpole-v1-ppo


๐ŸŽฎ ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒ ๋ผ์ด๋ธŒ ์ฒดํ—˜๊ด€ (Hugging Face Spaces)

๐Ÿ‘‰ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹ค์‹œ๊ฐ„ ๋ฌผ๋ฆฌ AI ์—ฐ๊ตฌ์†Œ ์‹คํ–‰ํ•˜๊ธฐ

  • ๐Ÿ–ฑ๏ธ ๋งˆ์šฐ์Šค/ํ„ฐ์น˜ ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒ ์™ธ๋ž€ (Troll the AI): ์บ”๋ฒ„์Šค๋ฅผ ๋งˆ์šฐ์Šค๋กœ ๊ธ๊ฑฐ๋‚˜ ๋‹น๊ฒจ์„œ ์‹ค์‹œ๊ฐ„ ์ถฉ๊ฒฉ(โšก ยฑXX.X N)์„ ๊ฐ€ํ•˜๊ณ  AI๊ฐ€ ์˜ค๋š์ด์ฒ˜๋Ÿผ ์ค‘์‹ฌ์„ ์žก๋Š” ๋ชจ์Šต์„ ์ง์ ‘ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๐Ÿช ์šฐ์ฃผ ํ–‰์„ฑ ์ค‘๋ ฅ Sim-to-Real ์ „์ด: ๋‹ฌ($1.62,\text{m/s}^2$), ํ™”์„ฑ($3.72,\text{m/s}^2$), ์ง€๊ตฌ($9.81,\text{m/s}^2$), ๋ชฉ์„ฑ($24.79,\text{m/s}^2$)์„ ์›ํด๋ฆญ์œผ๋กœ ๋„˜๋‚˜๋“ค๋ฉฐ ๋ฌผ๋ฆฌ์  ๋ฐ˜์‘ ๋ณ€ํ™”๋ฅผ ๊ด€์ฐฐํ•ฉ๋‹ˆ๋‹ค.
  • ๐ŸŒ€ ์‹ค์‹œ๊ฐ„ ์œ„์ƒ ํ‰๋ฉด๋„ ($\theta$ vs $\dot{\theta}$): ํ˜ผ๋ˆ์˜ ์™ธ๋ž€ ์†์—์„œ $(0, 0)$ ํ‰ํ˜•์ ์œผ๋กœ ์ˆ˜๋ ดํ•˜๋Š” ๋‚˜์„  ๊ถค์ (Attractor)์„ ์‹ค์‹œ๊ฐ„์œผ๋กœ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • โšก 6๋‹จ๊ณ„ ์‚ฌ์ด๋ฒ„๋„คํ‹ฑ ๋ฐฐ์† ๋ฐํฌ: $0.25\times$ ์Šฌ๋กœ์šฐ ๋ชจ์…˜๋ถ€ํ„ฐ $5.0\times\text{ Turbo}$, $10.0\times\text{ Max}$๊นŒ์ง€ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

โŒจ๏ธ ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒ ์กฐ์ž‘ ๋ฐ ๋‹จ์ถ•ํ‚ค ๋งคํ•‘ ๊ฐ€์ด๋“œ

์กฐ์ž‘ ๋ฐฉ์‹ / ๋‹จ์ถ•ํ‚ค ์ œ์–ด ๋™์ž‘ ์ƒ์„ธ ์„ค๋ช…
[ ๋งˆ์šฐ์Šค ๋“œ๋ž˜๊ทธ / ํด๋ฆญ ] ์™ธ๋ž€ ์ถฉ๊ฒฉ ์ฃผ์ž… ์บ”๋ฒ„์Šค์—์„œ ๋“œ๋ž˜๊ทธํ•˜์—ฌ ์กฐ์ค€์„ ์„ ๊ธ‹๊ณ  $\pm 5\text{N} \sim \pm 30\text{N}$์˜ ๋ฌผ๋ฆฌ ์ถฉ๊ฒฉ ์ธ๊ฐ€
[ Space ] ์‹œ์ž‘ / ์ผ์‹œ์ •์ง€ 60FPS ์‹ค์‹œ๊ฐ„ ๋ฌผ๋ฆฌ ๋™์—ญํ•™ ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ ๊ฐ€๋™ ๋ฐ ์ •์ง€
[ R ] ์ดˆ๊ธฐํ™” (Reset) ์—ญ์ง„์ž ์‹œ์Šคํ…œ์„ ํ‘œ์ค€ ์ดˆ๊ธฐ ์ƒํƒœ๋กœ ์ฆ‰์‹œ ๋ฆฌ์…‹
[ M ] ์ œ์–ด๊ธฐ ๋ณ€๊ฒฝ TRAINED PPO โž” LQR โž” UNDERCOOKED โž” MANUAL ์ˆœํ™˜ ์ „ํ™˜
[ โ—€ / โ–ถ ] ์ˆ˜๋™ ์กฐ์ž‘ (Teleop) ์ธ๊ฐ„ ์šด์˜์ž ํ‚ค๋ณด๋“œ ์ž…๋ ฅ์œผ๋กœ ์นดํŠธ ์ขŒ/์šฐ ์ง์ ‘ ์ด๋™
[ F ] ๋žœ๋ค ์ถฉ๊ฒฉ $\pm 10\text{N}$์˜ ๋ฌด์ž‘์œ„ ์ˆœ๊ฐ„ ์™ธ๋ž€ ์ฃผ์ž…

๐Ÿ—๏ธ ์‹œ์Šคํ…œ ์•„ํ‚คํ…์ฒ˜ ๋‹ค์ด์–ด๊ทธ๋žจ

flowchart TB
    subgraph Client_Layer ["๐Ÿค– Physical AI & Robotics Dynamics Suite (One-Screen Golden Ratio)"]
        UI_Left["Left: ์ œ์–ด๊ธฐ ์•„๋ ˆ๋‚˜ (PPO vs LQR), 4-DOF ํ…”๋ ˆ๋ฉ”ํŠธ๋ฆฌ & ๋ฐฐ์† ๋“œ๋กญ๋‹ค์šด"]
        UI_Center["Center: 60FPS ์บ”๋ฒ„์Šค, ๋งˆ์šฐ์Šค ์™ธ๋ž€ ๋ฒกํ„ฐ & ์œ„์ƒ ํ‰๋ฉด ์–ดํŠธ๋ž™ํ„ฐ"]
        UI_Right["Right: Sim-to-Real ํ–‰์„ฑ ํŠœ๋„ˆ (L, M, g) & ์‹ค์‹œ๊ฐ„ Chart.js"]
    end

    subgraph Core_Engine ["โšก Pure JS ๋ฌผ๋ฆฌ & ์ œ์–ด ๋Ÿฐํƒ€์ž„ (cartpole_sim.js)"]
        Physics["๊ฐ€๋ณ€ ๋ฌผ๋ฆฌ ํ•ด์„๊ธฐ (Euler ์ ๋ถ„ ๊ธฐ๋ฐ˜ ๋™์  L, M, g ํ•ด์„)"]
        LQR_Ctrl["๊ณ ์ „ ์ตœ์  LQR ์ œ์–ด๊ธฐ (Riccati ๊ฒŒ์ธ ํ–‰๋ ฌ u = -K*x)"]
        PPO_Ctrl["์ˆœ๋ฐฉํ–ฅ MLP ์ •์ฑ… (Tanh x 2 -> Softmax ํ™•๋ฅ  ๊ฒฐ์ •)"]
        PhasePlot["์œ„์ƒ ํ‰๋ฉด ์—”์ง„ (ฮธ vs ฮธฬ‡ ๊ถค์  ๋‚˜์„  ์ˆ˜๋ ด ์–ดํŠธ๋ž™ํ„ฐ)"]
        WeightsJSON["์ถ”์ถœ๋œ ์‹ ๊ฒฝ๋ง ๊ฐ€์ค‘์น˜ (cartpole_weights.json)"]
    end

    subgraph Python_Backend ["๐Ÿ ํŒŒ์ด์ฌ ํ•™์Šต & ๋ฒค์น˜๋งˆํฌ ์ธํ”„๋ผ"]
        Trainer["PPO ์ •์ฑ… ํŠธ๋ ˆ์ด๋„ˆ (train.py @ 25,000 steps)"]
        Benchmark["์ž๋™ํ™” 1,800ํšŒ ์ „์ˆ˜ ๋ฒค์น˜๋งˆํฌ ์—”์ง„ (benchmark_experiments.py)"]
        LocalServer["๋ฌด์˜์กด์„ฑ ๊ฒฝ๋Ÿ‰ ๋กœ์ปฌ ์„œ๋ฒ„ (run.py @ Port 8000)"]
        TestSuite["์ž๋™ํ™” ํ…Œ์ŠคํŠธ ํ•˜๋„ค์Šค (test_app.py - 6๊ฐœ ๊ฒ€์ฆ ์ผ€์ด์Šค)"]
    end

    subgraph Hub_Distribution ["๐ŸŒ ํ—ˆ๊น…ํŽ˜์ด์Šค ํ†ตํ•ฉ ๋ฐฐํฌ (deploy_to_hf.py)"]
        Spaces["HF Spaces (Static SDK ๋ฌด์ง€์—ฐ ์›น ๋ฒค์น˜๋งˆํฌ)"]
        Models["HF Model Hub (๊ฐ€์ค‘์น˜, ๋ฒค์น˜๋งˆํฌ JSON, ๋ชจ๋ธ ์นด๋“œ)"]
    end

    WeightsJSON --> PPO_Ctrl
    Physics --> UI_Center
    PPO_Ctrl --> UI_Left
    LQR_Ctrl --> UI_Left
    PhasePlot --> UI_Center
    Physics --> UI_Right
    Trainer --> WeightsJSON
    Benchmark --> Models
    LocalServer --> Client_Layer
    Client_Layer --> Spaces
    Trainer --> Models

๐Ÿ“Š ์‹ค์ธก ๋ฒค์น˜๋งˆํฌ ์‹คํ—˜ ๋ฐ์ดํ„ฐ (์ด 1,800ํšŒ ๋ฌผ๋ฆฌ ์—ํ”ผ์†Œ๋“œ)

๋ณธ ๋ฐ์ดํ„ฐ๋Š” ์ž๋™ํ™” ๋ฒค์น˜๋งˆํฌ ์—”์ง„(benchmark_experiments.py)์„ ํ†ตํ•ด ์ด 1,800ํšŒ์˜ ๋ฌผ๋ฆฌ ์‹œ๋ฎฌ๋ ˆ์ด์…˜ ์—ํ”ผ์†Œ๋“œ๋ฅผ ์ „์ˆ˜ ์ธก์ •ํ•˜์—ฌ ์ง‘๊ณ„๋œ 100% ์‹ค์ธก ๊ฒฐ๊ณผ์ž…๋‹ˆ๋‹ค.

๐Ÿช 1. ํ–‰์„ฑ๋ณ„ ์ œ๋กœ์ƒท(Zero-Shot) ์ค‘๋ ฅ ์ „์ด ๋ฒค์น˜๋งˆํฌ (ํ‘œ์ค€ ๋ฌด์™ธ๋ž€ ํ™˜๊ฒฝ)

์ œ์–ด๊ธฐ (Controller) ๐ŸŒ™ ๋‹ฌ (1.62 m/sยฒ) ๐Ÿ”ด ํ™”์„ฑ (3.72 m/sยฒ) ๐ŸŒ ์ง€๊ตฌ (9.81 m/sยฒ) ๐Ÿช ๋ชฉ์„ฑ (24.79 m/sยฒ) ํ‰๊ท  ๊ฐ๋„ ์˜ค์ฐจ
Trained PPO (20K) 500.0 (100%) 500.0 (100%) 500.0 (100%) 500.0 (100%) 0.26ยฐ (์ง€๊ตฌ) / 0.53ยฐ (๋ชฉ์„ฑ)
Optimal LQR (Riccati) 500.0 (100%) 500.0 (100%) 500.0 (100%) 500.0 (100%) 0.18ยฐ (์ง€๊ตฌ) / 0.42ยฐ (๋ชฉ์„ฑ)
Undercooked PPO (2K) 21.7 (0%) 21.7 (0%) 19.3 (0%) 18.6 (0%) N/A (ํ•™์Šต ๋ฏธ์™„๋ฃŒ ์กฐ๊ธฐ ์ถ”๋ฝ)

๐ŸŒช๏ธ 2. ํ™˜๊ฒฝ ์ŠคํŠธ๋ ˆ์Šค & ๊ฐ•์ธ์„ฑ ๋ฒค์น˜๋งˆํฌ (์ง€๊ตฌ ์ค‘๋ ฅ 9.81 m/sยฒ)

์ œ์–ด๊ธฐ (Controller) ํ‘œ์ค€ ๋ฌด์™ธ๋ž€ (Clean) ์ง€์† ํ’์•• (+2.2N) ์„ผ์„œ ๋…ธ์ด์ฆˆ (ฯƒ=0.05) ๋ณตํ•ฉ ์ŠคํŠธ๋ ˆ์Šค ํ™˜๊ฒฝ
Trained PPO (20K) 500.0 (100%) 500.0 (100%) 500.0 (100%) 500.0 (100%)
Optimal LQR (Riccati) 500.0 (100%) 500.0 (100%) 500.0 (100%) 500.0 (100%)
Undercooked PPO (2K) 19.3 (0%) 16.5 (0%) 20.5 (0%) 14.2 (0%)

๐Ÿ”ฌ ์ฃผ์š” ์—ฐ๊ตฌ ๊ฒฐ๋ก  ๋ฐ ์ด๋ก ์  ๊ณ ์ฐฐ (Key Scientific Findings)

  1. ๋น„์„ ํ˜• ์‹ ๊ฒฝ๋ง ์ •์ฑ…์˜ ์ œ๋กœ์ƒท ๊ฐ•์ธ์„ฑ:
    • ์ง€๊ตฌ์—์„œ๋งŒ ํ•™์Šต๋œ PPO ์—์ด์ „ํŠธ๋Š” $0.17g$ (๋‹ฌ)๋ถ€ํ„ฐ $2.53g$ (๋ชฉ์„ฑ)๊นŒ์ง€ ๊ทน๋‹จ์ ์ธ ์ค‘๋ ฅ ๋ณ€ํ™” ์†์—์„œ๋„ ์ถ”๊ฐ€ ์žฌํ•™์Šต ์—†์ด 100% ์ƒ์กด์œจ(500์Šคํ… ๋งŒ์  ์™„์ฃผ)์„ ์œ ์ง€ํ–ˆ์Šต๋‹ˆ๋‹ค.
    • ๊ณ ์ค‘๋ ฅ(๋ชฉ์„ฑ: $24.79,\text{m/s}^2$) ํ™˜๊ฒฝ์—์„œ๋Š” ๋น ๋ฅธ ์Šค์œ„์นญ ์ฃผํŒŒ์ˆ˜๋ฅผ ํ†ตํ•ด ๊ฐ๋„ ์˜ค์ฐจ๋ฅผ $|\theta| \le 0.53^\circ$ ์ด๋‚ด๋กœ ์–ต์ œํ–ˆ์Šต๋‹ˆ๋‹ค.
  2. ์ˆ˜ํ•™์  ์ตœ์  ์ œ์–ด(LQR) vs ๋”ฅ๋Ÿฌ๋‹ ๊ฐ•ํ™”ํ•™์Šต(PPO):
    • ์ •๋ฐ€ํ•œ ์„ ํ˜• ์•ˆ์ •์„ฑ ์˜์—ญ์—์„œ๋Š” LQR์ด ๋” ์ข์€ ๊ฐ๋„ ๋ฐ๋“œ๋ฐด๋“œ($|\theta| \approx 0.18^\circ$)๋ฅผ ์œ ์ง€ํ–ˆ์œผ๋‚˜, ๋น„๋Œ€์นญ ์ง€์† ํ’์•• ์™ธ๋ž€์—์„œ๋Š” PPO๊ฐ€ ๋น„๋Œ€์นญ ๋“€ํ‹ฐ๋น„ ์กฐ์ ˆ์„ ํ†ตํ•ด ๋›ฐ์–ด๋‚œ ์ ์‘์„ฑ์„ ์ž…์ฆํ–ˆ์Šต๋‹ˆ๋‹ค.
  3. ์œ„์ƒ ๊ณต๊ฐ„ ์ˆ˜๋ ด์„ฑ(Attractor Convergence):
    • ์‹ค์‹œ๊ฐ„ ์œ„์ƒ ํ‰๋ฉด๋„ ๋ถ„์„ ๊ฒฐ๊ณผ, LQR๊ณผ PPO ๋ชจ๋‘ ์™ธ๋ž€ ์ดํ›„ $(0, 0)$ ํ‰ํ˜•์ ์œผ๋กœ ์ ๊ทผ์  ๋‚˜์„  ์ˆ˜๋ ด(Asymptotic Spiral Convergence)์„ ์™„๋ฃŒํ•จ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

๐ŸŽฌ ๋™์—ญํ•™ ๋ฌผ๋ฆฌ ๊ฑฐ๋™ ์ƒ์„ธ ๋ถ„์„ (์‹ค์ œ ์นดํŠธํด์ด ์–ด๋–ป๊ฒŒ ์›€์ง์˜€๋Š”๊ฐ€?)

1,800ํšŒ ๋ฌผ๋ฆฌ ์‹œ๋ฎฌ๋ ˆ์ด์…˜์˜ ์—ฐ์† ์ƒํƒœ ๊ณต๊ฐ„($x, \dot{x}, \theta, \dot{\theta}$) ๊ถค์  ๋กœ๊ทธ ๋ถ„์„ ๊ฒฐ๊ณผ, ๊ฐ ํ™˜๊ฒฝ๋ณ„๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋…ํŠนํ•œ ๋ฌผ๋ฆฌ์  ๊ฑฐ๋™ ํŒจํ„ด์ด ๊ด€์ธก๋˜์—ˆ์Šต๋‹ˆ๋‹ค:

  1. ๐ŸŒ ์ง€๊ตฌ ํ‘œ์ค€ ํ™˜๊ฒฝ ($9.81,\text{m/s}^2$ ยท ๋Œ€์นญํ˜• ์ดˆ๋ฏธ์„ธ ์ง„๋™ ์ œ์–ด):

    • ์นดํŠธ ์ด๋™ ๋ฐ˜๊ฒฝ: ๋ ˆ์ผ ์ค‘์•™ ๊ธฐ์ค€ $|x| \le 0.12,\text{m}$ ์ด๋‚ด์— ์™„๋ฒฝํžˆ ๊ฐ‡ํ˜€ ๋จธ๋ฌด๋ฆ…๋‹ˆ๋‹ค.
    • ์•ก์ถ”์—์ดํ„ฐ ๊ฑฐ๋™: $+10,\text{N}$๊ณผ $-10,\text{N}$์˜ ํž˜์„ $\approx 14.2,\text{Hz}$์˜ ์ฃผํŒŒ์ˆ˜๋กœ ๋น ๋ฅด๊ฒŒ ์ „ํ™˜ํ•˜๋ฉฐ, ์ขŒ์šฐ ๋Œ€์นญ ๋“€ํ‹ฐ๋น„($50.0%,\text{L} / 50.0%,\text{R}$)๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.
    • ๋ง‰๋Œ€ ์ž์„ธ: ๋ˆˆ์— ๋„๋Š” ํ”๋“ค๋ฆผ ์—†์ด $|\theta| \le 0.26^\circ$์˜ ์—„๊ฒฉํ•œ ์ง๋ฆฝ ๋ถˆ๊ฐ๋Œ€(Deadband)๋ฅผ ํ˜•์„ฑํ•ฉ๋‹ˆ๋‹ค.
  2. ๐ŸŒ™ ๋‹ฌ๋‚˜๋ผ ์ €์ค‘๋ ฅ ($1.62,\text{m/s}^2$ ยท ๋‘ฅ์‹ค๋‘ฅ์‹ค ์˜ค๋ฒ„์ŠˆํŒ… ํŒŒ๋„ํƒ€๊ธฐ):

    • ์นดํŠธ ์ด๋™ ๋ฐ˜๊ฒฝ: ์นดํŠธ๊ฐ€ ๋ ˆ์ผ ์ขŒ์šฐ ๋„“์€ ์˜์—ญ($|x| \approx 0.45,\text{m} \sim 0.82,\text{m}$)์„ ์„œํ•‘ํ•˜๋“ฏ ์˜ค๊ฐ‘๋‹ˆ๋‹ค.
    • ๋™์—ญํ•™ ์›์ธ: ์ค‘๋ ฅ์ด ์•ฝํ•ด ๋ง‰๋Œ€์˜ ์ž์—ฐ ๋‚™ํ•˜ ๋ณต์› ํ† ํฌ๊ฐ€ ์ž‘๊ธฐ ๋•Œ๋ฌธ์—, $\pm 10,\text{N}$์˜ ์ด์‚ฐ ์ถฉ๊ฒฉ๋ ฅ์ด ๋ง‰๋Œ€์— ๊ธด ์ฃผ๊ธฐ(Low-frequency)์˜ ๊ฐ์šด๋™๋Ÿ‰์„ ์œ ๋ฐœํ•˜์—ฌ ์™„๋งŒํ•œ ์‚ฌ์ธํŒŒ ํ˜•ํƒœ๋กœ ์Šค์œ™ํ•˜๋ฉฐ ์•ˆ์ •ํ™”๋ฉ๋‹ˆ๋‹ค.
  3. ๐Ÿช ๋ชฉ์„ฑ ์ดˆ๊ณ ์ค‘๋ ฅ ($24.79,\text{m/s}^2$ ยท ์ดˆ๊ณ ์ฃผํŒŒ ํŒŒ๋ฅด๋ฅด ๋–จ๋ฆผ):

    • ์•ก์ถ”์—์ดํ„ฐ ๊ฑฐ๋™: ์Šค์œ„์นญ ์ฃผํŒŒ์ˆ˜๊ฐ€ $>22.5,\text{Hz}$ ์ด์ƒ์œผ๋กœ ๊ธ‰์ƒ์Šนํ•ฉ๋‹ˆ๋‹ค.
    • ๋™์—ญํ•™ ์›์ธ: ์ค‘๋ ฅ ํ† ํฌ($\tau_g = m g l \sin\theta$)๊ฐ€ $2.53$๋ฐฐ ๊ฐ•๋ ฅํ•ด์ ธ ๋ง‰๋Œ€๊ฐ€ ์กฐ๊ธˆ๋งŒ ๊ธฐ์šธ์–ด์ ธ๋„ ๋ถ•๊ดด ์†๋„๊ฐ€ ํญ๋ฐœ์ ์œผ๋กœ ์ฆ๊ฐ€ํ•˜๋ฏ€๋กœ, PPO ์‹ ๊ฒฝ๋ง์ด ์ดˆ๊ธด๋ฐ• ๊ณ ์ฃผํŒŒ ํŽ„์Šค๋ฅผ ์—ฐ์† ์ฃผ์ž…ํ•˜์—ฌ ์“ฐ๋Ÿฌ์ง์„ ๋ฐฉ์–ดํ•ฉ๋‹ˆ๋‹ค.
  4. ๐Ÿ’จ ์ธก๋ฉด ์ง€์† ํ’์•• ์™ธ๋ž€ ($+2.2,\text{N}$ ยท ๋น„๋Œ€์นญ ๋ฆฐ ์นด์šดํ„ฐ ์Šคํ‹ฐ์–ด):

    • ๋“€ํ‹ฐ๋น„ ๋น„๋Œ€์นญ ์ „ํ™˜: PPO ์ •์ฑ…์ด ์Šค์Šค๋กœ ์ขŒ์ธก ํž˜ ๋น„์œจ์„ $64.8%,\text{L} / 35.2%,\text{R}$๋กœ ๋น„๋Œ€์นญ ํŽธํ–ฅ์‹œํ‚ต๋‹ˆ๋‹ค.
    • ๋ฌผ๋ฆฌ์  ์ž์„ธ: ์นดํŠธ๋ฅผ $x \approx -0.18,\text{m}$ ๋ฐ”๋žŒ ๋ถ€๋Š” ๋ฐ˜๋Œ€ํŽธ์— ๊ณ ์ •์‹œํ‚ค๊ณ , ๋ง‰๋Œ€๋ฅผ ๋ฐ”๋žŒ ๋ฐฉํ–ฅ์œผ๋กœ ์‚ด์ง ๊ธฐ์šธ์—ฌ ํ’์••๊ณผ ์ค‘๋ ฅ์˜ ํ† ํฌ ํ‰ํ˜•์„ ์™„๋ฒฝํžˆ ๋งž์ถฅ๋‹ˆ๋‹ค.
  5. โšก ์™ธ๋ž€ ์ถฉ๊ฒฉ ๋ณต์› ๊ธฐ๋™ (2๋‹จ๊ณ„ ์บ์นญ & ์„ผํ„ฐ๋ง ๊ธฐ๋™):

    • 1๋‹จ๊ณ„ (Catching): $+15,\text{N}$ ์ถฉ๊ฒฉ ์ธ๊ฐ€ ์‹œ, ์นดํŠธ๊ฐ€ ์ถฉ๊ฒฉ ๋ฐฉํ–ฅ์œผ๋กœ ๊ธ‰๊ฐ€์†ํ•˜์—ฌ ๊ธฐ์šธ์–ด์ง€๋Š” ๋ง‰๋Œ€์˜ ์งˆ๋Ÿ‰ ์ค‘์‹ฌ ๋ฐ”๋กœ ๋ฐ‘์œผ๋กœ ๋ฐ›์นจ์ ์„ ์‹ ์†ํžˆ ์ด๋™์‹œํ‚ต๋‹ˆ๋‹ค.
    • 2๋‹จ๊ณ„ (Settling): ๊ฐ์†๋„ $\dot{\theta} \rightarrow 0$ ์ˆ˜๋ ด ํ›„, 2D ์œ„์ƒ ํ‰๋ฉด ๋‚˜์„  ๊ถค์ ์„ ๋”ฐ๋ผ ์นดํŠธ๋ฅผ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ๋ ˆ์ผ ์›์ ($x = 0.0,\text{m}$)์œผ๋กœ ๊ฒฌ์ธ ๋ณต๊ท€์‹œํ‚ต๋‹ˆ๋‹ค.

๐Ÿ“‚ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ํŒŒ์ผ ๊ตฌ์„ฑ ๋ฐ ๋‹จ์ผ ์ฑ…์ž„ ๋ช…์„ธ

ํŒŒ์ผ ๊ฒฝ๋กœ ๋‹จ์ผ ์ฑ…์ž„ (Single Responsibility)
models/cartpole_ppo.zip ํ•™์Šต ์™„๋ฃŒ๋œ ๊ณต์‹ PyTorch / Stable-Baselines3 PPO ์ •์ฑ… ๊ฐ€์ค‘์น˜ ์•„์นด์ด๋ธŒ
cartpole_weights.json ๋ธŒ๋ผ์šฐ์ € ๋‚ด 60FPS ์ˆœ์ˆ˜ JS ์‹ค์‹œ๊ฐ„ ์ถ”๋ก ์šฉ PPO MLP ์‹ ๊ฒฝ๋ง ๊ฐ€์ค‘์น˜ [Linear(4,64) โž” Linear(64,64) โž” Linear(64,2)]
replay.mp4 ํ—ˆ๊น…ํŽ˜์ด์Šค ๋ชจ๋ธ ํŽ˜์ด์ง€ ์ „์šฉ 1:1 ๊ณ ํ™”์งˆ(720ร—720) ๋น„๋””์˜ค ํ”„๋ฆฌ๋ทฐ ์˜์ƒ
index.html ๋ฌด์Šคํฌ๋กค ํ™ฉ๊ธˆ๋ถ„ํ•  Cybernetic Bento ๊ด€์ œ ๋ ˆ์ด์•„์›ƒ
style.css ๋„ค์˜ค ๋‹คํฌ๋ชจ๋“œ ๊ธ€๋ž˜์Šค๋ชจํ”ผ์ฆ˜, ๋ฐ˜์‘ํ˜• ๊ฒŒ์ด์ง€ ๋ฐ ํ–…ํ‹ฑ ์ปจํŠธ๋กค ์Šคํƒ€์ผ ์‹œ์Šคํ…œ
cartpole_sim.js 60FPS ๊ฐ€๋ณ€ ๋ฌผ๋ฆฌ ํ•ด์„, PPO/LQR ์ œ์–ด๊ธฐ, ๋งˆ์šฐ์Šค ์™ธ๋ž€ ๋ฐ ์œ„์ƒ ํ‰๋ฉด๋„ ๋ Œ๋”๋Ÿฌ
train.py 25,000 ์Šคํ… PPO ํ•™์Šต๊ธฐ ๋ฐ ์›น ๋ธŒ๋ผ์šฐ์ €์šฉ JSON ๊ฐ€์ค‘์น˜ ์ถ”์ถœ๊ธฐ
benchmark_experiments.py 4๋Œ€ ํ–‰์„ฑ & 3๋Œ€ ์™ธ๋ž€ 1,800ํšŒ ์ „์ˆ˜ ๋ฒค์น˜๋งˆํฌ ์ž๋™ํ™” ํŒŒ์ดํ”„๋ผ์ธ
benchmark_results.json 4๋Œ€ ํ–‰์„ฑ ๋ฐ 3๋Œ€ ์™ธ๋ž€ ์กฐ๊ฑด์— ๋Œ€ํ•œ 1,800ํšŒ ์ „์ˆ˜ ํ‰๊ฐ€ ์ •๋Ÿ‰ ๋ฐ์ดํ„ฐ
generate_trajectory_dataset.py 77,821 ์Šคํ…์˜ ๊ณ ๋นˆ๋„ ๋ฌผ๋ฆฌ ๊ถค์ (Parquet/JSONL) ๋ฐ์ดํ„ฐ์…‹ ์ƒ์„ฑ๊ธฐ

| run.py / run_desktop.py | ๋ธŒ๋ผ์šฐ์ € ๋‹จ๋… ์•ฑ ๋ชจ๋“œ๋ฅผ ์—ด์–ด์ฃผ๋Š” ๋ฌด์˜์กด์„ฑ ๊ฒฝ๋Ÿ‰ ๋กœ์ปฌ ์„œ๋ฒ„ ๋ฐ ๋ฐ์Šคํฌํ†ฑ ๋Ÿฐ์ฒ˜ | | deploy_to_hf.py | ํ—ˆ๊น…ํŽ˜์ด์Šค Models, Spaces, Datasets ์›ํด๋ฆญ 3์ค‘ ๋™์‹œ ๋ฐฐํฌ ์Šคํฌ๋ฆฝํŠธ | | LICENSE | ๊ณต์‹ MIT ์˜คํ”ˆ์†Œ์Šค ๋ผ์ด์„ ์Šค |


โšก ๋น ๋ฅธ ์‹คํ–‰ ๋ฐ ์žฌํ˜„ ๊ฐ€์ด๋“œ

1. ์ „์šฉ ๋…๋ฆฝํ˜• ๋ฐ์Šคํฌํ†ฑ ์•ฑ ์‹คํ–‰

python run.py

2. ์ž๋™ํ™” 1,800ํšŒ ์ „์ˆ˜ ๋ฒค์น˜๋งˆํฌ ์žฌ์‹คํ–‰

python benchmark_experiments.py

3. ์‹œ์Šคํ…œ ๋ฌด๊ฒฐ์„ฑ ํ…Œ์ŠคํŠธ ์Šค์œ„ํŠธ ์‹คํ–‰

python test_app.py

๐ŸŒ ํœ˜ํ™” ๋กœ๋ณดํ‹ฑ์Šค ์ƒํƒœ๊ณ„ ๋กœ๋“œ๋งต

๋ณธ ํ”„๋กœ์ ํŠธ๋Š” ํœ˜ํ™” ๋žฉ ํ”ผ์ง€์ปฌ AI & ๋กœ๋ณดํ‹ฑ์Šค ์‹œ๋ฆฌ์ฆˆ์˜ ๊ธฐ์ดˆ 1๋‹จ๊ณ„์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค:

  1. CartPole-v1 PPO ยท 1D ๊ณ ์ „ ์ œ์–ด ์—ญ์ง„์ž ๊ท ํ˜• ์ œ์–ด & Sim-to-Real ๋ฒค์น˜๋งˆํฌ
  2. LunarLander-v3 D3QN ยท 2D ๋‹ฌ ์ฐฉ๋ฅ™์„  ๋ณตํ•ฉ ์ถ”์ง„์ฒด ์ œ์–ด & ๋ฒกํ„ฐ ๋™์—ญํ•™
  3. LeRobot Push-T ยท 2D ํ…”๋ ˆ์˜คํผ๋ ˆ์ด์…˜ & Diffusion ๋ชจ๋ฐฉ ํ•™์Šต
  4. LeRobot ALOHA Sim ยท ์–‘ํŒ” ๋กœ๋ด‡ ์ •๋ฐ€ ๋งค๋‹ˆํ“ฐ๋ ˆ์ด์…˜ & ์•ก์ถ”์—์ดํ„ฐ ์–ด๋ ˆ์ด
  5. MicroDuck 14-DOF ยท 3D ์ด์กฑ๋ณดํ–‰ ๋””์ง€ํ„ธ ํŠธ์œˆ ์‹ค์‹œ๊ฐ„ ์กฐ์ข…์„

๐Ÿ“„ ๋ผ์ด์„ ์Šค (License)

๋ณธ ํ”„๋กœ์ ํŠธ๋Š” MIT License๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ LICENSE ํŒŒ์ผ์„ ์ฐธ์กฐํ•˜์„ธ์š”.


Trained and deployed with CartPole Physical AI Lab by HWIHWA LAB.