sot-talos-balance  2.0.5
Collection of dynamic-graph entities aimed at implementing balance control on talos.
hip-flexibility-compensation.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/factory.h>
21 #include <math.h>
22 
23 #include <limits>
24 #include <sot/core/debug.hh>
25 #include <sot/core/stop-watch.hh>
26 
27 namespace dynamicgraph {
28 namespace sot {
29 namespace talos_balance {
30 namespace dg = ::dynamicgraph;
31 using namespace dg;
32 using namespace dg::command;
33 
34 #define PROFILE_HIPFLEXIBILITYCOMPENSATION_TAUFILT_COMPUTATION \
35  "HipFlexibilityCompensation: Torque filter computation "
36 #define PROFILE_HIPFLEXIBILITYCOMPENSATION_DELTAQ_COMPUTATION \
37  "HipFlexibilityCompensation: Angular correction computation "
38 #define PROFILE_HIPFLEXIBILITYCOMPENSATION_QCMD_COMPUTATION \
39  "HipFlexibilityCompensation: Corrected joint configuration computation "
40 
41 #define JOINT_DES_SIGNALS m_q_desSIN
42 
43 #define INPUT_SIGNALS \
44  m_phaseSIN << m_tauSIN << m_K_rSIN << m_K_lSIN //<< m_K_dSIN
45 
46 #define OUTPUT_SIGNALS m_tau_filtSOUT << m_delta_qSOUT << m_q_cmdSOUT
47 
50 typedef HipFlexibilityCompensation EntityClassName;
51 
52 /* --- DG FACTORY ---------------------------------------------------- */
53 DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(HipFlexibilityCompensation,
54  "HipFlexibilityCompensation");
55 
56 /* ------------------------------------------------------------------- */
57 /* --- CONSTRUCTION -------------------------------------------------- */
58 /* ------------------------------------------------------------------- */
60  : Entity(name),
61  CONSTRUCT_SIGNAL_IN(phase, int),
62  CONSTRUCT_SIGNAL_IN(q_des, dynamicgraph::Vector),
63  CONSTRUCT_SIGNAL_IN(tau, dynamicgraph::Vector),
64  CONSTRUCT_SIGNAL_IN(K_l, double),
65  CONSTRUCT_SIGNAL_IN(K_r, double),
66  CONSTRUCT_SIGNAL_OUT(tau_filt, dynamicgraph::Vector, m_tauSIN),
67  CONSTRUCT_SIGNAL_OUT(delta_q, dynamicgraph::Vector,
68  INPUT_SIGNALS << m_tau_filtSOUT),
69  CONSTRUCT_SIGNAL_OUT(q_cmd, dynamicgraph::Vector,
70  JOINT_DES_SIGNALS << m_delta_qSOUT),
71  m_initSucceeded(false),
72  m_torqueLowPassFilterFrequency(1),
73  m_delta_q_saturation(0.01),
74  m_rate_limiter(0.003) {
75  Entity::signalRegistration(JOINT_DES_SIGNALS << INPUT_SIGNALS
76  << OUTPUT_SIGNALS);
77 
78  /* Commands. */
79  addCommand("init", makeCommandVoid2(
81  docCommandVoid2("Initialize the entity.",
82  "Robot time step", "Robot name")));
83 
84  addCommand(
85  "setTorqueLowPassFilterFrequency",
86  makeCommandVoid1(
88  docCommandVoid1(
89  "Set the LowPassFilter frequency for the torque computation.",
90  "Value of the frequency")));
91  addCommand(
92  "setAngularSaturation",
93  makeCommandVoid1(
95  docCommandVoid1(
96  "Set the saturation for the angular correction computation.",
97  "Value of the saturation")));
98  addCommand(
99  "setRateLimiter",
100  makeCommandVoid1(
102  docCommandVoid1("Set the rate for the rate limiter of delta_q.",
103  "Value of the limiter")));
104 
105  addCommand(
106  "getTorqueLowPassFilterFrequency",
107  makeDirectGetter(
109  docDirectGetter(
110  "Get the current value of the torque LowPassFilter frequency.",
111  "frequency (double)")));
112 
113  addCommand(
114  "getAngularSaturation",
115  makeDirectGetter(
116  *this, &m_delta_q_saturation,
117  docDirectGetter("Get the current value of the Angular Saturation.",
118  "saturation (double)")));
119 
120  addCommand("getRateLimiter",
121  makeDirectGetter(
122  *this, &m_rate_limiter,
123  docDirectGetter("Get the current value of the rate limiter.",
124  "rate (double)")));
125 }
126 
127 /* --- COMMANDS ---------------------------------------------------------- */
128 
130  const std::string& robotName) {
131  if (!m_q_desSIN.isPlugged())
132  return SEND_MSG("Init failed: signal q_des is not plugged", MSG_TYPE_ERROR);
133  if (!m_tauSIN.isPlugged())
134  return SEND_MSG("Init failed: signal tau is not plugged", MSG_TYPE_ERROR);
135  if (!m_K_rSIN.isPlugged())
136  return SEND_MSG("Init failed: signal K_r is not plugged", MSG_TYPE_ERROR);
137  if (!m_K_lSIN.isPlugged())
138  return SEND_MSG("Init failed: signal K_l is not plugged", MSG_TYPE_ERROR);
139 
140  m_dt = dt;
141  std::string robotName_nonconst(robotName);
142 
143  if (!isNameInRobotUtil(robotName_nonconst)) {
144  SEND_MSG("You should have a robotUtil pointer initialized before",
145  MSG_TYPE_ERROR);
146  } else {
147  m_robot_util = getRobotUtil(robotName_nonconst);
148  std::cerr << "m_robot_util:" << m_robot_util << std::endl;
149  }
150 
151  m_initSucceeded = true;
152  const Vector& tau = m_tauSIN.accessCopy();
153  m_previous_delta_q.resize(tau.size());
154  m_previous_delta_q.setZero();
155  m_previous_tau.resize(tau.size());
156  m_previous_tau.setZero();
157 }
158 
160  const double& frequency) {
161  m_torqueLowPassFilterFrequency = frequency;
162 }
163 
165  const double& saturation) {
166  m_delta_q_saturation = saturation;
167 }
168 
170  m_rate_limiter = rate;
171 }
172 
174  const Vector& signal,
175  Vector& previous_signal) {
176  // delta_q = alpha * previous_delta_q(-1) + (1-alpha) * delta_q_des
177  double alpha = exp(-m_dt * 2 * M_PI * frequency);
178  Vector output = alpha * previous_signal + signal * (1 - alpha);
179  return output;
180 }
181 
183  Vector& previous_signal,
184  Vector& output) {
185  Vector rate = (signal - previous_signal) / m_dt;
186  // Falling slew rate = - Rising slew rate = - m_rate_limiter
187  for (unsigned int i = 0; i < signal.size(); i++) {
188  if (rate[i] > m_rate_limiter) {
189  output[i] = m_dt * m_rate_limiter + previous_signal[i];
190  } else if (rate[i] < -m_rate_limiter) {
191  output[i] = m_dt * (-m_rate_limiter) + previous_signal[i];
192  } else {
193  output[i] = signal[i];
194  }
195  }
196 }
197 /* ------------------------------------------------------------------- */
198 /* --- SIGNALS ------------------------------------------------------- */
199 /* ------------------------------------------------------------------- */
200 
202  if (!m_initSucceeded) {
203  SEND_WARNING_STREAM_MSG(
204  "Cannot compute signal tau_filt before initialization!");
205  return s;
206  }
207 
209 
210  const Vector& tau = m_tauSIN(iter);
211 
212  if (s.size() != tau.size()) s.resize(tau.size());
213 
214  if (iter < 5) {
215  s = tau;
216  } else {
217  // Low pass filter
218  s = lowPassFilter(m_torqueLowPassFilterFrequency, tau, m_previous_tau);
219  }
220  m_previous_tau = s;
222 
223  return s;
224 }
225 
227  if (!m_initSucceeded) {
228  SEND_WARNING_STREAM_MSG(
229  "Cannot compute signal delta_q before initialization!");
230  return s;
231  }
232 
234 
235  const Vector& tau = m_tau_filtSOUT(iter);
236  const int phase =
237  m_phaseSIN.isPlugged()
238  ? m_phaseSIN(iter)
239  : 1; // always active if unplugged - actual phase unrelevant
240  const double K_r = m_K_rSIN(iter);
241  const double K_l = m_K_lSIN(iter);
242 
243  if (s.size() != tau.size()) s.resize(tau.size());
244 
245  s.setZero();
246 
247  if (phase != 0) {
248  s[1] = tau[1] / K_l; // torque/flexibility of left hip (roll)
249  s[7] = tau[7] / K_r; // torque/flexibility of right hip (roll)
250  }
251 
252  // Angular Saturation
253  // left hip
254  if (s[1] > m_delta_q_saturation) {
255  s[1] = m_delta_q_saturation;
256  } else if (s[1] < -m_delta_q_saturation) {
257  s[1] = -m_delta_q_saturation;
258  }
259  // right hip
260  if (s[7] > m_delta_q_saturation) {
261  s[7] = m_delta_q_saturation;
262  } else if (s[7] < -m_delta_q_saturation) {
263  s[7] = -m_delta_q_saturation;
264  }
265 
267  return s;
268 }
269 
271  if (!m_initSucceeded) {
272  SEND_WARNING_STREAM_MSG(
273  "Cannot compute signal q_cmd before initialization!");
274  return s;
275  }
276 
278 
279  const Vector& q_des = m_q_desSIN(iter);
280  const Vector& delta_q = m_delta_qSOUT(iter);
281 
282  assert((q_des.size() == delta_q.size()) ||
283  (q_des.size() == delta_q.size() + 6));
284 
285  if (s.size() != q_des.size()) s.resize(q_des.size());
286 
287  if (m_limitedSignal.size() != delta_q.size())
288  m_limitedSignal.resize(delta_q.size());
289  rateLimiter(delta_q, m_previous_delta_q, m_limitedSignal);
290  m_previous_delta_q = m_limitedSignal;
291 
292  if (iter < 5) {
293  s = q_des;
294  } else {
295  s = q_des;
296  s.tail(m_limitedSignal.size()) += m_limitedSignal;
297  }
298 
300  return s;
301 }
302 
303 /* ------------------------------------------------------------------- */
304 /* --- ENTITY INHERITANCE -------------------------------------------- */
305 /* ------------------------------------------------------------------- */
306 
307 void HipFlexibilityCompensation::display(std::ostream& os) const {
308  os << "HipFlexibilityCompensation " << getName();
309  try {
310  getProfiler().report_all(3, os);
311  } catch (ExceptionSignal e) {
312  }
313 }
314 
315 } // namespace talos_balance
316 } // namespace sot
317 } // namespace dynamicgraph
dynamicgraph::sot::talos_balance::HipFlexibilityCompensation::display
virtual void display(std::ostream &os) const
Definition: hip-flexibility-compensation.cpp:307
dynamicgraph::sot::talos_balance::HipFlexibilityCompensation::rateLimiter
void rateLimiter(const dynamicgraph::Vector &signal, dynamicgraph::Vector &previous_signal, dynamicgraph::Vector &output)
Compute the limiter of a signal given the previous signal (based on first derivative).
Definition: hip-flexibility-compensation.cpp:182
JOINT_DES_SIGNALS
#define JOINT_DES_SIGNALS
Definition: hip-flexibility-compensation.cpp:41
dynamicgraph::sot::talos_balance::HipFlexibilityCompensation::m_delta_q_saturation
double m_delta_q_saturation
Definition: hip-flexibility-compensation.hh:120
sot_talos_balance.test.appli_admittance_end_effector.sot
sot
Definition: appli_admittance_end_effector.py:117
sot_talos_balance.test.appli_ankle_admittance.robotName
string robotName
Definition: appli_ankle_admittance.py:33
dynamicgraph::sot::talos_balance::HipFlexibilityCompensation::setRateLimiter
void setRateLimiter(const double &rate)
Set the value of the limiter for the the rate limiter of delta_q.
Definition: hip-flexibility-compensation.cpp:169
dynamicgraph
Definition: treeview.dox:24
dynamicgraph::sot::talos_balance::HipFlexibilityCompensation::setAngularSaturation
void setAngularSaturation(const double &saturation)
Set the value of the saturation for the angular correction computation.
Definition: hip-flexibility-compensation.cpp:164
dynamicgraph::sot::talos_balance::HipFlexibilityCompensation::m_rate_limiter
double m_rate_limiter
Definition: hip-flexibility-compensation.hh:121
dynamicgraph::sot::talos_balance::HipFlexibilityCompensation::m_previous_tau
dynamicgraph::Vector m_previous_tau
Definition: hip-flexibility-compensation.hh:123
dynamicgraph::sot::talos_balance::HipFlexibilityCompensation::m_initSucceeded
bool m_initSucceeded
Definition: hip-flexibility-compensation.hh:116
dynamicgraph::sot::talos_balance::HipFlexibilityCompensation::m_dt
double m_dt
true if the entity has been successfully initialized
Definition: hip-flexibility-compensation.hh:118
dynamicgraph::sot::talos_balance::HipFlexibilityCompensation::HipFlexibilityCompensation
EIGEN_MAKE_ALIGNED_OPERATOR_NEW HipFlexibilityCompensation(const std::string &name)
Definition: hip-flexibility-compensation.cpp:59
dynamicgraph::sot::talos_balance::DEFINE_SIGNAL_OUT_FUNCTION
DEFINE_SIGNAL_OUT_FUNCTION(dq, dynamicgraph::Vector)
Definition: admittance-controller-end-effector.cpp:210
sot_talos_balance.test.test_admittance_single_joint.tau
tau
Definition: test_admittance_single_joint.py:20
dynamicgraph::sot::talos_balance::HipFlexibilityCompensation::lowPassFilter
dynamicgraph::Vector lowPassFilter(const double &frequency, const dynamicgraph::Vector &signal, dynamicgraph::Vector &previous_signal)
Compute the low pass filter of a signal given a frequency and the previous signal.
Definition: hip-flexibility-compensation.cpp:173
dynamicgraph::sot::talos_balance::HipFlexibilityCompensation::m_robot_util
RobotUtilShrPtr m_robot_util
Definition: hip-flexibility-compensation.hh:126
dynamicgraph::sot::talos_balance::math::Vector
Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > Vector
Definition: fwd.hh:36
dynamicgraph::sot::talos_balance::HipFlexibilityCompensation::setTorqueLowPassFilterFrequency
void setTorqueLowPassFilterFrequency(const double &frequency)
Set the LowPassFilter frequency for the torque computation.
Definition: hip-flexibility-compensation.cpp:159
hip-flexibility-compensation.hh
sot_talos_balance.test.appli_admittance_single_joint.dt
dt
Definition: appli_admittance_single_joint.py:17
PROFILE_HIPFLEXIBILITYCOMPENSATION_TAUFILT_COMPUTATION
#define PROFILE_HIPFLEXIBILITYCOMPENSATION_TAUFILT_COMPUTATION
Definition: hip-flexibility-compensation.cpp:34
dynamicgraph::sot::talos_balance::DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(AdmittanceControllerEndEffector, "AdmittanceControllerEndEffector")
dynamicgraph::sot::talos_balance::HipFlexibilityCompensation::m_torqueLowPassFilterFrequency
double m_torqueLowPassFilterFrequency
Definition: hip-flexibility-compensation.hh:119
dynamicgraph::sot::talos_balance::EntityClassName
AdmittanceControllerEndEffector EntityClassName
Definition: admittance-controller-end-effector.cpp:46
dynamicgraph::sot::talos_balance::HipFlexibilityCompensation::m_previous_delta_q
dynamicgraph::Vector m_previous_delta_q
Definition: hip-flexibility-compensation.hh:122
OUTPUT_SIGNALS
#define OUTPUT_SIGNALS
Definition: hip-flexibility-compensation.cpp:46
dynamicgraph::sot::talos_balance::HipFlexibilityCompensation::init
void init(const double &dt, const std::string &robotName)
Initialize the entity.
Definition: hip-flexibility-compensation.cpp:129
INPUT_SIGNALS
#define INPUT_SIGNALS
Definition: hip-flexibility-compensation.cpp:43
PROFILE_HIPFLEXIBILITYCOMPENSATION_DELTAQ_COMPUTATION
#define PROFILE_HIPFLEXIBILITYCOMPENSATION_DELTAQ_COMPUTATION
Definition: hip-flexibility-compensation.cpp:36
sot_talos_balance.test.appli_dcm_zmp_control.name
name
Definition: appli_dcm_zmp_control.py:298
PROFILE_HIPFLEXIBILITYCOMPENSATION_QCMD_COMPUTATION
#define PROFILE_HIPFLEXIBILITYCOMPENSATION_QCMD_COMPUTATION
Definition: hip-flexibility-compensation.cpp:38