This site is version 0.0.1. Most of the code on this site is drafted by an agent and needs review. I apologize for the AI-speak, we are working on rewriting it!
viv-lang.org

← Posts

demoAIRobotics

LQR computes the cart-pole's gains from the Riccati equation

The PD-controlled cart-pole has four gains that were tuned by hand. Linearize the same dynamics, choose how much each state error and each unit of push should cost, and the Riccati equation gives the gains instead. From 25 degrees they land the pole thirteen times closer to upright than the hand-tuned ones, for a third less cost and about the same peak push.

Look inside this program

  • Atlas

    The program’s map: every function and which calls which.

  • There’s no recorded run of this program yet.

Linearize the cart-pole about the upright and you have . Pick for how much you dislike each state and for how much you dislike pushing, and the gains that minimize are , where solves the algebraic Riccati equation. The only choices made by hand are and , and they state the tradeoff directly: angle error against cart position, and state error against force.

and are not written out here. They are computed from the library's own cartpole_rate by central differences, so the linear model matches the nonlinear one this post simulates, and the first test checks that they agree near upright.

comes from integrating the differential Riccati equation backwards until it stops changing, which takes only matrix multiplication and addition. To check it, put back into the algebraic equation: the largest entry of the residual is .

What comes out, on this cart-pole with these weights: , and a closed loop whose slowest mode decays like . Simulating the nonlinear cart-pole for six seconds from 25 degrees, those gains end 0.00096 rad from upright against the hand-tuned gains' 0.0124, thirteen times closer, with an integrated cost of 6.13 against 8.98 and a peak force of 27.5 N against 26.2. The hand-tuned gains also balance the pole; the Riccati gains are the ones that minimize the cost set by and .

Printed

K: [-4.47214, -8.22385, -63.0331, -16.0163]
residual: 6.53699e-13
cl_re: [-8.39442, -4.45241, -1.28419, -1.28419]
slowest: -1.28419
lqr_run: [0.000962049, 6.13006, 27.5034]
pd_run: [0.0124326, 8.9753, 26.1799]
The pole's angle, from 25 degrees
LQR, gains computedPD, gains by hand
−100102000.51.01.52.02.53.0secondsdegrees from upright

Tests 5 of 5 pass

  • the linear model A z + B u matches the nonlinear rate near upright (passes)
  • P solves the algebraic Riccati equation: the residual is under 1e-8 (passes)
  • every closed-loop eigenvalue has a negative real part (passes)
  • from 25 degrees the pole ends upright, within a thousandth of a radian (passes)
  • the computed gains cost less than the hand-tuned ones on the same start (passes)

Checked when the site was built: 5 of 5 tests passed, in 0.23 s. Download 2026-09-22-lqr-balances-the-cart-pole.viv