Simulating an Inverted Pendulum with an LQR Controller (Python)

This is the part 6 in a series of blog posts devoted to the classic control problem of an inverted pendulum on a driven cart. This series is still in production (Nov. 2020) but when finished they will be structured as follows.

  1. Derivation of Simple Pendulum (Python Simulation) - link
  2. Building a Physical Inverted Pendulum
  3. Controlling Inverted Pendulum with PID controller
  4. State Space Model of Inverted Pendulum - link
  5. Designing the Optimal Controller for an Inverted Pendulum (LQR control) - link
  6. Simulating an Inverted Pendulum with an LQR Controller (Python) - link
  7. Deploying an LQR Controller on a Physical Inverted Pendulum

The associated code can be found on GitHub and a video series on YouTube (not currently released as of Nov. 2020). While this project aims to be encompassing and self contained, it does assume familiarity with classical mechanics, linear algebra, differential equations, some control theory, and programming (Python).

Animation of aggressive pendulum recovery. Initial state = [-1; pi-0.5; -5; 0], Final state = [1; pi; 0; 0]

Intro

In the previous 2 blog posts I have explored the state space model of an inverted pendulum and derived the optimal LQR controller for stabilizing the system. Before going to the trouble of building a physical inverted pendulum lets first verify that the controller works as expected in simulation.

If you wish to dive right into the code it can be found on my GitHub

Code Overview

To provide an explanation of the code line by line is difficult outside of video format. As such I will touch on the highlights. There are two files: variables.py and simulation.py. If you have read the previous 2 blog posts the variables.py file should be fairly clear, I have just defined all the relevant variables that have been previously discussed. Feel free to adjust the mass of the cart, rod, damping etc. You can also experiment with different values in the Q and R matrices, as discussed in the previous blog post.

The file simulation.py builds off the existing code from part one of this series, the animate() function is largely unchanged. The primary difference is that the non-linear equation for the simple pendulum has been replaced by the function StateSpace(t, i). This function evaluates the non-linear inverted pendulum with the applied LQR input control.

Show Comments