|
| 1 | +# Inverted Pendulum |
| 2 | + |
| 3 | +`examples/inverted_pendulum/` ships two PPO tasks for the classical cart-pole problem on flat |
| 4 | +ground. The extension mirrors `examples/unitree/`: `ManagerBasedRlEnv` over Genesis, rsl_rl PPO, |
| 5 | +a `BodyVelocitySensor` on the pole link, and the unified `genelab train` / `genelab play` CLI. |
| 6 | + |
| 7 | +## Tasks |
| 8 | + |
| 9 | +| Task id | Problem | |
| 10 | +|---------|---------| |
| 11 | +| `GeneLab-Inverted-Pendulum-v0` | Single inverted pole on a cart. | |
| 12 | +| `GeneLab-Double-Inverted-Pendulum-v0` | Two stacked inverted poles on a cart. | |
| 13 | + |
| 14 | +## Installation |
| 15 | + |
| 16 | +The extension depends on the `rl` extra (rsl_rl). Pick the `torch-*` extra that matches the |
| 17 | +hardware. |
| 18 | + |
| 19 | +```bash |
| 20 | +uv sync --extra rl --extra torch-cu128 |
| 21 | +uv pip install -e examples/inverted_pendulum |
| 22 | + |
| 23 | +uv run genelab list tasks |
| 24 | +# -> GeneLab-Inverted-Pendulum-v0 |
| 25 | +# -> GeneLab-Double-Inverted-Pendulum-v0 |
| 26 | +``` |
| 27 | + |
| 28 | +## Single inverted pendulum |
| 29 | + |
| 30 | +```bash |
| 31 | +uv run genelab train GeneLab-Inverted-Pendulum-v0 \ |
| 32 | + --num-envs 4096 --max-iterations 150 |
| 33 | + |
| 34 | +uv run genelab play GeneLab-Inverted-Pendulum-v0 \ |
| 35 | + --checkpoint logs/rsl_rl/inverted_pendulum_flat/<run>/model_150.pt --vis |
| 36 | +``` |
| 37 | + |
| 38 | +`--checkpoint` makes `play` route through the RL runner with `--agent trained` by default. |
| 39 | + |
| 40 | +## Double inverted pendulum |
| 41 | + |
| 42 | +```bash |
| 43 | +uv run genelab train GeneLab-Double-Inverted-Pendulum-v0 \ |
| 44 | + --num-envs 4096 --max-iterations 300 |
| 45 | + |
| 46 | +uv run genelab play GeneLab-Double-Inverted-Pendulum-v0 \ |
| 47 | + --checkpoint logs/rsl_rl/double_inverted_pendulum_flat/<run>/model_300.pt --vis |
| 48 | +``` |
| 49 | + |
| 50 | +## Sensor and underactuation |
| 51 | + |
| 52 | +Only the cart slide joint is PD-controlled. The pole hinges default to `kp=0, kv=0` so the |
| 53 | +pendulum stays underactuated and the policy must learn balance through cart motion alone. A |
| 54 | +`BodyVelocitySensor` attached to the top pole supplies a noisy angular-velocity observation |
| 55 | +(corrupted with `Unoise` in the policy group, clean in the critic group). |
| 56 | + |
| 57 | +## Interactive disturbance |
| 58 | + |
| 59 | +Play mode launches a single environment (`num_envs=1`) and enables Genesis' |
| 60 | +`MouseInteractionPlugin`. Left-click on the cart or pole and drag — a spring force pulls the |
| 61 | +clicked link toward the cursor while the policy keeps balancing. Scroll wheel rotates the drag |
| 62 | +plane around the surface normal. Release the button to remove the force. |
| 63 | + |
| 64 | +!!! tip "Smoke-test budget" |
| 65 | + A 5–10 iteration run with `--num-envs 64 --max-iterations 5` is enough to validate wiring |
| 66 | + end-to-end. The reward signal will still be noisy at that scale; convergence requires the |
| 67 | + 150 / 300 iteration budgets above. |
| 68 | + |
| 69 | +## Logs |
| 70 | + |
| 71 | +Both tasks write to `logs/rsl_rl/<experiment>/<timestamp>_/` like the Unitree examples: |
| 72 | + |
| 73 | +- `params/env.json` and `params/agent.json` — frozen configs at run time. |
| 74 | +- `model_<iter>.pt` — checkpoints saved every `save_interval` iterations. |
| 75 | +- TensorBoard event files alongside the checkpoints. |
| 76 | + |
| 77 | +## See also |
| 78 | + |
| 79 | +- [Unitree G1 quickstart](../getting-started/quickstart.md#unitree-g1) |
| 80 | +- [Sensors](../concepts/sensors.md) |
| 81 | +- [Play and Train CLI](../cli/play-train.md) |
0 commit comments