Stabilizer.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-2019, CNRS-UM LIRMM
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #pragma once
29 
30 #include <mc_tasks/CoMTask.h>
31 #include <mc_tasks/CoPTask.h>
32 
33 #include <eigen-quadprog/QuadProg.h>
34 #include <lipm_walking/Contact.h>
35 #include <lipm_walking/Pendulum.h>
36 #include <lipm_walking/Sole.h>
40 
41 namespace lipm_walking
42 {
43 
58 struct Stabilizer
59 {
60  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
61 
62  static constexpr double MAX_AVERAGE_DCM_ERROR = 0.05;
63  static constexpr double MAX_COM_ADMITTANCE = 20;
64  static constexpr double MAX_COP_ADMITTANCE = 0.1;
65  static constexpr double MAX_DCM_D_GAIN = 2.;
66  static constexpr double MAX_DCM_I_GAIN = 100.;
67  static constexpr double MAX_DCM_P_GAIN = 20.;
68  static constexpr double MAX_DFZ_ADMITTANCE =
69  5e-4;
70  static constexpr double MAX_DFZ_DAMPING =
71  10.;
72  static constexpr double MAX_FDC_RX_VEL =
73  0.2;
74  static constexpr double MAX_FDC_RY_VEL =
75  0.2;
76  static constexpr double MAX_FDC_RZ_VEL =
77  0.2;
78  static constexpr double MAX_ZMPCC_COM_OFFSET = 0.05;
79  static constexpr double MIN_DSP_FZ = 15.;
91  Stabilizer(const mc_rbdyn::Robot & robot, const Pendulum & pendulum, double dt);
92 
98  void addGUIElements(std::shared_ptr<mc_rtc::gui::StateBuilder> gui);
99 
105  void addLogEntries(mc_rtc::Logger & logger);
106 
112  void addTasks(mc_solver::QPSolver & solver);
113 
117  void disable();
118 
124  Eigen::Vector3d computeZMP(const sva::ForceVecd & wrench) const;
125 
129  void configure(const mc_rtc::Configuration &);
130 
138  bool detectTouchdown(const std::shared_ptr<mc_tasks::force::CoPTask> footTask, const Contact & contact);
139 
143  void reconfigure();
144 
150  void removeTasks(mc_solver::QPSolver & solver);
151 
157  void reset(const mc_rbdyn::Robots & robots);
158 
164  void run();
165 
175  void seekTouchdown(std::shared_ptr<mc_tasks::force::CoPTask> footTask);
176 
184  void setContact(std::shared_ptr<mc_tasks::force::CoPTask> footTask, const Contact & contact);
185 
193  void setSwingFoot(std::shared_ptr<mc_tasks::force::CoPTask> footTask);
194 
201  {
202  return contactState_;
203  }
204 
209  {
210  contactState_ = contactState;
211  }
212 
218  void sole(const Sole & sole)
219  {
220  sole_ = sole;
221  }
222 
234  void updateState(const Eigen::Vector3d & com,
235  const Eigen::Vector3d & comd,
236  const sva::ForceVecd & wrench,
237  double leftFootRatio);
238 
247  void wrenchFaceMatrix(const Sole & sole)
248  {
249  double X = sole.halfLength;
250  double Y = sole.halfWidth;
251  double mu = sole.friction;
252  // clang-format off
253  wrenchFaceMatrix_ <<
254  // mx, my, mz, fx, fy, fz,
255  0, 0, 0, -1, 0, -mu,
256  0, 0, 0, +1, 0, -mu,
257  0, 0, 0, 0, -1, -mu,
258  0, 0, 0, 0, +1, -mu,
259  -1, 0, 0, 0, 0, -Y,
260  +1, 0, 0, 0, 0, -Y,
261  0, -1, 0, 0, 0, -X,
262  0, +1, 0, 0, 0, -X,
263  +mu, +mu, -1, -Y, -X, -(X + Y) * mu,
264  +mu, -mu, -1, -Y, +X, -(X + Y) * mu,
265  -mu, +mu, -1, +Y, -X, -(X + Y) * mu,
266  -mu, -mu, -1, +Y, +X, -(X + Y) * mu,
267  +mu, +mu, +1, +Y, +X, -(X + Y) * mu,
268  +mu, -mu, +1, +Y, -X, -(X + Y) * mu,
269  -mu, +mu, +1, -Y, +X, -(X + Y) * mu,
270  -mu, -mu, +1, -Y, -X, -(X + Y) * mu;
271  // clang-format on
272  }
273 
279  Eigen::Vector3d zmp() const
280  {
281  return computeZMP(distribWrench_);
282  }
283 
284 private:
288  struct FDQPWeights
289  {
295  void configure(const mc_rtc::Configuration & config)
296  {
297  double ankleTorqueWeight = config("ankle_torque");
298  double forceRatioWeight = config("force_ratio");
299  double netWrenchWeight = config("net_wrench");
300  ankleTorqueSqrt = std::sqrt(ankleTorqueWeight);
301  forceRatioSqrt = std::sqrt(forceRatioWeight);
302  netWrenchSqrt = std::sqrt(netWrenchWeight);
303  }
304 
305  public:
306  double ankleTorqueSqrt;
307  double forceRatioSqrt;
308  double netWrenchSqrt;
309  };
310 
314  void checkGains();
315 
319  void checkInTheAir();
320 
324  sva::ForceVecd computeDesiredWrench();
325 
331  void distributeWrench(const sva::ForceVecd & desiredWrench);
332  void distributeWrenchQuadProg(const sva::ForceVecd & desiredWrench);
333 
341  void saturateWrench(const sva::ForceVecd & desiredWrench, std::shared_ptr<mc_tasks::force::CoPTask> & footTask);
342  void saturateWrenchQuadProg(const sva::ForceVecd & desiredWrench,
343  std::shared_ptr<mc_tasks::force::CoPTask> & footTask);
344 
348  void setSupportFootGains();
349 
360  void updateCoMTaskZMPCC();
361 
369  void updateFootForceDifferenceControl();
370 
374  void updateZMPFrame();
375 
381  sva::ForceVecd contactAdmittance()
382  {
383  return {{copAdmittance_.y(), copAdmittance_.x(), 0.}, {0., 0., 0.}};
384  }
385 
386 public:
389  std::shared_ptr<mc_tasks::CoMTask> comTask;
390  std::shared_ptr<mc_tasks::force::CoPTask> leftFootTask;
391  std::shared_ptr<mc_tasks::force::CoPTask> rightFootTask;
393 private:
394  ContactState contactState_ = ContactState::DoubleSupport;
395  Eigen::Matrix<double, 16, 6> wrenchFaceMatrix_;
396  Eigen::QuadProgDense qpSolver_;
397  Eigen::Vector2d comAdmittance_ = Eigen::Vector2d::Zero();
398  Eigen::Vector2d copAdmittance_ = Eigen::Vector2d::Zero();
399  Eigen::Vector3d comStiffness_ = {1000., 1000., 100.};
400  Eigen::Vector3d dcmAverageError_ =
401  Eigen::Vector3d::Zero();
402  Eigen::Vector3d dcmError_ = Eigen::Vector3d::Zero();
403  Eigen::Vector3d dcmVelError_ =
404  Eigen::Vector3d::Zero();
405  Eigen::Vector3d measuredCoM_ = Eigen::Vector3d::Zero();
406  Eigen::Vector3d measuredCoMd_ = Eigen::Vector3d::Zero();
407  Eigen::Vector3d measuredZMP_ = Eigen::Vector3d::Zero();
408  Eigen::Vector3d zmpError_ = Eigen::Vector3d::Zero();
409  Eigen::Vector3d zmpccCoMAccel_ = Eigen::Vector3d::Zero();
410  Eigen::Vector3d zmpccCoMOffset_ = Eigen::Vector3d::Zero();
411  Eigen::Vector3d zmpccCoMVel_ = Eigen::Vector3d::Zero();
412  Eigen::Vector3d zmpccError_ = Eigen::Vector3d::Zero();
413  Eigen::Vector4d polePlacement_ = {-10., -5., -1., 10.};
414  ExponentialMovingAverage dcmIntegrator_;
415  FDQPWeights fdqpWeights_;
416  LeakyIntegrator zmpccIntegrator_;
417  StationaryOffsetFilter dcmDerivator_;
418  bool inTheAir_ = false;
419  bool zmpccOnlyDS_ = true;
420  const Pendulum & pendulum_;
421  const mc_rbdyn::Robot & controlRobot_;
422  double comWeight_ = 1000.;
423  double contactWeight_ = 100000.;
424  double dcmDerivGain_ = 0.;
425  double dcmIntegralGain_ = 5.;
426  double dcmPropGain_ = 1.;
427  double dfzAdmittance_ = 1e-4;
428  double dfzDamping_ = 0.;
429  double dfzForceError_ = 0.;
430  double dfzHeightError_ = 0.;
431  double dt_ = 0.005;
432  double leftFootRatio_ = 0.5;
433  double mass_ = 38.;
434  double runTime_ = 0.;
435  double swingFootStiffness_ = 2000.;
436  double swingFootWeight_ = 500.;
437  double vdcFrequency_ = 1.;
438  double vdcHeightError_ = 0.;
439  double vdcStiffness_ = 1000.;
440  Sole sole_;
441  mc_rtc::Configuration config_;
442  std::vector<std::string> comActiveJoints_;
443  sva::ForceVecd distribWrench_ = sva::ForceVecd::Zero();
444  sva::ForceVecd measuredWrench_ = sva::ForceVecd::Zero();
445  sva::MotionVecd contactDamping_ = sva::MotionVecd::Zero();
446  sva::MotionVecd contactStiffness_ = sva::MotionVecd::Zero();
447  sva::PTransformd zmpFrame_ = sva::PTransformd::Identity();
448 };
449 
450 } // namespace lipm_walking
static constexpr double MAX_DFZ_DAMPING
Maximum normalized damping in [Hz] for foot force difference control.
Definition: Stabilizer.h:70
Contact rightFootContact
Current right foot contact.
Definition: Stabilizer.h:388
ContactState
Contact state: set of feet in contact.
Definition: Contact.h:48
static constexpr double MAX_DCM_I_GAIN
Maximum DCM average integral gain in [Hz].
Definition: Stabilizer.h:66
ContactState contactState()
Get contact state.
Definition: Stabilizer.h:200
Exponential Moving Average.
Stabilizer(const mc_rbdyn::Robot &robot, const Pendulum &pendulum, double dt)
Initialize stabilizer.
Definition: Stabilizer.cpp:70
void disable()
Disable all feedback components.
Definition: Stabilizer.cpp:233
static constexpr double MIN_DSP_FZ
Minimum normal contact force in [N] for DSP, used to avoid low-force targets when close to contact sw...
Definition: Stabilizer.h:79
void wrenchFaceMatrix(const Sole &sole)
Update H-representation of contact wrench cones.
Definition: Stabilizer.h:247
void seekTouchdown(std::shared_ptr< mc_tasks::force::CoPTask > footTask)
Configure foot task for contact seeking.
Definition: Stabilizer.cpp:412
void addLogEntries(mc_rtc::Logger &logger)
Log stabilizer entries.
Definition: Stabilizer.cpp:76
static constexpr double MAX_FDC_RZ_VEL
Maximum z-axis angular velocity in [rad] / [s] for foot damping control.
Definition: Stabilizer.h:76
void addTasks(mc_solver::QPSolver &solver)
Add tasks to QP solver.
Definition: Stabilizer.cpp:358
void reconfigure()
Apply stored configuration.
Definition: Stabilizer.cpp:251
double halfLength
Half-length of the sole in [m].
Definition: Sole.h:45
State of the inverted pendulum model.
Definition: Pendulum.h:40
void contactState(ContactState contactState)
Set desired contact state.
Definition: Stabilizer.h:208
Contact leftFootContact
Current left foot contact.
Definition: Stabilizer.h:387
static constexpr double MAX_FDC_RX_VEL
Maximum x-axis angular velocity in [rad] / [s] for foot damping control.
Definition: Stabilizer.h:72
void run()
Update QP task targets.
Definition: Stabilizer.cpp:490
double halfWidth
Half-width of the sole in [m].
Definition: Sole.h:46
Remove stationary offset from an input signal.
static EIGEN_MAKE_ALIGNED_OPERATOR_NEW constexpr double MAX_AVERAGE_DCM_ERROR
Maximum average (integral) DCM error in [m].
Definition: Stabilizer.h:62
void reset(const mc_rbdyn::Robots &robots)
Reset CoM and foot CoP tasks.
Definition: Stabilizer.cpp:308
void sole(const Sole &sole)
Set model sole properties.
Definition: Stabilizer.h:218
bool detectTouchdown(const std::shared_ptr< mc_tasks::force::CoPTask > footTask, const Contact &contact)
Detect foot touchdown based on both force and distance.
Definition: Stabilizer.cpp:400
Eigen::Vector3d computeZMP(const sva::ForceVecd &wrench) const
Compute ZMP of a wrench in the output frame.
Definition: Stabilizer.cpp:474
static constexpr double MAX_DFZ_ADMITTANCE
Maximum admittance in [s] / [kg] for foot force difference control.
Definition: Stabilizer.h:68
static constexpr double MAX_ZMPCC_COM_OFFSET
Maximum CoM offset due to admittance control in [m].
Definition: Stabilizer.h:78
double friction
Friction coefficient.
Definition: Sole.h:44
static constexpr double MAX_DCM_D_GAIN
Maximum DCM derivative gain (no unit)
Definition: Stabilizer.h:65
static constexpr double MAX_FDC_RY_VEL
Maximum y-axis angular velocity in [rad] / [s] for foot damping control.
Definition: Stabilizer.h:74
std::shared_ptr< mc_tasks::CoMTask > comTask
CoM position task.
Definition: Stabilizer.h:389
void addGUIElements(std::shared_ptr< mc_rtc::gui::StateBuilder > gui)
Add GUI panel.
Definition: Stabilizer.cpp:127
std::shared_ptr< mc_tasks::force::CoPTask > leftFootTask
Left foot hybrid position/force control task.
Definition: Stabilizer.h:390
static constexpr double MAX_COM_ADMITTANCE
Maximum admittance for CoM admittance control.
Definition: Stabilizer.h:63
std::shared_ptr< mc_tasks::force::CoPTask > rightFootTask
Right foot hybrid position/force control task.
Definition: Stabilizer.h:391
static constexpr double MAX_COP_ADMITTANCE
Maximum CoP admittance for foot damping control.
Definition: Stabilizer.h:64
Leaky integrator.
Walking stabilization based on linear inverted pendulum tracking.
Definition: Stabilizer.h:58
Eigen::Vector3d zmp() const
ZMP target after wrench distribution.
Definition: Stabilizer.h:279
void setContact(std::shared_ptr< mc_tasks::force::CoPTask > footTask, const Contact &contact)
Configure foot task for contact at a given location.
Definition: Stabilizer.cpp:372
void updateState(const Eigen::Vector3d &com, const Eigen::Vector3d &comd, const sva::ForceVecd &wrench, double leftFootRatio)
Update real-robot state.
Definition: Stabilizer.cpp:518
Main controller namespace.
Definition: build.dox:1
void removeTasks(mc_solver::QPSolver &solver)
Remove tasks from QP solver.
Definition: Stabilizer.cpp:365
void setSwingFoot(std::shared_ptr< mc_tasks::force::CoPTask > footTask)
Configure foot task for swinging.
Definition: Stabilizer.cpp:393
Contacts wrap foot frames with extra info from the footstep plan.
Definition: Contact.h:58
Foot sole properties.
Definition: Sole.h:38
static constexpr double MAX_DCM_P_GAIN
Maximum DCM proportional gain in [Hz].
Definition: Stabilizer.h:67
void configure(const mc_rtc::Configuration &)
Read configuration from dictionary.
Definition: Stabilizer.cpp:245