Project 2: balance a cart-pole with LQR on MuJoCo’s linearization

Level 8 (after Lessons 3.2, 8.1 and 8.2; Level 21.4 for the theory) · Time 3 to 4 hours · Difficulty 3 of 5

Objective

Balance the course cart-pole (models/cartpole.xml) upright from a tilted start by linear-quadratic regulation, using MuJoCo itself to compute the linear model. You will see that MuJoCo is a source of models for control design, not only a place to test controllers.

Prerequisites

Starter code

starter.py asks for three functions:

The tests use $Q = \mathrm{diag}(1, 10, 0.1, 0.1)$ and $R = 0.01$.

Expected behaviour

The linear model predicts one simulated step from a small perturbation to within $2 \times 10^{-5}$. The closed-loop matrix $A - BK$ has all eigenvalues inside the unit circle. From a 0.15 rad tilt the pole never exceeds 0.2 rad, the cart stays within 1.4 m of the centre (the rail ends at 1.5 m), the force never exceeds the actuator’s 20 N, and after 10 s the pole is upright to $10^{-3}$ rad. The same gains still balance a pole 50% heavier than the one they were designed for.

Tests

MJC_IMPL=starter pytest projects/p02_cartpole
pytest projects/p02_cartpole

Common failures

Extension challenges

  1. Swing the pole up from hanging with an energy-based controller, then switch to LQR near upright.
  2. Add an actuator delay (delay and nsample on the motor, MuJoCo 3.5+) and find the largest delay the LQR controller tolerates. Compare with a prediction from the linear model.
  3. Design the controller for a pole 50% heavier and test it on the nominal one. Is robustness symmetric?

Solution

solution.py, about 25 lines.