sot-talos-balance  2.0.5
Collection of dynamic-graph entities aimed at implementing balance control on talos.
simple-zmp-estimator.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2018, Gepetto team, LAAS-CNRS
3  *
4  * This file is part of sot-talos-balance.
5  * sot-talos-balance is free software: you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public License
7  * as published by the Free Software Foundation, either version 3 of
8  * the License, or (at your option) any later version.
9  * sot-talos-balance is distributed in the hope that it will be
10  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
11  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU Lesser General Public License for more details. You should
13  * have received a copy of the GNU Lesser General Public License along
14  * with sot-talos-balance. If not, see <http://www.gnu.org/licenses/>.
15  */
16 
18 
19 #include <dynamic-graph/all-commands.h>
20 #include <dynamic-graph/command-bind.h>
21 #include <dynamic-graph/factory.h>
22 
23 #include <sot/core/debug.hh>
24 #include <sot/core/stop-watch.hh>
25 
26 namespace dynamicgraph {
27 namespace sot {
28 namespace talos_balance {
29 namespace dg = ::dynamicgraph;
30 using namespace dg;
31 using namespace dg::command;
32 
33 // Size to be aligned "-------------------------------------------------------"
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 "
40 
41 #define INPUT_SIGNALS \
42  m_wrenchLeftSIN << m_wrenchRightSIN << m_poseLeftSIN << m_poseRightSIN
43 
44 #define OUTPUT_SIGNALS \
45  m_copLeftSOUT << m_copRightSOUT << m_zmpSOUT << m_emergencyStopSOUT
46 
49 typedef SimpleZmpEstimator EntityClassName;
50 
51 /* --- DG FACTORY ---------------------------------------------------- */
52 DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(SimpleZmpEstimator, "SimpleZmpEstimator");
53 
54 /* ------------------------------------------------------------------- */
55 /* --- CONSTRUCTION -------------------------------------------------- */
56 /* ------------------------------------------------------------------- */
58  const double& eps)
59  : Entity(name),
60  CONSTRUCT_SIGNAL_IN(wrenchLeft, dynamicgraph::Vector),
61  CONSTRUCT_SIGNAL_IN(wrenchRight, dynamicgraph::Vector),
62  CONSTRUCT_SIGNAL_IN(poseLeft, MatrixHomogeneous),
63  CONSTRUCT_SIGNAL_IN(poseRight, MatrixHomogeneous),
64  CONSTRUCT_SIGNAL_OUT(copLeft, dynamicgraph::Vector,
65  m_wrenchLeftSIN << m_poseLeftSIN),
66  CONSTRUCT_SIGNAL_OUT(copRight, dynamicgraph::Vector,
67  m_wrenchRightSIN << m_poseRightSIN),
68  CONSTRUCT_SIGNAL_OUT(zmp, dynamicgraph::Vector,
69  m_wrenchLeftSIN << m_wrenchRightSIN << m_copLeftSOUT
70  << m_copRightSOUT),
71  CONSTRUCT_SIGNAL_OUT(emergencyStop, bool, m_zmpSOUT),
72  m_eps(eps),
73  m_initSucceeded(false) {
74  Entity::signalRegistration(INPUT_SIGNALS << OUTPUT_SIGNALS);
75 
76  /* Commands. */
77  addCommand("init",
78  makeCommandVoid0(*this, &SimpleZmpEstimator::init,
79  docCommandVoid0("Initialize the entity.")));
80  addCommand(
81  "getForceThreshold",
82  makeDirectGetter(*this, &m_eps,
83  docDirectGetter("Get force threshold", "double")));
84  addCommand(
85  "setForceThreshold",
86  makeDirectSetter(*this, &m_eps,
87  docDirectSetter("Set force threshold", "double")));
88 }
89 
91  if (!m_wrenchLeftSIN.isPlugged())
92  return SEND_MSG("Init failed: signal wrenchLeft is not plugged",
93  MSG_TYPE_ERROR);
94  if (!m_poseLeftSIN.isPlugged())
95  return SEND_MSG("Init failed: signal poseLeft is not plugged",
96  MSG_TYPE_ERROR);
97  if (!m_wrenchRightSIN.isPlugged())
98  return SEND_MSG("Init failed: signal wrenchRight is not plugged",
99  MSG_TYPE_ERROR);
100  if (!m_poseRightSIN.isPlugged())
101  return SEND_MSG("Init failed: signal poseRight is not plugged",
102  MSG_TYPE_ERROR);
103 
104  m_initSucceeded = true;
105 }
106 
107 /* ------------------------------------------------------------------- */
108 /* --- SIGNALS ------------------------------------------------------- */
109 /* ------------------------------------------------------------------- */
110 
112  const dg::Vector& wrench, const MatrixHomogeneous& pose) const {
113  const double h = pose(2, 3);
114 
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];
120 
121  double px, py;
122  if (fz >= m_eps / 2) {
123  px = (-ty - fx * h) / fz;
124  py = (tx - fy * h) / fz;
125  } else {
126  px = 0.0;
127  py = 0.0;
128  }
129  const double pz = -h;
130 
131  Eigen::Vector3d copLocal;
132  copLocal[0] = px;
133  copLocal[1] = py;
134  copLocal[2] = pz;
135 
136  Eigen::Vector3d cop = pose.linear() * copLocal + pose.translation();
137 
138  return cop;
139 }
140 
142  if (!m_initSucceeded) {
143  SEND_WARNING_STREAM_MSG(
144  "Cannot compute signal copLeft before initialization!");
145  return s;
146  }
147  if (s.size() != 3) s.resize(3);
148 
150 
151  const dynamicgraph::Vector& wrenchLeft = m_wrenchLeftSIN(iter);
152  const MatrixHomogeneous& poseLeft = m_poseLeftSIN(iter);
153 
154  assert(wrenchLeft.size() == 6 && "Unexpected size of signal wrenchLeft");
155 
156  s = computeCoP(wrenchLeft, poseLeft);
157 
159 
160  return s;
161 }
162 
164  if (!m_initSucceeded) {
165  SEND_WARNING_STREAM_MSG(
166  "Cannot compute signal copRight before initialization!");
167  return s;
168  }
169  if (s.size() != 3) s.resize(3);
170 
172 
173  const dynamicgraph::Vector& wrenchRight = m_wrenchRightSIN(iter);
174  const MatrixHomogeneous& poseRight = m_poseRightSIN(iter);
175 
176  assert(wrenchRight.size() == 6 && "Unexpected size of signal wrenchRight");
177 
178  s = computeCoP(wrenchRight, poseRight);
179 
181 
182  return s;
183 }
184 
186  if (!m_initSucceeded) {
187  m_emergency_stop_triggered = true;
188  SEND_WARNING_STREAM_MSG("Cannot compute signal zmp before initialization!");
189  return s;
190  }
191  if (s.size() != 3) s.resize(3);
192 
193  getProfiler().start(PROFILE_SIMPLEZMPESTIMATOR_ZMP_COMPUTATION);
194 
195  const dynamicgraph::Vector& wrenchLeft = m_wrenchLeftSIN(iter);
196  const dynamicgraph::Vector& copLeft = m_copLeftSOUT(iter);
197 
198  const dynamicgraph::Vector& wrenchRight = m_wrenchRightSIN(iter);
199  const dynamicgraph::Vector& copRight = m_copRightSOUT(iter);
200 
201  assert(wrenchLeft.size() == 6 && "Unexpected size of signal wrenchLeft");
202  assert(wrenchRight.size() == 6 && "Unexpected size of signal wrenchRight");
203 
204  const double fzLeft = wrenchLeft[2];
205  const double fzRight = wrenchRight[2];
206 
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;
211  s = copLeft;
212  } else if (fzLeft < e2 && fzRight >= e2) {
213  m_emergency_stop_triggered = false;
214  s = copRight;
215  } else if (fz >= m_eps) {
216  m_emergency_stop_triggered = false;
217  s = (copLeft * fzLeft + copRight * fzRight) / fz;
218  } else {
219  m_emergency_stop_triggered = true;
220  SEND_WARNING_STREAM_MSG("Foot forces on the z-axis are both zero!");
221  s.setZero(3);
222  }
223 
224  getProfiler().stop(PROFILE_SIMPLEZMPESTIMATOR_ZMP_COMPUTATION);
225 
226  return s;
227 }
228 
229 DEFINE_SIGNAL_OUT_FUNCTION(emergencyStop, bool) {
230  const dynamicgraph::Vector& zmp =
231  m_zmpSOUT(iter); // dummy to trigger zmp computation
232  (void)zmp; // disable unused variable warning
233  s = m_emergency_stop_triggered;
234  return s;
235 }
236 
237 /* --- COMMANDS ---------------------------------------------------------- */
238 
239 /* ------------------------------------------------------------------- */
240 /* --- ENTITY -------------------------------------------------------- */
241 /* ------------------------------------------------------------------- */
242 
243 void SimpleZmpEstimator::display(std::ostream& os) const {
244  os << "SimpleZmpEstimator " << getName();
245  try {
246  getProfiler().report_all(3, os);
247  } catch (ExceptionSignal e) {
248  }
249 }
250 } // namespace talos_balance
251 } // namespace sot
252 } // namespace dynamicgraph
dynamicgraph::sot::talos_balance::SimpleZmpEstimator::m_initSucceeded
bool m_initSucceeded
Definition: simple-zmp-estimator.hh:89
sot_talos_balance.test.appli_admittance_end_effector.sot
sot
Definition: appli_admittance_end_effector.py:117
PROFILE_SIMPLEZMPESTIMATOR_ZMP_COMPUTATION
#define PROFILE_SIMPLEZMPESTIMATOR_ZMP_COMPUTATION
Definition: simple-zmp-estimator.cpp:34
dynamicgraph
Definition: treeview.dox:24
PROFILE_SIMPLEZMPESTIMATOR_COPRIGHT_COMPUTATION
#define PROFILE_SIMPLEZMPESTIMATOR_COPRIGHT_COMPUTATION
Definition: simple-zmp-estimator.cpp:38
simple-zmp-estimator.hh
dynamicgraph::sot::talos_balance::SimpleZmpEstimator::m_eps
double m_eps
Definition: simple-zmp-estimator.hh:78
dynamicgraph::sot::talos_balance::DEFINE_SIGNAL_OUT_FUNCTION
DEFINE_SIGNAL_OUT_FUNCTION(dq, dynamicgraph::Vector)
Definition: admittance-controller-end-effector.cpp:210
OUTPUT_SIGNALS
#define OUTPUT_SIGNALS
Definition: simple-zmp-estimator.cpp:44
dynamicgraph::sot::talos_balance::math::Vector
Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > Vector
Definition: fwd.hh:36
sot_talos_balance.test.script_test_end_effector.wrench
wrench
Definition: script_test_end_effector.py:9
dynamicgraph::sot::talos_balance::SimpleZmpEstimator::display
virtual void display(std::ostream &os) const
Definition: simple-zmp-estimator.cpp:243
PROFILE_SIMPLEZMPESTIMATOR_COPLEFT_COMPUTATION
#define PROFILE_SIMPLEZMPESTIMATOR_COPLEFT_COMPUTATION
Definition: simple-zmp-estimator.cpp:36
dynamicgraph::sot::talos_balance::DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(AdmittanceControllerEndEffector, "AdmittanceControllerEndEffector")
dynamicgraph::sot::talos_balance::EntityClassName
AdmittanceControllerEndEffector EntityClassName
Definition: admittance-controller-end-effector.cpp:46
dynamicgraph::sot::talos_balance::SimpleZmpEstimator::init
void init()
Definition: simple-zmp-estimator.cpp:90
sot_talos_balance.test.appli_ankle_admittance.h
h
Definition: appli_ankle_admittance.py:37
sot_talos_balance.test.appli_dcm_zmp_control.name
name
Definition: appli_dcm_zmp_control.py:298
dynamicgraph::sot::talos_balance::SimpleZmpEstimator::SimpleZmpEstimator
EIGEN_MAKE_ALIGNED_OPERATOR_NEW SimpleZmpEstimator(const std::string &name, const double &eps=1.0)
Definition: simple-zmp-estimator.cpp:57
INPUT_SIGNALS
#define INPUT_SIGNALS
Definition: simple-zmp-estimator.cpp:41
dynamicgraph::sot::talos_balance::SimpleZmpEstimator::computeCoP
Eigen::Vector3d computeCoP(const dynamicgraph::Vector &wrench, const MatrixHomogeneous &pose) const
Definition: simple-zmp-estimator.cpp:111