Skip to content

Commit 43537ce

Browse files
markusgftGiftthaler Markus (CR/PJ-AI-R31)
authored andcommitted
adding convenience call to Linear System
1 parent 78fb0e7 commit 43537ce

File tree

2 files changed

+74
-38
lines changed

2 files changed

+74
-38
lines changed

ct_core/include/ct/core/integration/sensitivity/SensitivityApproximation.h

Lines changed: 47 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -140,17 +140,21 @@ class SensitivityApproximation : public Sensitivity<STATE_DIM, CONTROL_DIM, SCAL
140140
case SensitivityApproximationSettings::APPROXIMATION::TUSTIN:
141141
{
142142
/*!
143-
* the Tustin (also known as 'Heun') approximation uses the state and control at the *start* and at the *end*
144-
* of the ZOH interval to generate linear approximations A and B in a trapezoidal fashion.
145-
*/
143+
* the Tustin (also known as 'Heun') approximation uses the state and control at the *start* and at the *end*
144+
* of the ZOH interval to generate linear approximations A and B in a trapezoidal fashion.
145+
*/
146+
147+
//! continuous-time A and B matrices
148+
state_matrix_t Ac_front;
149+
state_control_matrix_t Bc_front;
150+
151+
// front derivatives
152+
linearSystem_->getDerivatives(Ac_front, Bc_front, x, u, n * settings_.dt_);
153+
Ac_front *= settings_.dt_;
146154

147-
//! continuous-time A matrices
148-
state_matrix_t Ac_front = settings_.dt_ * linearSystem_->getDerivativeState(x, u, n * settings_.dt_);
149155
state_matrix_t Ac_back =
150156
settings_.dt_ * linearSystem_->getDerivativeState(x_next, u, (n + 1) * settings_.dt_);
151157

152-
//! the continuous-time B matrices
153-
state_control_matrix_t Bc_front = linearSystem_->getDerivativeControl(x, u, n * settings_.dt_);
154158

155159
//! tustin approximation
156160
state_matrix_t aNewInv;
@@ -175,50 +179,59 @@ class SensitivityApproximation : public Sensitivity<STATE_DIM, CONTROL_DIM, SCAL
175179
void forwardEuler(const StateVector<STATE_DIM, SCALAR>& x_n,
176180
const ControlVector<CONTROL_DIM, SCALAR>& u_n,
177181
const int& n,
178-
state_matrix_t& A,
179-
state_control_matrix_t& B)
182+
state_matrix_t& A_discr,
183+
state_control_matrix_t& B_discr)
180184
{
181185
/*!
182186
* the Forward Euler approximation uses the state and control at the *start* of the ZOH interval to
183187
* generate linear approximations A and B.
184188
*/
185-
A = state_matrix_t::Identity();
186-
A += settings_.dt_ * linearSystem_->getDerivativeState(x_n, u_n, n * settings_.dt_);
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_);
187192

188-
B = settings_.dt_ * linearSystem_->getDerivativeControl(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;
189195
}
190196

191197
void backwardEuler(const StateVector<STATE_DIM, SCALAR>& x_n,
192198
const ControlVector<CONTROL_DIM, SCALAR>& u_n,
193199
const int& n,
194-
state_matrix_t& A,
195-
state_control_matrix_t& B)
200+
state_matrix_t& A_discr,
201+
state_control_matrix_t& B_discr)
196202
{
197203
/*!
198204
* the Backward Euler approximation uses the state and control at the *end* of the ZOH interval to
199205
* generate linear approximations A and B.
200206
*/
201-
state_matrix_t aNew = settings_.dt_ * linearSystem_->getDerivativeState(x_n, u_n, n * settings_.dt_);
202-
A.template topLeftCorner<STATE_DIM, STATE_DIM>() =
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_);
210+
211+
state_matrix_t aNew = settings_.dt_ * A_cont;
212+
A_discr.setZero();
213+
A_discr.template topLeftCorner<STATE_DIM, STATE_DIM>() =
203214
(state_matrix_t::Identity() - aNew).colPivHouseholderQr().inverse();
204215

205-
B = A * settings_.dt_ * linearSystem_->getDerivativeControl(x_n, u_n, n * settings_.dt_);
216+
B_discr = A_discr * settings_.dt_ * B_cont;
206217
}
207218

208219

