A two-wheeled self-balancing robot that I built to get more familiar with LQR control. I first implemented a PID controller as a baseline and compared it with the LQR's performance. I also wanted to implement an MPC, but it turned out to be too computationally demanding for the STM32G474RE used in the first version. I therefore upgraded the hardware to allow more sophisticated control strategies as well as wireless control of the robot.
Model
The robot is modelled as a wheeled inverted pendulum. The nonlinear equations of motion are linearised around the upright position, which gives a four-state model (wheel position and velocity, pitch angle and pitch rate) that is used for the LQR design in MATLAB and for testing the controllers in simulation before running them on the robot.
Estimation and control
The pitch angle is estimated from the IMU with a complementary filter: the gyroscope is accurate over short time spans, the accelerometer provides the long-term reference. The controller runs in a fixed-rate loop triggered by a hardware timer on the STM32 and commands the wheel speed of the two stepper motors.
The PID controller keeps the robot upright but lets it drift away over time, because it only controls the pitch angle. The LQR uses the full state, so it also holds the robot's position and recovers noticeably better from pushes. Tuning is reduced to choosing the weights of the cost function, which made the design much more systematic.
Next steps
Next, I want to implement an MPC on the upgraded hardware so that input limits (maximum wheel speed and acceleration of the steppers) are handled explicitly by the controller.


