25 #ifndef SRC_NUMERICS_INCLUDE_CORBO_NUMERICS_EXPLICIT_INTEGRATORS_H_
26 #define SRC_NUMERICS_INCLUDE_CORBO_NUMERICS_EXPLICIT_INTEGRATORS_H_
47 class IntegratorExplicitEuler :
public NumericalIntegratorExplicitInterface
69 system.dynamics(x1, u1, x2);
74 #ifdef MESSAGE_SUPPORT
76 void toMessage(messages::ExplicitIntegrator& message)
const override
78 NumericalIntegratorExplicitInterface::toMessage(message);
79 message.mutable_explicit_euler();
97 class IntegratorExplicitRungeKutta2 :
public NumericalIntegratorExplicitInterface
108 _k1.resize(state_dim);
109 _k2.resize(state_dim);
137 x2 = x1 + (
_k1 +
_k2) / 2.0;
140 #ifdef MESSAGE_SUPPORT
142 void toMessage(messages::ExplicitIntegrator& message)
const override
144 NumericalIntegratorExplicitInterface::toMessage(message);
145 message.mutable_runge_kutta_2();
178 _k1.resize(state_dim);
179 _k2.resize(state_dim);
180 _k3.resize(state_dim);
191 fun(x1 + (
_k1 / 2.0),
_k2);
215 #ifdef MESSAGE_SUPPORT
217 void toMessage(messages::ExplicitIntegrator& message)
const override
219 NumericalIntegratorExplicitInterface::toMessage(message);
220 message.mutable_runge_kutta_3();
255 _k1.resize(state_dim);
256 _k2.resize(state_dim);
257 _k3.resize(state_dim);
258 _k4.resize(state_dim);
297 #ifdef MESSAGE_SUPPORT
299 void toMessage(messages::ExplicitIntegrator& message)
const override
301 NumericalIntegratorExplicitInterface::toMessage(message);
302 message.mutable_runge_kutta_4();
327 class IntegratorExplicitRungeKutta5 :
public NumericalIntegratorExplicitInterface
338 _k1.resize(state_dim);
339 _k2.resize(state_dim);
340 _k3.resize(state_dim);
341 _k4.resize(state_dim);
342 _k5.resize(state_dim);
343 _k6.resize(state_dim);
354 fun(x1 + 4.0 *
_k1 / 11.0,
_k2);
396 #ifdef MESSAGE_SUPPORT
398 void toMessage(messages::ExplicitIntegrator& message)
const override
400 NumericalIntegratorExplicitInterface::toMessage(message);
401 message.mutable_runge_kutta_5();
436 int getConvergenceOrder()
const override {
return 6; }
438 void initialize(
int state_dim)
override
440 _k1.resize(state_dim);
441 _k2.resize(state_dim);
442 _k3.resize(state_dim);
443 _k4.resize(state_dim);
444 _k5.resize(state_dim);
445 _k6.resize(state_dim);
446 _k7.resize(state_dim);
447 _k8.resize(state_dim);
454 if (x1.size() != _k1.size()) initialize(x1.size());
458 fun(x1 + 2.0 * _k1 / 33.0, _k2);
460 fun(x1 + 4.0 * _k2 / 33.0, _k3);
462 fun(x1 + (_k1 + 3.0 * _k3) / 22.0, _k4);
464 fun(x1 + (43.0 * _k1 - 165.0 * _k3 + 144.0 * _k4) / 64.0, _k5);
466 fun(x1 + (-4053483.0 * _k1 + 16334703.0 * _k3 - 12787632.0 * _k4 + 1057536.0 * _k5) / 826686.0, _k6);
468 fun(x1 + (169364139.0 * _k1 - 663893307.0 * _k3 + 558275718.0 * _k4 - 29964480.0 * _k5 + 35395542.0 * _k6) / 80707214.0, _k7);
470 fun(x1 + (-733.0 * _k1 + 3102.0 * _k3) / 176.0 - (335763.0 * _k4 / 23296.0) + (216.0 * _k5 / 77.0) - (4617.0 * _k6 / 2816.0) +
471 (7203.0 * _k7 / 9152.0),
475 x2 = x1 + (336336.0 * _k1 + 1771561.0 * _k4 + 1916928.0 * _k5 + 597051.0 * _k6 + 1411788.0 * _k7 + 256256.0 * _k8) / 6289920.0;
482 if (x1.size() != _k1.size()) initialize(x1.size());
486 system.
dynamics(x1 + 2.0 * _k1 / 33.0, u1, _k2);
488 system.
dynamics(x1 + 4.0 * _k2 / 33.0, u1, _k3);
490 system.
dynamics(x1 + (_k1 + 3.0 * _k3) / 22.0, u1, _k4);
492 system.
dynamics(x1 + (43.0 * _k1 - 165.0 * _k3 + 144.0 * _k4) / 64.0, u1, _k5);
494 system.
dynamics(x1 + (-4053483.0 * _k1 + 16334703.0 * _k3 - 12787632.0 * _k4 + 1057536.0 * _k5) / 826686.0, u1, _k6);
496 system.
dynamics(x1 + (169364139.0 * _k1 - 663893307.0 * _k3 + 558275718.0 * _k4 - 29964480.0 * _k5 + 35395542.0 * _k6) / 80707214.0, u1,
499 system.
dynamics(x1 + (-733.0 * _k1 + 3102.0 * _k3) / 176.0 - (335763.0 * _k4 / 23296.0) + (216.0 * _k5 / 77.0) - (4617.0 * _k6 / 2816.0) +
500 (7203.0 * _k7 / 9152.0),
504 x2 = x1 + (336336.0 * _k1 + 1771561.0 * _k4 + 1916928.0 * _k5 + 597051.0 * _k6 + 1411788.0 * _k7 + 256256.0 * _k8) / 6289920.0;
507 #ifdef MESSAGE_SUPPORT
509 void toMessage(messages::ExplicitIntegrator& message)
const override
511 NumericalIntegratorExplicitInterface::toMessage(message);
512 message.mutable_runge_kutta_6();
548 int getConvergenceOrder()
const override {
return 7; }
550 void initialize(
int state_dim)
override
552 _k1.resize(state_dim);
553 _k2.resize(state_dim);
554 _k3.resize(state_dim);
555 _k4.resize(state_dim);
556 _k5.resize(state_dim);
557 _k6.resize(state_dim);
558 _k7.resize(state_dim);
559 _k8.resize(state_dim);
560 _k9.resize(state_dim);
561 _k10.resize(state_dim);
562 _k11.resize(state_dim);
566 void solveIVP(
const Eigen::VectorXd& x1,
double dt,
const std::function<
void(
const Eigen::VectorXd&,
Eigen::Ref<Eigen::VectorXd>)>& fun,
569 if (x1.size() != _k1.size()) initialize(x1.size());
573 fun(x1 + 2.0 * _k1 / 27.0, _k2);
575 fun(x1 + (_k1 + 3.0 * _k2) / 36.0, _k3);
577 fun(x1 + (_k1 + 3.0 * _k3) / 24.0, _k4);
579 fun(x1 + (80.0 * _k1 - 300.0 * _k3 + 300.0 * _k4) / 192.0, _k5);
581 fun(x1 + (_k1 + 5.0 * _k4 + 4.0 * _k5) / 20.0, _k6);
583 fun(x1 + (-25.0 * _k1 + 125.0 * _k4 - 260.0 * _k5 + 250.0 * _k6) / 108.0, _k7);
585 fun(x1 + (93.0 * _k1 + 244.0 * _k5 - 200.0 * _k6 + 13.0 * _k7) / 900.0, _k8);
587 fun(x1 + (1080.0 * _k1 - 4770.0 * _k4 + 8448.0 * _k5 - 6420.0 * _k6 + 402.0 * _k7 + 1620.0 * _k8) / 540.0, _k9);
589 fun(x1 + (-12285.0 * _k1 + 3105.0 * _k4 - 105408.0 * _k5 + 83970.0 * _k6 - 4617.0 * _k7 + 41310.0 * _k8 - 1215.0 * _k9) / 14580.0,
592 fun(x1 + (2383.0 * _k1 - 8525.0 * _k4 + 17984.0 * _k5 - 15050.0 * _k6 + 2133.0 * _k7 + 2250.0 * _k8 + 1125.0 * _k9 + 1800.0 * _k10) / 4100.0,
596 x2 = x1 + (41.0 * _k1 + 272.0 * _k6 + 216.0 * _k7 + 216.0 * _k8 + 27.0 * _k9 + 27.0 * _k10 + 41.0 * _k11) / 840.0;
603 if (x1.size() != _k1.size()) initialize(x1.size());
607 system.
dynamics(x1 + 2.0 * _k1 / 27.0, u1, _k2);
609 system.
dynamics(x1 + (_k1 + 3.0 * _k2) / 36.0, u1, _k3);
611 system.
dynamics(x1 + (_k1 + 3.0 * _k3) / 24.0, u1, _k4);
613 system.
dynamics(x1 + (80.0 * _k1 - 300.0 * _k3 + 300.0 * _k4) / 192.0, u1, _k5);
615 system.
dynamics(x1 + (_k1 + 5.0 * _k4 + 4.0 * _k5) / 20.0, u1, _k6);
617 system.
dynamics(x1 + (-25.0 * _k1 + 125.0 * _k4 - 260.0 * _k5 + 250.0 * _k6) / 108.0, u1, _k7);
619 system.
dynamics(x1 + (93.0 * _k1 + 244.0 * _k5 - 200.0 * _k6 + 13.0 * _k7) / 900.0, u1, _k8);
621 system.
dynamics(x1 + (12.0 * _k1 - 53.0 * _k4) / 6.0 + (1408.0 * _k5 - 1070.0 * _k6 + 67.0 * _k7 + 270.0 * _k8) / 90.0, u1, _k9);
623 system.
dynamics(x1 + (-12285.0 * _k1 + 3105.0 * _k4 - 105408.0 * _k5 + 83970.0 * _k6 - 4617.0 * _k7 + 41310.0 * _k8 - 1215.0 * _k9) / 14580.0,
627 x1 + (2383.0 * _k1 - 8525.0 * _k4 + 17984.0 * _k5 - 15050.0 * _k6 + 2133.0 * _k7 + 2250.0 * _k8 + 1125.0 * _k9 + 1800.0 * _k10) / 4100.0,
631 x2 = x1 + (41.0 * _k1 + 272.0 * _k6 + 216.0 * _k7 + 216.0 * _k8 + 27.0 * _k9 + 27.0 * _k10 + 41.0 * _k11) / 840.0;
634 #ifdef MESSAGE_SUPPORT
636 void toMessage(messages::ExplicitIntegrator& message)
const override
638 NumericalIntegratorExplicitInterface::toMessage(message);
639 message.mutable_runge_kutta_7();
653 Eigen::VectorXd _k10;
654 Eigen::VectorXd _k11;
679 int getConvergenceOrder()
const override {
return _p2; }
681 void initialize(
int state_dim)
override
683 _integrator1->initialize(state_dim);
684 _integrator2->initialize(state_dim);
688 void solveIVP(
const Eigen::VectorXd& x1,
double dt,
const std::function<
void(
const Eigen::VectorXd&,
Eigen::Ref<Eigen::VectorXd>)>& fun,
702 while (
std::abs(_tau - dt) > std::numeric_limits<double>::epsilon())
705 if ((_tau + _h) > dt)
715 _integrator1->solveIVP(_help2, _h, fun, _help);
716 _integrator2->solveIVP(_help2, _h, fun, x2);
721 for (
int k = 0; k < _help.size(); k++)
723 _epsilon_hat = _epsilon_hat +
pow(_help(k), 2.0);
725 _epsilon_hat =
std::pow(_epsilon_hat, 0.5);
728 _h_new =
pow(0.9 * (_tol / _epsilon_hat), (1.0 / (
double(_p1) + 1.0))) * _h;
729 if (_epsilon_hat > _tol)
746 void solveIVP(
const StateVector& x1,
const InputVector& u1,
double dt,
const SystemDynamicsInterface& system,
760 while (
std::abs(_tau - dt) > std::numeric_limits<double>::epsilon())
763 if ((_tau + _h) > dt)
773 _integrator1->solveIVP(_help2, u1, _h, system, _help);
774 _integrator2->solveIVP(_help2, u1, _h, system, x2);
779 for (
int k = 0; k < _help.size(); k++)
781 _epsilon_hat = _epsilon_hat +
pow(_help(k), 2.0);
783 _epsilon_hat =
pow(_epsilon_hat, 0.5);
786 _h_new =
std::pow(0.9 * (_tol / _epsilon_hat), (1.0 / (
double(_p1) + 1.0))) * _h;
787 if (_epsilon_hat > _tol)
803 #ifdef MESSAGE_SUPPORT
804 void toMessage(messages::IntegratorAdaptiveStepSize& message)
const
806 message.set_tol(_tol);
807 if (_integrator1) _integrator1->toMessage(*message.mutable_integrator1());
808 if (_integrator2) _integrator2->toMessage(*message.mutable_integrator2());
810 void fromMessage(
const messages::IntegratorAdaptiveStepSize& message, std::stringstream* issues =
nullptr)
812 _tol = message.tol();
815 util::get_oneof_field_type(message.integrator1(),
"explicit_integrator", type,
false);
820 int1->fromMessage(message.integrator1(), issues);
822 _p1 = int1->getConvergenceOrder();
826 if (issues) *issues <<
"IntegratorAdaptiveStepSize: unknown integrator1 specified.\n";
831 util::get_oneof_field_type(message.integrator2(),
"explicit_integrator", type,
false);
836 int2->fromMessage(message.integrator2(), issues);
838 _p2 = int2->getConvergenceOrder();
842 if (issues) *issues <<
"IntegratorAdaptiveStepSize: unknown integrator2 specified.\n";
846 if (_p1 >= _p2 && issues)
847 *issues <<
"The chosen methods are not applicable! The order of the first method has to be lower than the order of the second method!\n";
850 void toMessage(messages::ExplicitIntegrator& message)
const override
852 NumericalIntegratorExplicitInterface::toMessage(message);
853 toMessage(*message.mutable_adaptive_step_size());
855 void fromMessage(
const messages::DynamicsEval& message, std::stringstream* issues =
nullptr)
override
857 NumericalIntegratorExplicitInterface::fromMessage(message, issues);
858 fromMessage(message.integrator().adaptive_step_size(), issues);
875 Eigen::VectorXd _help;
876 Eigen::VectorXd _help2;
890 class IntegratorMultiStageFixedStep :
public NumericalIntegratorExplicitInterface
915 for (
int i = 1; i <
n; ++i)
920 if (dt_remainder > 0)
_integrator->solveIVP(
_x_sub, u1, dt_remainder, system, x2);
938 for (
int i = 1; i <
n; ++i)
943 if (dt_remainder > 1e-8)
949 #ifdef MESSAGE_SUPPORT
950 void fromMessage(
const messages::IntegratorMultiStageFixedStep& message, std::stringstream* issues =
nullptr)
956 util::get_oneof_field_type(message.integrator(),
"explicit_integrator", type,
false);
961 integrator->fromMessage(message.integrator(), issues);
966 if (issues) *issues <<
"IntegratorMultiStageFixedStep: unknown integrator specified.\n";
971 void toMessage(messages::IntegratorMultiStageFixedStep& message)
const
979 void fromMessage(
const messages::ExplicitIntegrator& message, std::stringstream* issues =
nullptr)
override
981 NumericalIntegratorExplicitInterface::fromMessage(message);
982 fromMessage(message.multi_stage_fixed_step());
986 void toMessage(messages::ExplicitIntegrator& message)
const override
988 NumericalIntegratorExplicitInterface::toMessage(message);
989 toMessage(*message.mutable_multi_stage_fixed_step());
1011 class IntegratorMultiStageScaled :
public NumericalIntegratorExplicitInterface
1026 double inner_dt = dt / (double)
_n;
1028 _x_sub.resize(x1.size());
1030 for (
int i = 1; i <
_n; ++i)
1042 double inner_dt = dt / (double)
_n;
1044 _x_sub.resize(x1.size());
1046 for (
int i = 1; i <
_n; ++i)
1056 #ifdef MESSAGE_SUPPORT
1057 void fromMessage(
const messages::IntegratorMultiStageScaled& message, std::stringstream* issues =
nullptr)
1063 util::get_oneof_field_type(message.integrator(),
"explicit_integrator", type,
false);
1068 integrator->fromMessage(message.integrator(), issues);
1073 if (issues) *issues <<
"IntegratorMultiStageScaled: unknown integrator specified.\n";
1078 void toMessage(messages::IntegratorMultiStageScaled& message)
const
1086 void fromMessage(
const messages::ExplicitIntegrator& message, std::stringstream* issues =
nullptr)
override
1088 NumericalIntegratorExplicitInterface::fromMessage(message);
1089 fromMessage(message.multi_stage_scaled());
1093 void toMessage(messages::ExplicitIntegrator& message)
const override
1095 NumericalIntegratorExplicitInterface::toMessage(message);
1096 toMessage(*message.mutable_multi_stage_scaled());
1111 #endif // SRC_NUMERICS_INCLUDE_CORBO_NUMERICS_EXPLICIT_INTEGRATORS_H_