1#ifndef __multicontact_api_scenario_contact_sequence_hpp__
2#define __multicontact_api_scenario_contact_sequence_hpp__
4#include <ndcurves/curve_abc.h>
5#include <ndcurves/fwd.h>
6#include <ndcurves/piecewise_curve.h>
7#include <ndcurves/polynomial.h>
8#include <ndcurves/se3_curve.h>
10#include <boost/serialization/vector.hpp>
20template <
class _ContactPhase>
23 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
54 return !(*
this == other);
89 throw std::invalid_argument(
"Given Id is greater than the vector size");
99 throw std::invalid_argument(
"Given Id is greater than the vector size");
122 const double phaseDuration = -1) {
125 throw std::invalid_argument(
126 "In breakContact : effector is not currently in contact : " + eeName);
127 if (phaseDuration > 0) {
129 throw std::invalid_argument(
130 "In breakContact : duration is specified but current phase "
131 "interval in not initialised.");
148 if (name != eeName) {
172 const double phaseDuration = -1) {
175 throw std::invalid_argument(
176 "In createContact : effector is already in contact : " + eeName);
177 if (phaseDuration > 0) {
179 throw std::invalid_argument(
180 "In createContact : duration is specified but current phase "
181 "interval in not initialised.");
227 const double durationBreak = -1,
228 const double durationCreate = -1) {
230 throw std::invalid_argument(
231 "In moveEffectorToPlacement : effector is not currently in contact "
267 const double durationBreak = -1,
268 const double durationCreate = -1) {
270 throw std::invalid_argument(
271 "In moveEffectorToPlacement : effector is not currently in contact "
289 if (current_t < 0.) {
290 std::cout <<
"Initial time is negative." << std::endl;
293 for (
size_t i = 0; i <
size(); ++i) {
296 std::cout <<
"For phase " << i
297 <<
" initial time is not equal to previous final time."
302 std::cout <<
"For phase " << i <<
" final time is before initial time."
321 std::cout <<
"Phase without any contact at id : 0" << std::endl;
331 if (variations > 1) {
332 std::cout <<
"Several contact changes between adjacents phases at id : "
340 <<
"Contact repositionning without intermediate phase at id : " << i
346 std::cout <<
"Phase without any contact at id : " << i << std::endl;
349 if (variations == 0) {
350 std::cout <<
"No contact change between adjacents phases at id : " << i
366 std::cout <<
"Initial CoM position not defined." << std::endl;
371 std::cout <<
"Intermediate CoM position not defined for phase : " << i
377 std::cout <<
"Init CoM position do not match final CoM of previous "
385 std::cout <<
"Init CoM velocity do not match final velocity of "
386 "previous phase for id : "
394 std::cout <<
"Init CoM acceleration do not match final acceleration "
395 "of previous phase for id : "
402 std::cout <<
"Final CoM position not defined." << std::endl;
418 std::cout <<
"Init AM value do not match final value of previous phase "
425 std::cout <<
"Init AM derivative do not match final AM derivative of "
426 "previous phase for id : "
452 std::cout <<
"Initial configuration not defined." << std::endl;
457 std::cout <<
"Intermediate configuration not defined for phase : " << i
463 std::cout <<
"Init configuration do not match final configuration of "
464 "previous phase for id : "
470 std::cout <<
"Final configuration not defined." << std::endl;
488 std::cout <<
"CoM position trajectory not defined for phase : " << i
493 std::cout <<
"CoM velocity trajectory not defined for phase : " << i
498 std::cout <<
"CoM acceleration trajectory not defined for phase : " << i
502 if (phase.m_c->dim() != 3) {
503 std::cout <<
"CoM trajectory is not of dimension 3 for phase : " << i
507 if (phase.m_dc->dim() != 3) {
509 <<
"CoM velocity trajectory is not of dimension 3 for phase : " << i
513 if (phase.m_ddc->dim() != 3) {
515 <<
"CoM acceleration trajectory is not of dimension 3 for phase : "
519 if (phase.m_c->min() != phase.timeInitial()) {
520 std::cout <<
"CoM trajectory do not start at t_init for phase : " << i
524 if (phase.m_dc->min() != phase.timeInitial()) {
526 <<
"CoM velocity trajectory do not start at t_init for phase : "
530 if (phase.m_ddc->min() != phase.timeInitial()) {
532 <<
"CoM acceleration trajectory do not start at t_init for phase : "
536 if (phase.m_c->max() != phase.timeFinal()) {
537 std::cout <<
"CoM trajectory do not end at t_final for phase : " << i
541 if (phase.m_dc->max() != phase.timeFinal()) {
543 <<
"CoM velocity trajectory do not end at t_final for phase : " << i
547 if (phase.m_ddc->max() != phase.timeFinal()) {
549 <<
"CoM acceleration trajectory do not end at t_final for phase : "
553 if (!(*phase.m_c)(phase.m_c->min()).isApprox(phase.m_c_init)) {
554 std::cout <<
"CoM trajectory do not start at c_init for phase : " << i
558 if (phase.m_dc_init.isZero()) {
559 if (!(*phase.m_dc)(phase.m_dc->min()).isZero()) {
561 <<
"CoM velocity trajectory do not start at dc_init for phase : "
567 else if (!(*phase.m_dc)(phase.m_dc->min())
568 .isApprox(phase.m_dc_init, 1e-6)) {
570 <<
"CoM velocity trajectory do not start at dc_init for phase : "
574 if (phase.m_ddc_init.isZero()) {
575 if (!(*phase.m_ddc)(phase.m_ddc->min()).isZero()) {
576 std::cout <<
"CoM acceleration trajectory do not start at ddc_init "
581 }
else if (!(*phase.m_ddc)(phase.m_ddc->min())
582 .isApprox(phase.m_ddc_init, 1e-6)) {
583 std::cout <<
"CoM acceleration trajectory do not start at ddc_init for "
588 if (!(*phase.m_c)(phase.m_c->max()).isApprox(phase.m_c_final)) {
589 std::cout <<
"CoM trajectory do not end at c_final for phase : " << i
593 if (phase.m_dc_final.isZero()) {
594 if (!(*phase.m_dc)(phase.m_dc->max()).isZero()) {
596 <<
"CoM velocity trajectory do not end at dc_final for phase : "
600 }
else if (!(*phase.m_dc)(phase.m_dc->max())
601 .isApprox(phase.m_dc_final, 1e-6)) {
603 <<
"CoM velocity trajectory do not end at dc_final for phase : "
607 if (phase.m_ddc_final.isZero()) {
608 if (!(*phase.m_ddc)(phase.m_ddc->max()).isZero()) {
609 std::cout <<
"CoM acceleration trajectory do not end at ddc_final "
614 }
else if (!(*phase.m_ddc)(phase.m_ddc->max())
615 .isApprox(phase.m_ddc_final, 1e-6)) {
616 std::cout <<
"CoM acceleration trajectory do not end at ddc_final for "
638 std::cout <<
"AM position trajectory not defined for phase : " << i
643 std::cout <<
"AM velocity trajectory not defined for phase : " << i
647 if (phase.m_L->dim() != 3) {
648 std::cout <<
"AM trajectory is not of dimension 3 for phase : " << i
652 if (phase.m_dL->dim() != 3) {
654 <<
"AM derivative trajectory is not of dimension 3 for phase : "
658 if (phase.m_L->min() != phase.timeInitial()) {
659 std::cout <<
"AM trajectory do not start at t_init for phase : " << i
663 if (phase.m_dL->min() != phase.timeInitial()) {
665 <<
"AM derivative trajectory do not start at t_init for phase : "
669 if (phase.m_L->max() != phase.timeFinal()) {
670 std::cout <<
"AM trajectory do not end at t_final for phase : " << i
674 if (phase.m_dL->max() != phase.timeFinal()) {
676 <<
"AM derivative trajectory do not end at t_final for phase : "
680 if (phase.m_L_init.isZero()) {
681 if (!(*phase.m_L)(phase.m_L->min()).isZero()) {
682 std::cout <<
"AM trajectory do not start at L_init for phase : " << i
686 }
else if (!(*phase.m_L)(phase.m_L->min()).isApprox(phase.m_L_init)) {
687 std::cout <<
"AM trajectory do not start at L_init for phase : " << i
691 if (phase.m_dL_init.isZero()) {
692 if (!(*phase.m_dL)(phase.m_dL->min()).isZero()) {
694 <<
"AM derivative trajectory do not start at dL_init for phase : "
698 }
else if (!(*phase.m_dL)(phase.m_dL->min())
699 .isApprox(phase.m_dL_init, 1e-6)) {
701 <<
"AM derivative trajectory do not start at dL_init for phase : "
705 if (phase.m_L_final.isZero()) {
706 if (!(*phase.m_L)(phase.m_L->max()).isZero()) {
707 std::cout <<
"AM trajectory do not end at L_final for phase : " << i
711 }
else if (!(*phase.m_L)(phase.m_L->max())
712 .isApprox(phase.m_L_final, 1e-6)) {
713 std::cout <<
"AM trajectory do not end at L_final for phase : " << i
717 if (phase.m_dL_final.isZero()) {
718 if (!(*phase.m_dL)(phase.m_dL->max()).isZero()) {
720 <<
"AM derivative trajectory do not end at dL_final for phase : "
724 }
else if (!(*phase.m_dL)(phase.m_dL->max()).isApprox(phase.m_dL_final)) {
726 <<
"AM derivative trajectory do not end at dL_final for phase : "
757 const Scalar prec = Eigen::NumTraits<Scalar>::dummy_precision(),
758 const bool use_rotation =
true)
const {
764 std::cout <<
"No end effector trajectory for " << eeName
765 <<
" at phase " << i <<
" but it is in contact at phase "
766 << i + 1 << std::endl;
772 std::cout <<
"Effector trajectory for " << eeName
773 <<
" do not start at t_init in phase " << i << std::endl;
777 std::cout <<
"Effector trajectory for " << eeName
778 <<
" do not end at t_final in phase " << i << std::endl;
786 !(pTrajMax.toHomogeneousMatrix() - pPhaseMax.toHomogeneousMatrix())
787 .isMuchSmallerThan(1.0, prec)) ||
788 !(pTrajMax.translation() - pPhaseMax.translation())
789 .isMuchSmallerThan(1.0, prec)) {
790 std::cout <<
"Effector trajectory for " << eeName
791 <<
" do not end at it's contact placement in the next "
794 std::cout <<
"Last point : " << std::endl
795 << pTrajMax << std::endl
796 <<
"Next contact : " << std::endl
797 << pPhaseMax << std::endl;
807 if ((use_rotation && !(pTrajMin.toHomogeneousMatrix() -
808 pPhaseMin.toHomogeneousMatrix())
809 .isMuchSmallerThan(1.0, prec)) ||
810 !(pTrajMin.translation() - pPhaseMin.translation())
811 .isMuchSmallerThan(1.0, prec)) {
812 std::cout <<
"Effector trajectory for " << eeName
813 <<
" do not start at it's contact placement in the "
814 "previous phase, for phase "
816 std::cout <<
"First point : " << std::endl
817 << pTrajMin << std::endl
818 <<
"Previous contact : " << std::endl
819 << pPhaseMin << std::endl;
840 std::cout <<
"joint position trajectory not defined for phase : " << i
844 if (phase.m_q->min() != phase.timeInitial()) {
845 std::cout <<
"joint trajectory do not start at t_init for phase : " << i
849 if (phase.m_q->max() != phase.timeFinal()) {
850 std::cout <<
"joint trajectory do not end at t_final for phase : " << i
854 if (!(*phase.m_q)(phase.m_q->min()).isApprox(phase.m_q_init)) {
855 std::cout <<
"joint trajectory do not start at q_init for phase : " << i
859 if (!(*phase.m_q)(phase.m_q->max()).isApprox(phase.m_q_final)) {
860 std::cout <<
"joint trajectory do not end at q_final for phase : " << i
881 std::cout <<
"joint velocity trajectory not defined for phase : " << i
886 std::cout <<
"joint acceleration trajectory not defined for phase : "
890 if (phase.m_dq->min() != phase.timeInitial()) {
892 <<
"joint velocity trajectory do not start at t_init for phase : "
896 if (phase.m_ddq->min() != phase.timeInitial()) {
897 std::cout <<
"joint acceleration trajectory do not start at t_init for "
902 if (phase.m_dq->max() != phase.timeFinal()) {
904 <<
"joint velocity trajectory do not end at t_final for phase : "
908 if ((phase.m_ddq->max() != phase.timeFinal()) &&
910 std::cout <<
"joint acceleration trajectory do not end at t_final for "
932 std::cout <<
"Torque trajectory not defined for phase : " << i
937 if (phase.m_tau->min() != phase.timeInitial()) {
938 std::cout <<
"Torque trajectory do not start at t_init for phase : "
942 if ((phase.m_tau->max() != phase.timeFinal()) && i <
size() - 1) {
943 std::cout <<
"Torque trajectory do not end at t_final for phase : " << i
963 for (std::string eeName : phase.effectorsInContact()) {
964 if (phase.contactForces().count(eeName) == 0) {
965 std::cout <<
"No contact forces trajectory for effector " << eeName
966 <<
" at phase " << i << std::endl;
969 if (phase.contactNormalForces().count(eeName) == 0) {
970 std::cout <<
"No contact normal force trajectory for effector "
971 << eeName <<
" for phase " << i << std::endl;
974 if (phase.contactForces().at(eeName)->min() != phase.timeInitial()) {
975 std::cout <<
"Contact forces trajectory for effector " << eeName
976 <<
" do not start at t_init for phase " << i << std::endl;
979 if (phase.contactForces().at(eeName)->max() != phase.timeFinal()) {
980 std::cout <<
"Contact forces trajectory for effector " << eeName
981 <<
" do not end at t_final for phase " << i << std::endl;
984 if (phase.contactNormalForces().at(eeName)->min() !=
985 phase.timeInitial()) {
986 std::cout <<
"Contact normal force trajectory for effector " << eeName
987 <<
" do not start at t_init for phase " << i << std::endl;
990 if (phase.contactNormalForces().at(eeName)->max() !=
992 std::cout <<
"Contact normal force trajectory for effector " << eeName
993 <<
" do not end at t_final for phase " << i << std::endl;
1011 if (!phase.m_root) {
1012 std::cout <<
"Root trajectory not defined for phase : " << i
1016 if (phase.m_root->min() != phase.timeInitial()) {
1017 std::cout <<
"Root trajectory do not start at t_init for phase : " << i
1021 if (phase.m_root->max() != phase.timeFinal()) {
1022 std::cout <<
"Root trajectory do not start at t_final for phase : " << i
1039 for (
const std::string& eeName : phase.effectorsInContact()) {
1040 if (phase.contactPatches().at(eeName).friction() <= 0.) {
1041 std::cout <<
"Friction not defined for phase " << i
1042 <<
" and effector " << eeName << std::endl;
1059 for (
const std::string& eeName : phase.effectorsInContact()) {
1060 if (phase.contactPatches().at(eeName).m_contact_model.m_contact_type ==
1062 std::cout <<
"ContactModel not defined for phase " << i
1063 <<
" and effector " << eeName << std::endl;
1081 std::cout <<
"ZMP trajectory not defined for phase : " << i
1085 if (phase.m_zmp->dim() != 3) {
1086 std::cout <<
"ZMP trajectory is not of dimension 3 for phase : " << i
1090 if (phase.m_zmp->min() != phase.timeInitial()) {
1091 std::cout <<
"ZMP trajectory do not start at t_init for phase : " << i
1095 if (phase.m_zmp->max() != phase.timeFinal()) {
1096 std::cout <<
"ZMP trajectory do not end at t_final for phase : " << i
1113 std::set<std::string> res_set;
1115 for (
const std::string& eeName : phase.effectorsInContact()) {
1116 res_set.insert(eeName);
1119 return t_strings(res_set.begin(), res_set.end());
1130 res.add_curve_ptr(phase.m_c);
1143 res.add_curve_ptr(phase.m_dc);
1156 res.add_curve_ptr(phase.m_ddc);
1169 res.add_curve_ptr(phase.m_L);
1182 res.add_curve_ptr(phase.m_dL);
1195 res.add_curve_ptr(phase.m_zmp);
1209 res.add_curve_ptr(phase.m_wrench);
1222 res.add_curve_ptr(phase.m_q);
1235 res.add_curve_ptr(phase.m_dq);
1248 res.add_curve_ptr(phase.m_ddq);
1261 res.add_curve_ptr(phase.m_tau);
1274 res.add_curve_ptr(phase.m_root);
1289 const std::string& eeName)
const {
1294 size_t last_phase = 0;
1298 if (first_phase > i) {
1302 first_placement = curve->operator()(curve->min());
1307 throw std::invalid_argument(
1308 "The contact sequence doesn't have any phase with an effector "
1310 " for the given effector name");
1311 if (first_phase > 0) {
1314 new SE3Curve_t(first_placement, first_placement,
1317 res.add_curve_ptr(ptr_init);
1320 for (
size_t i = first_phase; i <= last_phase; ++i) {
1324 last_placement = res(res.max());
1331 res.add_curve_ptr(ptr);
1337 new SE3Curve_t(last_placement, last_placement,
1340 res.add_curve_ptr(ptr_final);
1355 const std::string& eeName)
const {
1360 if (phase.contactForces().count(eeName) > 0) {
1361 dim = phase.contactForces().at(eeName)->dim();
1368 Eigen::MatrixXd zeros = Eigen::MatrixXd::Zero(dim, 1);
1371 if (phase.contactForces().count(eeName) > 0) {
1372 res.add_curve_ptr(phase.contactForces().at(eeName));
1375 new polynomial_t(zeros, phase.timeInitial(), phase.timeFinal()));
1376 res.add_curve_ptr(ptr);
1392 const std::string& eeName)
const {
1394 Eigen::MatrixXd zeros = Eigen::MatrixXd::Zero(1, 1);
1397 if (phase.contactNormalForces().count(eeName) > 0) {
1398 res.add_curve_ptr(phase.contactNormalForces().at(eeName));
1401 new polynomial_t(zeros, phase.timeInitial(), phase.timeFinal()));
1402 res.add_curve_ptr(ptr);
1421 throw std::invalid_argument(
"No phase found for the given time.");
1454 template <
class Archive>
1455 void save(Archive& ar,
const unsigned int )
const {
1456 const size_t m_size =
size();
1457 ar& boost::serialization::make_nvp(
"size", m_size);
1458 for (
typename ContactPhaseVector::const_iterator it =
1461 ar& boost::serialization::make_nvp(
"contact_phase", *it);
1465 template <
class Archive>
1466 void load(Archive& ar,
const unsigned int ) {
1468 ar >> boost::serialization::make_nvp(
"size", m_size);
1473 ar >> boost::serialization::make_nvp(
"contact_phase", *it);
1477 BOOST_SERIALIZATION_SPLIT_MEMBER()
#define MULTICONTACT_API_DEFINE_CLASS_TEMPLATE_VERSION(Template, Type)
Definition archive.hpp:22