6 #include <dynamic-graph/factory.h>
8 #include <sot/core/debug.hh>
9 #include <sot/core/stop-watch.hh>
13 #include "pinocchio/algorithm/frames.hpp"
18 namespace dg = ::dynamicgraph;
20 using namespace dg::command;
22 using namespace pinocchio;
23 using boost::math::normal;
25 void se3Interp(
const pinocchio::SE3& s1,
const pinocchio::SE3& s2,
26 const double alpha, pinocchio::SE3& s12) {
27 const Eigen::Vector3d t_(s1.translation() * alpha +
28 s2.translation() * (1 - alpha));
30 const Eigen::Vector3d w(pinocchio::log3(s1.rotation()) * alpha +
31 pinocchio::log3(s2.rotation()) * (1 - alpha));
33 s12 = pinocchio::SE3(pinocchio::exp3(w), t_);
35 void rpyToMatrix(
double roll,
double pitch,
double yaw, Eigen::Matrix3d& R) {
36 Eigen::AngleAxisd rollAngle(roll, Eigen::Vector3d::UnitX());
37 Eigen::AngleAxisd pitchAngle(pitch, Eigen::Vector3d::UnitY());
38 Eigen::AngleAxisd yawAngle(yaw, Eigen::Vector3d::UnitZ());
39 Eigen::Quaternion<double> q = yawAngle * pitchAngle * rollAngle;
43 void rpyToMatrix(
const Eigen::Vector3d& rpy, Eigen::Matrix3d& R) {
47 void matrixToRpy(
const Eigen::Matrix3d& M, Eigen::Vector3d& rpy) {
48 double m = sqrt(M(2, 1) * M(2, 1) + M(2, 2) * M(2, 2));
49 rpy(1) = atan2(-M(2, 0), m);
50 if (fabs(fabs(rpy(1)) - 0.5 * M_PI) < 0.001) {
52 rpy(2) = -atan2(M(0, 1), M(1, 1));
54 rpy(2) = atan2(M(1, 0), M(0, 0));
55 rpy(0) = atan2(M(2, 1), M(2, 2));
60 Eigen::Vector4d& q12) {
61 q12(0) = q2(0) * q1(0) - q2(1) * q1(1) - q2(2) * q1(2) - q2(3) * q1(3);
62 q12(1) = q2(0) * q1(1) + q2(1) * q1(0) - q2(2) * q1(3) + q2(3) * q1(2);
63 q12(2) = q2(0) * q1(2) + q2(1) * q1(3) + q2(2) * q1(0) - q2(3) * q1(1);
64 q12(3) = q2(0) * q1(3) - q2(1) * q1(2) + q2(2) * q1(1) + q2(3) * q1(0);
68 const Eigen::Vector4d& quat,
69 Eigen::Vector3d& rotatedPoint) {
70 const Eigen::Vector4d p4(0.0, point(0), point(1), point(2));
71 const Eigen::Vector4d quat_conj(quat(0), -quat(1), -quat(2), -quat(3));
72 Eigen::Vector4d q_tmp1, q_tmp2;
75 rotatedPoint(0) = q_tmp2(1);
76 rotatedPoint(1) = q_tmp2(2);
77 rotatedPoint(2) = q_tmp2(3);
80 #define PROFILE_BASE_POSITION_ESTIMATION "base-est position estimation"
81 #define PROFILE_BASE_VELOCITY_ESTIMATION "base-est velocity estimation"
82 #define PROFILE_BASE_KINEMATICS_COMPUTATION "base-est kinematics computation"
84 #define INPUT_SIGNALS \
85 m_joint_positionsSIN << m_joint_velocitiesSIN << m_imu_quaternionSIN \
86 << m_forceLLEGSIN << m_forceRLEGSIN << m_dforceLLEGSIN \
87 << m_dforceRLEGSIN << m_w_lf_inSIN << m_w_rf_inSIN \
88 << m_K_fb_feet_posesSIN << m_lf_ref_xyzquatSIN \
89 << m_rf_ref_xyzquatSIN << m_accelerometerSIN \
91 #define OUTPUT_SIGNALS \
92 m_qSOUT << m_vSOUT << m_v_kinSOUT << m_v_flexSOUT << m_v_imuSOUT \
93 << m_v_gyrSOUT << m_lf_xyzquatSOUT << m_rf_xyzquatSOUT << m_a_acSOUT \
94 << m_v_acSOUT << m_q_lfSOUT << m_q_rfSOUT << m_q_imuSOUT \
95 << m_w_lfSOUT << m_w_rfSOUT << m_w_lf_filteredSOUT \
96 << m_w_rf_filteredSOUT
110 CONSTRUCT_SIGNAL_IN(joint_positions,
dynamicgraph::Vector),
111 CONSTRUCT_SIGNAL_IN(joint_velocities,
dynamicgraph::Vector),
112 CONSTRUCT_SIGNAL_IN(imu_quaternion,
dynamicgraph::Vector),
117 CONSTRUCT_SIGNAL_IN(w_lf_in, double),
118 CONSTRUCT_SIGNAL_IN(w_rf_in, double),
119 CONSTRUCT_SIGNAL_IN(K_fb_feet_poses, double),
120 CONSTRUCT_SIGNAL_IN(lf_ref_xyzquat,
dynamicgraph::Vector),
121 CONSTRUCT_SIGNAL_IN(rf_ref_xyzquat,
dynamicgraph::Vector),
122 CONSTRUCT_SIGNAL_IN(accelerometer,
dynamicgraph::Vector),
124 CONSTRUCT_SIGNAL_INNER(kinematics_computations,
dynamicgraph::Vector,
125 m_joint_positionsSIN << m_joint_velocitiesSIN),
127 m_kinematics_computationsSINNER
128 << m_joint_positionsSIN << m_imu_quaternionSIN
129 << m_forceLLEGSIN << m_forceRLEGSIN
130 << m_w_lf_inSIN << m_w_rf_inSIN
131 << m_K_fb_feet_posesSIN << m_w_lf_filteredSOUT
132 << m_w_rf_filteredSOUT << m_lf_ref_xyzquatSIN
133 << m_rf_ref_xyzquatSIN),
135 m_kinematics_computationsSINNER
136 << m_accelerometerSIN << m_gyroscopeSIN
137 << m_qSOUT << m_dforceLLEGSIN
139 CONSTRUCT_SIGNAL_OUT(v_kin,
dynamicgraph::Vector, m_vSOUT),
140 CONSTRUCT_SIGNAL_OUT(v_flex,
dynamicgraph::Vector, m_vSOUT),
141 CONSTRUCT_SIGNAL_OUT(v_imu,
dynamicgraph::Vector, m_vSOUT),
142 CONSTRUCT_SIGNAL_OUT(v_gyr,
dynamicgraph::Vector, m_vSOUT),
143 CONSTRUCT_SIGNAL_OUT(lf_xyzquat,
dynamicgraph::Vector, m_qSOUT),
144 CONSTRUCT_SIGNAL_OUT(rf_xyzquat,
dynamicgraph::Vector, m_qSOUT),
145 CONSTRUCT_SIGNAL_OUT(a_ac,
dynamicgraph::Vector, m_vSOUT),
146 CONSTRUCT_SIGNAL_OUT(v_ac,
dynamicgraph::Vector, m_vSOUT),
147 CONSTRUCT_SIGNAL_OUT(q_lf,
dynamicgraph::Vector, m_qSOUT),
148 CONSTRUCT_SIGNAL_OUT(q_rf,
dynamicgraph::Vector, m_qSOUT),
150 m_qSOUT << m_imu_quaternionSIN),
151 CONSTRUCT_SIGNAL_OUT(w_lf, double, m_forceLLEGSIN),
152 CONSTRUCT_SIGNAL_OUT(w_rf, double, m_forceRLEGSIN),
153 CONSTRUCT_SIGNAL_OUT(w_lf_filtered, double, m_w_lfSOUT),
154 CONSTRUCT_SIGNAL_OUT(w_rf_filtered, double, m_w_rfSOUT),
155 m_initSucceeded(false),
156 m_reset_foot_pos(true),
158 m_zmp_std_dev_rf(1.0),
159 m_zmp_std_dev_lf(1.0),
160 m_fz_std_dev_rf(1.0),
161 m_fz_std_dev_lf(1.0),
162 m_zmp_margin_lf(0.0),
163 m_zmp_margin_rf(0.0) {
166 m_K_rf << 4034, 23770, 239018, 707, 502, 936;
167 m_K_lf << 4034, 23770, 239018, 707, 502, 936;
175 docCommandVoid2(
"Initialize the entity.",
"time step (double)",
176 "URDF file path (string)")));
178 addCommand(
"set_fz_stable_windows_size",
182 "Set the windows size used to detect that feet is stable",
184 addCommand(
"set_alpha_w_filter",
187 docCommandVoid1(
"Set the filter parameter to filter weights",
192 docCommandVoid1(
"Set the filter parameter for removing "
193 "DC from accelerometer data",
195 addCommand(
"set_alpha_DC_vel",
198 docCommandVoid1(
"Set the filter parameter for removing DC "
199 "from velocity integrated from acceleration",
202 "reset_foot_positions",
204 docCommandVoid0(
"Reset the position of the feet.")));
209 docDirectGetter(
"Weight of imu-based orientation in sensor fusion",
211 addCommand(
"set_imu_weight",
215 "Set the weight of imu-based orientation in sensor fusion",
218 "set_zmp_std_dev_right_foot",
220 docCommandVoid1(
"Set the standard deviation of the ZMP "
221 "measurement errors for the right foot",
224 "set_zmp_std_dev_left_foot",
226 docCommandVoid1(
"Set the standard deviation of the ZMP "
227 "measurement errors for the left foot",
229 addCommand(
"set_normal_force_std_dev_right_foot",
232 docCommandVoid1(
"Set the standard deviation of the normal "
233 "force measurement errors for the right foot",
235 addCommand(
"set_normal_force_std_dev_left_foot",
238 docCommandVoid1(
"Set the standard deviation of the normal "
239 "force measurement errors for the left foot",
241 addCommand(
"set_stiffness_right_foot",
245 "Set the 6d stiffness of the spring at the right foot",
248 "set_stiffness_left_foot",
251 docCommandVoid1(
"Set the 6d stiffness of the spring at the left foot",
254 "set_right_foot_sizes",
258 "Set the size of the right foot (pos x, neg x, pos y, neg y)",
261 "set_left_foot_sizes",
265 "Set the size of the left foot (pos x, neg x, pos y, neg y)",
268 "set_zmp_margin_right_foot",
271 docCommandVoid1(
"Set the ZMP margin for the right foot",
"double")));
273 "set_zmp_margin_left_foot",
276 docCommandVoid1(
"Set the ZMP margin for the left foot",
"double")));
278 "set_normal_force_margin_right_foot",
281 docCommandVoid1(
"Set the normal force margin for the right foot",
284 "set_normal_force_margin_left_foot",
287 docCommandVoid1(
"Set the normal force margin for the left foot",
295 std::string localName(robotRef);
296 if (isNameInRobotUtil(localName)) {
298 std::cerr <<
"m_robot_util:" <<
m_robot_util << std::endl;
301 "You should have an entity controller manager initialized before",
306 pinocchio::urdf::buildModel(
m_robot_util->m_urdf_filename,
307 pinocchio::JointModelFreeFlyer(),
m_model);
331 SE3(Matrix3::Identity(),
332 -Eigen::Map<const Vector3>(
333 &
m_robot_util->m_foot_util.m_Right_Foot_Force_Sensor_XYZ(0)));
349 }
catch (
const std::exception& e) {
350 std::cout << e.what();
351 SEND_MSG(
"Init failed: Could load URDF :" +
m_robot_util->m_urdf_filename,
361 return SEND_MSG(
"windows_size should be a positive integer",
367 if (a < 0.0 || a > 1.0)
368 return SEND_MSG(
"alpha should be in [0..1]", MSG_TYPE_ERROR);
373 if (a < 0.0 || a > 1.0)
374 return SEND_MSG(
"alpha should be in [0..1]", MSG_TYPE_ERROR);
379 if (a < 0.0 || a > 1.0)
380 return SEND_MSG(
"alpha should be in [0..1]", MSG_TYPE_ERROR);
388 return SEND_MSG(
"Imu weight must be nonnegative", MSG_TYPE_ERROR);
395 "Stiffness vector should have size 6, not " + toString(k.size()),
403 "Stiffness vector should have size 6, not " + toString(k.size()),
410 return SEND_MSG(
"Standard deviation must be a positive number",
417 return SEND_MSG(
"Standard deviation must be a positive number",
424 return SEND_MSG(
"Standard deviation must be a positive number",
431 return SEND_MSG(
"Standard deviation must be a positive number",
439 "Foot size vector should have size 4, not " + toString(s.size()),
447 "Foot size vector should have size 4, not " + toString(s.size()),
469 pinocchio::Force f(w);
471 if (f.linear()[2] == 0.0)
return;
472 zmp[0] = -f.angular()[1] / f.linear()[2];
473 zmp[1] = f.angular()[0] / f.linear()[2];
477 const Vector4& foot_sizes,
478 double std_dev,
double margin) {
479 double fs0 = foot_sizes[0] - margin;
480 double fs1 = foot_sizes[1] + margin;
481 double fs2 = foot_sizes[2] - margin;
482 double fs3 = foot_sizes[3] + margin;
484 if (zmp[0] > fs0 || zmp[0] < fs1 || zmp[1] > fs2 || zmp[1] < fs3)
return 0;
486 double cdx = ((cdf(
m_normal, (fs0 - zmp[0]) / std_dev) -
487 cdf(
m_normal, (fs1 - zmp[0]) / std_dev)) -
490 double cdy = ((cdf(
m_normal, (fs2 - zmp[1]) / std_dev) -
491 cdf(
m_normal, (fs3 - zmp[1]) / std_dev)) -
499 if (fz < margin)
return 0.0;
500 return (cdf(
m_normal, (fz - margin) / std_dev) - 0.5) * 2.0;
504 const Vector6& ftrf) {
506 SE3
dummy, dummy1, lfMff, rfMff;
514 lfMff,
dummy, dummy1);
517 const Vector3& ankle_2_sole_xyz =
519 const SE3 groundMfoot(Matrix3::Identity(), -1.0 * ankle_2_sole_xyz);
520 lfMff = groundMfoot * lfMff;
521 rfMff = groundMfoot * rfMff;
524 const Vector3 w(0.5 * (pinocchio::log3(lfMff.rotation()) +
525 pinocchio::log3(rfMff.rotation())));
526 SE3 oMff = SE3(pinocchio::exp3(w),
527 0.5 * (lfMff.translation() + rfMff.translation()));
529 oMff.translation()(0) += 9.562e-03;
531 m_oMlfs = oMff * lfMff.inverse() * groundMfoot;
532 m_oMrfs = oMff * rfMff.inverse() * groundMfoot;
535 Eigen::Quaternion<double> quat_lf(
m_oMlfs.rotation());
542 Eigen::Quaternion<double> quat_rf(
m_oMrfs.rotation());
552 sendMsg(
"Reference pos of left foot:\n" + toString(
m_oMlfs), MSG_TYPE_INFO);
553 sendMsg(
"Reference pos of right foot:\n" + toString(
m_oMrfs), MSG_TYPE_INFO);
567 const SE3& oMfs,
const int foot_id,
568 SE3& oMff, SE3& oMfa, SE3& fsMff) {
570 xyz << -ft[0] / K(0), -ft[1] / K(1), -ft[2] / K(2);
572 rpyToMatrix(-ft[3] / K(3), -ft[4] / K(4), -ft[5] / K(5), R);
573 const SE3 fsMfa(R, xyz);
575 const SE3 faMff(
m_data->oMf[foot_id].inverse());
580 fsMff = fsMfa * faMff;
588 if (!m_initSucceeded) {
589 SEND_WARNING_STREAM_MSG(
590 "Cannot compute signal kinematics_computations before initialization!");
594 const Eigen::VectorXd& qj = m_joint_positionsSIN(iter);
595 const Eigen::VectorXd& dq = m_joint_velocitiesSIN(iter);
597 static_cast<Eigen::VectorXd::Index
>(m_robot_util->m_nbJoints) &&
598 "Unexpected size of signal joint_positions");
600 static_cast<Eigen::VectorXd::Index
>(m_robot_util->m_nbJoints) &&
601 "Unexpected size of signal joint_velocities");
604 m_robot_util->joints_sot_to_urdf(qj, m_q_pin.tail(m_robot_util->m_nbJoints));
605 m_robot_util->joints_sot_to_urdf(dq, m_v_pin.tail(m_robot_util->m_nbJoints));
610 m_q_pin.head<6>().setZero();
612 m_v_pin.head<6>().setZero();
613 pinocchio::forwardKinematics(m_model, *m_data, m_q_pin, m_v_pin);
614 pinocchio::framesForwardKinematics(m_model, *m_data);
622 if (!m_initSucceeded) {
623 SEND_WARNING_STREAM_MSG(
"Cannot compute signal q before initialization!");
627 static_cast<Eigen::VectorXd::Index
>(m_robot_util->m_nbJoints + 6))
628 s.resize(m_robot_util->m_nbJoints + 6);
630 const Eigen::VectorXd& qj = m_joint_positionsSIN(iter);
631 const Eigen::Vector4d& quatIMU_vec = m_imu_quaternionSIN(iter);
632 const Vector6& ftrf = m_forceRLEGSIN(iter);
633 const Vector6& ftlf = m_forceLLEGSIN(iter);
638 if (m_w_lf_inSIN.isPlugged())
639 wL = m_w_lf_inSIN(iter);
641 wL = m_w_lf_filteredSOUT(iter);
642 if (m_left_foot_is_stable ==
false) wL = 0.0;
644 if (m_w_rf_inSIN.isPlugged())
645 wR = m_w_rf_inSIN(iter);
647 wR = m_w_rf_filteredSOUT(iter);
648 if (m_right_foot_is_stable ==
false) wR = 0.0;
652 static_cast<Eigen::VectorXd::Index
>(m_robot_util->m_nbJoints) &&
653 "Unexpected size of signal joint_positions");
657 if (wR == 0.0 && wL == 0.0) {
658 SEND_WARNING_STREAM_MSG(
659 "The robot is flying!" +
660 (
"- forceRLEG: " + toString(ftrf.transpose())) +
661 "- forceLLEG: " + toString(ftlf.transpose()) +
662 "- m_right_foot_is_stable: " + toString(m_right_foot_is_stable) +
663 "- m_left_foot_is_stable: " + toString(m_left_foot_is_stable));
668 m_kinematics_computationsSINNER(iter);
670 if (m_reset_foot_pos) reset_foot_positions_impl(ftlf, ftrf);
674 SE3 oMlfa, oMrfa, lfsMff, rfsMff;
675 kinematics_estimation(ftrf, m_K_rf, m_oMrfs,
676 static_cast<int>(m_right_foot_id), m_oMff_rf, oMrfa,
678 kinematics_estimation(ftlf, m_K_lf, m_oMlfs,
679 static_cast<int>(m_left_foot_id), m_oMff_lf, oMlfa,
684 m_data->oMf[m_IMU_body_id]);
686 const SE3 chestMff(ffMchest.inverse());
689 Vector3 rpy_chest, rpy_chest_lf, rpy_chest_rf,
693 matrixToRpy((m_oMff_lf * ffMchest).rotation(), rpy_chest_lf);
694 matrixToRpy((m_oMff_rf * ffMchest).rotation(), rpy_chest_rf);
695 Eigen::Quaternion<double> quatIMU(quatIMU_vec[0], quatIMU_vec[1],
696 quatIMU_vec[2], quatIMU_vec[3]);
697 matrixToRpy(quatIMU.toRotationMatrix(), rpy_chest_imu);
700 double wSum = wL + wR + m_w_imu;
701 rpy_chest(0) = (rpy_chest_lf[0] * wL + rpy_chest_rf[0] * wR +
702 rpy_chest_imu[0] * m_w_imu) /
704 rpy_chest(1) = (rpy_chest_lf[1] * wL + rpy_chest_rf[1] * wR +
705 rpy_chest_imu[1] * m_w_imu) /
707 rpy_chest(2) = (rpy_chest_lf[2] * wL + rpy_chest_rf[2] * wR) / (wL + wR);
710 m_oRff = m_oRchest * chestMff.rotation();
716 m_oRff * m_data->oMf[m_left_foot_id].translation();
718 m_oRff * m_data->oMf[m_right_foot_id].translation();
720 m_q_pin.head<3>() = ((oMlfa.translation() - pos_lf_ff) * wL +
721 (oMrfa.translation() - pos_rf_ff) * wR) /
724 m_q_sot.tail(m_robot_util->m_nbJoints) = qj;
725 base_se3_to_sot(m_q_pin.head<3>(), m_oRff, m_q_sot.head<6>());
730 const SE3 oMff_est(m_oRff, m_q_pin.head<3>());
733 if (m_K_fb_feet_posesSIN.isPlugged()) {
734 const double K_fb = m_K_fb_feet_posesSIN(iter);
735 if (K_fb > 0.0 && m_w_imu > 0.0) {
736 assert(m_w_imu > 0.0 &&
737 "Update of the feet 6d poses should not be done if wIMU = 0.0");
739 "Feedback gain on foot correction should be less than 1.0 "
740 "(K_fb_feet_poses>1.0)");
742 const SE3 oMlfs_est(oMff_est * (lfsMff.inverse()));
743 const SE3 oMrfs_est(oMff_est * (rfsMff.inverse()));
745 SE3 leftDrift = m_oMlfs.inverse() * oMlfs_est;
746 SE3 rightDrift = m_oMrfs.inverse() * oMrfs_est;
750 SE3 rightDrift_delta;
751 se3Interp(leftDrift, SE3::Identity(), K_fb * wR, leftDrift_delta);
752 se3Interp(rightDrift, SE3::Identity(), K_fb * wL, rightDrift_delta);
755 if (m_right_foot_is_stable ==
false) rightDrift_delta = rightDrift;
756 if (m_left_foot_is_stable ==
false) leftDrift_delta = leftDrift;
757 if (m_right_foot_is_stable ==
false && m_left_foot_is_stable ==
false) {
759 rightDrift_delta = SE3::Identity();
760 leftDrift_delta = SE3::Identity();
762 m_oMlfs = m_oMlfs * leftDrift_delta;
763 m_oMrfs = m_oMrfs * rightDrift_delta;
765 SE3 oMlfs_ref, oMrfs_ref;
766 if (m_lf_ref_xyzquatSIN.isPlugged() and
767 m_rf_ref_xyzquatSIN.isPlugged()) {
769 const Vector7& lf_ref_xyzquat_vec = m_lf_ref_xyzquatSIN(iter);
770 const Vector7& rf_ref_xyzquat_vec = m_rf_ref_xyzquatSIN(iter);
771 const Eigen::Quaterniond ql(
772 m_lf_ref_xyzquatSIN(iter)(3), m_lf_ref_xyzquatSIN(iter)(4),
773 m_lf_ref_xyzquatSIN(iter)(5), m_lf_ref_xyzquatSIN(iter)(6));
774 const Eigen::Quaterniond qr(
775 m_rf_ref_xyzquatSIN(iter)(3), m_rf_ref_xyzquatSIN(iter)(4),
776 m_rf_ref_xyzquatSIN(iter)(5), m_rf_ref_xyzquatSIN(iter)(6));
777 oMlfs_ref = SE3(ql.toRotationMatrix(), lf_ref_xyzquat_vec.head<3>());
778 oMrfs_ref = SE3(qr.toRotationMatrix(), rf_ref_xyzquat_vec.head<3>());
780 oMlfs_ref = m_oMlfs_default_ref;
781 oMrfs_ref = m_oMrfs_default_ref;
785 const Vector3 translation_feet_drift =
786 0.5 * ((oMlfs_ref.translation() - m_oMlfs.translation()) +
787 (oMrfs_ref.translation() - m_oMrfs.translation()));
789 const Vector3 V_ref = oMrfs_ref.translation() - oMlfs_ref.translation();
790 const Vector3 V_est = m_oMrfs.translation() - m_oMlfs.translation();
793 const double yaw_drift =
794 (atan2(V_ref(1), V_ref(0)) - atan2(V_est(1), V_est(0)));
797 const Vector3 rpy_feet_drift(0., 0., yaw_drift);
798 Matrix3 rotation_feet_drift;
800 const SE3 drift_to_ref(rotation_feet_drift, translation_feet_drift);
801 m_oMlfs = m_oMlfs * drift_to_ref;
802 m_oMrfs = m_oMrfs * drift_to_ref;
807 m_oMlfs_xyzquat.head<3>() = m_oMlfs.translation();
808 Eigen::Quaternion<double> quat_lf(m_oMlfs.rotation());
809 m_oMlfs_xyzquat(3) = quat_lf.w();
810 m_oMlfs_xyzquat(4) = quat_lf.x();
811 m_oMlfs_xyzquat(5) = quat_lf.y();
812 m_oMlfs_xyzquat(6) = quat_lf.z();
814 m_oMrfs_xyzquat.head<3>() = m_oMrfs.translation();
815 Eigen::Quaternion<double> quat_rf(m_oMrfs.rotation());
816 m_oMrfs_xyzquat(3) = quat_rf.w();
817 m_oMrfs_xyzquat(4) = quat_rf.x();
818 m_oMrfs_xyzquat(5) = quat_rf.y();
819 m_oMrfs_xyzquat(6) = quat_rf.z();
826 if (!m_initSucceeded) {
827 SEND_WARNING_STREAM_MSG(
828 "Cannot compute signal lf_xyzquat before initialization! iter" +
832 if (s.size() != 7) s.resize(7);
838 if (!m_initSucceeded) {
839 SEND_WARNING_STREAM_MSG(
840 "Cannot compute signal rf_xyzquat before initialization! iter" +
844 if (s.size() != 7) s.resize(7);
850 if (!m_initSucceeded) {
851 SEND_WARNING_STREAM_MSG(
852 "Cannot compute signal q_lf before initialization!");
856 static_cast<Eigen::VectorXd::Index
>(m_robot_util->m_nbJoints + 6))
857 s.resize(m_robot_util->m_nbJoints + 6);
859 const Eigen::VectorXd& q = m_qSOUT(iter);
860 s.tail(m_robot_util->m_nbJoints) = q.tail(m_robot_util->m_nbJoints);
861 base_se3_to_sot(m_oMff_lf.translation(), m_oMff_lf.rotation(), s.head<6>());
867 if (!m_initSucceeded) {
868 SEND_WARNING_STREAM_MSG(
869 "Cannot compute signal q_rf before initialization!");
873 static_cast<Eigen::VectorXd::Index
>(m_robot_util->m_nbJoints + 6))
874 s.resize(m_robot_util->m_nbJoints + 6);
876 const Eigen::VectorXd& q = m_qSOUT(iter);
877 s.tail(m_robot_util->m_nbJoints) = q.tail(m_robot_util->m_nbJoints);
878 base_se3_to_sot(m_oMff_rf.translation(), m_oMff_rf.rotation(), s.head<6>());
884 if (!m_initSucceeded) {
885 SEND_WARNING_STREAM_MSG(
886 "Cannot compute signal q_imu before initialization!");
890 static_cast<Eigen::VectorXd::Index
>(m_robot_util->m_nbJoints + 6))
891 s.resize(m_robot_util->m_nbJoints + 6);
893 const Eigen::VectorXd& q = m_qSOUT(iter);
894 s.tail(m_robot_util->m_nbJoints) = q.tail(m_robot_util->m_nbJoints);
896 const Eigen::Vector4d& quatIMU_vec = m_imu_quaternionSIN(iter);
897 Eigen::Quaternion<double> quatIMU(quatIMU_vec);
898 base_se3_to_sot(q.head<3>(), quatIMU.toRotationMatrix(), s.head<6>());
904 if (!m_initSucceeded) {
905 SEND_WARNING_STREAM_MSG(
906 "Cannot compute signal w_lf before initialization!");
910 const Vector6& wrench = m_forceLLEGSIN(iter);
913 compute_zmp(wrench, zmp);
914 double w_zmp = compute_zmp_weight(zmp, m_left_foot_sizes, m_zmp_std_dev_lf,
917 compute_force_weight(wrench(2), m_fz_std_dev_lf, m_fz_margin_lf);
920 if (wrench(2) > m_fz_margin_lf)
921 m_lf_fz_stable_cpt++;
923 m_lf_fz_stable_cpt = 0;
925 if (m_lf_fz_stable_cpt >= m_fz_stable_windows_size) {
926 m_lf_fz_stable_cpt = m_fz_stable_windows_size;
927 m_left_foot_is_stable =
true;
929 m_left_foot_is_stable =
false;
936 if (!m_initSucceeded) {
937 SEND_WARNING_STREAM_MSG(
938 "Cannot compute signal w_rf before initialization!");
942 const Vector6& wrench = m_forceRLEGSIN(iter);
945 compute_zmp(wrench, zmp);
946 double w_zmp = compute_zmp_weight(zmp, m_right_foot_sizes, m_zmp_std_dev_rf,
949 compute_force_weight(wrench(2), m_fz_std_dev_rf, m_fz_margin_rf);
952 if (wrench(2) > m_fz_margin_rf)
953 m_rf_fz_stable_cpt++;
955 m_rf_fz_stable_cpt = 0;
957 if (m_rf_fz_stable_cpt >= m_fz_stable_windows_size) {
958 m_rf_fz_stable_cpt = m_fz_stable_windows_size;
959 m_right_foot_is_stable =
true;
961 m_right_foot_is_stable =
false;
968 if (!m_initSucceeded) {
969 SEND_WARNING_STREAM_MSG(
970 "Cannot compute signal w_rf_filtered before initialization!");
973 double w_rf = m_w_rfSOUT(iter);
975 m_alpha_w_filter * w_rf +
976 (1 - m_alpha_w_filter) * m_w_rf_filtered;
982 if (!m_initSucceeded) {
983 SEND_WARNING_STREAM_MSG(
984 "Cannot compute signal w_lf_filtered before initialization!");
987 double w_lf = m_w_lfSOUT(iter);
989 m_alpha_w_filter * w_lf +
990 (1 - m_alpha_w_filter) * m_w_lf_filtered;
996 if (!m_initSucceeded) {
997 SEND_WARNING_STREAM_MSG(
"Cannot compute signal v before initialization!");
1001 static_cast<Eigen::VectorXd::Index
>(m_robot_util->m_nbJoints + 6))
1002 s.resize(m_robot_util->m_nbJoints + 6);
1004 m_kinematics_computationsSINNER(iter);
1009 const Eigen::VectorXd& dq = m_joint_velocitiesSIN(iter);
1010 const Eigen::Vector3d& acc_imu = m_accelerometerSIN(iter);
1011 const Eigen::Vector3d& gyr_imu = m_gyroscopeSIN(iter);
1012 const Vector6& dftrf = m_dforceRLEGSIN(iter);
1013 const Vector6& dftlf = m_dforceLLEGSIN(iter);
1015 static_cast<Eigen::VectorXd::Index
>(m_robot_util->m_nbJoints) &&
1016 "Unexpected size of signal joint_velocities");
1022 if (m_w_lf_inSIN.isPlugged())
1023 wL = m_w_lf_inSIN(iter);
1025 wL = m_w_lf_filteredSOUT(iter);
1026 if (m_left_foot_is_stable ==
false) wL = 0.0;
1028 if (m_w_rf_inSIN.isPlugged())
1029 wR = m_w_rf_inSIN(iter);
1031 wR = m_w_rf_filteredSOUT(iter);
1032 if (m_right_foot_is_stable ==
false) wR = 0.0;
1036 if (wR == 0.0 && wL == 0.0) {
1042 const Frame& f_lf = m_model.frames[m_left_foot_id];
1043 const Motion v_lf_local = m_data->v[f_lf.parent];
1044 const SE3 ffMlf = m_data->oMi[f_lf.parent];
1046 -ffMlf.act(v_lf_local).toVector();
1048 v_kin_l.head<3>() = m_oRff * v_kin_l.head<3>();
1049 v_kin_l.segment<3>(3) = m_oRff * v_kin_l.segment<3>(3);
1051 const Frame& f_rf = m_model.frames[m_right_foot_id];
1052 const Motion v_rf_local = m_data->v[f_rf.parent];
1053 const SE3 ffMrf = m_data->oMi[f_rf.parent];
1055 -ffMrf.act(v_rf_local).toVector();
1057 v_kin_r.head<3>() = m_oRff * v_kin_r.head<3>();
1058 v_kin_r.segment<3>(3) = m_oRff * v_kin_r.segment<3>(3);
1060 m_v_kin.head<6>() = (wR * v_kin_r + wL * v_kin_l) / (wL + wR);
1065 v_flex_l << -dftlf[0] / m_K_lf(0), -dftlf[1] / m_K_lf(1),
1066 -dftlf[2] / m_K_lf(2), -dftlf[3] / m_K_lf(3), -dftlf[4] / m_K_lf(4),
1067 -dftlf[5] / m_K_lf(5);
1068 v_flex_r << -dftrf[0] / m_K_rf(0), -dftrf[1] / m_K_rf(1),
1069 -dftrf[2] / m_K_rf(2), -dftrf[3] / m_K_rf(3), -dftrf[4] / m_K_rf(4),
1070 -dftrf[5] / m_K_rf(5);
1071 const Eigen::Matrix<double, 6, 6> lfAff = ffMlf.inverse().toActionMatrix();
1072 const Eigen::Matrix<double, 6, 6> rfAff = ffMrf.inverse().toActionMatrix();
1073 Eigen::Matrix<double, 12, 6> A;
1075 Eigen::Matrix<double, 12, 1> b;
1076 b << v_flex_l, v_flex_r;
1079 m_v_flex.head<6>() = (A.transpose() * A).ldlt().solve(A.transpose() * b);
1080 m_v_flex.head<3>() = m_oRff * m_v_flex.head<3>();
1085 const Matrix3 ffRimu = (m_data->oMf[m_IMU_body_id]).rotation();
1086 const Matrix3 lfRimu = ffMlf.rotation().transpose() * ffRimu;
1087 const Matrix3 rfRimu = ffMrf.rotation().transpose() * ffRimu;
1089 const SE3 chestMimu(
1090 Matrix3::Identity(),
1093 const SE3 ffMchest(m_data->oMf[m_IMU_body_id]);
1095 const SE3 imuMff = (ffMchest * chestMimu).inverse();
1098 const Frame& f_imu = m_model.frames[m_IMU_body_id];
1100 (imuMff * ffMlf).act(v_lf_local).angular() -
1101 m_data->v[f_imu.parent].angular();
1103 (imuMff * ffMrf).act(v_rf_local).angular() -
1104 m_data->v[f_imu.parent].angular();
1105 Motion v_gyr_ankle_l(
Vector3(0., 0., 0.), lfRimu * gVo_a_l);
1106 Motion v_gyr_ankle_r(
Vector3(0., 0., 0.), rfRimu * gVo_a_r);
1107 Vector6 v_gyr_l = -ffMlf.inverse().act(v_gyr_ankle_l).toVector();
1108 Vector6 v_gyr_r = -ffMrf.inverse().act(v_gyr_ankle_r).toVector();
1109 m_v_gyr.head<6>() = (wL * v_gyr_l + wR * v_gyr_r) / (wL + wR);
1117 const Vector3 acc_world = m_oRchest * acc_imu;
1127 if (m_isFirstIterFlag) {
1128 m_last_DCacc = acc_world;
1129 m_isFirstIterFlag =
false;
1130 sendMsg(
"iter:" + toString(iter) +
"\n", MSG_TYPE_INFO);
1133 acc_world * (1 - m_alpha_DC_acc) + m_last_DCacc * (m_alpha_DC_acc);
1136 m_last_DCacc = DCacc;
1137 const Vector3 ACacc = acc_world - DCacc;
1140 const Vector3 vel = m_last_vel + ACacc * m_dt;
1145 vel * (1 - m_alpha_DC_vel) + m_last_DCvel * (m_alpha_DC_vel);
1146 m_last_DCvel = DCvel;
1147 const Vector3 ACvel = vel - DCvel;
1152 const Vector3 imuVimu = m_oRchest.transpose() * ACvel;
1154 const Motion imuWimu(imuVimu, gyr_imu);
1160 const SE3 ffMimu = ffMchest * chestMimu;
1161 const Motion v = ffMimu.act(imuWimu);
1162 m_v_imu.head<6>() = v.toVector();
1163 m_v_imu.head<3>() = m_oRff * m_v_imu.head<3>();
1167 m_v_sot.head<6>() = m_v_gyr.head<6>() + m_v_kin.head<6>();
1171 m_v_sot.tail(m_robot_util->m_nbJoints) = dq;
1172 m_v_kin.tail(m_robot_util->m_nbJoints) = dq;
1173 m_v_flex.tail(m_robot_util->m_nbJoints) = dq;
1174 m_v_gyr.tail(m_robot_util->m_nbJoints) = dq;
1175 m_v_imu.tail(m_robot_util->m_nbJoints) = dq;
1183 if (!m_initSucceeded) {
1184 SEND_WARNING_STREAM_MSG(
1185 "Cannot compute signal v_kin before initialization!");
1194 if (!m_initSucceeded) {
1195 SEND_WARNING_STREAM_MSG(
1196 "Cannot compute signal v_flex before initialization!");
1200 s = m_v_flex + m_v_kin;
1205 if (!m_initSucceeded) {
1206 SEND_WARNING_STREAM_MSG(
1207 "Cannot compute signal v_imu before initialization!");
1216 if (!m_initSucceeded) {
1217 SEND_WARNING_STREAM_MSG(
1218 "Cannot compute signal v_gyr before initialization!");
1227 if (!m_initSucceeded) {
1228 SEND_WARNING_STREAM_MSG(
1229 "Cannot compute signal v_ac before initialization!");
1238 if (!m_initSucceeded) {
1239 SEND_WARNING_STREAM_MSG(
1240 "Cannot compute signal a_ac before initialization!");
1255 os <<
"BaseEstimator " << getName();
1257 getProfiler().report_all(3, os);
1258 }
catch (ExceptionSignal e) {