- 3.0.2 core module.
DynamicsLinearizerNumDiff.h
Go to the documentation of this file.
1 /**********************************************************************************************************************
2 This file is part of the Control Toolbox (https://github.com/ethz-adrl/control-toolbox), copyright by ETH Zurich.
3 Licensed under the BSD-2 license (see LICENSE file in main directory)
4 **********************************************************************************************************************/
5 #pragma once
6 
7 namespace ct {
8 namespace core {
9 
11 
27 template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR, typename TIME>
29 {
30 public:
31  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
32 
35 
38 
39  typedef std::function<void(const state_vector_t&, const TIME&, const control_vector_t&, state_vector_t&)>
41 
43 
49  DynamicsLinearizerNumDiff(dynamics_fct_t dyn, bool doubleSidedDerivative = true)
50  : dynamics_fct_(dyn), doubleSidedDerivative_(doubleSidedDerivative)
51  {
52  dFdx_.setZero();
53  dFdu_.setZero();
54  eps_ = sqrt(Eigen::NumTraits<SCALAR>::epsilon());
55  }
56 
61  dFdx_(rhs.dFdx_),
62  dFdu_(rhs.dFdu_),
63  eps_(rhs.eps_)
64  {
65  }
66 
67 
69 
82  const state_matrix_t& getDerivativeState(const state_vector_t& x, const control_vector_t& u, const TIME t = TIME(0))
83  {
85  dynamics_fct_(x, t, u, res_ref_);
86 
87  for (size_t i = 0; i < STATE_DIM; i++)
88  {
89  // inspired from http://en.wikipedia.org/wiki/Numerical_differentiation#Practical_considerations_using_floating_point_arithmetic
90  SCALAR h = eps_ * std::max(std::abs<SCALAR>(x(i)), SCALAR(1.0));
91  SCALAR x_ph = x(i) + h;
92  SCALAR dxp = x_ph - x(i);
93 
94  state_vector_t x_perturbed = x;
95  x_perturbed(i) = x_ph;
96 
97  // evaluate dynamics at perturbed state
98  state_vector_t res_plus;
99  dynamics_fct_(x_perturbed, t, u, res_plus);
100 
102  {
103  SCALAR x_mh = x(i) - h;
104  SCALAR dxm = x(i) - x_mh;
105 
106  x_perturbed = x;
107  x_perturbed(i) = x_mh;
108 
109  state_vector_t res_minus;
110  dynamics_fct_(x_perturbed, t, u, res_minus);
111 
112  dFdx_.col(i) = (res_plus - res_minus) / (dxp + dxm);
113  }
114  else
115  {
116  dFdx_.col(i) = (res_plus - res_ref_) / dxp;
117  }
118  }
119 
120  return dFdx_;
121  }
122 
124 
137  const state_control_matrix_t& getDerivativeControl(const state_vector_t& x,
138  const control_vector_t& u,
139  const TIME t = TIME(0))
140  {
142  dynamics_fct_(x, t, u, res_ref_);
143 
144  for (size_t i = 0; i < CONTROL_DIM; i++)
145  {
146  // inspired from http://en.wikipedia.org/wiki/Numerical_differentiation#Practical_considerations_using_floating_point_arithmetic
147  SCALAR h = eps_ * std::max(std::abs<SCALAR>(u(i)), SCALAR(1.0));
148  SCALAR u_ph = u(i) + h;
149  SCALAR dup = u_ph - u(i);
150 
151  control_vector_t u_perturbed = u;
152  u_perturbed(i) = u_ph;
153 
154  // evaluate dynamics at perturbed state
155  state_vector_t res_plus;
156  dynamics_fct_(x, t, u_perturbed, res_plus);
157 
159  {
160  SCALAR u_mh = u(i) - h;
161  SCALAR dum = u(i) - u_mh;
162 
163  u_perturbed = u;
164  u_perturbed(i) = u_mh;
165 
166  state_vector_t res_minus;
167  dynamics_fct_(x, t, u_perturbed, res_minus);
168 
169  dFdu_.col(i) = (res_plus - res_minus) / (dup + dum);
170  }
171  else
172  {
173  dFdu_.col(i) = (res_plus - res_ref_) / dup;
174  }
175  }
176 
177  return dFdu_;
178  }
179 
181 protected:
183 
185 
187 
188 
189  // internally used variables
190  state_matrix_t dFdx_;
191  state_control_matrix_t dFdu_;
192 
193  state_vector_t res_ref_;
194 };
195 
196 } // namespace core
197 } // namespace ct
DynamicsLinearizerNumDiff(const DynamicsLinearizerNumDiff &rhs)
copy constructor
Definition: DynamicsLinearizerNumDiff.h:58
state_control_matrix_t dFdu_
Jacobian wrt input.
Definition: DynamicsLinearizerNumDiff.h:191
Definition: StateMatrix.h:12
std::function< void(const state_vector_t &, const TIME &, const control_vector_t &, state_vector_t &)> dynamics_fct_t
dynamics function signature
Definition: DynamicsLinearizerNumDiff.h:40
clear all close all load ct GNMSLog0 mat reformat t
DynamicsLinearizerNumDiff(dynamics_fct_t dyn, bool doubleSidedDerivative=true)
default constructor
Definition: DynamicsLinearizerNumDiff.h:49
Definition: ControlVector.h:12
bool doubleSidedDerivative_
flag if double sided numerical differentiation should be used
Definition: DynamicsLinearizerNumDiff.h:184
dynamics_fct_t dynamics_fct_
function handle to system dynamics
Definition: DynamicsLinearizerNumDiff.h:182
CppAD::AD< CppAD::cg::CG< double > > SCALAR
StateMatrix< STATE_DIM, SCALAR > state_matrix_t
state Jacobian type (A)
Definition: DynamicsLinearizerNumDiff.h:36
SCALAR eps_
perturbation for numerical differentiation
Definition: DynamicsLinearizerNumDiff.h:186
StateControlMatrix< STATE_DIM, CONTROL_DIM, SCALAR > state_control_matrix_t
control Jacobian type (B)
Definition: DynamicsLinearizerNumDiff.h:37
const state_control_matrix_t & getDerivativeControl(const state_vector_t &x, const control_vector_t &u, const TIME t=TIME(0))
get the Jacobian with respect to the input
Definition: DynamicsLinearizerNumDiff.h:137
state_matrix_t dFdx_
Jacobian wrt state.
Definition: DynamicsLinearizerNumDiff.h:190
EIGEN_MAKE_ALIGNED_OPERATOR_NEW typedef StateVector< STATE_DIM, SCALAR > state_vector_t
state vector type
Definition: DynamicsLinearizerNumDiff.h:33
Definition: StateVector.h:12
for i
const state_matrix_t & getDerivativeState(const state_vector_t &x, const control_vector_t &u, const TIME t=TIME(0))
get the Jacobian with respect to the state
Definition: DynamicsLinearizerNumDiff.h:82
ControlVector< CONTROL_DIM, SCALAR > control_vector_t
control vector type
Definition: DynamicsLinearizerNumDiff.h:34
Computes the linearization of a system dynamics function through numerical finite differencing...
Definition: DynamicsLinearizerNumDiff.h:28
bool getDoubleSidedDerivativeFlag() const
Definition: DynamicsLinearizerNumDiff.h:180
Definition: StateControlMatrix.h:12
state_vector_t res_ref_
reference result for numerical differentiation
Definition: DynamicsLinearizerNumDiff.h:193