No GPU, No Simulator Download, No Excuse
Most robotics repos want you to install half a lab before you see a single curve, which is a strange way to teach anyone how control actually works. pendulumlab makes the whole loop small enough to audit on a lunch break. The state is angle and angular velocity. The action is torque. The reward is upright, smooth, and cheap to compute.
This is not pretending to replace MuJoCo or Isaac Lab. Those are for when your pendulum also needs friction, sensor noise, and a PhD thesis attached. This is for when you want to see the actual control loop instead of trusting it exists somewhere inside a config file you'll never open.
Cross-Entropy Method, No Smoke Machine
The policy is a linear torque controller. The optimizer is cross-entropy method: sample gain vectors, score them on identical starting conditions, keep the elites, tighten the distribution around them, repeat until the pendulum stops embarrassing itself.
I like this benchmark because every number has somewhere to live. If the controller gets better, the CSV says so. If the reward changes, the curve changes. No hidden checkpoint, no borrowed environment, no API key required to watch a pendulum learn not to fall over.
The Number
Doing nothing gets you a return of -54.30, which is the pendulum's way of telling you it face-planted immediately. A hand-tuned PD controller gets to 137.39, training wheels included. CEM, learning entirely from its own rollouts with nobody touching a dial, lands at 217.38 and holds a final-window upright reward of 1.000.
4 tests pass locally and on GitHub Actions across Python 3.9, 3.11, and 3.13. The benchmark writes `artifacts/reward_curve.csv` and `artifacts/reward_curve.svg` every run, which is more receipts than most control demos ever hand you.