17 #include <dynamic-graph/all-commands.h>
18 #include <dynamic-graph/factory.h>
20 #include <sot/core/debug.hh>
21 #include <sot/core/stop-watch.hh>
24 #include "pinocchio/algorithm/frames.hpp"
28 namespace talos_balance {
29 namespace dg = ::dynamicgraph;
31 using namespace dg::command;
33 using namespace pinocchio;
34 using boost::math::normal;
36 void se3Interp(
const pinocchio::SE3& s1,
const pinocchio::SE3& s2,
37 const double alpha, pinocchio::SE3& s12) {
38 const Eigen::Vector3d t_(s1.translation() * alpha +
39 s2.translation() * (1 - alpha));
41 const Eigen::Vector3d w(pinocchio::log3(s1.rotation()) * alpha +
42 pinocchio::log3(s2.rotation()) * (1 - alpha));
44 s12 = pinocchio::SE3(pinocchio::exp3(w), t_);
47 void rpyToMatrix(
double roll,
double pitch,
double yaw, Eigen::Matrix3d& R) {
48 Eigen::AngleAxisd rollAngle(roll, Eigen::Vector3d::UnitX());
49 Eigen::AngleAxisd pitchAngle(pitch, Eigen::Vector3d::UnitY());
50 Eigen::AngleAxisd yawAngle(yaw, Eigen::Vector3d::UnitZ());
51 Eigen::Quaternion<double>
q = yawAngle * pitchAngle * rollAngle;
55 void rpyToMatrix(
const Eigen::Vector3d& rpy, Eigen::Matrix3d& R) {
59 void matrixToRpy(
const Eigen::Matrix3d& M, Eigen::Vector3d& rpy) {
60 double m = sqrt(M(2, 1) * M(2, 1) + M(2, 2) * M(2, 2));
61 rpy(1) = atan2(-M(2, 0), m);
62 if (fabs(fabs(rpy(1)) - 0.5 * M_PI) < 0.001) {
64 rpy(2) = -atan2(M(0, 1), M(1, 1));
66 rpy(2) = atan2(M(1, 0), M(0, 0));
67 rpy(0) = atan2(M(2, 1), M(2, 2));
99 double mean = (a1 + a2) / 2.;
100 if ((a1 - a2) > EIGEN_PI || (a1 - a2) < -EIGEN_PI) {
101 return mean > 0 ? -EIGEN_PI + mean : EIGEN_PI + mean;
106 inline double wEulerMean(
double a1,
double a2,
double w1,
double w2) {
107 double wMean = (a1 * w1 + a2 * w2) / (w1 + w2);
108 if (a1 - a2 >= EIGEN_PI)
109 return (EIGEN_PI * (w1 - w2) / (w2 + w1) - wMean) < 0
110 ? -EIGEN_PI + wMean - EIGEN_PI * (w1 - w2) / (w2 + w1)
111 : EIGEN_PI + wMean - EIGEN_PI * (w1 - w2) / (w2 + w1);
112 else if (a1 - a2 < -EIGEN_PI)
113 return (EIGEN_PI * (w2 - w1) / (w1 + w2) - wMean) < 0
114 ? -EIGEN_PI + wMean - EIGEN_PI * (w2 - w1) / (w1 + w2)
115 : EIGEN_PI + wMean - EIGEN_PI * (w2 - w1) / (w1 + w2);
147 #define PROFILE_BASE_POSITION_ESTIMATION "base-est position estimation"
148 #define PROFILE_BASE_VELOCITY_ESTIMATION "base-est velocity estimation"
149 #define PROFILE_BASE_KINEMATICS_COMPUTATION "base-est kinematics computation"
151 #define INPUT_SIGNALS \
152 m_joint_positionsSIN << m_joint_velocitiesSIN << m_imu_quaternionSIN \
153 << m_forceLLEGSIN << m_forceRLEGSIN << m_dforceLLEGSIN \
154 << m_dforceRLEGSIN << m_w_lf_inSIN << m_w_rf_inSIN \
155 << m_K_fb_feet_posesSIN << m_lf_ref_xyzquatSIN \
156 << m_rf_ref_xyzquatSIN << m_accelerometerSIN \
158 #define OUTPUT_SIGNALS \
159 m_qSOUT << m_vSOUT << m_q_lfSOUT << m_q_rfSOUT << m_q_imuSOUT << m_w_lfSOUT \
160 << m_w_rfSOUT << m_w_lf_filteredSOUT << m_w_rf_filteredSOUT \
161 << m_lf_xyzquatSOUT << m_rf_xyzquatSOUT << m_v_acSOUT << m_a_acSOUT \
162 << m_v_kinSOUT << m_v_imuSOUT << m_v_gyrSOUT << m_v_flexSOUT
183 CONSTRUCT_SIGNAL_IN(
w_lf_in, double),
184 CONSTRUCT_SIGNAL_IN(
w_rf_in, double),
191 m_joint_positionsSIN << m_joint_velocitiesSIN),
193 m_kinematics_computationsSINNER
194 << m_joint_positionsSIN << m_imu_quaternionSIN
195 << m_forceLLEGSIN << m_forceRLEGSIN
196 << m_w_lf_inSIN << m_w_rf_inSIN
197 << m_K_fb_feet_posesSIN << m_w_lf_filteredSOUT
198 << m_w_rf_filteredSOUT << m_lf_ref_xyzquatSIN
199 << m_rf_ref_xyzquatSIN),
201 m_kinematics_computationsSINNER
202 << m_accelerometerSIN << m_gyroscopeSIN
203 << m_qSOUT << m_dforceLLEGSIN
216 m_qSOUT << m_imu_quaternionSIN),
217 CONSTRUCT_SIGNAL_OUT(w_lf, double, m_forceLLEGSIN),
218 CONSTRUCT_SIGNAL_OUT(w_rf, double, m_forceRLEGSIN),
219 CONSTRUCT_SIGNAL_OUT(w_lf_filtered, double, m_w_lfSOUT),
220 CONSTRUCT_SIGNAL_OUT(w_rf_filtered, double, m_w_rfSOUT),
221 m_initSucceeded(false),
222 m_reset_foot_pos(true),
224 m_zmp_std_dev_rf(1.0),
225 m_zmp_std_dev_lf(1.0),
226 m_fz_std_dev_rf(1.0),
227 m_fz_std_dev_lf(1.0),
228 m_zmp_margin_lf(0.0),
229 m_zmp_margin_rf(0.0) {
241 docCommandVoid2(
"Initialize the entity.",
"time step (double)",
242 "URDF file path (string)")));
244 addCommand(
"set_fz_stable_windows_size",
248 "Set the windows size used to detect that feet is stable",
250 addCommand(
"set_alpha_w_filter",
253 docCommandVoid1(
"Set the filter parameter to filter weights",
258 docCommandVoid1(
"Set the filter parameter for removing "
259 "DC from accelerometer data",
261 addCommand(
"set_alpha_DC_vel",
264 docCommandVoid1(
"Set the filter parameter for removing DC "
265 "from velocity integrated from acceleration",
268 "reset_foot_positions",
270 docCommandVoid0(
"Reset the position of the feet.")));
275 docDirectGetter(
"Weight of imu-based orientation in sensor fusion",
277 addCommand(
"set_imu_weight",
281 "Set the weight of imu-based orientation in sensor fusion",
284 "set_zmp_std_dev_right_foot",
286 docCommandVoid1(
"Set the standard deviation of the ZMP "
287 "measurement errors for the right foot",
290 "set_zmp_std_dev_left_foot",
292 docCommandVoid1(
"Set the standard deviation of the ZMP "
293 "measurement errors for the left foot",
296 "set_normal_force_std_dev_right_foot",
299 docCommandVoid1(
"Set the standard deviation of the normal force "
300 "measurement errors for the right foot",
302 addCommand(
"set_normal_force_std_dev_left_foot",
305 docCommandVoid1(
"Set the standard deviation of the normal "
306 "force measurement errors for the left foot",
308 addCommand(
"set_stiffness_right_foot",
312 "Set the 6d stiffness of the spring at the right foot",
315 "set_stiffness_left_foot",
318 docCommandVoid1(
"Set the 6d stiffness of the spring at the left foot",
321 "set_right_foot_sizes",
325 "Set the size of the right foot (pos x, neg x, pos y, neg y)",
328 "set_left_foot_sizes",
332 "Set the size of the left foot (pos x, neg x, pos y, neg y)",
335 "set_zmp_margin_right_foot",
338 docCommandVoid1(
"Set the ZMP margin for the right foot",
"double")));
340 "set_zmp_margin_left_foot",
343 docCommandVoid1(
"Set the ZMP margin for the left foot",
"double")));
345 "set_normal_force_margin_right_foot",
348 docCommandVoid1(
"Set the normal force margin for the right foot",
351 "set_normal_force_margin_left_foot",
354 docCommandVoid1(
"Set the normal force margin for the left foot",
362 std::string localName(robotRef);
363 if (isNameInRobotUtil(localName)) {
365 std::cerr <<
"m_robot_util:" <<
m_robot_util << std::endl;
367 SEND_MSG(
"You should have a robotUtil pointer initialized before",
372 pinocchio::urdf::buildModel(
m_robot_util->m_urdf_filename,
373 pinocchio::JointModelFreeFlyer(),
m_model);
388 std::cerr <<
"IMU in Torso" <<
m_torsoMimu << std::endl;
400 SE3(Matrix3::Identity(),
401 -Eigen::Map<const Vector3>(
402 &
m_robot_util->m_foot_util.m_Right_Foot_Force_Sensor_XYZ(0)));
418 }
catch (
const std::exception& e) {
419 std::cout << e.what();
420 SEND_MSG(
"Init failed: Could load URDF :" +
m_robot_util->m_urdf_filename,
430 return SEND_MSG(
"windows_size should be a positive integer",
436 if (a < 0.0 || a > 1.0)
437 return SEND_MSG(
"alpha should be in [0..1]", MSG_TYPE_ERROR);
442 if (a < 0.0 || a > 1.0)
443 return SEND_MSG(
"alpha should be in [0..1]", MSG_TYPE_ERROR);
448 if (a < 0.0 || a > 1.0)
449 return SEND_MSG(
"alpha should be in [0..1]", MSG_TYPE_ERROR);
457 return SEND_MSG(
"Imu weight must be nonnegative", MSG_TYPE_ERROR);
465 "Stiffness vector should have size 6, not " + toString(k.size()),
474 "Stiffness vector should have size 6, not " + toString(k.size()),
481 return SEND_MSG(
"Standard deviation must be a positive number",
488 return SEND_MSG(
"Standard deviation must be a positive number",
494 const double& std_dev) {
496 return SEND_MSG(
"Standard deviation must be a positive number",
502 const double& std_dev) {
504 return SEND_MSG(
"Standard deviation must be a positive number",
512 "Foot size vector should have size 4, not " + toString(s.size()),
520 "Foot size vector should have size 4, not " + toString(s.size()),
534 const double& margin) {
539 const double& margin) {
544 pinocchio::Force f(w);
546 if (f.linear()[2] == 0.0)
return;
547 zmp[0] = -f.angular()[1] / f.linear()[2];
548 zmp[1] = f.angular()[0] / f.linear()[2];
552 const Vector4& foot_sizes,
553 double std_dev,
double margin) {
554 double fs0 = foot_sizes[0] - margin;
555 double fs1 = foot_sizes[1] + margin;
556 double fs2 = foot_sizes[2] - margin;
557 double fs3 = foot_sizes[3] + margin;
559 if (zmp[0] > fs0 || zmp[0] < fs1 || zmp[1] > fs2 || zmp[1] < fs3)
return 0;
561 double cdx = ((cdf(
m_normal, (fs0 - zmp[0]) / std_dev) -
562 cdf(
m_normal, (fs1 - zmp[0]) / std_dev)) -
565 double cdy = ((cdf(
m_normal, (fs2 - zmp[1]) / std_dev) -
566 cdf(
m_normal, (fs3 - zmp[1]) / std_dev)) -
574 if (fz < margin)
return 0.0;
575 return (cdf(
m_normal, (fz - margin) / std_dev) - 0.5) * 2.0;
579 const Vector6& ftrf) {
581 SE3 dummy, dummy1, lfMff, rfMff;
591 const Vector3& ankle_2_sole_xyz =
593 const SE3 groundMfoot(Matrix3::Identity(), -1.0 * ankle_2_sole_xyz);
594 lfMff = groundMfoot * lfMff;
595 rfMff = groundMfoot * rfMff;
598 const Vector3 w(0.5 * (pinocchio::log3(lfMff.rotation()) +
599 pinocchio::log3(rfMff.rotation())));
600 SE3 oMff = SE3(pinocchio::exp3(w),
601 0.5 * (lfMff.translation() + rfMff.translation()));
605 m_oMlfs = oMff * lfMff.inverse() * groundMfoot;
606 m_oMrfs = oMff * rfMff.inverse() * groundMfoot;
609 Eigen::Quaternion<double> quat_lf(
m_oMlfs.rotation());
616 Eigen::Quaternion<double> quat_rf(
m_oMrfs.rotation());
626 sendMsg(
"Reference pos of left foot:\n" + toString(
m_oMlfs), MSG_TYPE_INFO);
627 sendMsg(
"Reference pos of right foot:\n" + toString(
m_oMrfs), MSG_TYPE_INFO);
641 const Vector6& ft,
const Vector6&
K,
const SE3& oMfs,
642 const pinocchio::FrameIndex foot_id, SE3& oMff, SE3& oMfa, SE3& fsMff) {
644 xyz << -ft[0] /
K(0), -ft[1] /
K(1), -ft[2] /
K(2);
647 const SE3 fsMfa(R, xyz);
649 const SE3 faMff(
m_data->oMf[foot_id].inverse());
654 fsMff = fsMfa * faMff;
662 if (!m_initSucceeded) {
663 SEND_WARNING_STREAM_MSG(
664 "Cannot compute signal kinematics_computations before initialization!");
668 const Eigen::VectorXd& qj = m_joint_positionsSIN(iter);
669 const Eigen::VectorXd& dq = m_joint_velocitiesSIN(iter);
670 assert(qj.size() == m_robot_util->m_nbJoints &&
671 "Unexpected size of signal joint_positions");
672 assert(dq.size() == m_robot_util->m_nbJoints &&
673 "Unexpected size of signal joint_velocities");
676 m_robot_util->joints_sot_to_urdf(qj, m_q_pin.tail(m_robot_util->m_nbJoints));
677 m_robot_util->joints_sot_to_urdf(dq, m_v_pin.tail(m_robot_util->m_nbJoints));
682 m_q_pin.head<6>().setZero();
684 m_v_pin.head<6>().setZero();
685 pinocchio::forwardKinematics(m_model, *m_data, m_q_pin, m_v_pin);
686 pinocchio::framesForwardKinematics(m_model, *m_data);
694 if (!m_initSucceeded) {
695 SEND_WARNING_STREAM_MSG(
"Cannot compute signal q before initialization!");
698 if (s.size() !=
static_cast<Eigen::Index>(m_robot_util->m_nbJoints + 6))
699 s.resize(m_robot_util->m_nbJoints + 6);
701 const Eigen::VectorXd& qj = m_joint_positionsSIN(iter);
702 const Eigen::Vector4d& quatIMU_vec = m_imu_quaternionSIN(iter);
703 const Vector6& ftrf = m_forceRLEGSIN(iter);
704 const Vector6& ftlf = m_forceLLEGSIN(iter);
709 if (m_w_lf_inSIN.isPlugged()) {
710 wL = m_w_lf_inSIN(iter);
712 wL = m_w_lf_filteredSOUT(iter);
713 if (m_left_foot_is_stable ==
false) wL = 0.0;
715 if (m_w_rf_inSIN.isPlugged()) {
716 wR = m_w_rf_inSIN(iter);
718 wR = m_w_rf_filteredSOUT(iter);
719 if (m_right_foot_is_stable ==
false) wR = 0.0;
722 assert(qj.size() == m_robot_util->m_nbJoints &&
723 "Unexpected size of signal joint_positions");
727 if (wR == 0.0 && wL == 0.0) {
728 SEND_WARNING_STREAM_MSG(
729 "The robot is flying!" +
730 (
"- forceRLEG: " + toString(ftrf.transpose())) +
731 "- forceLLEG: " + toString(ftlf.transpose()) +
732 "- m_right_foot_is_stable: " + toString(m_right_foot_is_stable) +
733 "- m_left_foot_is_stable: " + toString(m_left_foot_is_stable));
738 m_kinematics_computationsSINNER(iter);
740 if (m_reset_foot_pos) reset_foot_positions_impl(ftlf, ftrf);
744 SE3 oMlfa, oMrfa, lfsMff, rfsMff;
745 kinematics_estimation(ftrf, m_K_rf, m_oMrfs, m_right_foot_id, m_oMff_rf,
747 kinematics_estimation(ftlf, m_K_lf, m_oMlfs, m_left_foot_id, m_oMff_lf,
752 m_data->oMi[m_torso_id]);
758 Vector3 rpy_torso, rpy_torso_lf, rpy_torso_rf,
762 matrixToRpy((m_oMff_lf * ffMtorso).rotation(), rpy_torso_lf);
763 matrixToRpy((m_oMff_rf * ffMtorso).rotation(), rpy_torso_rf);
764 Eigen::Quaterniond quatIMU(quatIMU_vec[0], quatIMU_vec[1], quatIMU_vec[2],
766 Eigen::Quaterniond quat_torsoMimu(
767 m_torsoMimu.rotation());
768 Eigen::Quaterniond quat_torso_imu(
769 quatIMU * quat_torsoMimu);
772 matrixToRpy(quat_torso_imu.toRotationMatrix(), rpy_torso_imu);
776 rpy_torso[0] =
wEulerMean(rpy_torso_lf[0], rpy_torso_rf[0], wL, wR);
777 rpy_torso[0] =
wEulerMean(rpy_torso[0], rpy_torso_imu[0], wL + wR, m_w_imu);
778 rpy_torso[1] =
wEulerMean(rpy_torso_lf[1], rpy_torso_rf[1], wL, wR);
779 rpy_torso[1] =
wEulerMean(rpy_torso[1], rpy_torso_imu[1], wL + wR, m_w_imu);
780 rpy_torso[2] =
wEulerMean(rpy_torso_lf[2], rpy_torso_rf[2], wL, wR);
783 m_oRff = m_oRtorso * torsoMff.rotation();
789 m_oRff * m_data->oMf[m_left_foot_id].translation();
791 m_oRff * m_data->oMf[m_right_foot_id].translation();
793 m_q_pin.head<3>() = ((oMlfa.translation() - pos_lf_ff) * wL +
794 (oMrfa.translation() - pos_rf_ff) * wR) /
797 m_q_sot.tail(m_robot_util->m_nbJoints) = qj;
798 base_se3_to_sot(m_q_pin.head<3>(), m_oRff, m_q_sot.head<6>());
803 const SE3 oMff_est(m_oRff, m_q_pin.head<3>());
806 if (m_K_fb_feet_posesSIN.isPlugged()) {
807 const double K_fb = m_K_fb_feet_posesSIN(iter);
808 if (K_fb > 0.0 && m_w_imu > 0.0) {
809 assert(m_w_imu > 0.0 &&
810 "Update of the feet 6d poses should not be done if wIMU = 0.0");
812 "Feedback gain on foot correction should be less than 1.0 "
813 "(K_fb_feet_poses>1.0)");
815 const SE3 oMlfs_est(oMff_est * (lfsMff.inverse()));
816 const SE3 oMrfs_est(oMff_est * (rfsMff.inverse()));
818 SE3 leftDrift = m_oMlfs.inverse() * oMlfs_est;
819 SE3 rightDrift = m_oMrfs.inverse() * oMrfs_est;
823 SE3 rightDrift_delta;
824 se3Interp(leftDrift, SE3::Identity(), K_fb * wR, leftDrift_delta);
825 se3Interp(rightDrift, SE3::Identity(), K_fb * wL, rightDrift_delta);
828 if (m_right_foot_is_stable ==
false) rightDrift_delta = rightDrift;
829 if (m_left_foot_is_stable ==
false) leftDrift_delta = leftDrift;
830 if (m_right_foot_is_stable ==
false && m_left_foot_is_stable ==
false) {
832 rightDrift_delta = SE3::Identity();
833 leftDrift_delta = SE3::Identity();
843 m_oMlfs = m_oMlfs * leftDrift_delta;
844 m_oMrfs = m_oMrfs * rightDrift_delta;
846 SE3 oMlfs_ref, oMrfs_ref;
847 if (m_lf_ref_xyzquatSIN.isPlugged() and
848 m_rf_ref_xyzquatSIN.isPlugged()) {
850 const Vector7& lf_ref_xyzquat_vec = m_lf_ref_xyzquatSIN(iter);
851 const Vector7& rf_ref_xyzquat_vec = m_rf_ref_xyzquatSIN(iter);
852 const Eigen::Quaterniond ql(
853 m_lf_ref_xyzquatSIN(iter)(6), m_lf_ref_xyzquatSIN(iter)(3),
854 m_lf_ref_xyzquatSIN(iter)(4), m_lf_ref_xyzquatSIN(iter)(5));
855 const Eigen::Quaterniond qr(
856 m_rf_ref_xyzquatSIN(iter)(6), m_rf_ref_xyzquatSIN(iter)(3),
857 m_rf_ref_xyzquatSIN(iter)(4), m_rf_ref_xyzquatSIN(iter)(5));
858 oMlfs_ref = SE3(ql.toRotationMatrix(), lf_ref_xyzquat_vec.head<3>());
859 oMrfs_ref = SE3(qr.toRotationMatrix(), rf_ref_xyzquat_vec.head<3>());
861 oMlfs_ref = m_oMlfs_default_ref;
862 oMrfs_ref = m_oMrfs_default_ref;
866 const Vector3 translation_feet_drift =
867 0.5 * ((oMlfs_ref.translation() - m_oMlfs.translation()) +
868 (oMrfs_ref.translation() - m_oMrfs.translation()));
870 const Vector3 V_ref = oMrfs_ref.translation() - oMlfs_ref.translation();
871 const Vector3 V_est = m_oMrfs.translation() - m_oMlfs.translation();
874 const double yaw_drift =
875 (atan2(V_ref(1), V_ref(0)) - atan2(V_est(1), V_est(0)));
878 const Vector3 rpy_feet_drift(0., 0., yaw_drift);
879 Matrix3 rotation_feet_drift;
881 const SE3 drift_to_ref(rotation_feet_drift, translation_feet_drift);
889 m_oMlfs = m_oMlfs * drift_to_ref;
890 m_oMrfs = m_oMrfs * drift_to_ref;
897 }
else if (K_fb < -1e-3)
899 if (m_lf_ref_xyzquatSIN.isPlugged() and
900 m_rf_ref_xyzquatSIN.isPlugged()) {
902 const Vector7& lf_ref_xyzquat_vec = m_lf_ref_xyzquatSIN(iter);
903 const Vector7& rf_ref_xyzquat_vec = m_rf_ref_xyzquatSIN(iter);
904 const Eigen::Quaterniond ql(
905 m_lf_ref_xyzquatSIN(iter)(6), m_lf_ref_xyzquatSIN(iter)(3),
906 m_lf_ref_xyzquatSIN(iter)(4), m_lf_ref_xyzquatSIN(iter)(5));
907 const Eigen::Quaterniond qr(
908 m_rf_ref_xyzquatSIN(iter)(6), m_rf_ref_xyzquatSIN(iter)(3),
909 m_rf_ref_xyzquatSIN(iter)(4), m_rf_ref_xyzquatSIN(iter)(5));
910 m_oMlfs = SE3(ql.toRotationMatrix(), lf_ref_xyzquat_vec.head<3>());
911 m_oMrfs = SE3(qr.toRotationMatrix(), rf_ref_xyzquat_vec.head<3>());
913 m_oMlfs = m_oMlfs_default_ref;
914 m_oMrfs = m_oMrfs_default_ref;
921 m_oMlfs_xyzquat.head<3>() = m_oMlfs.translation();
922 Eigen::Quaternion<double> quat_lf(m_oMlfs.rotation());
923 m_oMlfs_xyzquat(3) = quat_lf.x();
924 m_oMlfs_xyzquat(4) = quat_lf.y();
925 m_oMlfs_xyzquat(5) = quat_lf.z();
926 m_oMlfs_xyzquat(6) = quat_lf.w();
928 m_oMrfs_xyzquat.head<3>() = m_oMrfs.translation();
929 Eigen::Quaternion<double> quat_rf(m_oMrfs.rotation());
930 m_oMrfs_xyzquat(3) = quat_rf.x();
931 m_oMrfs_xyzquat(4) = quat_rf.y();
932 m_oMrfs_xyzquat(5) = quat_rf.z();
933 m_oMrfs_xyzquat(6) = quat_rf.w();
940 if (!m_initSucceeded) {
941 SEND_WARNING_STREAM_MSG(
942 "Cannot compute signal lf_xyzquat before initialization!");
945 if (s.size() != 7) s.resize(7);
946 const Eigen::VectorXd&
q = m_qSOUT(iter);
953 if (!m_initSucceeded) {
954 SEND_WARNING_STREAM_MSG(
955 "Cannot compute signal rf_xyzquat before initialization!");
958 if (s.size() != 7) s.resize(7);
959 const Eigen::VectorXd&
q = m_qSOUT(iter);
966 if (!m_initSucceeded) {
967 SEND_WARNING_STREAM_MSG(
968 "Cannot compute signal q_lf before initialization!");
971 if (s.size() !=
static_cast<Eigen::Index>(m_robot_util->m_nbJoints + 6))
972 s.resize(m_robot_util->m_nbJoints + 6);
974 const Eigen::VectorXd&
q = m_qSOUT(iter);
975 s.tail(m_robot_util->m_nbJoints) =
q.tail(m_robot_util->m_nbJoints);
976 base_se3_to_sot(m_oMff_lf.translation(), m_oMff_lf.rotation(), s.head<6>());
982 if (!m_initSucceeded) {
983 SEND_WARNING_STREAM_MSG(
984 "Cannot compute signal q_rf before initialization!");
987 if (s.size() !=
static_cast<Eigen::Index>(m_robot_util->m_nbJoints + 6))
988 s.resize(m_robot_util->m_nbJoints + 6);
990 const Eigen::VectorXd&
q = m_qSOUT(iter);
991 s.tail(m_robot_util->m_nbJoints) =
q.tail(m_robot_util->m_nbJoints);
992 base_se3_to_sot(m_oMff_rf.translation(), m_oMff_rf.rotation(), s.head<6>());
998 if (!m_initSucceeded) {
999 SEND_WARNING_STREAM_MSG(
1000 "Cannot compute signal q_imu before initialization!");
1003 if (s.size() !=
static_cast<Eigen::Index>(m_robot_util->m_nbJoints + 6))
1004 s.resize(m_robot_util->m_nbJoints + 6);
1006 const Eigen::VectorXd&
q = m_qSOUT(iter);
1007 s.tail(m_robot_util->m_nbJoints) =
q.tail(m_robot_util->m_nbJoints);
1009 m_data->oMi[m_torso_id]);
1011 const SE3 torsoMff(ffMtorso.inverse());
1013 const Eigen::Vector4d& quatIMU_vec = m_imu_quaternionSIN(iter);
1015 Eigen::Quaterniond quatIMU(quatIMU_vec[0], quatIMU_vec[1], quatIMU_vec[2],
1017 Eigen::Quaterniond quat_torsoMimu(m_torsoMimu.rotation());
1018 Eigen::Quaterniond quat_torso_imu(quatIMU * quat_torsoMimu);
1020 base_se3_to_sot(
q.head<3>(), m_oRff, s.head<6>());
1027 if (!m_initSucceeded) {
1028 SEND_WARNING_STREAM_MSG(
1029 "Cannot compute signal w_lf before initialization!");
1036 compute_zmp(
wrench, zmp);
1037 double w_zmp = compute_zmp_weight(zmp, m_left_foot_sizes, m_zmp_std_dev_lf,
1040 compute_force_weight(
wrench(2), m_fz_std_dev_lf, m_fz_margin_lf);
1043 if (
wrench(2) > m_fz_margin_lf)
1044 m_lf_fz_stable_cpt++;
1046 m_lf_fz_stable_cpt = 0;
1048 if (m_lf_fz_stable_cpt >= m_fz_stable_windows_size) {
1049 m_lf_fz_stable_cpt = m_fz_stable_windows_size;
1050 m_left_foot_is_stable =
true;
1052 m_left_foot_is_stable =
false;
1059 if (!m_initSucceeded) {
1060 SEND_WARNING_STREAM_MSG(
1061 "Cannot compute signal w_rf before initialization!");
1068 compute_zmp(
wrench, zmp);
1069 double w_zmp = compute_zmp_weight(zmp, m_right_foot_sizes, m_zmp_std_dev_rf,
1072 compute_force_weight(
wrench(2), m_fz_std_dev_rf, m_fz_margin_rf);
1075 if (
wrench(2) > m_fz_margin_rf)
1076 m_rf_fz_stable_cpt++;
1078 m_rf_fz_stable_cpt = 0;
1080 if (m_rf_fz_stable_cpt >= m_fz_stable_windows_size) {
1081 m_rf_fz_stable_cpt = m_fz_stable_windows_size;
1082 m_right_foot_is_stable =
true;
1084 m_right_foot_is_stable =
false;
1091 if (!m_initSucceeded) {
1092 SEND_WARNING_STREAM_MSG(
1093 "Cannot compute signal w_rf_filtered before initialization!");
1096 double w_rf = m_w_rfSOUT(iter);
1098 m_alpha_w_filter * w_rf +
1099 (1 - m_alpha_w_filter) * m_w_rf_filtered;
1100 s = m_w_rf_filtered;
1105 if (!m_initSucceeded) {
1106 SEND_WARNING_STREAM_MSG(
1107 "Cannot compute signal w_lf_filtered before initialization!");
1110 double w_lf = m_w_lfSOUT(iter);
1112 m_alpha_w_filter * w_lf +
1113 (1 - m_alpha_w_filter) * m_w_lf_filtered;
1114 s = m_w_lf_filtered;
1119 if (!m_initSucceeded) {
1120 SEND_WARNING_STREAM_MSG(
"Cannot compute signal v before initialization!");
1123 if (s.size() !=
static_cast<Eigen::Index>(m_robot_util->m_nbJoints + 6))
1124 s.resize(m_robot_util->m_nbJoints + 6);
1126 m_kinematics_computationsSINNER(iter);
1131 const Eigen::VectorXd& dq = m_joint_velocitiesSIN(iter);
1132 const Eigen::Vector3d& acc_imu = m_accelerometerSIN(iter);
1133 const Eigen::Vector3d& gyr_imu = m_gyroscopeSIN(iter);
1135 const Vector6& dftrf = m_dforceRLEGSIN(iter);
1136 const Vector6& dftlf = m_dforceLLEGSIN(iter);
1137 assert(dq.size() == m_robot_util->m_nbJoints &&
1138 "Unexpected size of signal joint_velocities");
1144 if (m_w_lf_inSIN.isPlugged()) {
1145 wL = m_w_lf_inSIN(iter);
1147 wL = m_w_lf_filteredSOUT(iter);
1148 if (m_left_foot_is_stable ==
false) wL = 0.0;
1150 if (m_w_rf_inSIN.isPlugged()) {
1151 wR = m_w_rf_inSIN(iter);
1153 wR = m_w_rf_filteredSOUT(iter);
1154 if (m_right_foot_is_stable ==
false) wR = 0.0;
1158 if (wR == 0.0 && wL == 0.0) {
1164 const Frame& f_lf = m_model.frames[m_left_foot_id];
1165 const Motion& v_lf_local = m_data->v[f_lf.parent];
1166 const SE3& ffMlf = m_data->oMi[f_lf.parent];
1168 -ffMlf.act(v_lf_local).toVector();
1170 v_kin_l.head<3>() = m_oRff * v_kin_l.head<3>();
1171 v_kin_l.segment<3>(3) = m_oRff * v_kin_l.segment<3>(3);
1173 const Frame& f_rf = m_model.frames[m_right_foot_id];
1174 const Motion& v_rf_local = m_data->v[f_rf.parent];
1175 const SE3& ffMrf = m_data->oMi[f_rf.parent];
1177 -ffMrf.act(v_rf_local).toVector();
1179 v_kin_r.head<3>() = m_oRff * v_kin_r.head<3>();
1180 v_kin_r.segment<3>(3) = m_oRff * v_kin_r.segment<3>(3);
1182 m_v_kin.head<6>() = (wR * v_kin_r + wL * v_kin_l) / (wL + wR);
1187 v_flex_l << -dftlf[0] / m_K_lf(0), -dftlf[1] / m_K_lf(1),
1188 -dftlf[2] / m_K_lf(2), -dftlf[3] / m_K_lf(3), -dftlf[4] / m_K_lf(4),
1189 -dftlf[5] / m_K_lf(5);
1190 v_flex_r << -dftrf[0] / m_K_rf(0), -dftrf[1] / m_K_rf(1),
1191 -dftrf[2] / m_K_rf(2), -dftrf[3] / m_K_rf(3), -dftrf[4] / m_K_rf(4),
1192 -dftrf[5] / m_K_rf(5);
1193 const Eigen::Matrix<double, 6, 6> lfAff = ffMlf.inverse().toActionMatrix();
1194 const Eigen::Matrix<double, 6, 6> rfAff = ffMrf.inverse().toActionMatrix();
1195 Eigen::Matrix<double, 12, 6> A;
1197 Eigen::Matrix<double, 12, 1> b;
1198 b << v_flex_l, v_flex_r;
1201 m_v_flex.head<6>() = (A.transpose() * A).ldlt().solve(A.transpose() * b);
1202 m_v_flex.head<3>() = m_oRff * m_v_flex.head<3>();
1207 const SE3& ffMtorso =
1208 m_data->oMi[m_torso_id];
1210 const Matrix3& ffRtorso = ffMtorso.rotation();
1211 const Matrix3 ffRimu = ffRtorso * m_torsoMimu.rotation();
1215 const Matrix3 lfRimu = ffMlf.rotation().transpose() * ffRimu;
1216 const Matrix3 rfRimu = ffMrf.rotation().transpose() * ffRimu;
1226 Vector3(gyr_imu(0), gyr_imu(1),
1230 Vector3(gyr_imu(0), gyr_imu(1),
1233 Motion v_gyr_ankle_l(
Vector3(0., 0., 0.), lfRimu * gVo_a_l);
1234 Motion v_gyr_ankle_r(
Vector3(0., 0., 0.), rfRimu * gVo_a_r);
1235 Vector6 v_gyr_l = ffMlf.inverse().actInv(v_gyr_ankle_l).toVector();
1236 Vector6 v_gyr_r = ffMrf.inverse().actInv(v_gyr_ankle_r).toVector();
1237 m_v_gyr.head<6>() = (wL * v_gyr_l + wR * v_gyr_r) / (wL + wR);
1245 const Vector3 acc_world = m_oRtorso * acc_imu;
1255 if (m_isFirstIterFlag) {
1256 m_last_DCacc = acc_world;
1257 m_isFirstIterFlag =
false;
1258 sendMsg(
"iter:" + toString(iter) +
"\n", MSG_TYPE_INFO);
1261 acc_world * (1 - m_alpha_DC_acc) + m_last_DCacc * (m_alpha_DC_acc);
1264 m_last_DCacc = DCacc;
1265 const Vector3 ACacc = acc_world - DCacc;
1268 const Vector3 vel = m_last_vel + ACacc * m_dt;
1273 vel * (1 - m_alpha_DC_vel) + m_last_DCvel * (m_alpha_DC_vel);
1274 m_last_DCvel = DCvel;
1275 const Vector3 ACvel = vel - DCvel;
1280 const Vector3 imuVimu = m_oRtorso.transpose() * ACvel;
1282 const Motion imuWimu(imuVimu, gyr_imu);
1289 const SE3 ffMimu = ffMtorso * m_torsoMimu;
1290 const Motion v = ffMimu.act(imuWimu);
1291 m_v_imu.head<6>() = v.toVector();
1294 m_v_sot.head<6>() = m_v_kin.head<6>();
1300 m_v_sot.tail(m_robot_util->m_nbJoints) = dq;
1301 m_v_kin.tail(m_robot_util->m_nbJoints) = dq;
1302 m_v_flex.tail(m_robot_util->m_nbJoints) = dq;
1303 m_v_gyr.tail(m_robot_util->m_nbJoints) = dq;
1304 m_v_imu.tail(m_robot_util->m_nbJoints) = dq;
1312 if (!m_initSucceeded) {
1313 SEND_WARNING_STREAM_MSG(
1314 "Cannot compute signal v_kin before initialization!");
1323 if (!m_initSucceeded) {
1324 SEND_WARNING_STREAM_MSG(
1325 "Cannot compute signal v_flex before initialization!");
1329 s = m_v_flex + m_v_kin;
1334 if (!m_initSucceeded) {
1335 SEND_WARNING_STREAM_MSG(
1336 "Cannot compute signal v_imu before initialization!");
1345 if (!m_initSucceeded) {
1346 SEND_WARNING_STREAM_MSG(
1347 "Cannot compute signal v_gyr before initialization!");
1356 if (!m_initSucceeded) {
1357 SEND_WARNING_STREAM_MSG(
1358 "Cannot compute signal v_ac before initialization!");
1367 if (!m_initSucceeded) {
1368 SEND_WARNING_STREAM_MSG(
1369 "Cannot compute signal a_ac before initialization!");
1384 os <<
"TalosBaseEstimator " << getName();
1386 getProfiler().report_all(3, os);
1387 }
catch (ExceptionSignal e) {