@@ -140,17 +140,21 @@ class SensitivityApproximation : public Sensitivity<STATE_DIM, CONTROL_DIM, SCAL
140
140
case SensitivityApproximationSettings::APPROXIMATION::TUSTIN:
141
141
{
142
142
/* !
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_ ;
146
154
147
- // ! continuous-time A matrices
148
- state_matrix_t Ac_front = settings_.dt_ * linearSystem_->getDerivativeState (x, u, n * settings_.dt_ );
149
155
state_matrix_t Ac_back =
150
156
settings_.dt_ * linearSystem_->getDerivativeState (x_next, u, (n + 1 ) * settings_.dt_ );
151
157
152
- // ! the continuous-time B matrices
153
- state_control_matrix_t Bc_front = linearSystem_->getDerivativeControl (x, u, n * settings_.dt_ );
154
158
155
159
// ! tustin approximation
156
160
state_matrix_t aNewInv;
@@ -175,50 +179,59 @@ class SensitivityApproximation : public Sensitivity<STATE_DIM, CONTROL_DIM, SCAL
175
179
void forwardEuler (const StateVector<STATE_DIM, SCALAR>& x_n,
176
180
const ControlVector<CONTROL_DIM, SCALAR>& u_n,
177
181
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 )
180
184
{
181
185
/* !
182
186
* the Forward Euler approximation uses the state and control at the *start* of the ZOH interval to
183
187
* generate linear approximations A and B.
184
188
*/
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_ );
187
192
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;
189
195
}
190
196
191
197
void backwardEuler (const StateVector<STATE_DIM, SCALAR>& x_n,
192
198
const ControlVector<CONTROL_DIM, SCALAR>& u_n,
193
199
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 )
196
202
{
197
203
/* !
198
204
* the Backward Euler approximation uses the state and control at the *end* of the ZOH interval to
199
205
* generate linear approximations A and B.
200
206
*/
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>() =
203
214
(state_matrix_t::Identity () - aNew).colPivHouseholderQr ().inverse ();
204
215
205
- B = A * settings_.dt_ * linearSystem_-> getDerivativeControl (x_n, u_n, n * settings_. dt_ ) ;
216
+ B_discr = A_discr * settings_.dt_ * B_cont ;
206
217
}
207
218
208
219
209
220
void matrixExponential (const StateVector<STATE_DIM, SCALAR>& x_n,
210
221
const ControlVector<CONTROL_DIM, SCALAR>& u_n,
211
222
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 )
214
225
{
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
+
216
230
state_matrix_t Adt = settings_.dt_ * Ac;
217
231
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;
222
235
}
223
236
224
237
@@ -245,14 +258,13 @@ class SensitivityApproximation : public Sensitivity<STATE_DIM, CONTROL_DIM, SCAL
245
258
StateVector<STATE_DIM, SCALAR> x_interm = x;
246
259
x_interm.topRows (P_DIM) = x_next.topRows (P_DIM);
247
260
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);
256
268
257
269
getSymplecticEulerApproximation<V_DIM, P_DIM>(Ac1, Ac2, Bc1, Bc2, A_sym, B_sym);
258
270
}
@@ -277,10 +289,9 @@ class SensitivityApproximation : public Sensitivity<STATE_DIM, CONTROL_DIM, SCAL
277
289
{
278
290
const SCALAR& dt = settings_.dt_ ;
279
291
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);
284
295
285
296
getSymplecticEulerApproximation<V_DIM, P_DIM>(Ac1, Ac1, Bc1, Bc1, A_sym, B_sym);
286
297
}
0 commit comments