5 #ifndef LODESTAR_ZEROORDERHOLD_HPP
6 #define LODESTAR_ZEROORDERHOLD_HPP
9 #include <unsupported/Eigen/MatrixFunctions>
10 #include "Lodestar/systems/StateSpace.hpp"
11 #include "Lodestar/aux/CompileTimeQualifiers.hpp"
23 template<
typename TScalar =
double,
int TStateDim = Eigen::Dynamic,
int TInputDim = Eigen::Dynamic,
int TOutputDim = Eigen::Dynamic>
25 template<
int TTStateDim = TStateDim,
int TTInputDim = TInputDim,
int TTOutputDim = TOutputDim, typename ::std::enable_if<
26 (TTStateDim >= 0) && (TTInputDim >= 0) && (TTOutputDim >= 0)>::type * =
nullptr>
27 mallocStruct() : upperXM(decltype(upperXM)::Zero()), lowerXM(decltype(lowerXM)::Zero()),
28 XM(decltype(XM)::Zero()), XXM(
29 decltype(XXM)::Zero())
32 template<
int TTStateDim = TStateDim,
int TTInputDim = TInputDim,
int TTOutputDim = TOutputDim, typename ::std::enable_if<
33 (TTStateDim < 0) && (TTInputDim < 0) && (TTOutputDim < 0)>::type * =
nullptr>
37 Eigen::Matrix<TScalar, TStateDim, LS_STATIC_UNLESS_DYNAMIC(TStateDim + TInputDim)> upperXM;
38 Eigen::Matrix<TScalar, TInputDim, LS_STATIC_UNLESS_DYNAMIC(TStateDim + TInputDim)> lowerXM;
39 Eigen::Matrix<TScalar, LS_STATIC_UNLESS_DYNAMIC(TStateDim + TInputDim), LS_STATIC_UNLESS_DYNAMIC(
40 TStateDim + TInputDim)> XM;
41 Eigen::Matrix<TScalar, TStateDim, LS_STATIC_UNLESS_DYNAMIC(TStateDim + TInputDim)> XXM;
57 c2d(
const Eigen::MatrixXd &A,
const Eigen::MatrixXd &B,
58 const Eigen::MatrixXd &C,
const Eigen::MatrixXd &D,
double dt);
73 c2d(Eigen::MatrixXd *A, Eigen::MatrixXd *B, Eigen::MatrixXd *C, Eigen::MatrixXd *D,
double dt);
76 template<
typename TScalar,
int TStateDim,
int TInputDim,
int TOutputDim>
80 LS_IS_DYNAMIC_DEFAULT(TStateDim, TInputDim, TOutputDim));
82 template<
typename TScalar,
int TStateDim,
int TInputDim,
int TOutputDim>
86 LS_IS_STATIC_DEFAULT(TStateDim, TInputDim, TOutputDim));
124 d2c(
const Eigen::MatrixXd &A,
const Eigen::MatrixXd &B,
125 const Eigen::MatrixXd &C,
const Eigen::MatrixXd &D,
double dt);
140 d2c(Eigen::MatrixXd *A, Eigen::MatrixXd *B,
141 Eigen::MatrixXd *C, Eigen::MatrixXd *D,
double dt);
206 template<
typename TScalar,
int TStateDim,
int TInputDim,
int TOutputDim>
210 LS_IS_DYNAMIC_DEFAULT(TStateDim, TInputDim, TOutputDim));
221 template<
typename TScalar,
int TStateDim,
int TInputDim,
int TOutputDim>
225 LS_IS_STATIC_DEFAULT(TStateDim, TInputDim, TOutputDim));
230 template<
typename TScalar,
int TStateDim,
int TInputDim,
int TOutputDim>
235 LS_IS_DYNAMIC(TStateDim, TInputDim, TOutputDim))
242 memStruct->upperXM.block(0, 0, n, n) << (ss->
getA());
243 memStruct->upperXM.block(0, n, n, m) << (ss->
getB());
245 memStruct->lowerXM.setZero();
247 memStruct->XM.block(0, 0, n, n + m) << memStruct->upperXM;
248 memStruct->XM.block(n, 0, m, n + m) << memStruct->lowerXM;
250 memStruct->XXM = (memStruct->XM * dt).exp().block(0, 0, n, n + m);
252 out->
setA(memStruct->XXM.block(0, 0, n, n));
253 out->
setB(memStruct->XXM.block(0, n, n, m));
254 out->
setC(Eigen::MatrixXd::Identity(n, n));
255 out->
setD(Eigen::MatrixXd::Zero(n, m));
260 template<
typename TScalar,
int TStateDim,
int TInputDim,
int TOutputDim>
265 LS_IS_STATIC(TStateDim, TInputDim, TOutputDim))
269 memStruct->upperXM.template block<TStateDim, TStateDim>(0, 0);
270 memStruct->upperXM.template block<TStateDim, TStateDim>(0, 0) << (ss->
getA());
271 memStruct->upperXM.template block<TStateDim, TInputDim>(0, TStateDim) << (ss->
getB());
273 memStruct->lowerXM.setZero();
275 memStruct->XM.template block<TStateDim, TStateDim + TInputDim>(0, 0) << memStruct->upperXM;
276 memStruct->XM.template block<TInputDim, TStateDim + TInputDim>(TStateDim, 0) << memStruct->lowerXM;
278 memStruct->XXM = (memStruct->XM * dt).exp().template block<TStateDim, TStateDim + TInputDim>(0, 0);
280 out->
setA(memStruct->XXM.template block<TStateDim, TStateDim>(0, 0));
281 out->
setB(memStruct->XXM.template block<TStateDim, TInputDim>(0, TStateDim));
285 template<
typename TScalar,
int TStateDim,
int TInputDim,
int TOutputDim>
290 LS_IS_DYNAMIC(TStateDim, TInputDim, TOutputDim))
297 memStruct->upperXM.block(0, 0, n, n) << (ss->
getA());
298 memStruct->upperXM.block(0, n, n, m) << (ss->
getB());
300 memStruct->lowerXM.setZero();
301 memStruct->lowerXM.block(0, n, m, m).setIdentity();
303 memStruct->XM.block(0, 0, n, n + m) << memStruct->upperXM;
304 memStruct->XM.block(n, 0, m, n + m) << memStruct->lowerXM;
306 memStruct->XXM = (memStruct->XM).log().block(0, 0, n, n + m) / dt;
308 out->
setA(memStruct->XXM.block(0, 0, n, n));
309 out->
setB(memStruct->XXM.block(0, n, n, m));
312 template<
typename TScalar,
int TStateDim,
int TInputDim,
int TOutputDim>
317 LS_IS_STATIC(TStateDim, TInputDim, TOutputDim))
321 memStruct->upperXM.template block<TStateDim, TStateDim>(0, 0) << (ss->
getA());
322 memStruct->upperXM.template block<TStateDim, TInputDim>(0, TStateDim) << (ss->
getB());
324 memStruct->lowerXM.setZero();
325 memStruct->lowerXM.template block<TInputDim, TInputDim>(0, TStateDim)
326 << Eigen::Matrix<TScalar, TInputDim, TInputDim>::Identity();
328 memStruct->XM.template block<TStateDim, TStateDim + TInputDim>(0, 0) << memStruct->upperXM;
329 memStruct->XM.template block<TInputDim, TStateDim + TInputDim>(TStateDim, 0) << memStruct->lowerXM;
331 memStruct->XXM = (memStruct->XM).log().template block<TStateDim, TStateDim + TInputDim>(0, 0) / dt;
333 out->
setA(memStruct->XXM.template block<TStateDim, TStateDim>(0, 0));
334 out->
setB(memStruct->XXM.template block<TStateDim, TInputDim>(0, TStateDim));
337 #endif //LODESTAR_ZEROORDERHOLD_HPP