6#include <Eigen/Eigenvalues>
7#include <Eigen/Cholesky>
15 template<
class T,
int NStates,
int NInputs,
int NPerfOutputs,
int NMeasOutputs,
int NDisturbances>
17 const Eigen::Matrix<T, NStates, NStates>& A,
18 const Eigen::Matrix<T, NStates, NDisturbances>& Bw,
19 const Eigen::Matrix<T, NStates, NInputs>& Bu,
20 const Eigen::Matrix<T, NPerfOutputs, NStates>& Cz,
21 const Eigen::Matrix<T, NPerfOutputs, NInputs>& Duz,
22 const Eigen::Matrix<T, NMeasOutputs, NStates>& Cy,
23 const Eigen::Matrix<T, NMeasOutputs, NDisturbances>& Dwy,
24 const Eigen::Matrix<T, NInputs, NInputs>& R,
25 const Eigen::Matrix<T, NMeasOutputs, NMeasOutputs>& S
29 const Eigen::Matrix<T, NStates, NStates> Q = Cz.transpose() * Cz;
30 const Eigen::Matrix<T, NStates, NStates> W = Bw * Bw.transpose();
35 const Eigen::Matrix<T, NStates, NInputs> N1 = Cz.transpose() * Duz;
40 const Eigen::Matrix<T, NStates, NMeasOutputs> N2 = Bw * Dwy.transpose();
41 const Eigen::Matrix<T, NStates, NStates> Y =
controlpp::care_solver(A.transpose().eval(), Cy.transpose().eval(), W, S, N2);
45 const Eigen::Matrix<T, NInputs, NStates> F = -R.ldlt().solve(Bu.transpose() * X + Duz.transpose() * Cz);
49 const Eigen::Matrix<T, NStates, NMeasOutputs> M = Y * Cy.transpose() + Bw * Dwy.transpose();
50 const Eigen::Matrix<T, NStates, NMeasOutputs> L = -S.ldlt().solve(M.transpose()).transpose();
53 const Eigen::Matrix<T, NStates, NStates> A_K = A + Bu * F + L * Cy;
54 const Eigen::Matrix<T, NStates, NMeasOutputs> B_K = -L;
55 const Eigen::Matrix<T, NInputs, NStates> C_K = F;
185 template<
class T,
int NStates,
int NInputs,
int NPerfOutputs,
int NMeasOutputs,
int NDisturbances>
186 requires(NInputs>1 && NMeasOutputs>1)
188 const Eigen::Matrix<T, NStates, NStates>& A,
189 const Eigen::Matrix<T, NStates, NDisturbances>& Bw,
190 const Eigen::Matrix<T, NStates, NInputs>& Bu,
191 const Eigen::Matrix<T, NPerfOutputs, NStates>& Cz,
192 const Eigen::Matrix<T, NPerfOutputs, NInputs>& Duz,
193 const Eigen::Matrix<T, NMeasOutputs, NStates>& Cy,
194 const Eigen::Matrix<T, NMeasOutputs, NDisturbances>& Dwy,
195 const Eigen::Vector<T, NInputs> r = Eigen::Vector<T, NInputs>::Zero(),
196 const Eigen::Vector<T, NMeasOutputs> s = Eigen::Vector<T, NMeasOutputs>::Zero()
200 const Eigen::Matrix<T, NInputs, NInputs> R = Duz.transpose() * Duz + Eigen::DiagonalMatrix<T, NInputs>(r.array() * r.array()).toDenseMatrix();
201 const Eigen::Matrix<T, NMeasOutputs, NMeasOutputs> S = (Dwy * Dwy.transpose() + Eigen::DiagonalMatrix<T, NMeasOutputs>(s.array() * s.array()).toDenseMatrix()).eval();
210 template<
class T,
int NStates,
int NInputs,
int NPerfOutputs,
int NMeasOutputs,
int NDisturbances>
212 const Eigen::Matrix<T, NStates, NStates>& A,
213 const Eigen::Matrix<T, NStates, NDisturbances>& Bw,
214 const Eigen::Matrix<T, NStates, NInputs>& Bu,
215 const Eigen::Matrix<T, NPerfOutputs, NStates>& Cz,
216 const Eigen::Matrix<T, NPerfOutputs, NInputs>& Duz,
217 const Eigen::Matrix<T, NMeasOutputs, NStates>& Cy,
218 const Eigen::Matrix<T, NMeasOutputs, NDisturbances>& Dwy,
219 const T& r_scalar = 0,
220 const T& s_scalar = 0
224 const Eigen::Vector<T, NInputs> r = Eigen::Vector<T, NInputs>::Constant(
static_cast<T
>(r_scalar * r_scalar));
225 const Eigen::Vector<T, NMeasOutputs> s = Eigen::Vector<T, NMeasOutputs>::Constant(
static_cast<T
>(s_scalar * s_scalar));
228 const Eigen::Matrix<T, NInputs, NInputs> R = Duz.transpose() * Duz + Eigen::DiagonalMatrix<T, NInputs>(r).toDenseMatrix();
229 const Eigen::Matrix<T, NMeasOutputs, NMeasOutputs> S = (Dwy * Dwy.transpose() + Eigen::DiagonalMatrix<T, NMeasOutputs>(s).toDenseMatrix()).eval();
238 template<
class T,
int NStates,
int NInputs=1,
int NPerfOutputs=1,
int NMeasOutputs=1,
int NDisturbances=1>
240 Eigen::Matrix<T, NStates, NStates>
A;
241 Eigen::Matrix<T, NStates, NDisturbances>
Bw;
242 Eigen::Matrix<T, NStates, NInputs>
Bu;
243 Eigen::Matrix<T, NPerfOutputs, NStates>
Cz;
244 Eigen::Matrix<T, NPerfOutputs, NInputs>
Duz;
245 Eigen::Matrix<T, NMeasOutputs, NStates>
Cy;
246 Eigen::Matrix<T, NMeasOutputs, NDisturbances>
Dwy;
249 template<
class T,
int NStates,
int NInputs=1,
int NPerfOutputs=1,
int NMeasOutputs=1,
int NDisturbances=1>
251 stream <<
"A:\n" << G.
A <<
"\n";
252 stream <<
"Bw:\n" << G.
Bw <<
"\n";
253 stream <<
"Bu:\n" << G.
Bu <<
"\n";
254 stream <<
"Cz:\n" << G.
Cz <<
"\n";
255 stream <<
"Duz:\n" << G.
Duz <<
"\n";
256 stream <<
"Cy:\n" << G.
Cy <<
"\n";
257 stream <<
"Dwy:\n" << G.
Dwy <<
"\n";
273 template<
class T,
int NStates,
int NInputs,
int NPerfOutputs,
int NMeasOutputs,
int NDisturbances>
276 const Eigen::Vector<T, NInputs>& control_penalty = Eigen::Vector<T, NInputs>::Zero(),
277 const Eigen::Vector<T, NMeasOutputs>& measurement_noise = Eigen::Vector<T, NMeasOutputs>::Zero()
280 Gss.
A, Gss.
Bw, Gss.
Bu,
283 control_penalty, measurement_noise
287 template<
class T,
int NStates,
int NInputs,
int NPerfOutputs,
int NMeasOutputs,
int NDisturbances>
290 const T& control_penalty =
static_cast<T
>(0),
291 const T& measurement_noise =
static_cast<T
>(0)
294 Gss.
A, Gss.
Bw, Gss.
Bu,
297 control_penalty, measurement_noise
337 int PNumOrder,
int PDenOrder,
338 int MNumOrder,
int MDenOrder,
339 int WdNumOrder,
int WdDenOrder,
340 int WzNumOrder,
int WzDenOrder>
346 const T& control_penalty,
347 const T& measurement_noise
349 constexpr int NStates = PDenOrder + MDenOrder + WdDenOrder + WzDenOrder;
350 constexpr int NInputs = 1;
351 constexpr int NPerfOutputs = 1;
352 constexpr int NMeasOutputs = 1;
353 constexpr int NDisturbances = 1;
365 Gp.
A.template block<PDenOrder, PDenOrder>(0, 0) = P_ss.A();
366 Gp.
A.template block<WdDenOrder, WdDenOrder>(PDenOrder, PDenOrder) = Wd_ss.A();
367 Gp.
A.template block<WzDenOrder, WzDenOrder>(PDenOrder + WdDenOrder, PDenOrder + WdDenOrder) = Wz_ss.A();
368 Gp.
A.template block<MDenOrder, MDenOrder>(PDenOrder + WdDenOrder + WzDenOrder, PDenOrder + WdDenOrder + WzDenOrder) = M_ss.A();
371 const Eigen::Matrix<T, WzDenOrder, PDenOrder> BzCp = Wz_ss.B() * P_ss.C();
372 Gp.
A.template block<WzDenOrder, PDenOrder>(PDenOrder + WdDenOrder, 0) = BzCp;
374 const Eigen::Matrix<T, WzDenOrder, WdDenOrder> BzCd = Wz_ss.B() * Wd_ss.C();
375 Gp.
A.template block<WzDenOrder, WdDenOrder>(PDenOrder + WdDenOrder, PDenOrder) = BzCd;
377 const Eigen::Matrix<T, MDenOrder, PDenOrder> BmCp = M_ss.B() * P_ss.C();
378 Gp.
A.template block<MDenOrder, PDenOrder>(PDenOrder + WdDenOrder, 0) = BmCp;
380 const Eigen::Matrix<T, MDenOrder, WdDenOrder> BmCd = M_ss.B() * Wd_ss.C();
381 Gp.
A.template block<MDenOrder, WdDenOrder>(PDenOrder + WdDenOrder, PDenOrder) = BmCd;
385 Gp.
Bw.template block<WdDenOrder, 1>(PDenOrder, 0) = Wd_ss.B();
389 Gp.
Bu.template block<PDenOrder, 1>(0, 0) = P_ss.B();
393 Gp.
Cz.template block<1, WzDenOrder>(0, PDenOrder + WdDenOrder) = Wz_ss.C();
397 Gp.
Cy.template block<1, MDenOrder>(0, PDenOrder + WdDenOrder + WzDenOrder) = M_ss.C();
401 Gp.
Dwy(0, 0) = measurement_noise;
Definition ContinuousStateSpace.hpp:10
Continuous transfer functions in the s lapace plain.
Definition ContinuousTransferFunction.hpp:28
The main namespace for the Control++ library.
Definition Bode.cpp:3
ContinuousStateSpace< T, NStates, NMeasOutputs, NInputs > continuous_h2(const ContinuousGeneralisedPlant< T, NStates, NInputs, NPerfOutputs, NMeasOutputs, NDisturbances > &Gss, const Eigen::Vector< T, NInputs > &control_penalty=Eigen::Vector< T, NInputs >::Zero(), const Eigen::Vector< T, NMeasOutputs > &measurement_noise=Eigen::Vector< T, NMeasOutputs >::Zero())
Constructs a continuous H2 controller from a continuous state space plant model.
Definition H2Controller.hpp:274
std::ostream & operator<<(std::ostream &stream, EBodeCsvReadError val)
Definition Bode.cpp:5
ContinuousStateSpace< T, NStates, NMeasOutputs, NInputs > continous_h2(const Eigen::Matrix< T, NStates, NStates > &A, const Eigen::Matrix< T, NStates, NDisturbances > &Bw, const Eigen::Matrix< T, NStates, NInputs > &Bu, const Eigen::Matrix< T, NPerfOutputs, NStates > &Cz, const Eigen::Matrix< T, NPerfOutputs, NInputs > &Duz, const Eigen::Matrix< T, NMeasOutputs, NStates > &Cy, const Eigen::Matrix< T, NMeasOutputs, NDisturbances > &Dwy, const Eigen::Matrix< T, NInputs, NInputs > &R, const Eigen::Matrix< T, NMeasOutputs, NMeasOutputs > &S)
Definition H2Controller.hpp:16
ContinuousStateSpace< T, DenOrder, 1, 1 > to_state_space(const ContinuousTransferFunction< T, NumOrder, DenOrder > &ctf)
constructs a continuous state space function from a continuous transfer function
Definition ContinuousStateSpace.hpp:91
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
A continuous generalised plant model.
Definition H2Controller.hpp:239
Eigen::Matrix< T, NMeasOutputs, NStates > Cy
Definition H2Controller.hpp:245
Eigen::Matrix< T, NStates, NDisturbances > Bw
Definition H2Controller.hpp:241
Eigen::Matrix< T, NStates, NStates > A
Definition H2Controller.hpp:240
Eigen::Matrix< T, NMeasOutputs, NDisturbances > Dwy
Definition H2Controller.hpp:246
Eigen::Matrix< T, NPerfOutputs, NInputs > Duz
Definition H2Controller.hpp:244
Eigen::Matrix< T, NStates, NInputs > Bu
Definition H2Controller.hpp:242
Eigen::Matrix< T, NPerfOutputs, NStates > Cz
Definition H2Controller.hpp:243