Processing math: 100%

LQR Control Using Factor Graphs

GTSAM Posts

Authors: Gerry Chen, Yetong Zhang, and Frank Dellaert

Introduction

Factor graph structure. The objective factors are marked with dashed lines, and the constrain factors are marked with solid lines.
Figure 1 Factor graph structure for an LQR problem with 3 time steps. The cost factors are marked with dashed lines and the dynamics constraint factors are marked with solid lines.


In this post we explain how optimal control problems can be formulated as factor graphs and solved by performing variable elimination on the factor graph.

Specifically, we will show the factor graph formulation and solution for the Linear Quadratic Regulator (LQR). LQR is a state feedback controller which derives the optimal gains for a linear system with quadratic costs on control effort and state error.

We consider the finite-horizon, discrete LQR problem. The task is to find the optimal controls uk at time instances tk so that a total cost is minimized. Note that we will later see the optimal controls can be represented in the form uk=Kkxk for some optimal gain matrices Kk. The LQR problem can be represented as a constrained optimization problem where the costs of control and state error are represented by the minimization objective (1), and the system dynamics are represented by the constraints (2).

argminu1N  xTNQxN+N1k=1xTkQxk+uTkRuk s.t.  xk+1=Axk+Buk  for k=1 to N1

We can visualize the objective function and constraints in the form of a factor graph as shown in Figure 1. This is a simple Markov chain, with the oldest states and controls on the left, and the newest states and controls on the right. The ternary factors represent the dynamics model constraints and the unary factors represent the state and control costs we seek to minimize via least-squares.

Variable Elimination

To optimize the factor graph, which represents minimizing the least squares objectives above, we can simply eliminate the factors from right to left. In this section we demonstrate the variable elimination graphically and algebraically, but the matrix elimination is also provided in the Appendix.

Elimination of state $x_2$
Figure 2a Elimination of state x2

Eliminate a State

Let us start at the last state, x2. Gathering the two factors (marked in red Figure 2a), we have (3) the objective function ϕ1, and (4) the constraint equation on x2, u1 and x1:

ϕ1(x2)=xT2Qx2

x2=Ax1+Bu1

By substituting x2 from the dynamics constraint (4) into the objective function (3), we create a new factor representing the cost of state x2 as a function of x1 and u1:

ϕ2(x1,u1)=(Ax1+Bu1)TQ(Ax1+Bu1)

The resulting factor graph is illustrated in Figure 2b. Note that the dynamics constraint is now represented by the bayes net factors shown as gray arrows.

To summarize, we used the dynamics constraint to eliminate variable x2 and the two factors marked in red, and we replaced them with a new binary cost factor on x1 and u1, marked in blue.

next >>

Intuition

Comparison between LQR control as solved by factor graphs and by the Ricatti Equation. (they are the same)
Figure 5 Example LQR control solutions as solved by factor graphs (middle) and the traditional Discrete Algebraic Ricatti Equations (right). The optimal control gains and cost-to-go factors are compared (left). All plots show exact agreement between factor graph and Ricatti equation solutions.

We introduce the cost-to-go (also known as return cost, optimal state value function, or simply value function) as Vk(x):=xTPkx which intuitively represents the total cost that will be accrued from here on out, assuming optimal control.

In our factor graph representation, it is becomes obvious that Vk(x) corresponds to the total cost at and after the state xk assuming optimal control because we eliminate variables backwards in time with the objective of minimizing cost. Eliminating a state just re-expresses the future cost in terms of prior states/controls. Each time we eliminate a control, u, the future cost is recalculated assuming optimal control (i.e. ϕ4(x)=ϕ3(x,u)).

This “cost-to-go” is depicted as a heatmap in Figure 5. The heat maps depict the Vk showing that the cost is high when x is far from 0, but also showing that after iterating sufficient far backwards in time, Vk(x) begins to converge. That is to say, the V0(x) is very similar for N=30 and N=100. Similarly, the leftmost plot of Figure 5 depicts Kk and Pk and shows that they (predictably) converge as well.

This convergence allows us to see that we can extend to the infinite horizon LQR problem (continued in the next section).

Equivalence to the Ricatti Equation

In traditional descriptions of discrete, finite-horizon LQR (i.e. Chow, Kirk, Stanford), the control law and cost function are given by

uk=Kkxk

Kk=(R+BTPk+1B)1BTPk+1A

Pk=Q+ATPk+1AKTkBTPk+1A

with Pk commonly referred to as the solution to the dynamic Ricatti equation and PN=Q is the value of the Ricatti function at the final time step. (12) and (13) correspond to the same results as we derived in (9) and (10) respectively.

Recall that P0 and K0 appear to converge as the number of time steps grows. They will approach a stationary solution to the equations

K=(R+BTPB)1BTPAP=Q+ATPAKTBTPA

