8 #include <unsupported/Eigen/MatrixFunctions> 10 #define SYMPLECTIC_ENABLED \ 11 template <size_t V, size_t P> \ 12 typename std::enable_if<(V > 0 && P > 0), void>::type 13 #define SYMPLECTIC_DISABLED \ 14 template <size_t V, size_t P> \ 15 typename std::enable_if<(V <= 0 || P <= 0), void>::type 27 template <
size_t STATE_DIM,
29 size_t P_DIM = STATE_DIM / 2,
30 size_t V_DIM = STATE_DIM / 2,
35 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
46 : linearSystem_(linearSystem), settings_(dt, approx)
54 : linearSystem_(linearSystem), settings_(settings)
62 if (other.linearSystem_ !=
nullptr)
63 linearSystem_ = std::shared_ptr<LinearSystem<STATE_DIM, CONTROL_DIM, SCALAR>>(other.linearSystem_->clone());
91 linearSystem_ = linearSystem;
113 const size_t numSteps,
115 state_control_matrix_t& B)
override 117 if (linearSystem_ ==
nullptr)
118 throw std::runtime_error(
"Error in SensitivityApproximation: linearSystem not properly set.");
127 forwardEuler(x, u, n, A, B);
132 backwardEuler(x, u, n + 1, A, B);
137 symplecticEuler<V_DIM, P_DIM>(x, u, x_next,
n, A, B);
147 state_matrix_t Ac_front;
149 state_control_matrix_t Bc_front;
152 linearSystem_->getDerivatives(Ac_front, Bc_front, x, u, n * settings_.
dt_);
153 Ac_front *= settings_.
dt_;
155 state_matrix_t Ac_back =
156 settings_.
dt_ * linearSystem_->getDerivativeState(x_next, u, (n + 1) * settings_.
dt_);
160 state_matrix_t aNewInv;
161 aNewInv.template topLeftCorner<STATE_DIM, STATE_DIM>() =
162 (state_matrix_t::Identity() - Ac_back).colPivHouseholderQr().inverse();
163 A = aNewInv * (state_matrix_t::Identity() + Ac_front);
164 B = aNewInv * settings_.
dt_ * Bc_front;
169 matrixExponential(x, u, n, A, B);
173 throw std::runtime_error(
"Unknown Approximation type in SensitivityApproximation.");
182 state_matrix_t& A_discr,
183 state_control_matrix_t& B_discr)
189 state_matrix_t A_cont;
190 state_control_matrix_t B_cont;
191 linearSystem_->getDerivatives(A_cont, B_cont, x_n, u_n, n * settings_.
dt_);
193 A_discr = state_matrix_t::Identity() + settings_.
dt_ * A_cont;
194 B_discr = settings_.
dt_ * B_cont;
200 state_matrix_t& A_discr,
201 state_control_matrix_t& B_discr)
207 state_matrix_t A_cont;
208 state_control_matrix_t B_cont;
209 linearSystem_->getDerivatives(A_cont, B_cont, x_n, u_n, n * settings_.
dt_);
211 state_matrix_t aNew = settings_.
dt_ * A_cont;
213 A_discr.template topLeftCorner<STATE_DIM, STATE_DIM>() =
214 (state_matrix_t::Identity() - aNew).colPivHouseholderQr().inverse();
216 B_discr = A_discr * settings_.
dt_ * B_cont;
223 state_matrix_t& A_discr,
224 state_control_matrix_t& B_discr)
227 state_control_matrix_t Bc;
228 linearSystem_->getDerivatives(Ac, Bc, x_n, u_n, n * settings_.
dt_);
230 state_matrix_t Adt = settings_.
dt_ * Ac;
232 A_discr.template topLeftCorner<STATE_DIM, STATE_DIM>() = Adt.exp();
233 B_discr.template topLeftCorner<STATE_DIM, CONTROL_DIM>() =
234 Ac.inverse() * (A_discr - state_matrix_t::Identity()) * Bc;
252 state_matrix_t& A_sym,
253 state_control_matrix_t& B_sym)
259 x_interm.topRows(P_DIM) = x_next.topRows(P_DIM);
262 state_control_matrix_t Bc1;
263 linearSystem_->getDerivatives(Ac1, Bc1, x, u, n * dt);
266 state_control_matrix_t Bc2;
267 linearSystem_->getDerivatives(Ac2, Bc2, x_interm, u, n * dt);
269 getSymplecticEulerApproximation<V_DIM, P_DIM>(Ac1, Ac2, Bc1, Bc2, A_sym, B_sym);
287 state_matrix_t& A_sym,
288 state_control_matrix_t& B_sym)
293 state_control_matrix_t Bc1;
294 linearSystem_->getDerivatives(Ac1, Bc1, x, u, n * dt);
296 getSymplecticEulerApproximation<V_DIM, P_DIM>(Ac1, Ac1, Bc1, Bc1, A_sym, B_sym);
310 const state_matrix_t& Ac2,
311 const state_control_matrix_t& Bc1,
312 const state_control_matrix_t& Bc2,
313 state_matrix_t& A_sym,
314 state_control_matrix_t& B_sym)
318 typedef Eigen::Matrix<SCALAR, P_DIM, P_DIM> p_matrix_t;
319 typedef Eigen::Matrix<SCALAR, V_DIM, V_DIM> v_matrix_t;
320 typedef Eigen::Matrix<SCALAR, P_DIM, V_DIM> p_v_matrix_t;
321 typedef Eigen::Matrix<SCALAR, V_DIM, P_DIM> v_p_matrix_t;
322 typedef Eigen::Matrix<SCALAR, P_DIM, CONTROL_DIM> p_control_matrix_t;
323 typedef Eigen::Matrix<SCALAR, V_DIM, CONTROL_DIM> v_control_matrix_t;
327 const Eigen::Ref<const p_matrix_t> A11 = Ac1.topLeftCorner(P_DIM, P_DIM);
328 const Eigen::Ref<const p_v_matrix_t> A12 = Ac1.topRightCorner(P_DIM, V_DIM);
329 const Eigen::Ref<const p_control_matrix_t> B1 = Bc1.topRows(P_DIM);
332 const Eigen::Ref<const v_p_matrix_t> A21 = Ac2.bottomLeftCorner(V_DIM, P_DIM);
333 const Eigen::Ref<const v_matrix_t> A22 = Ac2.bottomRightCorner(V_DIM, V_DIM);
334 const Eigen::Ref<const v_control_matrix_t> B2 = Bc2.bottomRows(V_DIM);
337 A_sym.topLeftCorner(P_DIM, P_DIM) = p_matrix_t::Identity() + dt * A11;
338 A_sym.topRightCorner(P_DIM, V_DIM) = dt * A12;
339 A_sym.bottomLeftCorner(V_DIM, P_DIM) = dt * (A21 * (p_matrix_t::Identity() + dt * A11));
340 A_sym.bottomRightCorner(V_DIM, V_DIM) = v_matrix_t::Identity() + dt * (A22 + dt * A21 * A12);
343 B_sym.topRows(P_DIM) = dt * B1;
344 B_sym.bottomRows(V_DIM) = dt * (B2 + dt * A21 * B1);
354 state_control_matrix_t& B)
356 throw std::runtime_error(
"SensitivityApproximation : selected symplecticEuler but System is not symplectic.");
363 state_matrix_t& A_sym,
364 state_control_matrix_t& B_sym)
366 throw std::runtime_error(
"SensitivityApproximation : selected symplecticEuler but System is not symplectic.");
370 const state_matrix_t& Ac2,
371 const state_control_matrix_t& Bc1,
372 const state_control_matrix_t& Bc2,
373 state_matrix_t& A_sym,
374 state_control_matrix_t B_sym)
376 throw std::runtime_error(
"SensitivityApproximation : selected symplecticEuler but System is not symplectic.");
380 std::shared_ptr<LinearSystem<STATE_DIM, CONTROL_DIM, SCALAR>> linearSystem_;
391 #undef SYMPLECTIC_ENABLED 392 #undef SYMPLECTIC_DISABLED interface class for a general linear system or linearized system
Definition: LinearSystem.h:23
APPROXIMATION approximation_
type of discretization strategy used.
Definition: Sensitivity.h:29
APPROXIMATION
different discrete-time approximations to linear systems
Definition: Sensitivity.h:15
virtual void setTimeDiscretization(const SCALAR &dt) override
update the time discretization
Definition: SensitivityApproximation.h:96
ct::core::ControlVector< control_dim > u
virtual void setLinearSystem(const std::shared_ptr< LinearSystem< STATE_DIM, CONTROL_DIM, SCALAR >> &linearSystem) override
update the linear system
Definition: SensitivityApproximation.h:88
SensitivityApproximation(const SCALAR &dt, const std::shared_ptr< LinearSystem< STATE_DIM, CONTROL_DIM, SCALAR >> &linearSystem=nullptr, const SensitivityApproximationSettings::APPROXIMATION &approx=SensitivityApproximationSettings::APPROXIMATION::FORWARD_EULER)
constructor
Definition: SensitivityApproximation.h:42
#define SYMPLECTIC_ENABLED
Definition: SensitivityApproximation.h:10
Definition: StateMatrix.h:12
SensitivityApproximationSettings::APPROXIMATION getApproximation() const
retrieve the approximation type for the discrete-time system
Definition: SensitivityApproximation.h:86
virtual void setApproximation(const SensitivityApproximationSettings::APPROXIMATION &approx) override
update the approximation type for the discrete-time system
Definition: SensitivityApproximation.h:79
Definition: ControlVector.h:12
virtual SensitivityApproximation< STATE_DIM, CONTROL_DIM, P_DIM, V_DIM, SCALAR > * clone() const override
deep cloning
Definition: SensitivityApproximation.h:72
double dt_
discretization time-step
Definition: Sensitivity.h:26
CppAD::AD< CppAD::cg::CG< double > > SCALAR
virtual void getAandB(const StateVector< STATE_DIM, SCALAR > &x, const ControlVector< CONTROL_DIM, SCALAR > &u, const StateVector< STATE_DIM, SCALAR > &x_next, const int n, const size_t numSteps, state_matrix_t &A, state_control_matrix_t &B) override
get A and B matrix for linear time invariant system
Definition: SensitivityApproximation.h:109
constexpr size_t n
Definition: MatrixInversionTest.cpp:14
Definition: StateVector.h:12
SensitivityApproximation(const SensitivityApproximationSettings &settings, const std::shared_ptr< LinearSystem< STATE_DIM, CONTROL_DIM, SCALAR >> &linearSystem=nullptr)
constructor
Definition: SensitivityApproximation.h:52
void updateSettings(const SensitivityApproximationSettings &settings)
update the settings
Definition: SensitivityApproximation.h:98
SensitivityApproximation(const SensitivityApproximation &other)
copy constructor
Definition: SensitivityApproximation.h:60
ct::core::StateVector< state_dim > x
Definition: Sensitivity.h:33
settings for the SensitivityApproximation
Definition: Sensitivity.h:12
interface class for a general linear system or linearized system
Definition: SensitivityApproximation.h:32
virtual ~SensitivityApproximation()
destructor
Definition: SensitivityApproximation.h:68
StateControlMatrix< STATE_DIM, CONTROL_DIM, SCALAR > state_control_matrix_t
input Jacobian type
Definition: SensitivityApproximation.h:38
#define SYMPLECTIC_DISABLED
Definition: SensitivityApproximation.h:13
Definition: StateControlMatrix.h:12
EIGEN_MAKE_ALIGNED_OPERATOR_NEW typedef StateMatrix< STATE_DIM, SCALAR > state_matrix_t
state Jacobian type
Definition: SensitivityApproximation.h:37