209220
void matrixExponential(const StateVector<STATE_DIM, SCALAR>& x_n,
210221
const ControlVector<CONTROL_DIM, SCALAR>& u_n,
211222
const int& n,
212-
state_matrix_t& A,
213-
state_control_matrix_t& B)
223+
state_matrix_t& A_discr,
224+
state_control_matrix_t& B_discr)
214225
{
215-
state_matrix_t Ac = linearSystem_->getDerivativeState(x_n, u_n, settings_.dt_ * n);
226+
state_matrix_t Ac;
227+
state_control_matrix_t Bc;
228+
linearSystem_->getDerivatives(Ac, Bc, x_n, u_n, n * settings_.dt_);
229+
216230
state_matrix_t Adt = settings_.dt_ * Ac;
217231

218-
A.template topLeftCorner<STATE_DIM, STATE_DIM>() = Adt.exp();
219-
B.template topLeftCorner<STATE_DIM, CONTROL_DIM>() =
220-
Ac.inverse() * (A - state_matrix_t::Identity()) *
221-
linearSystem_->getDerivativeControl(x_n, u_n, settings_.dt_ * n);
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;
222235
}
223236

224237

@@ -245,14 +258,13 @@ class SensitivityApproximation : public Sensitivity<STATE_DIM, CONTROL_DIM, SCAL
245258
StateVector<STATE_DIM, SCALAR> x_interm = x;
246259
x_interm.topRows(P_DIM) = x_next.topRows(P_DIM);
247260

248-
state_matrix_t Ac1 =
249-
linearSystem_->getDerivativeState(x, u, n * dt); // continuous time A matrix for start state and control
250-
state_control_matrix_t Bc1 =
251-
linearSystem_->getDerivativeControl(x, u, n * dt); // continuous time B matrix for start state and control
252-
state_matrix_t Ac2 = linearSystem_->getDerivativeState(
253-
x_interm, u, n * dt); // continuous time A matrix for intermediate state and control
254-
state_control_matrix_t Bc2 = linearSystem_->getDerivativeControl(
255-
x_interm, u, n * dt); // continuous time B matrix for intermediate state and control
261+
state_matrix_t Ac1; // continuous time A matrix for start state and control
262+
state_control_matrix_t Bc1; // continuous time B matrix for start state and control
263+
linearSystem_->getDerivatives(Ac1, Bc1, x, u, n * dt);
264+
265+
state_matrix_t Ac2; // continuous time A matrix for intermediate state and control
266+
state_control_matrix_t Bc2; // continuous time B matrix for intermediate state and control
267+
linearSystem_->getDerivatives(Ac2, Bc2, x_interm, u, n * dt);
256268

257269
getSymplecticEulerApproximation<V_DIM, P_DIM>(Ac1, Ac2, Bc1, Bc2, A_sym, B_sym);
258270
}
@@ -277,10 +289,9 @@ class SensitivityApproximation : public Sensitivity<STATE_DIM, CONTROL_DIM, SCAL
277289
{
278290
const SCALAR& dt = settings_.dt_;
279291

280-
state_matrix_t Ac1 =
281-
linearSystem_->getDerivativeState(x, u, n * dt); // continuous time A matrix for start state and control
282-
state_control_matrix_t Bc1 =
283-
linearSystem_->getDerivativeControl(x, u, n * dt); // continuous time B matrix for start state and control
292+
state_matrix_t Ac1; // continuous time A matrix for start state and control
293+
state_control_matrix_t Bc1; // continuous time B matrix for start state and control
294+
linearSystem_->getDerivatives(Ac1, Bc1, x, u, n * dt);
284295

285296
getSymplecticEulerApproximation<V_DIM, P_DIM>(Ac1, Ac1, Bc1, Bc1, A_sym, B_sym);
286297
}

ct_core/include/ct/core/systems/continuous_time/linear/LinearSystem.h

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,31 @@ class LinearSystem : public ControlledSystem<STATE_DIM, CONTROL_DIM, SCALAR>
9191
virtual const state_control_matrix_t& getDerivativeControl(const state_vector_t& x,
9292
const control_vector_t& u,
9393
const time_t t = time_t(0.0)) = 0;
94+
95+
96+
/**
97+
* @brief Get both linear system matrices A and B in one call.
98+
*
99+
* Motvation: For certain derived instances, it may be more efficient to compute A and B simulatenously.
100+
* In that case, this method can be overloaded for maximum efficiency. As default case, it simply calls above
101+
* methods independently.
102+
*
103+
* @param A matrix A of linear system
104+
* @param B matrix B of linear system
105+
* @param x the current state
106+
* @param u the current input
107+
* @param t the current time
108+
*/
109+
virtual void getDerivatives(state_matrix_t& A,
110+
state_control_matrix_t& B,
111+
const state_vector_t& x,
112+
const control_vector_t& u,
113+
const time_t t = time_t(0.0))
114+
{
115+
A = getDerivativeState(x, u, t);
116+
B = getDerivativeControl(x, u, t);
117+
}
94118
};
95-
}
96-
}
119+
120+
} // namespace core
121+
} // namespace ct

0 commit comments

Comments
 (0)