LQR Control
LQR Brief OverviewLinear Quadratic RegulatorIntroductionThe Linear Quadratic Regulator (LQR) is a wellknown method that provides optimally controlled feedback gains to enable the closedloop stable and high performance design of systems. FullState FeedbackFor the derivation of the linear quadratic regulator we consider a linear system statespace representation:
The feedback gain is a matrix The closedloop system dynamics are then written: where The Maximum PrincipleTowards a generic procedure for solving optimal control problems, we derive a methodology based on the calculus of variations. The problem statement for a fixed end time choose where As understood, where subscripts denote partial derivatives. The last term above can be evaluated using integration by parts as:
The last term is zero, since we cannot vary the initial of the state by changing something later in time. This writing of
The second and third requirements are met by explicitly setting:
The evolution of Gradient Method Solution for the General CaseNumerical solutions to the general problem are iterative, and the simplest approach is the gradient method. Its steps are as follows:
The first three steps are consistent in the sense that LQR SolutionIn the case of the Linear Quadratic Regulator (with zero terminal cost), we set where the requirement that
so that:
Since the systems are clearly linear, we try a connection This has to hold for all Optimal FullState FeedbackThis equation is the Matrix Algebraic Riccati Equation (MARE), whose solution Properties and Use of the LQR

Python ImplementationSimple Python code for the lqr/discrete lqr functions
from __future__ import division, print_function import numpy as np import scipy.linalg def lqr(A,B,Q,R): """Solve the continuous time lqr controller. dx/dt = A x + B u cost = integral x.T*Q*x + u.T*R*u """ #ref Bertsekas, p.151 #first, try to solve the ricatti equation X = np.matrix(scipy.linalg.solve_continuous_are(A, B, Q, R)) #compute the LQR gain K = np.matrix(scipy.linalg.inv(R)*(B.T*X)) eigVals, eigVecs = scipy.linalg.eig(AB*K) return K, X, eigVals def dlqr(A,B,Q,R): """Solve the discrete time lqr controller. x[k+1] = A x[k] + B u[k] cost = sum x[k].T*Q*x[k] + u[k].T*R*u[k] """ #ref Bertsekas, p.151 #first, try to solve the ricatti equation X = np.matrix(scipy.linalg.solve_discrete_are(A, B, Q, R)) #compute the LQR gain K = np.matrix(scipy.linalg.inv(B.T*X*B+R)*(B.T*X*A)) eigVals, eigVecs = scipy.linalg.eig(AB*K) return K, X, eigVals 