rsLQR  0.1
Using the rsLQR Algorithm

This page provides some details on how to use the rsLQR solver to solve an LQR problem.

Part I: Defining the problem

First, create a new LQRProblem with ndlqr_NewLQRProblem

LQRProblem* lqrprob = ndlqr_NewLQRProblem(nstates, ninputs, nhorizon);

Next, fill in the LQRProblem data. You can choose to define an array of LQRData structs and use ndlqr_InitializeLQRProblem(), or loop over time steps and do it yourself

lqrprob->nhorizon = nhorizon;
for (int i = 0; i < nstates; ++i) {
lqrprob->x0[i] = x0[i]; // assumes x0 is defined somewhere
}
for (int k = 0; i < nhorizon; ++k) {
// Assumes all of the following data is defined
LQRData* data = lqrprob->lqrdata[k];
ndlqr_InitializeLQRData(data, Q, R, q, r, c, A, B, d);
}

Part II: Setting up the solver

Initialize a new solver

NdLqrSolver* solver = rdlqr_NewNdLqrSolver(nstates, ninputs, nhorizon);

Then copy in the data from the LQRProblem

Optionally, you can also set the number of threads.

ndlqr_SetNumThreads(solver, num_threads);

Note that this just requests the number of threads from OpenMP, but doesn't provide a guarantee that this number of threads will be provided. Check the actual number of threads afterwards with ndlqr_GetNumThreads();

Part III: Solving

Call the ndlqr_Solve() method to solve the system:

ndlqr_Solve(solver);

Right now the solve can't be separated between the factorization step and the solve step.

Part IV: Getting the solution and post-processing

You can print the summary using

For retrieving the solution vector, you can use one of two methods:

int nvars = ndlqr_GetNumVars(solver);
double* soln = (double*) malloc(nvars * sizeof(double));
ndlqr_CopySolution(solver, soln);

or

Matrix soln = ndlqr_GetSolution(solver);

Note that the second method return a Matrix whose data is still owned by the solver (avoids a memory allocation or copy). Do not free this memory and be aware that editing it will edit the data stored in the solver.

Part V: Freeing the solver

Don't forget to free the solver!

ndlqr_GetNumVars
int ndlqr_GetNumVars(NdLqrSolver *solver)
Gets the total number of decision variables for the problem.
Definition: solver.c:211
ndlqr_InitializeLQRData
int ndlqr_InitializeLQRData(LQRData *lqrdata, double *Q, double *R, double *q, double *r, double c, double *A, double *B, double *d)
Copy data into an initialized LQRData structure.
Definition: lqr_data.c:10
ndlqr_CopySolution
int ndlqr_CopySolution(NdLqrSolver *solver, double *soln)
Copies the solution vector to a user-supplied array.
Definition: solve.c:197
Matrix
Represents a matrix of double-precision data.
Definition: matrix.h:71
NdLqrSolver
Main solver for rsLQR.
Definition: solver.h:114
ndlqr_NewLQRProblem
LQRProblem * ndlqr_NewLQRProblem(int nstates, int ninputs, int nhorizon)
Initialize a new LQRProblem data with unitialized data.
Definition: lqr_problem.c:16
ndlqr_GetSolution
Matrix ndlqr_GetSolution(NdLqrSolver *solver)
Return the solution vector.
Definition: solve.c:192
LQRData
Holds the data for a single time step of LQR.
Definition: lqr_data.h:54
ndlqr_SetNumThreads
int ndlqr_SetNumThreads(NdLqrSolver *solver, int num_threads)
Set the number of threads to be used during the solve.
Definition: solver.c:213
ndlqr_InitializeWithLQRProblem
int ndlqr_InitializeWithLQRProblem(const LQRProblem *lqrprob, NdLqrSolver *solver)
Initialize the solver with data from an LQR Problem.
Definition: solver.c:122
ndlqr_Solve
int ndlqr_Solve(NdLqrSolver *solver)
Solve an LQR problem using rsLQR.
Definition: solve.c:38
ndlqr_PrintSolveSummary
void ndlqr_PrintSolveSummary(NdLqrSolver *solver)
Prints a summary of the solve.
Definition: solver.c:196
LQRProblem
Describes an LQR problem with affine terms.
Definition: lqr_problem.h:31
ndlqr_FreeNdLqrSolver
int ndlqr_FreeNdLqrSolver(NdLqrSolver *solver)
Deallocates the memory for the solver.
Definition: solver.c:108