Controlpp
Loading...
Searching...
No Matches
LQRController.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <Eigen/Dense>
4
5#include <controlpp/math.hpp>
7
8
9namespace controlpp{
10
23 template<class T, int NStates, int NInputs>
24 Eigen::Matrix<T, NInputs, NStates> lqr_continuous(
25 const Eigen::Matrix<T, NStates, NStates>& A,
26 const Eigen::Matrix<T, NStates, NInputs>& B,
27 const Eigen::Matrix<T, NStates, NStates>& Q = Eigen::Matrix<T, NStates, NStates>::Identity(),
28 const Eigen::Matrix<T, NInputs, NInputs>& R = Eigen::Matrix<T, NInputs, NInputs>::Identity()
29 ){
30 const Eigen::Matrix<T, NStates, NStates> P = care_solver(A, B, Q, R);
31 const Eigen::Matrix<T, NInputs, NStates> K = R.llt().solve(B.transpose() * P);
32 return K;
33 }
34
47 template<class T, int NStates, int NInputs>
48 Eigen::Matrix<T, NInputs, NStates> lqr_discrete(
49 const Eigen::Matrix<T, NStates, NStates>& A,
50 const Eigen::Matrix<T, NStates, NInputs>& B,
51 const Eigen::Matrix<T, NStates, NStates>& Q = Eigen::Matrix<T, NStates, NStates>::Identity(),
52 const Eigen::Matrix<T, NInputs, NInputs>& R = Eigen::Matrix<T, NInputs, NInputs>::Identity()
53 ){
54 const Eigen::Matrix<T, NStates, NStates> P = dare_solver(A, B, Q, R);
55 const Eigen::Matrix<T, NInputs, NInputs> M1 = R + B.transpose() * P * B;
56 const Eigen::Matrix<T, NInputs, NStates> M2 = B.transpose() * P * A;
57 const Eigen::Matrix<T, NInputs, NStates> K = M1.ldlt().solve(M2);
58 return K;
59 }
60
88 template<class T, int NStates, int NInputs, int NOutputs>
89 Eigen::Matrix<T, NInputs, NStates> lqr(
91 const Eigen::Matrix<T, NStates, NStates>& Q,
92 const Eigen::Matrix<T, NInputs, NInputs>& R
93 ){
94 return lqr_discrete(Gss.A(), Gss.B(), Q, R);
95 }
96
124 template<
125 class T, int NStates, int NInputs, int NOutputs,
126 std::convertible_to<T> U1 = T, std::convertible_to<T> U2 = T>
127 Eigen::Matrix<T, NInputs, NStates> lqr(
129 const U1& r = static_cast<U1>(1),
130 const U2& eps = static_cast<U2>(0.001)
131 ){
132 const Eigen::Matrix<T, NStates, NStates> Iq = Eigen::Matrix<T, NStates, NStates>::Identity();
133 const Eigen::Matrix<T, NStates, NStates> Q1 = Gss.C().transpose() * Gss.C();
134 const Eigen::Matrix<T, NStates, NStates> Q = Q1 + Iq * (Q1.norm() * (eps * eps));
135 const Eigen::Matrix<T, NInputs, NInputs> R = Eigen::Matrix<T, NInputs, NInputs>::Ones() * (r * r);
136 return lqr_discrete(Gss.A(), Gss.B(), Q, R);
137 }
138
163 template<class T, int NStates, int NInputs, int NOutputs, std::convertible_to<T> U1 = T, std::convertible_to<T> U2 = T>
164 Eigen::Matrix<T, NInputs, NStates> lqr_bryson(
166 const Eigen::Vector<T, NOutputs>& x_max,
167 const Eigen::Vector<T, NInputs>& u_max
168 ){
169
170 const Eigen::Vector<T, NOutputs> q = static_cast<T>(1) / x_max.array().square();
171 const Eigen::Matrix<T, NStates, NStates> Iq = Eigen::Matrix<T, NStates, NStates>::Identity();
172 const Eigen::Matrix<T, NStates, NStates> Q1 = Gss.C().transpose() * q.asDiagonal() * Gss.C();
173 const Eigen::Matrix<T, NStates, NStates> Q = Q1 + Iq * (Q1.norm() * 0.000001);
174
175 const Eigen::Vector<T, NOutputs> r = static_cast<T>(1) / u_max.array().square();
176 const Eigen::Matrix<T, NInputs, NInputs> R = r.asDiagonal();
177
178 return lqr_discrete(Gss.A(), Gss.B(), Q, R);
179 }
180
181 template<class T, int NStates, int NInputs, int NOutputs>
182 Eigen::Matrix<T, NInputs, NOutputs> lqr_feed_forward(
184 Eigen::Matrix<T, NInputs, NStates> LQR
185 ){
186 // LQR feed forward
187 const Eigen::Matrix<double, NStates, NStates> I = controlpp::identity_like(Gss.A());
188 const Eigen::Matrix<double, NStates, NStates> M1 = I - Gss.A() + Gss.B() * LQR;
189 const Eigen::Matrix<double, 1, 1> M = Gss.C() * M1.partialPivLu().solve(Gss.B());
190 const Eigen::Matrix<T, NInputs, NOutputs> F = M.inverse().eval();
191 return F;
192 }
193}
Matrix (A, B, C, D) representation of a linear time invariant system.
Definition DiscreteStateSpace.hpp:41
C_matrix_type & C()
Definition DiscreteStateSpace.hpp:108
B_matrix_type & B()
Definition DiscreteStateSpace.hpp:107
A_matrix_type & A()
Definition DiscreteStateSpace.hpp:106
The main namespace for the Control++ library.
Definition Bode.cpp:3
Eigen::Matrix< T, NInputs, NOutputs > lqr_feed_forward(const DiscreteStateSpace< T, NStates, NInputs, NOutputs > Gss, Eigen::Matrix< T, NInputs, NStates > LQR)
Definition LQRController.hpp:182
Eigen::Matrix< T, Rows, Cols, Options, MaxRows, MaxCols > identity_like(const Eigen::Matrix< T, Rows, Cols, Options, MaxRows, MaxCols > &unused)
Definition math.hpp:205
Eigen::Matrix< T, NStates, NStates > dare_solver(const Eigen::Matrix< T, NStates, NStates, AOpt, AMaxR, AMaxC > &A, const Eigen::Matrix< T, NStates, NInputs, BOpt, BMaxR, BMaxC > &B, const Eigen::Matrix< T, NStates, NStates, QOpt, QMaxR, QMaxC > &Q, const Eigen::Matrix< T, NInputs, NInputs, ROpt, RMaxR, RMaxC > &R)
Solves the discrete time riccati equation (DARE)
Definition math.hpp:668
Eigen::Matrix< T, NInputs, NStates > lqr_bryson(const DiscreteStateSpace< T, NStates, NInputs, NOutputs > Gss, const Eigen::Vector< T, NOutputs > &x_max, const Eigen::Vector< T, NInputs > &u_max)
Construcs a discrete LQR controller with weights trying to limit states and controller outputs.
Definition LQRController.hpp:164
Eigen::Matrix< T, NInputs, NStates > lqr_discrete(const Eigen::Matrix< T, NStates, NStates > &A, const Eigen::Matrix< T, NStates, NInputs > &B, const Eigen::Matrix< T, NStates, NStates > &Q=Eigen::Matrix< T, NStates, NStates >::Identity(), const Eigen::Matrix< T, NInputs, NInputs > &R=Eigen::Matrix< T, NInputs, NInputs >::Identity())
Synthesizes the continuous LQR gain from plant matrices (A, B) and weights (Q, R)
Definition LQRController.hpp:48
Eigen::Matrix< T, NInputs, NStates > lqr_continuous(const Eigen::Matrix< T, NStates, NStates > &A, const Eigen::Matrix< T, NStates, NInputs > &B, const Eigen::Matrix< T, NStates, NStates > &Q=Eigen::Matrix< T, NStates, NStates >::Identity(), const Eigen::Matrix< T, NInputs, NInputs > &R=Eigen::Matrix< T, NInputs, NInputs >::Identity())
Synthesizes the continuous LQR gain from plant matrices (A, B) and weights (Q, R)
Definition LQRController.hpp:24
Eigen::Matrix< T, NInputs, NStates > lqr(const DiscreteStateSpace< T, NStates, NInputs, NOutputs > Gss, const Eigen::Matrix< T, NStates, NStates > &Q, const Eigen::Matrix< T, NInputs, NInputs > &R)
Computes a discrete LQR controller from a discrete state space plant model.
Definition LQRController.hpp:89
Eigen::Matrix< T, NStates, NStates > care_solver(const Eigen::Matrix< T, NStates, NStates, AOpt, AMaxR, AMaxC > &A, const Eigen::Matrix< T, NStates, NInputs, BOpt, BMaxR, BMaxC > &B, const Eigen::Matrix< T, NStates, NStates, QOpt, QMaxR, QMaxC > &Q, const Eigen::Matrix< T, NInputs, NInputs, ROpt, RMaxR, RMaxC > &R)
Solves the continuous time riccati equation (CARE)
Definition math.hpp:608