sot-talos-balance  2.0.5
Collection of dynamic-graph entities aimed at implementing balance control on talos.
dcm-controller.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_DCMCONTROLLER_ZMPREF_COMPUTATION \
35  "DcmController: zmpRef computation "
36 #define PROFILE_DCMCONTROLLER_WRENCHREF_COMPUTATION \
37  "DcmController: wrenchRef computation "
38 
39 #define INPUT_SIGNALS \
40  m_KpSIN << m_KiSIN << m_KzSIN << m_decayFactorSIN << m_omegaSIN << m_massSIN \
41  << m_comSIN << m_dcmSIN << m_dcmDesSIN << m_zmpDesSIN << m_zmpSIN
42 
43 #define OUTPUT_SIGNALS m_zmpRefSOUT << m_wrenchRefSOUT
44 
47 typedef DcmController EntityClassName;
48 
49 /* --- DG FACTORY ---------------------------------------------------- */
50 DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(DcmController, "DcmController");
51 
52 /* ------------------------------------------------------------------- */
53 /* --- CONSTRUCTION -------------------------------------------------- */
54 /* ------------------------------------------------------------------- */
56  : Entity(name),
57  CONSTRUCT_SIGNAL_IN(Kp, dynamicgraph::Vector),
58  CONSTRUCT_SIGNAL_IN(Ki, dynamicgraph::Vector),
59  CONSTRUCT_SIGNAL_IN(Kz, dynamicgraph::Vector),
60  CONSTRUCT_SIGNAL_IN(decayFactor, double),
61  CONSTRUCT_SIGNAL_IN(omega, double),
62  CONSTRUCT_SIGNAL_IN(mass, double),
63  CONSTRUCT_SIGNAL_IN(com, dynamicgraph::Vector),
64  CONSTRUCT_SIGNAL_IN(dcm, dynamicgraph::Vector),
65  CONSTRUCT_SIGNAL_IN(dcmDes, dynamicgraph::Vector),
66  CONSTRUCT_SIGNAL_IN(zmpDes, dynamicgraph::Vector),
67  CONSTRUCT_SIGNAL_IN(zmp, dynamicgraph::Vector),
68  CONSTRUCT_SIGNAL_OUT(zmpRef, dynamicgraph::Vector, INPUT_SIGNALS),
69  CONSTRUCT_SIGNAL_OUT(wrenchRef, dynamicgraph::Vector,
70  m_zmpRefSOUT << m_comSIN << m_omegaSIN << m_massSIN)
71  // dcomRef is set to depend from comRefSOUT to ensure position is updated
72  // before velocity
73  ,
74  m_initSucceeded(false) {
75  Entity::signalRegistration(INPUT_SIGNALS << OUTPUT_SIGNALS);
76 
77  /* Commands. */
78  addCommand("init", makeCommandVoid1(*this, &DcmController::init,
79  docCommandVoid1("Initialize the entity.",
80  "time step")));
81  addCommand(
82  "resetDcmIntegralError",
83  makeCommandVoid0(*this, &DcmController::resetDcmIntegralError,
84  docCommandVoid0("Set dcm integral error to zero.")));
85 }
86 
87 void DcmController::init(const double& dt) {
88  if (!m_KpSIN.isPlugged())
89  return SEND_MSG("Init failed: signal Kp is not plugged", MSG_TYPE_ERROR);
90  if (!m_KiSIN.isPlugged())
91  return SEND_MSG("Init failed: signal Ki is not plugged", MSG_TYPE_ERROR);
92  if (!m_decayFactorSIN.isPlugged())
93  return SEND_MSG("Init failed: signal decayFactor is not plugged",
94  MSG_TYPE_ERROR);
95  if (!m_omegaSIN.isPlugged())
96  return SEND_MSG("Init failed: signal omega is not plugged", MSG_TYPE_ERROR);
97  if (!m_massSIN.isPlugged())
98  return SEND_MSG("Init failed: signal mass is not plugged", MSG_TYPE_ERROR);
99  if (!m_comSIN.isPlugged())
100  return SEND_MSG("Init failed: signal com is not plugged", MSG_TYPE_ERROR);
101  if (!m_dcmSIN.isPlugged())
102  return SEND_MSG("Init failed: signal dcm is not plugged", MSG_TYPE_ERROR);
103  if (!m_dcmDesSIN.isPlugged())
104  return SEND_MSG("Init failed: signal dcmDes is not plugged",
105  MSG_TYPE_ERROR);
106  if (!m_zmpDesSIN.isPlugged())
107  return SEND_MSG("Init failed: signal zmpDes is not plugged",
108  MSG_TYPE_ERROR);
109 
110  m_dt = dt;
112  m_initSucceeded = true;
113 }
114 
116 
117 /* ------------------------------------------------------------------- */
118 /* --- SIGNALS ------------------------------------------------------- */
119 /* ------------------------------------------------------------------- */
120 
122  if (!m_initSucceeded) {
123  SEND_WARNING_STREAM_MSG(
124  "Cannot compute signal zmpRef before initialization!");
125  return s;
126  }
127  if (s.size() != 3) s.resize(3);
128 
129  getProfiler().start(PROFILE_DCMCONTROLLER_ZMPREF_COMPUTATION);
130 
131  const Vector& Kp = m_KpSIN(iter);
132  const Vector& Ki = m_KiSIN(iter);
133  const double& decayFactor = m_decayFactorSIN(iter);
134  const double& omega = m_omegaSIN(iter);
135  const Vector& dcm = m_dcmSIN(iter);
136  const Vector& dcmDes = m_dcmDesSIN(iter);
137  const Vector& zmpDes = m_zmpDesSIN(iter);
138 
139  assert(Kp.size() == 3 && "Unexpected size of signal Kp");
140  assert(Ki.size() == 3 && "Unexpected size of signal Ki");
141  assert(dcm.size() == 3 && "Unexpected size of signal dcm");
142  assert(dcmDes.size() == 3 && "Unexpected size of signal dcmDes");
143  assert(zmpDes.size() == 3 && "Unexpected size of signal zmpDes");
144 
145  const Eigen::Vector3d dcmError = dcmDes - dcm;
146 
147  Eigen::Vector3d zmpRef =
148  zmpDes -
149  (Eigen::Vector3d::Constant(1.0) + Kp / omega).cwiseProduct(dcmError) -
150  Ki.cwiseProduct(m_dcmIntegralError) / omega;
151  if (m_zmpSIN.isPlugged()) {
152  const Vector& zmp = m_zmpSIN(iter);
153  const Vector& Kz = m_KzSIN(iter);
154  assert(Kz.size() == 3 && "Unexpected size of signal Kz");
155  assert(zmp.size() == 3 && "Unexpected size of signal zmp");
156  zmpRef += (Kz / omega) * (zmpDes - zmp);
157  }
158  zmpRef[2] = 0.0; // maybe needs better way
159 
160  // update the integrator (AFTER using its value)
161  m_dcmIntegralError += (dcmError - decayFactor * m_dcmIntegralError) * m_dt;
162 
163  s = zmpRef;
164 
165  getProfiler().stop(PROFILE_DCMCONTROLLER_ZMPREF_COMPUTATION);
166 
167  return s;
168 }
169 
171  if (!m_initSucceeded) {
172  SEND_WARNING_STREAM_MSG(
173  "Cannot compute signal wrenchRef before initialization!");
174  return s;
175  }
176  if (s.size() != 6) s.resize(6);
177 
178  getProfiler().start(PROFILE_DCMCONTROLLER_WRENCHREF_COMPUTATION);
179 
180  const double& omega = m_omegaSIN(iter);
181  const double& mass = m_massSIN(iter);
182  const Vector& com = m_comSIN(iter);
183 
184  const Vector& zmpRef = m_zmpRefSOUT(iter);
185 
186  assert(com.size() == 3 && "Unexpected size of signal com");
187 
188  Eigen::Vector3d forceRef = mass * omega * omega * (com - zmpRef);
189  forceRef[2] = mass * 9.81; // maybe needs better way
190 
191  Eigen::Matrix<double, 6, 1> wrenchRef;
192  wrenchRef.head<3>() = forceRef;
193  const Eigen::Vector3d com3 = com;
194  wrenchRef.tail<3>() = com3.cross(forceRef);
195 
196  s = wrenchRef;
197 
199 
200  return s;
201 }
202 
203 /* --- COMMANDS ---------------------------------------------------------- */
204 
205 /* ------------------------------------------------------------------- */
206 /* --- ENTITY -------------------------------------------------------- */
207 /* ------------------------------------------------------------------- */
208 
209 void DcmController::display(std::ostream& os) const {
210  os << "DcmController " << getName();
211  try {
212  getProfiler().report_all(3, os);
213  } catch (ExceptionSignal e) {
214  }
215 }
216 } // namespace talos_balance
217 } // namespace sot
218 } // namespace dynamicgraph
sot_talos_balance.test.appli_admittance_end_effector.sot
sot
Definition: appli_admittance_end_effector.py:117
dynamicgraph::sot::talos_balance::DcmController::init
void init(const double &dt)
Definition: dcm-controller.cpp:87
dynamicgraph
Definition: treeview.dox:24
sot_talos_balance.test.appli_dcmZmpControl.dcmDes
dcmDes
Definition: appli_dcmZmpControl.py:29
sot_talos_balance.test.appli_ankle_admittance.mass
mass
Definition: appli_ankle_admittance.py:36
dynamicgraph::sot::talos_balance::DcmController::display
virtual void display(std::ostream &os) const
Definition: dcm-controller.cpp:209
dynamicgraph::sot::talos_balance::DcmController::m_dcmIntegralError
dynamicgraph::Vector m_dcmIntegralError
true if the entity has been successfully initialized
Definition: dcm-controller.hh:88
dynamicgraph::sot::talos_balance::DcmController::DcmController
EIGEN_MAKE_ALIGNED_OPERATOR_NEW DcmController(const std::string &name)
Definition: dcm-controller.cpp:55
PROFILE_DCMCONTROLLER_ZMPREF_COMPUTATION
#define PROFILE_DCMCONTROLLER_ZMPREF_COMPUTATION
Definition: dcm-controller.cpp:34
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.appli_admittance_single_joint.Kp
list Kp
Definition: appli_admittance_single_joint.py:33
dynamicgraph::sot::talos_balance::DcmController::resetDcmIntegralError
void resetDcmIntegralError()
Definition: dcm-controller.cpp:115
dynamicgraph::sot::talos_balance::math::Vector
Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > Vector
Definition: fwd.hh:36
sot_talos_balance.test.appli_dcmZmpControl.zmpDes
zmpDes
Definition: appli_dcmZmpControl.py:30
PROFILE_DCMCONTROLLER_WRENCHREF_COMPUTATION
#define PROFILE_DCMCONTROLLER_WRENCHREF_COMPUTATION
Definition: dcm-controller.cpp:36
sot_talos_balance.test.appli_admittance_single_joint.dt
dt
Definition: appli_admittance_single_joint.py:17
OUTPUT_SIGNALS
#define OUTPUT_SIGNALS
Definition: dcm-controller.cpp:43
INPUT_SIGNALS
#define INPUT_SIGNALS
Definition: dcm-controller.cpp:39
dynamicgraph::sot::talos_balance::DcmController::m_dt
double m_dt
Definition: dcm-controller.hh:89
dynamicgraph::sot::talos_balance::DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(AdmittanceControllerEndEffector, "AdmittanceControllerEndEffector")
sot_talos_balance.test.appli_ankle_admittance.omega
omega
Definition: appli_ankle_admittance.py:39
dynamicgraph::sot::talos_balance::DcmController::m_initSucceeded
bool m_initSucceeded
Definition: dcm-controller.hh:87
dynamicgraph::sot::talos_balance::EntityClassName
AdmittanceControllerEndEffector EntityClassName
Definition: admittance-controller-end-effector.cpp:46
sot_talos_balance.test.appli_dcm_zmp_control.name
name
Definition: appli_dcm_zmp_control.py:298
dcm-controller.hh