25 #ifndef SRC_NUMERICS_INCLUDE_CORBO_NUMERICS_QUADRATURE_H_
26 #define SRC_NUMERICS_INCLUDE_CORBO_NUMERICS_QUADRATURE_H_
48 class QuadratureRectangleRule :
public QuadratureCollocationInterface
63 void quadrature(
const std::vector<const Eigen::VectorXd*>& x1_points,
const std::vector<const Eigen::VectorXd*>& u1_points,
64 const Eigen::VectorXd& u2,
const Eigen::VectorXd& x2,
double dt,
const SystemDynamicsInterface& system,
67 assert(x1_points.size() == 1);
68 assert(u1_points.size() == 1);
70 system.dynamics(0.5 * (*x1_points.front() + x2), 0.5 * (*u1_points.front() + u2), integral_value);
74 void quadrature(
const std::vector<const Eigen::VectorXd*>& x1_points,
const std::vector<const Eigen::VectorXd*>& u1_points,
75 const Eigen::VectorXd& u2,
const Eigen::VectorXd& x2,
double dt,
78 assert(x1_points.size() == 1);
79 assert(u1_points.size() == 1);
81 fun(0.5 * (*x1_points.front() + x2), 0.5 * (*u1_points.front() + u2), integral_value);
85 bool interpolate(
const std::vector<const Eigen::VectorXd*>& x1_points,
const std::vector<const Eigen::VectorXd*>& u1_points,
86 const Eigen::VectorXd& u2,
const Eigen::VectorXd& x2,
double t1,
double dt,
double dt_interp,
87 const SystemDynamicsInterface& system,
bool skip_u2_x2, TimeSeries& ts_x, TimeSeries& ts_u)
override
89 assert(x1_points.size() == 1);
90 assert(u1_points.size() == 1);
92 Eigen::VectorXd xc = 0.5 * (*x1_points.front() + x2);
93 Eigen::VectorXd uc = 0.5 * (*u1_points.front() + u2);
95 if (dt_interp <= 0 || dt_interp >= dt)
104 for (
int i = 0; i <
n; ++i)
114 ts_x.add(t1 + dt, xc);
115 ts_u.add(t1 + dt, uc);
124 assert(integral_value.size() == x1.size());
125 assert(dt > 0 &&
"dt must be greater then zero!");
127 system.
dynamics(0.5 * (x1 + x2), u1, integral_value);
128 integral_value *= dt;
135 assert(integral_value.size() == x1.size());
136 assert(dt > 0 &&
"dt must be greater then zero!");
138 system.
dynamics(0.5 * (x1 + x2), u1, integral_value);
139 integral_value *= dt;
146 assert(integral_value.size() == x1.size());
147 assert(dt > 0 &&
"dt must be greater then zero!");
149 system.dynamics(0.5 * (x1 + x2), 0.5 * (u1 + u2), integral_value);
150 integral_value *= dt;
154 const SystemDynamicsInterface& system,
const std::vector<Eigen::VectorXd*>& intermediate_x,
158 system.dynamics(0.5 * (x1 + x2), 0.5 * (u1 + u2), integral_value);
159 integral_value *= dt;
163 const SystemDynamicsInterface& system,
const std::vector<Eigen::VectorXd*>& intermediate_u,
166 assert(integral_value.size() == x1.size());
167 assert(dt > 0 &&
"dt must be greater then zero!");
169 system.dynamics(0.5 * (x1 + x2), 0.5 * (u1 + u2), integral_value);
170 integral_value *= dt;
176 std::vector<Eigen::VectorXd*>& intermediate_u)
override
178 assert(integral_value.size() == x1.size());
179 assert(dt > 0 &&
"dt must be greater then zero!");
181 system.
dynamics(0.5 * (x1 + x2), 0.5 * (u1 + u2), integral_value);
182 integral_value *= dt;
189 assert(dt > 0 &&
"dt must be greater then zero!");
191 fun(0.5 * (x1 + x2), integral_value);
192 integral_value *= dt;
197 const std::vector<Eigen::VectorXd*>& intermediate_x,
const UnaryFunction& fun,
200 fun(0.5 * (x1 + x2), integral_value);
201 integral_value *= dt;
208 assert(intermediate_x.size() == 1);
209 assert(intermediate_x[0]->
size() == x1.size());
210 intermediate_x[0]->noalias() = 0.5 * (x1 + x2);
211 fun(*intermediate_x[0], integral_value);
212 integral_value *= dt;
220 assert(dt > 0 &&
"dt must be greater then zero!");
222 fun(0.5 * (x1 + x2), 0.5 * (u1 + u2), integral_value);
223 integral_value *= dt;
229 const std::vector<Eigen::VectorXd*>& intermediate_x,
const std::vector<Eigen::VectorXd*>& intermediate_u,
232 fun(0.5 * (x1 + x2), 0.5 * (u1 + u2), integral_value);
233 integral_value *= dt;
240 std::vector<Eigen::VectorXd*>& intermediate_u)
override
242 fun(0.5 * (x1 + x2), 0.5 * (u1 + u2), integral_value);
243 integral_value *= dt;
249 std::vector<Eigen::VectorXd>& controls)
override
257 Eigen::VectorXd xcenter = 0.5 * (x1 + x2);
258 Eigen::VectorXd ucenter = 0.5 * (u1 + u2);
262 states.push_back(x1);
263 controls.push_back(ucenter);
270 for (
int i = 0; i <
n; ++i, t += range.
getStep())
272 double tau = (t - range.
getStart()) / dt;
273 states.push_back(x1 + tau * (x2 - x1));
274 controls.push_back(ucenter);
278 states.push_back(x2);
279 controls.push_back(ucenter);
285 std::vector<Eigen::VectorXd*>& intermediate_u)
override
290 #ifdef MESSAGE_SUPPORT
292 void toMessage(messages::Quadrature& message)
const override
294 QuadratureCollocationInterface::toMessage(message);
295 message.mutable_rectangle_rule();
315 class QuadratureTrapezoidalRule :
public QuadratureCollocationInterface
330 void quadrature(
const std::vector<const Eigen::VectorXd*>& x1_points,
const std::vector<const Eigen::VectorXd*>& u1_points,
334 assert(x1_points.size() == 1);
335 assert(u1_points.size() == 1);
337 Eigen::VectorXd f1(x2.size());
338 system.
dynamics(*x1_points.front(), *u1_points.front(), f1);
339 system.
dynamics(x2, u2, integral_value);
340 integral_value = dt * 0.5 * (f1 + integral_value);
343 void quadrature(
const std::vector<const Eigen::VectorXd*>& x1_points,
const std::vector<const Eigen::VectorXd*>& u1_points,
344 const Eigen::VectorXd& u2,
const Eigen::VectorXd& x2,
double dt,
347 assert(x1_points.size() == 1);
348 assert(u1_points.size() == 1);
350 Eigen::VectorXd f1(x2.size());
351 fun(*x1_points.front(), *u1_points.front(), f1);
352 fun(x2, u2, integral_value);
353 integral_value = dt * 0.5 * (f1 + integral_value);
356 bool interpolate(
const std::vector<const Eigen::VectorXd*>& x1_points,
const std::vector<const Eigen::VectorXd*>& u1_points,
357 const Eigen::VectorXd& u2,
const Eigen::VectorXd& x2,
double t1,
double dt,
double dt_interp,
360 assert(x1_points.size() == 1);
361 assert(u1_points.size() == 1);
363 if (dt_interp <= 0 || dt_interp >= dt)
365 ts_x.
add(t1, *x1_points[0]);
366 ts_u.
add(t1, *u1_points[0]);
370 Eigen::VectorXd xvel = (x2 - *x1_points[0]) / dt;
371 Eigen::VectorXd uvel = (u2 - *u1_points[0]) / dt;
374 for (
int i = 0; i <
n; ++i)
376 ts_x.
add(t, *x1_points[0] + (
double)i * dt_interp * xvel);
377 ts_u.
add(t, *u1_points[0] + (
double)i * dt_interp * uvel);
384 ts_x.
add(t1 + dt, x2);
385 ts_u.
add(t1 + dt, u2);
394 assert(integral_value.size() == x1.size());
395 assert(dt > 0 &&
"dt must be greater then zero!");
397 Eigen::VectorXd f1(x1.size());
398 system.dynamics(x1, u1, f1);
399 system.dynamics(x2, u1, integral_value);
400 integral_value = dt * 0.5 * (f1 + integral_value);
407 assert(integral_value.size() == x1.size());
408 assert(dt > 0 &&
"dt must be greater then zero!");
410 Eigen::VectorXd f1(x1.size());
411 system.dynamics(x1, u1, f1);
412 system.dynamics(x2, u1, integral_value);
413 integral_value = dt * 0.5 * (f1 + integral_value);
420 assert(integral_value.size() == x1.size());
421 assert(dt > 0 &&
"dt must be greater then zero!");
423 Eigen::VectorXd f1(x1.size());
425 system.
dynamics(x2, u2, integral_value);
426 integral_value = dt * 0.5 * (f1 + integral_value);
434 assert(dt > 0 &&
"dt must be greater then zero!");
436 Eigen::VectorXd f1(integral_value.size());
438 system.
dynamics(x2, u2, integral_value);
439 integral_value = dt * 0.5 * (f1 + integral_value);
446 assert(integral_value.size() == x1.size());
447 assert(dt > 0 &&
"dt must be greater then zero!");
449 Eigen::VectorXd f1(x1.size());
452 integral_value = dt * 0.5 * (f1 + integral_value);
458 std::vector<Eigen::VectorXd*>& , std::vector<Eigen::VectorXd*>& )
override
460 assert(integral_value.size() == x1.size());
461 assert(dt > 0 &&
"dt must be greater then zero!");
463 Eigen::VectorXd f1(x1.size());
465 system.
dynamics(x2, u2, integral_value);
466 integral_value = dt * 0.5 * (f1 + integral_value);
472 assert(dt > 0 &&
"dt must be greater then zero!");
474 Eigen::VectorXd f1(integral_value.size());
476 fun(x2, integral_value);
477 integral_value = dt * 0.5 * (f1 + integral_value);
482 const std::vector<Eigen::VectorXd*>& ,
const UnaryFunction& fun,
485 assert(dt > 0 &&
"dt must be greater then zero!");
487 Eigen::VectorXd f1(integral_value.size());
489 fun(x2, integral_value);
490 integral_value = dt * 0.5 * (f1 + integral_value);
497 assert(dt > 0 &&
"dt must be greater then zero!");
499 Eigen::VectorXd f1(integral_value.size());
501 fun(x2, integral_value);
502 integral_value = dt * 0.5 * (f1 + integral_value);
510 assert(dt > 0 &&
"dt must be greater then zero!");
512 Eigen::VectorXd f1(integral_value.size());
514 fun(x2, u2, integral_value);
515 integral_value = dt * 0.5 * (f1 + integral_value);
521 const std::vector<Eigen::VectorXd*>& ,
const std::vector<Eigen::VectorXd*>& ,
524 assert(dt > 0 &&
"dt must be greater then zero!");
526 Eigen::VectorXd f1(integral_value.size());
528 fun(x2, u2, integral_value);
529 integral_value = dt * 0.5 * (f1 + integral_value);
536 std::vector<Eigen::VectorXd*>& )
override
538 assert(dt > 0 &&
"dt must be greater then zero!");
540 Eigen::VectorXd f1(integral_value.size());
542 fun(x2, u2, integral_value);
543 integral_value = dt * 0.5 * (f1 + integral_value);
549 std::vector<Eigen::VectorXd>& controls)
override
557 states.push_back(x1);
558 controls.push_back(u1);
560 if (dt < 1e-15)
return true;
569 for (
int i = 1; i <
n; ++i, t += range.
getStep())
572 states.push_back(x1 + tau * f1 + tau * tau / (2.0 * dt) * (f2 - f1));
573 controls.push_back(u1 + tau / dt * (u2 - u1));
577 states.push_back(x2);
578 controls.push_back(u2);
584 std::vector<Eigen::VectorXd*>& intermediate_u)
override
589 #ifdef MESSAGE_SUPPORT
591 void toMessage(messages::Quadrature& message)
const override
593 QuadratureCollocationInterface::toMessage(message);
594 message.mutable_trapezoidal_rule();
622 class QuadratureHermiteSimpsonLinearControl :
public QuadratureCollocationInterface
637 void quadrature(
const std::vector<const Eigen::VectorXd*>& x1_points,
const std::vector<const Eigen::VectorXd*>& u1_points,
638 const Eigen::VectorXd& u2,
const Eigen::VectorXd& x2,
double dt,
const SystemDynamicsInterface& system,
641 assert(x1_points.size() == 1);
642 assert(u1_points.size() == 1);
644 Eigen::VectorXd f1(x2.size());
645 system.dynamics(*x1_points.front(), *u1_points.front(), f1);
647 Eigen::VectorXd f2(x2.size());
648 system.dynamics(x2, u2, f2);
650 Eigen::VectorXd x_center = 0.5 * (*x1_points.front() + x2) + dt / 8.0 * (f1 - f2);
652 system.dynamics(x_center, 0.5 * (*u1_points.front() + u2), integral_value);
654 integral_value = dt / 6.0 * (f1 + 4.0 * integral_value + f2);
657 void quadrature(
const std::vector<const Eigen::VectorXd*>& x1_points,
const std::vector<const Eigen::VectorXd*>& u1_points,
658 const Eigen::VectorXd& u2,
const Eigen::VectorXd& x2,
double dt,
661 assert(x1_points.size() == 1);
662 assert(u1_points.size() == 1);
664 Eigen::VectorXd f1(x2.size());
665 fun(*x1_points.front(), *u1_points.front(), f1);
667 Eigen::VectorXd f2(x2.size());
670 Eigen::VectorXd x_center = 0.5 * (*x1_points.front() + x2) + dt / 8.0 * (f1 - f2);
672 fun(x_center, 0.5 * (*u1_points.front() + u2), integral_value);
674 integral_value = dt / 6.0 * (f1 + 4.0 * integral_value + f2);
677 bool interpolate(
const std::vector<const Eigen::VectorXd*>& x1_points,
const std::vector<const Eigen::VectorXd*>& u1_points,
678 const Eigen::VectorXd& u2,
const Eigen::VectorXd& x2,
double t1,
double dt,
double dt_interp,
681 assert(x1_points.size() == 1);
682 assert(u1_points.size() == 1);
684 if (dt_interp <= 0 || dt_interp >= dt)
686 ts_x.
add(t1, *x1_points[0]);
687 ts_u.
add(t1, *u1_points[0]);
691 Eigen::VectorXd f1(x2.size());
692 system.
dynamics(*x1_points.front(), *u1_points.front(), f1);
694 Eigen::VectorXd f2(x2.size());
697 Eigen::VectorXd fc(x2.size());
698 Eigen::VectorXd xc = 0.5 * (*x1_points.front() + x2) + dt / 8.0 * (f1 - f2);
699 system.
dynamics(xc, 0.5 * (*u1_points.front() + u2), fc);
701 Eigen::VectorXd uvel = (u2 - *u1_points[0]) / dt;
704 for (
int i = 0; i <
n; ++i)
706 double tau = (t - t1);
709 Eigen::VectorXd x_interp = *x1_points.front() + f1 * tau + 0.5 / dt * tau * tau * (-3.0 * f1 + 4.0 * fc - f2) +
710 1.0 / 3.0 / (dt * dt) *
std::pow(tau, 3) * (2.0 * f1 - 4.0 * fc + 2.0 * f2);
712 ts_x.
add(t1 + tau, x_interp);
713 ts_u.
add(t1 + tau, *u1_points[0] + (
double)i * dt_interp * uvel);
721 ts_x.
add(t1 + dt, x2);
722 ts_u.
add(t1 + dt, u2);
730 assert(integral_value.size() == x1.size());
731 assert(dt > 0 &&
"dt must be greater then zero!");
733 Eigen::VectorXd f1(x1.size());
734 system.dynamics(x1, u1, f1);
736 Eigen::VectorXd f2(x1.size());
737 system.dynamics(x2, u1, f2);
739 Eigen::VectorXd x_center = 0.5 * (x1 + x2) + dt / 8.0 * (f1 - f2);
741 system.dynamics(x_center, u1, integral_value);
743 integral_value = dt / 6.0 * (f1 + 4.0 * integral_value + f2);
749 assert(integral_value.size() == x1.size());
750 assert(dt > 0 &&
"dt must be greater then zero!");
751 assert(intermediate_x.size() == 1);
752 assert(intermediate_x[0]->
size() == x1.size());
754 Eigen::VectorXd f1(x1.size());
755 system.dynamics(x1, u1, f1);
757 Eigen::VectorXd f2(x1.size());
758 system.dynamics(x2, u1, f2);
760 intermediate_x[0]->noalias() = 0.5 * (x1 + x2) + dt / 8.0 * (f1 - f2);
762 system.dynamics(*intermediate_x[0], u1, integral_value);
764 integral_value = dt / 6.0 * (f1 + 4.0 * integral_value + f2);
771 assert(integral_value.size() == x1.size());
772 assert(dt > 0 &&
"dt must be greater then zero!");
774 Eigen::VectorXd f1(x1.size());
777 Eigen::VectorXd f2(x1.size());
780 Eigen::VectorXd x_center = 0.5 * (x1 + x2) + dt / 8.0 * (f1 - f2);
782 system.
dynamics(x_center, 0.5 * (u1 + u2), integral_value);
784 integral_value = dt / 6.0 * (f1 + 4.0 * integral_value + f2);
792 assert(intermediate_x.size() == 1);
793 assert(intermediate_x[0]->
size() == x1.size());
794 assert(intermediate_u.size() == 1);
795 assert(intermediate_u[0]->
size() == u1.size());
796 assert(dt > 0 &&
"dt must be greater then zero!");
798 Eigen::VectorXd f1(integral_value.size());
801 Eigen::VectorXd f2(integral_value.size());
804 system.
dynamics(*intermediate_x[0], *intermediate_u[0], integral_value);
806 integral_value = dt / 6.0 * (f1 + 4.0 * integral_value + f2);
808 assert(interm_x_error.size() == x1.size());
809 interm_x_error = *intermediate_x[0] - (0.5 * (x1 + x2) + dt / 8.0 * (f1 - f2));
816 assert(integral_value.size() == x1.size());
817 assert(dt > 0 &&
"dt must be greater then zero!");
818 assert(intermediate_x.size() == 1);
819 assert(intermediate_x[0]->
size() == x1.size());
820 assert(intermediate_u.size() == 1);
821 assert(intermediate_u[0]->
size() == u1.size());
823 Eigen::VectorXd f1(x1.size());
826 Eigen::VectorXd f2(x1.size());
829 intermediate_x[0]->noalias() = 0.5 * (x1 + x2) + dt / 8.0 * (f1 - f2);
831 system.
dynamics(*intermediate_x[0], *intermediate_u[0], integral_value);
833 integral_value = dt / 6.0 * (f1 + 4.0 * integral_value + f2);
838 std::vector<Eigen::VectorXd*>& intermediate_u)
override
840 assert(integral_value.size() == x1.size());
841 assert(dt > 0 &&
"dt must be greater then zero!");
842 assert(intermediate_x.size() == 1);
843 assert(intermediate_x[0]->
size() == x1.size());
844 assert(intermediate_u.size() == 1);
845 assert(intermediate_u[0]->
size() == u1.size());
847 Eigen::VectorXd f1(x1.size());
850 Eigen::VectorXd f2(x1.size());
853 intermediate_x[0]->noalias() = 0.5 * (x1 + x2) + dt / 8.0 * (f1 - f2);
854 intermediate_u[0]->noalias() = 0.5 * (u1 + u2);
856 system.
dynamics(*intermediate_x[0], *intermediate_u[0], integral_value);
858 integral_value = dt / 6.0 * (f1 + 4.0 * integral_value + f2);
865 assert(dt > 0 &&
"dt must be greater then zero!");
867 Eigen::VectorXd f1(integral_value.size());
870 Eigen::VectorXd f2(integral_value.size());
873 Eigen::VectorXd x_center = 0.5 * (x1 + x2) + dt / 8.0 * (f1 - f2);
875 fun(x_center, integral_value);
877 integral_value = dt / 6.0 * (f1 + 4.0 * integral_value + f2);
882 const std::vector<Eigen::VectorXd*>& intermediate_x,
const UnaryFunction& fun,
885 assert(intermediate_x.size() == 1);
886 assert(intermediate_x[0]->
size() == x1.size());
887 assert(dt > 0 &&
"dt must be greater then zero!");
889 Eigen::VectorXd f1(integral_value.size());
892 Eigen::VectorXd f2(integral_value.size());
895 fun(*intermediate_x[0], integral_value);
897 integral_value = dt / 6.0 * (f1 + 4.0 * integral_value + f2);
904 assert(intermediate_x.size() == 1);
905 assert(intermediate_x[0]->
size() == x1.size());
906 assert(dt > 0 &&
"dt must be greater then zero!");
908 Eigen::VectorXd f1(integral_value.size());
911 Eigen::VectorXd f2(integral_value.size());
914 *intermediate_x[0] = 0.5 * (x1 + x2) + dt / 8.0 * (f1 - f2);
916 fun(*intermediate_x[0], integral_value);
918 integral_value = dt / 6.0 * (f1 + 4.0 * integral_value + f2);
926 assert(dt > 0 &&
"dt must be greater then zero!");
928 Eigen::VectorXd f1(integral_value.size());
931 Eigen::VectorXd f2(integral_value.size());
934 Eigen::VectorXd x_center = 0.5 * (x1 + x2) + dt / 8.0 * (f1 - f2);
936 fun(x_center, 0.5 * (u1 + u2), integral_value);
938 integral_value = dt / 6.0 * (f1 + 4.0 * integral_value + f2);
944 const std::vector<Eigen::VectorXd*>& intermediate_x,
const std::vector<Eigen::VectorXd*>& intermediate_u,
947 assert(intermediate_x.size() == 1);
948 assert(intermediate_x[0]->
size() == x1.size());
949 assert(intermediate_u.size() == 1);
950 assert(intermediate_u[0]->
size() == u1.size());
951 assert(dt > 0 &&
"dt must be greater then zero!");
953 Eigen::VectorXd f1(integral_value.size());
956 Eigen::VectorXd f2(integral_value.size());
959 fun(*intermediate_x[0], *intermediate_u[0], integral_value);
961 integral_value = dt / 6.0 * (f1 + 4.0 * integral_value + f2);
968 std::vector<Eigen::VectorXd*>& intermediate_u)
override
970 assert(intermediate_x.size() == 1);
971 assert(intermediate_x[0]->
size() == x1.size());
972 assert(intermediate_u.size() == 1);
973 assert(intermediate_u[0]->
size() == u1.size());
974 assert(dt > 0 &&
"dt must be greater then zero!");
976 Eigen::VectorXd f1(integral_value.size());
979 Eigen::VectorXd f2(integral_value.size());
982 *intermediate_x[0] = 0.5 * (x1 + x2) + dt / 8.0 * (f1 - f2);
983 *intermediate_u[0] = 0.5 * (u1 + u2);
985 fun(*intermediate_x[0], *intermediate_u[0], integral_value);
987 integral_value = dt / 6.0 * (f1 + 4.0 * integral_value + f2);
993 std::vector<Eigen::VectorXd>& controls)
override
1001 states.push_back(x1);
1002 controls.push_back(u1);
1004 if (dt < 1e-15)
return true;
1012 Eigen::VectorXd xc = 0.5 * (x1 + x2) + dt / 8.0 * (f1 - f2);
1013 Eigen::VectorXd uc = 0.5 * (u1 + u2);
1020 for (
int i = 1; i <
n; ++i, t += range.
getStep())
1022 double tau = (t - range.
getStart());
1030 controls.push_back(u1 + tau / dt * (u2 - u1));
1033 Eigen::VectorXd x_interp = x1 + f1 * tau + 0.5 / dt * tau * tau * (-3.0 * f1 + 4.0 * fc - f2) +
1034 1.0 / 3.0 / (dt * dt) *
std::pow(tau, 3) * (2.0 * f1 - 4.0 * fc + 2.0 * f2);
1035 states.push_back(x_interp);
1040 states.push_back(x2);
1041 controls.push_back(u2);
1047 std::vector<Eigen::VectorXd*>& intermediate_u)
override
1049 assert(intermediate_u.size() == 1);
1050 assert(intermediate_u[0]->
size() == u1.size());
1051 *intermediate_u[0] = 0.5 * (u1 + u2);
1055 #ifdef MESSAGE_SUPPORT
1057 void toMessage(messages::Quadrature& message)
const override
1059 QuadratureCollocationInterface::toMessage(message);
1060 message.mutable_hermite_simpson_linear_u();
1087 class QuadratureHermiteSimpson :
public QuadratureCollocationInterface
1102 void quadrature(
const std::vector<const Eigen::VectorXd*>& x1_points,
const std::vector<const Eigen::VectorXd*>& u1_points,
1103 const Eigen::VectorXd& u2,
const Eigen::VectorXd& x2,
double dt,
const SystemDynamicsInterface& system,
1106 assert(x1_points.size() == 1);
1107 assert(u1_points.size() == 2);
1109 Eigen::VectorXd f1(integral_value.size());
1110 system.dynamics(*x1_points.front(), *u1_points[0], f1);
1112 Eigen::VectorXd f2(integral_value.size());
1113 system.dynamics(x2, u2, f2);
1115 Eigen::VectorXd x_mid = 0.5 * (*x1_points.front() + x2) + dt / 8.0 * (f1 - f2);
1116 system.dynamics(x_mid, *u1_points[1], integral_value);
1118 integral_value = dt / 6.0 * (f1 + 4.0 * integral_value + f2);
1121 void quadrature(
const std::vector<const Eigen::VectorXd*>& x1_points,
const std::vector<const Eigen::VectorXd*>& u1_points,
1122 const Eigen::VectorXd& u2,
const Eigen::VectorXd& x2,
double dt,
1125 assert(x1_points.size() == 1);
1126 assert(u1_points.size() == 2);
1128 Eigen::VectorXd f1(integral_value.size());
1129 fun(*x1_points.front(), *u1_points[0], f1);
1131 Eigen::VectorXd f2(integral_value.size());
1134 Eigen::VectorXd x_mid = 0.5 * (*x1_points.front() + x2) + dt / 8.0 * (f1 - f2);
1135 fun(x_mid, *u1_points[1], integral_value);
1137 integral_value = dt / 6.0 * (f1 + 4.0 * integral_value + f2);
1140 bool interpolate(
const std::vector<const Eigen::VectorXd*>& x1_points,
const std::vector<const Eigen::VectorXd*>& u1_points,
1141 const Eigen::VectorXd& u2,
const Eigen::VectorXd& x2,
double t1,
double dt,
double dt_interp,
1144 assert(x1_points.size() == 1);
1145 assert(u1_points.size() == 2);
1147 if (dt_interp <= 0 || dt_interp >= dt)
1149 ts_x.
add(t1, *x1_points[0]);
1150 ts_u.
add(t1, *u1_points[0]);
1154 Eigen::VectorXd f1(x2.size());
1155 system.
dynamics(*x1_points.front(), *u1_points.front(), f1);
1157 Eigen::VectorXd f2(x2.size());
1160 Eigen::VectorXd fc(x2.size());
1161 Eigen::VectorXd xc = 0.5 * (*x1_points.front() + x2) + dt / 8.0 * (f1 - f2);
1166 for (
int i = 0; i <
n; ++i)
1168 double tau = (t - t1);
1171 Eigen::VectorXd x_interp = *x1_points.front() + f1 * tau + 0.5 / dt * tau * tau * (-3.0 * f1 + 4.0 * fc - f2) +
1172 1.0 / 3.0 / (dt * dt) *
std::pow(tau, 3) * (2.0 * f1 - 4.0 * fc + 2.0 * f2);
1174 Eigen::VectorXd u_interp = *u1_points[0] + tau / dt * (-3.0 * *u1_points[0] + 4.0 * *u1_points[1] - u2) +
1175 2.0 * tau * tau / (dt * dt) * (*u1_points[0] - 2.0 * *u1_points[1] + u2);
1177 ts_x.
add(t1 + tau, x_interp);
1178 ts_u.
add(t1 + tau, u_interp);
1186 ts_x.
add(t1 + dt, x2);
1187 ts_u.
add(t1 + dt, u2);
1195 assert(integral_value.size() == x1.size());
1196 assert(dt > 0 &&
"dt must be greater then zero!");
1198 Eigen::VectorXd f1(x1.size());
1199 system.dynamics(x1, u1, f1);
1201 Eigen::VectorXd f2(x1.size());
1202 system.dynamics(x2, u1, f2);
1204 Eigen::VectorXd x_center = 0.5 * (x1 + x2) + dt / 8.0 * (f1 - f2);
1206 system.dynamics(x_center, u1, integral_value);
1208 integral_value = dt / 6.0 * (f1 + 4.0 * integral_value + f2);
1214 assert(integral_value.size() == x1.size());
1215 assert(dt > 0 &&
"dt must be greater then zero!");
1216 assert(intermediate_x.size() == 1);
1217 assert(intermediate_x[0]->
size() == x1.size());
1219 Eigen::VectorXd f1(x1.size());
1220 system.dynamics(x1, u1, f1);
1222 Eigen::VectorXd f2(x1.size());
1223 system.dynamics(x2, u1, f2);
1225 intermediate_x[0]->noalias() = 0.5 * (x1 + x2) + dt / 8.0 * (f1 - f2);
1227 system.dynamics(*intermediate_x[0], u1, integral_value);
1229 integral_value = dt / 6.0 * (f1 + 4.0 * integral_value + f2);
1237 "This function overload is not supported by HermiteSimpson-Collocation since we require the midpoint between u1 and u2 as extra "
1246 assert(intermediate_x.size() == 1);
1247 assert(intermediate_x[0]->
size() == x1.size());
1248 assert(intermediate_u.size() == 1);
1249 assert(intermediate_u[0]->
size() == u1.size());
1250 assert(dt > 0 &&
"dt must be greater then zero!");
1252 Eigen::VectorXd f1(integral_value.size());
1255 Eigen::VectorXd f2(integral_value.size());
1258 system.
dynamics(*intermediate_x[0], *intermediate_u[0], integral_value);
1260 integral_value = dt / 6.0 * (f1 + 4.0 * integral_value + f2);
1262 assert(interm_x_error.size() == x1.size());
1263 interm_x_error = *intermediate_x[0] - (0.5 * (x1 + x2) + dt / 8.0 * (f1 - f2));
1270 assert(intermediate_x.size() == 1);
1271 assert(intermediate_x[0]->
size() == x1.size());
1272 assert(intermediate_u.size() == 1);
1273 assert(intermediate_u[0]->
size() == u1.size());
1274 assert(dt > 0 &&
"dt must be greater then zero!");
1276 Eigen::VectorXd f1(integral_value.size());
1279 Eigen::VectorXd f2(integral_value.size());
1282 intermediate_x[0]->noalias() = 0.5 * (x1 + x2) + dt / 8.0 * (f1 - f2);
1283 system.
dynamics(*intermediate_x[0], *intermediate_u[0], integral_value);
1285 integral_value = dt / 6.0 * (f1 + 4.0 * integral_value + f2);
1290 std::vector<Eigen::VectorXd*>& intermediate_u)
override
1293 "This function overload is not supported by HermiteSimpson-Collocation since we require the midpoint between u1 and u2 as extra "
1301 assert(dt > 0 &&
"dt must be greater then zero!");
1303 Eigen::VectorXd f1(integral_value.size());
1306 Eigen::VectorXd f2(integral_value.size());
1309 Eigen::VectorXd x_center = 0.5 * (x1 + x2) + dt / 8.0 * (f1 - f2);
1311 fun(x_center, integral_value);
1313 integral_value = dt / 6.0 * (f1 + 4.0 * integral_value + f2);
1318 const std::vector<Eigen::VectorXd*>& intermediate_x,
const UnaryFunction& fun,
1321 assert(intermediate_x.size() == 1);
1322 assert(intermediate_x[0]->
size() == x1.size());
1323 assert(dt > 0 &&
"dt must be greater then zero!");
1325 Eigen::VectorXd f1(integral_value.size());
1328 Eigen::VectorXd f2(integral_value.size());
1331 fun(*intermediate_x[0], integral_value);
1333 integral_value = dt / 6.0 * (f1 + 4.0 * integral_value + f2);
1340 assert(intermediate_x.size() == 1);
1341 assert(intermediate_x[0]->
size() == x1.size());
1342 assert(dt > 0 &&
"dt must be greater then zero!");
1344 Eigen::VectorXd f1(integral_value.size());
1347 Eigen::VectorXd f2(integral_value.size());
1350 *intermediate_x[0] = 0.5 * (x1 + x2) + dt / 8.0 * (f1 - f2);
1352 fun(*intermediate_x[0], integral_value);
1354 integral_value = dt / 6.0 * (f1 + 4.0 * integral_value + f2);
1363 "This function overload is not supported by HermiteSimpson-Collocation since we require the midpoint between u1 and u2 as extra "
1370 const std::vector<Eigen::VectorXd*>& intermediate_x,
const std::vector<Eigen::VectorXd*>& intermediate_u,
1373 assert(intermediate_x.size() == 1);
1374 assert(intermediate_x[0]->
size() == x1.size());
1375 assert(intermediate_u.size() == 1);
1376 assert(intermediate_u[0]->
size() == u1.size());
1377 assert(dt > 0 &&
"dt must be greater then zero!");
1379 Eigen::VectorXd f1(integral_value.size());
1382 Eigen::VectorXd f2(integral_value.size());
1385 fun(*intermediate_x[0], *intermediate_u[0], integral_value);
1387 integral_value = dt / 6.0 * (f1 + 4.0 * integral_value + f2);
1394 std::vector<Eigen::VectorXd*>& intermediate_u)
override
1397 "This function overload is not supported by HermiteSimpson-Collocation since we require the midpoint between u1 and u2 as extra "
1404 std::vector<Eigen::VectorXd>& controls)
override
1409 bool interpolate(
const std::vector<const Eigen::VectorXd*>&
x,
const std::vector<const Eigen::VectorXd*>& u,
double dt,
1410 const SystemDynamicsInterface& system,
const Range& range, std::vector<Eigen::VectorXd>& states,
1411 std::vector<Eigen::VectorXd>& controls)
override
1413 if ((
x.size() != 2 &&
x.size() != 3) || u.size() != 3)
1415 PRINT_DEBUG_NAMED(
"x-dim must be 2 in compressed mode and 3 in uncompressed mode. U-dim must be 3");
1419 if (range.getStart() < 0 || range.getEnd() > dt)
1425 states.push_back(*
x[0]);
1426 controls.push_back(*u[0]);
1428 if (dt < 1e-15)
return true;
1430 Eigen::VectorXd f1(system.getStateDimension());
1431 system.dynamics(*
x[0], *u[0], f1);
1433 Eigen::VectorXd f2(system.getStateDimension());
1434 system.dynamics(*
x.back(), *u[2], f2);
1436 Eigen::VectorXd fc(system.getStateDimension());
1439 Eigen::VectorXd xc = 0.5 * (*
x[0] + *
x[1]) + dt / 8.0 * (f1 - f2);
1440 system.dynamics(xc, *u[1], fc);
1444 assert(
x.size() == 3);
1445 system.dynamics(*
x[1], *u[1], fc);
1448 int n = range.getNumInRange();
1449 double t = range.getStart() + range.getStep();
1450 for (
int i = 1; i <
n; ++i, t += range.getStep())
1452 double tau = (t - range.getStart());
1457 Eigen::VectorXd u_interp = *u[0] + tau / dt * (-3 * *u[0] + 4 * *u[1] - *u[2]) + 2 * tau * tau / (dt * dt) * (*u[0] - 2 * *u[1] + *u[2]);
1460 controls.push_back(u_interp);
1463 Eigen::VectorXd x_interp = *
x[0] + f1 * tau + 0.5 / dt * tau * tau * (-3.0 * f1 + 4.0 * fc - f2) +
1464 1.0 / 3.0 / (dt * dt) *
std::pow(tau, 3) * (2.0 * f1 - 4.0 * fc + 2.0 * f2);
1465 states.push_back(x_interp);
1468 if (range.includeEnd())
1470 states.push_back(*
x.back());
1471 controls.push_back(*u[2]);
1477 std::vector<Eigen::VectorXd*>& intermediate_u)
override
1482 #ifdef MESSAGE_SUPPORT
1484 void toMessage(messages::Quadrature& message)
const override
1486 QuadratureCollocationInterface::toMessage(message);
1487 message.mutable_hermite_simpson();
1496 #endif // SRC_NUMERICS_INCLUDE_CORBO_NUMERICS_QUADRATURE_H_