35 template <
typename T,
int NX,
int NU>
38 template <
typename T,
int NX,
int NU>
41 template <
typename T,
int NX,
int NU>
45 DynamicsSolverInitializer dynamics_solver_initializer = DynamicsSolverInitializer(
init);
46 this->SetDt(dynamics_solver_initializer.dt);
47 this->SetIntegrator(dynamics_solver_initializer.Integrator);
51 raw_control_limits_low_ = dynamics_solver_initializer.ControlLimitsLow;
52 raw_control_limits_high_ = dynamics_solver_initializer.ControlLimitsHigh;
54 if (debug_)
INFO_NAMED(object_name_,
"Initialized DynamicsSolver of type " << GetObjectName() <<
" with dt=" << dynamics_solver_initializer.dt <<
" and integrator=" << dynamics_solver_initializer.Integrator);
57 template <
typename T,
int NX,
int NU>
62 template <
typename T,
int NX,
int NU>
66 return SimulateOneStep(
x, u);
69 template <
typename T,
int NX,
int NU>
72 if (dt_in < 0.0001)
ThrowPretty(
"dt needs to be strictly greater than 0. Provided: " << dt_in);
76 template <
typename T,
int NX,
int NU>
87 Integrate(
x, xdot, dt_, xout);
121 template <
typename T,
int NX,
int NU>
124 assert(num_positions_ == num_velocities_);
125 assert(
x.size() == get_num_state());
126 assert(dx.size() == get_num_state_derivative());
127 assert(xout.size() == get_num_state());
128 if (dt < 1e-6)
ThrowPretty(
"dt needs to be positive!");
135 xout.noalias() =
x + dt * dx;
143 dx_new.head(num_positions_) = dt *
x.tail(num_velocities_) + (dt * dt) * dx.tail(num_velocities_);
144 dx_new.tail(num_velocities_) = dt * dx.tail(num_velocities_);
145 xout.noalias() =
x + dx_new;
158 template <
typename T,
int NX,
int NU>
161 const int num_timesteps =
static_cast<int>(
t / dt_);
163 for (
int i = 0; i < num_timesteps; ++i)
165 x_t_plus_1 = SimulateOneStep(x_t_plus_1, u);
170 template <
typename T,
int NX,
int NU>
173 assert(x_in.size() == get_num_state());
174 return x_in.head(num_positions_).eval();
177 template <
typename T,
int NX,
int NU>
180 return num_controls_;
183 template <
typename T,
int NX,
int NU>
186 return num_positions_;
189 template <
typename T,
int NX,
int NU>
192 return num_velocities_;
195 template <
typename T,
int NX,
int NU>
198 if (num_state_ == -1)
199 return num_positions_ + num_velocities_;
204 template <
typename T,
int NX,
int NU>
207 if (num_state_derivative_ == -1)
208 return 2 * num_velocities_;
210 return num_state_derivative_;
213 template <
typename T,
int NX,
int NU>
219 template <
typename T,
int NX,
int NU>
225 template <
typename T,
int NX,
int NU>
228 integrator_ = integrator_in;
231 template <
typename T,
int NX,
int NU>
234 if (integrator_in ==
"RK1")
236 else if (integrator_in ==
"SymplecticEuler")
238 else if (integrator_in ==
"RK2")
240 else if (integrator_in ==
"RK4")
243 ThrowPretty(
"Unknown integrator: " << integrator_in);
246 template <
typename T,
int NX,
int NU>
249 if (!control_limits_initialized_)
250 set_control_limits(raw_control_limits_low_, raw_control_limits_high_);
251 return control_limits_;
254 template <
typename T,
int NX,
int NU>
257 if (num_controls_ == -1)
258 ThrowPretty(
"Attempting to set control limits before num_controls is set.");
260 control_limits_initialized_ =
true;
261 control_limits_ = Eigen::MatrixXd(num_controls_, 2);
263 if (control_limits_low.size() == num_controls_)
264 control_limits_.col(0) = control_limits_low;
265 else if (control_limits_low.size() == 1)
266 control_limits_.col(0) = Eigen::VectorXd::Constant(num_controls_, control_limits_low(0));
268 ThrowPretty(
"Wrong control limits (low) size. Should either be 1 or " << num_controls_);
270 if (control_limits_high.size() == num_controls_)
271 control_limits_.col(1) = control_limits_high;
272 else if (control_limits_high.size() == 1)
273 control_limits_.col(1) = Eigen::VectorXd::Constant(num_controls_, control_limits_high(0));
275 ThrowPretty(
"Wrong control limits (high) size. Should either be 1 or " << num_controls_);
278 template <
typename T,
int NX,
int NU>
281 if (!has_state_limits_)
ThrowPretty(
"No StateLimits!");
282 if (state_in.size() != get_num_state())
ThrowPretty(
"Wrong size state passed in!");
283 assert(state_in.size() == state_limits_lower_.size());
284 assert(state_limits_lower_.size() == state_limits_upper_.size());
286 state_in = state_in.cwiseMax(state_limits_lower_).cwiseMin(state_limits_upper_);
289 template <
typename T,
int NX,
int NU>
292 if (second_order_derivatives_initialized_)
295 const int ndx = get_num_state_derivative();
297 fxx_default_ = Eigen::Tensor<T, 3>(ndx, ndx, ndx);
298 fxx_default_.setZero();
300 fuu_default_ = Eigen::Tensor<T, 3>(ndx, num_controls_, num_controls_);
301 fuu_default_.setZero();
303 fxu_default_ = Eigen::Tensor<T, 3>(ndx, ndx, num_controls_);
304 fxu_default_.setZero();
306 dStateDelta_.setIdentity(get_num_state_derivative(), get_num_state_derivative());
307 ddStateDelta_.setConstant(get_num_state_derivative(), Eigen::MatrixXd::Zero(get_num_state_derivative(), get_num_state_derivative()));
309 second_order_derivatives_initialized_ =
true;
312 template <
typename T,
int NX,
int NU>
315 if (!second_order_derivatives_initialized_) InitializeSecondOrderDerivatives();
319 template <
typename T,
int NX,
int NU>
322 if (!second_order_derivatives_initialized_) InitializeSecondOrderDerivatives();
326 template <
typename T,
int NX,
int NU>
329 if (!second_order_derivatives_initialized_) InitializeSecondOrderDerivatives();
333 template <
typename T,
int NX,
int NU>
336 ThrowPretty(
"This dynamics solver does not support inverse dynamics!");
339 template <
typename T,
int NX,
int NU>
342 const int nx = get_num_state();
343 const int ndx = get_num_state_derivative();
352 Eigen::MatrixXd fx_fd(ndx, ndx);
353 constexpr
double eps = 1e-6;
354 Eigen::VectorXd x_low(nx), x_high(nx), xdiff(ndx);
355 for (
int i = 0; i < ndx; ++i)
358 xdiff(i) = eps / 2.0;
360 Integrate(
x, -xdiff, 1., x_low);
361 Integrate(
x, xdiff, 1., x_high);
363 fx_fd.col(i) = (
f(x_high, u) -
f(x_low, u)) / eps;
367 integrator_ = previous_integrator;
372 template <
typename T,
int NX,
int NU>
378 template <
typename T,
int NX,
int NU>
381 const int ndx = get_num_state_derivative();
384 constexpr
double eps = 1e-6;
385 Eigen::MatrixXd fu_fd(ndx, num_controls_);
386 Eigen::VectorXd u_low(num_controls_), u_high(num_controls_);
387 for (
int i = 0; i < num_controls_; ++i)
391 u_low(i) -= eps / 2.0;
392 u_high(i) += eps / 2.0;
394 fu_fd.col(i) = (
f(
x, u_high) -
f(
x, u_low)) / eps;
400 template <
typename T,
int NX,
int NU>
406 template <
typename T,
int NX,
int NU>
415 Eigen::Block<Eigen::MatrixXd> da_dx = fx_.block(num_velocities_, 0, num_velocities_, get_num_state_derivative());
416 Eigen::Block<Eigen::MatrixXd> da_du = fu_.block(num_velocities_, 0, num_velocities_, num_controls_);
419 Fx_.setZero(get_num_state_derivative(), get_num_state_derivative());
420 Fu_.setZero(get_num_state_derivative(), get_num_controls());
427 Fx_.topRightCorner(num_velocities_, num_velocities_).diagonal().array() = dt_;
428 Fx_.bottomRows(num_velocities_).noalias() = dt_ * da_dx;
429 Fx_.diagonal().array() += 1.0;
431 Fu_.bottomRows(num_velocities_).noalias() = da_du * dt_;
437 Fx_.topRows(num_velocities_).noalias() = da_dx * dt_ * dt_;
438 Fx_.bottomRows(num_velocities_).noalias() = da_dx * dt_;
439 Fx_.topRightCorner(num_velocities_, num_velocities_).diagonal().array() += dt_;
440 Fx_.diagonal().array() += 1.0;
442 Fu_.topRows(num_velocities_).noalias() = da_du * dt_ * dt_;
443 Fu_.bottomRows(num_velocities_).noalias() = da_du * dt_;
451 template <
typename T,
int NX,
int NU>
457 template <
typename T,
int NX,
int NU>
463 template <
typename T,
int NX,
int NU>
469 template <
typename T,
int NX,
int NU>