19 #include <dynamic-graph/all-commands.h>
20 #include <dynamic-graph/command-bind.h>
21 #include <dynamic-graph/factory.h>
23 #include <sot/core/debug.hh>
24 #include <sot/core/stop-watch.hh>
28 namespace talos_balance {
29 namespace dg = ::dynamicgraph;
31 using namespace dg::command;
34 #define PROFILE_SIMPLEZMPESTIMATOR_ZMP_COMPUTATION \
35 "SimpleZmpEstimator: zmp computation "
36 #define PROFILE_SIMPLEZMPESTIMATOR_COPLEFT_COMPUTATION \
37 "SimpleZmpEstimator: copLeft computation "
38 #define PROFILE_SIMPLEZMPESTIMATOR_COPRIGHT_COMPUTATION \
39 "SimpleZmpEstimator: copRight computation "
41 #define INPUT_SIGNALS \
42 m_wrenchLeftSIN << m_wrenchRightSIN << m_poseLeftSIN << m_poseRightSIN
44 #define OUTPUT_SIGNALS \
45 m_copLeftSOUT << m_copRightSOUT << m_zmpSOUT << m_emergencyStopSOUT
62 CONSTRUCT_SIGNAL_IN(poseLeft, MatrixHomogeneous),
63 CONSTRUCT_SIGNAL_IN(poseRight, MatrixHomogeneous),
65 m_wrenchLeftSIN << m_poseLeftSIN),
67 m_wrenchRightSIN << m_poseRightSIN),
69 m_wrenchLeftSIN << m_wrenchRightSIN << m_copLeftSOUT
71 CONSTRUCT_SIGNAL_OUT(emergencyStop, bool, m_zmpSOUT),
73 m_initSucceeded(false) {
79 docCommandVoid0(
"Initialize the entity.")));
82 makeDirectGetter(*
this, &
m_eps,
83 docDirectGetter(
"Get force threshold",
"double")));
86 makeDirectSetter(*
this, &
m_eps,
87 docDirectSetter(
"Set force threshold",
"double")));
91 if (!m_wrenchLeftSIN.isPlugged())
92 return SEND_MSG(
"Init failed: signal wrenchLeft is not plugged",
94 if (!m_poseLeftSIN.isPlugged())
95 return SEND_MSG(
"Init failed: signal poseLeft is not plugged",
97 if (!m_wrenchRightSIN.isPlugged())
98 return SEND_MSG(
"Init failed: signal wrenchRight is not plugged",
100 if (!m_poseRightSIN.isPlugged())
101 return SEND_MSG(
"Init failed: signal poseRight is not plugged",
113 const double h = pose(2, 3);
115 const double fx =
wrench[0];
116 const double fy =
wrench[1];
117 const double fz =
wrench[2];
118 const double tx =
wrench[3];
119 const double ty =
wrench[4];
122 if (fz >=
m_eps / 2) {
123 px = (-ty - fx *
h) / fz;
124 py = (tx - fy *
h) / fz;
129 const double pz = -
h;
131 Eigen::Vector3d copLocal;
136 Eigen::Vector3d cop = pose.linear() * copLocal + pose.translation();
142 if (!m_initSucceeded) {
143 SEND_WARNING_STREAM_MSG(
144 "Cannot compute signal copLeft before initialization!");
147 if (s.size() != 3) s.resize(3);
152 const MatrixHomogeneous& poseLeft = m_poseLeftSIN(iter);
154 assert(wrenchLeft.size() == 6 &&
"Unexpected size of signal wrenchLeft");
156 s = computeCoP(wrenchLeft, poseLeft);
164 if (!m_initSucceeded) {
165 SEND_WARNING_STREAM_MSG(
166 "Cannot compute signal copRight before initialization!");
169 if (s.size() != 3) s.resize(3);
174 const MatrixHomogeneous& poseRight = m_poseRightSIN(iter);
176 assert(wrenchRight.size() == 6 &&
"Unexpected size of signal wrenchRight");
178 s = computeCoP(wrenchRight, poseRight);
186 if (!m_initSucceeded) {
187 m_emergency_stop_triggered =
true;
188 SEND_WARNING_STREAM_MSG(
"Cannot compute signal zmp before initialization!");
191 if (s.size() != 3) s.resize(3);
201 assert(wrenchLeft.size() == 6 &&
"Unexpected size of signal wrenchLeft");
202 assert(wrenchRight.size() == 6 &&
"Unexpected size of signal wrenchRight");
204 const double fzLeft = wrenchLeft[2];
205 const double fzRight = wrenchRight[2];
207 const double e2 = m_eps / 2;
208 const double fz = fzLeft + fzRight;
209 if (fzLeft >= e2 && fzRight < e2) {
210 m_emergency_stop_triggered =
false;
212 }
else if (fzLeft < e2 && fzRight >= e2) {
213 m_emergency_stop_triggered =
false;
215 }
else if (fz >= m_eps) {
216 m_emergency_stop_triggered =
false;
217 s = (copLeft * fzLeft + copRight * fzRight) / fz;
219 m_emergency_stop_triggered =
true;
220 SEND_WARNING_STREAM_MSG(
"Foot forces on the z-axis are both zero!");
233 s = m_emergency_stop_triggered;
244 os <<
"SimpleZmpEstimator " << getName();
246 getProfiler().report_all(3, os);
247 }
catch (ExceptionSignal e) {