as N. This is the Discrete Algebraic Ricatti Equations (DARE) and limNV0(x) and limNK0 are the cost-to-go and optimal control gain respectively for the infinite horizon LQR problem. Indeed, one way to calculate the solution to the DARE is to iterate on the dynamic Ricatti equation.

Implementation using GTSAM

**Edit (Apr 17, 2021): Code updated to new Python wrapper as of GTSAM 4.1.0.

You can view an example Jupyter notebook on google colab or download the modules/examples that you can use in your projects to:

  • Calculate the closed loop gain matrix, K, using GTSAM
  • Calculate the “cost-to-go” matrix, P (which is equivalent to the solutions to the dynamic Ricatti equation), using GTSAM
  • Calculate the LQR solution for a non-zero, non-constant goal position, using GTSAM
  • Visualize the cost-to-go and how it relates to factor graphs and the Ricatti equation
  • and more!

A brief example of the open-loop finite horizon LQR problem using factor graphs is shown below:

def solve_lqr(A, B, Q, R, X0=np.array([0., 0.]), num_time_steps=500):
    '''Solves a discrete, finite horizon LQR problem given system dynamics in
    state space representation.
    Arguments:
        A, B: nxn state transition matrix and nxp control input matrix
        Q, R: nxn state cost matrix and pxp control cost matrix
        X0: initial state (n-vector)
        num_time_steps: number of time steps, T
    Returns:
        x_sol, u_sol: Txn array of states and Txp array of controls
    '''
    n = np.size(A, 0)
    p = np.size(B, 1)

    # noise models
    prior_noise = gtsam.noiseModel.Constrained.All(n)
    dynamics_noise = gtsam.noiseModel.Constrained.All(n)
    q_noise = gtsam.noiseModel.Gaussian.Information(Q)
    r_noise = gtsam.noiseModel.Gaussian.Information(R)

    # Create an empty Gaussian factor graph
    graph = gtsam.GaussianFactorGraph()

    # Create the keys corresponding to unknown variables in the factor graph
    X = []
    U = []
    for k in range(num_time_steps):
        X.append(gtsam.symbol('x', k))
        U.append(gtsam.symbol('u', k))

    # set initial state as prior
    graph.add(X[0], np.eye(n), X0, prior_noise)

    # Add dynamics constraint as ternary factor
    #   A.x1 + B.u1 - I.x2 = 0
    for k in range(num_time_steps-1):
        graph.add(X[k], A, U[k], B, X[k+1], -np.eye(n),
                  np.zeros((n)), dynamics_noise)

    # Add cost functions as unary factors
    for x in X:
        graph.add(x, np.eye(n), np.zeros(n), q_noise)
    for u in U:
        graph.add(u, np.eye(p), np.zeros(p), r_noise)

    # Solve
    result = graph.optimize()
    x_sol = np.zeros((num_time_steps, n))
    u_sol = np.zeros((num_time_steps, p))
    for k in range(num_time_steps):
        x_sol[k, :] = result.at(X[k])
        u_sol[k] = result.at(U[k])
    
    return x_sol, u_sol

Future Work

The factor graph (Figure 1) for our finite horizon discrete LQR problem can be readily extended to LQG, iLQR, DDP, and reinforcement learning using non-deterministic dynamics factors, nonlinear factors, discrete factor graphs, and other features of GTSAM (stay tuned for future posts).




Appendix

Least Squares Implementation in GTSAM

GTSAM can be specified to use either of two methods for solving the least squares problems that appear in eliminating factor graphs: Cholesky Factorization or QR Factorization. Both arrive at the same result, but we will take a look at QR since it more immediately illustrates the elimination algorithm at work.

QR Factorization

NMElimination Matrix[Q1/2|II|0R1/2|IQ1/2|IA|0R1/2|IQ1/2|I][Q1/20IBA0R1/20Q1/20IBA0R1/20Q1/20]

factor graph partially eliminated
Figure 6a Initial factor graph and elimination matrix


wherePk=Q+ATPk+1AKTkBTPk+1A(P2=Q)
Dk=R+BTPk+1B
Kk=D1/2k(R+BTPk+1B)T/2BTPk+1A
=(R+BTPk+1B)1BTPk+1A


The factorization process is illustrated in Figure 6 for a 3-time step factor graph, where the noise matrices and elimination matrices are shown with the corresponding states of the graph. The noise matrix (NM) is 0 for a hard constraint and I for a minimization objective. The elimination matrix is formatted as an augmented matrix [A|b] for the linear least squares problem argminx||Axb||22 with x=[x2;u1;x1;u0;x0] is the vertical concatenation of all state and control vectors. The recursive expressions for P, D, and K when eliminating control variables (i.e. u1 in Figure 6e) are derived from block QR Factorization.

Note that all bi=0 in the augmented matrix for the LQR problem of finding minimal control to reach state 0, but simply changing values of bi intuitively extends GTSAM to solve LQR problems whose objectives are to reach different states or even follow trajectories.