angle-estimator.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2010,
3  * François Bleibel,
4  * Olivier Stasse,
5  *
6  * CNRS/AIST
7  *
8  */
9 
12 #include <dynamic-graph/command.h>
13 #include <dynamic-graph/factory.h>
15 
16 #include <sot/core/debug.hh>
17 
18 using namespace dynamicgraph::sot;
19 using namespace dynamicgraph;
20 
22 
24  : Entity(name),
25  sensorWorldRotationSIN(
26  NULL, "sotAngleEstimator(" + name +
27  ")::input(MatrixRotation)::sensorWorldRotation"),
28  sensorEmbeddedPositionSIN(
29  NULL, "sotAngleEstimator(" + name +
30  ")::input(MatrixHomo)::sensorEmbeddedPosition"),
31  contactWorldPositionSIN(NULL,
32  "sotAngleEstimator(" + name +
33  ")::input(MatrixHomo)::contactWorldPosition"),
34  contactEmbeddedPositionSIN(
35  NULL, "sotAngleEstimator(" + name +
36  ")::input(MatrixHomo)::contactEmbeddedPosition")
37 
38  ,
39  anglesSOUT(boost::bind(&AngleEstimator::computeAngles, this, _1, _2),
40  sensorWorldRotationSIN << sensorEmbeddedPositionSIN
41  << contactWorldPositionSIN
42  << contactEmbeddedPositionSIN,
43  "sotAngleEstimator(" + name + ")::output(Vector)::angles"),
44  flexibilitySOUT(boost::bind(&AngleEstimator::computeFlexibilityFromAngles,
45  this, _1, _2),
46  anglesSOUT,
47  "sotAngleEstimator(" + name +
48  ")::output(matrixRotation)::flexibility"),
49  driftSOUT(
50  boost::bind(&AngleEstimator::computeDriftFromAngles, this, _1, _2),
51  anglesSOUT,
52  "sotAngleEstimator(" + name + ")::output(matrixRotation)::drift"),
53  sensorWorldRotationSOUT(
54  boost::bind(&AngleEstimator::computeSensorWorldRotation, this, _1,
55  _2),
56  anglesSOUT << sensorWorldRotationSIN,
57  "sotAngleEstimator(" + name +
58  ")::output(matrixRotation)::sensorCorrectedRotation"),
59  waistWorldRotationSOUT(
60  boost::bind(&AngleEstimator::computeWaistWorldRotation, this, _1, _2),
61  sensorWorldRotationSOUT << sensorEmbeddedPositionSIN,
62  "sotAngleEstimator(" + name +
63  ")::output(matrixRotation)::waistWorldRotation"),
64  waistWorldPositionSOUT(
65  boost::bind(&AngleEstimator::computeWaistWorldPosition, this, _1, _2),
66  flexibilitySOUT << contactEmbeddedPositionSIN,
67  "sotAngleEstimator(" + name +
68  ")::output(MatrixHomogeneous)::waistWorldPosition"),
69  waistWorldPoseRPYSOUT(
70  boost::bind(&AngleEstimator::computeWaistWorldPoseRPY, this, _1, _2),
71  waistWorldPositionSOUT,
72  "sotAngleEstimator(" + name +
73  ")::output(vectorRollPitchYaw)::waistWorldPoseRPY")
74 
75  ,
76  jacobianSIN(NULL, "sotAngleEstimator(" + name + ")::input()::jacobian"),
77  qdotSIN(NULL, "sotAngleEstimator(" + name + ")::input()::qdot"),
78  xff_dotSOUT(
79  boost::bind(&AngleEstimator::compute_xff_dotSOUT, this, _1, _2),
80  jacobianSIN << qdotSIN,
81  "sotAngleEstimator(" + name + ")::output(vector)::xff_dot"),
82  qdotSOUT(boost::bind(&AngleEstimator::compute_qdotSOUT, this, _1, _2),
83  xff_dotSOUT << qdotSIN,
84  "sotAngleEstimator(" + name + ")::output(vector)::qdotOUT")
85 
86  ,
87  fromSensor_(true) {
88  sotDEBUGIN(5);
89 
105 
106  /* Commands. */
107  {
108  std::string docstring;
109  docstring =
110  " \n"
111  " Set flag specifying whether angle is measured from sensors or "
112  "simulated.\n"
113  " \n"
114  " Input:\n"
115  " - a boolean value.\n"
116  " \n";
117  addCommand("setFromSensor",
118  new ::dynamicgraph::command::Setter<AngleEstimator, bool>(
119  *this, &AngleEstimator::fromSensor, docstring));
120 
121  docstring =
122  " \n"
123  " Get flag specifying whether angle is measured from sensors or "
124  "simulated.\n"
125  " \n"
126  " No input,\n"
127  " return a boolean value.\n"
128  " \n";
129  addCommand("getFromSensor",
130  new ::dynamicgraph::command::Getter<AngleEstimator, bool>(
131  *this, &AngleEstimator::fromSensor, docstring));
132  }
133 
134  sotDEBUGOUT(5);
135 }
136 
138  sotDEBUGIN(5);
139 
140  sotDEBUGOUT(5);
141  return;
142 }
143 
144 /* --- SIGNALS -------------------------------------------------------------- */
145 /* --- SIGNALS -------------------------------------------------------------- */
146 /* --- SIGNALS -------------------------------------------------------------- */
148  const sigtime_t& time) {
149  sotDEBUGIN(15);
150 
151  res.resize(3);
152 
153  const MatrixRotation& worldestRchest = sensorWorldRotationSIN(time);
154  sotDEBUG(35) << "worldestRchest = " << std::endl << worldestRchest;
155  const MatrixHomogeneous& waistMchest = sensorEmbeddedPositionSIN(time);
156  MatrixRotation waistRchest;
157  waistRchest = waistMchest.linear();
158 
159  const MatrixHomogeneous& waistMleg = contactEmbeddedPositionSIN(time);
160  MatrixRotation waistRleg;
161  waistRleg = waistMleg.linear();
162  MatrixRotation chestRleg;
163  chestRleg = waistRchest.transpose() * waistRleg;
164  MatrixRotation worldestRleg;
165  worldestRleg = worldestRchest * chestRleg;
166 
167  sotDEBUG(35) << "worldestRleg = " << std::endl << worldestRleg;
168 
169  /* Euler angles with following code: (-z)xy, -z being the yaw drift, x the
170  * first flexibility and y the second flexibility. */
171  const double TOLERANCE_TH = 1e-6;
172 
173  const MatrixRotation& R = worldestRleg;
174  if ((fabs(R(0, 1)) < TOLERANCE_TH) && (fabs(R(1, 1)) < TOLERANCE_TH)) {
175  /* This means that cos(X) is very low, ie flex1 is close to 90deg.
176  * I take the case into account, but it is bloody never going
177  * to happens. */
178  if (R(2, 1) > 0)
179  res(0) = M_PI / 2;
180  else
181  res(0) = -M_PI / 2;
182  res(2) = atan2(-R(0, 2), R(0, 0));
183  res(1) = 0;
184 
185  /* To sum up: if X=PI/2, then Y and Z are in singularity.
186  * we cannot decide both of then. I fixed Y=0, which
187  * means that all the measurement coming from the sensor
188  * is assumed to be drift of the gyro. */
189  } else {
190  double& X = res(0);
191  double& Y = res(1);
192  double& Z = res(2);
193 
194  Y = atan2(R(2, 0), R(2, 2));
195  Z = atan2(R(0, 1), R(1, 1));
196  if (fabs(R(2, 0)) > fabs(R(2, 2))) {
197  X = atan2(R(2, 1) * sin(Y), R(2, 0));
198  } else {
199  X = atan2(R(2, 1) * cos(Y), R(2, 2));
200  }
201  }
202 
203  sotDEBUG(35) << "angles = " << res;
204 
205  sotDEBUGOUT(15);
206  return res;
207 }
208 
209 /* compute the transformation matrix of the flexibility, ie
210  * feetRleg.
211  */
213  MatrixRotation& res, const sigtime_t& time) {
214  sotDEBUGIN(15);
215 
216  const dynamicgraph::Vector& angles = anglesSOUT(time);
217  double cx = cos(angles(0));
218  double sx = sin(angles(0));
219  double cy = cos(angles(1));
220  double sy = sin(angles(1));
221 
222  res(0, 0) = cy;
223  res(0, 1) = 0;
224  res(0, 2) = -sy;
225 
226  res(1, 0) = -sx * sy;
227  res(1, 1) = cx;
228  res(1, 2) = -sx * cy;
229 
230  res(2, 0) = cx * sy;
231  res(2, 1) = sx;
232  res(2, 2) = cx * cy;
233 
234  sotDEBUGOUT(15);
235  return res;
236 }
237 
238 /* Compute the rotation matrix of the drift, ie the
239  * transfo from the world frame to the estimated (drifted) world
240  * frame: worldRworldest.
241  */
243  const sigtime_t& time) {
244  sotDEBUGIN(15);
245 
246  const dynamicgraph::Vector& angles = anglesSOUT(time);
247  double cz = cos(angles(2));
248  double sz = sin(angles(2));
249 
250  res(0, 0) = cz;
251  res(0, 1) = -sz;
252  res(0, 2) = 0;
253 
254  /* z is the positive angle (R_{-z} has been computed
255  *in the <angles> function). Thus, the /-/sin(z) is in 0,1. */
256  res(1, 0) = sz;
257  res(1, 1) = cz;
258  res(1, 2) = 0;
259 
260  res(2, 0) = 0;
261  res(2, 1) = 0;
262  res(2, 2) = 1;
263 
264  sotDEBUGOUT(15);
265  return res;
266 }
267 
269  MatrixRotation& res, const sigtime_t& time) {
270  sotDEBUGIN(15);
271 
272  const MatrixRotation& worldRworldest = driftSOUT(time);
273  const MatrixRotation& worldestRsensor = sensorWorldRotationSIN(time);
274 
275  res = worldRworldest * worldestRsensor;
276 
277  sotDEBUGOUT(15);
278  return res;
279 }
280 
282  MatrixRotation& res, const sigtime_t& time) {
283  sotDEBUGIN(15);
284 
285  // chest = sensor
286  const MatrixRotation& worldRsensor = sensorWorldRotationSOUT(time);
287  const MatrixHomogeneous& waistMchest = sensorEmbeddedPositionSIN(time);
288  MatrixRotation waistRchest;
289  waistRchest = waistMchest.linear();
290 
291  res = worldRsensor * waistRchest.transpose();
292 
293  sotDEBUGOUT(15);
294  return res;
295 }
296 
298  MatrixHomogeneous& res, const sigtime_t& time) {
299  sotDEBUGIN(15);
300 
301  const MatrixHomogeneous& waistMleg = contactEmbeddedPositionSIN(time);
302  const MatrixHomogeneous& contactPos = contactWorldPositionSIN(time);
303  MatrixHomogeneous legMwaist(waistMleg.inverse());
304  MatrixHomogeneous tmpRes;
305  if (fromSensor_) {
306  const MatrixRotation& Rflex = flexibilitySOUT(time); // footRleg
307  MatrixHomogeneous footMleg;
308  footMleg.linear() = Rflex;
309  footMleg.translation().setZero();
310 
311  tmpRes = footMleg * legMwaist;
312  } else {
313  tmpRes = legMwaist;
314  }
315 
316  res = contactPos * tmpRes;
317  sotDEBUGOUT(15);
318  return res;
319 }
320 
322  dynamicgraph::Vector& res, const sigtime_t& time) {
324 
325  VectorRollPitchYaw r = (M.linear().eulerAngles(2, 1, 0)).reverse();
327  t = M.translation();
328 
329  res.resize(6);
330  for (int i = 0; i < 3; ++i) {
331  res(i) = t(i);
332  res(i + 3) = r(i);
333  }
334 
335  return res;
336 }
337 
338 /* --- VELOCITY SIGS -------------------------------------------------------- */
339 
341  dynamicgraph::Vector& res, const sigtime_t& time) {
342  const dynamicgraph::Matrix& J = jacobianSIN(time);
343  const dynamicgraph::Vector& dq = qdotSIN(time);
344 
345  const Eigen::DenseIndex nr = J.rows(), nc = J.cols() - 6;
346  assert(nr == 6);
347  dynamicgraph::Matrix Ja(nr, nc);
348  dynamicgraph::Vector dqa(nc);
349  for (int j = 0; j < nc; ++j) {
350  for (int i = 0; i < nr; ++i) Ja(i, j) = J(i, j + 6);
351  dqa(j) = dq(j + 6);
352  }
353  dynamicgraph::Matrix Jff(6, 6);
354  for (int j = 0; j < 6; ++j)
355  for (int i = 0; i < 6; ++i) Jff(i, j) = J(i, j);
356 
357  res.resize(nr);
358  res = (Jff.inverse() * (Ja * dqa)) * (-1);
359  return res;
360 }
361 
363  dynamicgraph::Vector& res, const sigtime_t& time) {
364  const dynamicgraph::Vector& dq = qdotSIN(time);
365  const dynamicgraph::Vector& dx = xff_dotSOUT(time);
366 
367  assert(dx.size() == 6);
368 
369  const Eigen::DenseIndex nr = dq.size();
370  res.resize(nr);
371  res = dq;
372  for (int i = 0; i < 6; ++i) res(i) = dx(i);
373 
374  return res;
375 }
dynamicgraph::sot::AngleEstimator::sensorWorldRotationSIN
dg::SignalPtr< MatrixRotation, sigtime_t > sensorWorldRotationSIN
Definition: angle-estimator.h:62
dynamicgraph::sot::AngleEstimator::contactEmbeddedPositionSIN
dg::SignalPtr< MatrixHomogeneous, sigtime_t > contactEmbeddedPositionSIN
Definition: angle-estimator.h:68
dynamicgraph::sot::AngleEstimator::qdotSOUT
dg::SignalTimeDependent< dynamicgraph::Vector, sigtime_t > qdotSOUT
Definition: angle-estimator.h:87
dynamicgraph::sot::AngleEstimator::~AngleEstimator
virtual ~AngleEstimator(void)
Definition: angle-estimator.cpp:137
dynamicgraph::sot::MatrixHomogeneous
Eigen::Transform< double, 3, Eigen::Affine > SOT_CORE_EXPORT MatrixHomogeneous
dynamicgraph::sot::AngleEstimator::computeDriftFromAngles
MatrixRotation & computeDriftFromAngles(MatrixRotation &res, const sigtime_t &time)
Definition: angle-estimator.cpp:242
dynamicgraph::sot::AngleEstimator::flexibilitySOUT
dg::SignalTimeDependent< MatrixRotation, sigtime_t > flexibilitySOUT
Definition: angle-estimator.h:72
dynamicgraph
J
J
i
int i
dynamicgraph::Entity
command-getter.h
dynamicgraph::sot::AngleEstimator::computeWaistWorldPoseRPY
dynamicgraph::Vector & computeWaistWorldPoseRPY(dynamicgraph::Vector &res, const sigtime_t &time)
Definition: angle-estimator.cpp:321
dynamicgraph::sot::AngleEstimator::computeSensorWorldRotation
MatrixRotation & computeSensorWorldRotation(MatrixRotation &res, const sigtime_t &time)
Definition: angle-estimator.cpp:268
boost
debug.hh
dynamicgraph::Matrix
Eigen::MatrixXd Matrix
R
R
dynamicgraph::sot::AngleEstimator::fromSensor_
bool fromSensor_
Definition: angle-estimator.h:114
dynamicgraph::sot::AngleEstimator::sensorEmbeddedPositionSIN
dg::SignalPtr< MatrixHomogeneous, sigtime_t > sensorEmbeddedPositionSIN
Definition: angle-estimator.h:64
r
FCL_REAL r
dynamicgraph::sot::AngleEstimator::compute_qdotSOUT
dynamicgraph::Vector & compute_qdotSOUT(dynamicgraph::Vector &res, const sigtime_t &time)
Definition: angle-estimator.cpp:362
res
res
command-setter.h
dynamicgraph::sot::VectorRollPitchYaw
Eigen::Vector3d SOT_CORE_EXPORT VectorRollPitchYaw
sotDEBUGOUT
#define sotDEBUGOUT(level)
dynamicgraph::sot::AngleEstimator::computeWaistWorldPosition
MatrixHomogeneous & computeWaistWorldPosition(MatrixHomogeneous &res, const sigtime_t &time)
Definition: angle-estimator.cpp:297
dynamicgraph::sot::AngleEstimator::compute_xff_dotSOUT
dynamicgraph::Vector & compute_xff_dotSOUT(dynamicgraph::Vector &res, const sigtime_t &time)
Definition: angle-estimator.cpp:340
dynamicgraph::sot::AngleEstimator::waistWorldPositionSOUT
dg::SignalTimeDependent< MatrixHomogeneous, sigtime_t > waistWorldPositionSOUT
Definition: angle-estimator.h:80
dynamicgraph::sot::AngleEstimator::AngleEstimator
AngleEstimator(const std::string &name)
Definition: angle-estimator.cpp:23
dynamicgraph::sot::AngleEstimator::qdotSIN
dg::SignalPtr< dynamicgraph::Vector, sigtime_t > qdotSIN
Definition: angle-estimator.h:85
sotDEBUGIN
#define sotDEBUGIN(level)
angle-estimator.h
dynamicgraph::sot::AngleEstimator::driftSOUT
dg::SignalTimeDependent< MatrixRotation, sigtime_t > driftSOUT
Definition: angle-estimator.h:74
M
M
dynamicgraph::sot::AngleEstimator::waistWorldRotationSOUT
dg::SignalTimeDependent< MatrixRotation, sigtime_t > waistWorldRotationSOUT
Definition: angle-estimator.h:78
dynamicgraph::Vector
Eigen::VectorXd Vector
dynamicgraph::sot::AngleEstimator
Definition: angle-estimator.h:51
dynamicgraph::sot::AngleEstimator::waistWorldPoseRPYSOUT
dg::SignalTimeDependent< dynamicgraph::Vector, sigtime_t > waistWorldPoseRPYSOUT
Definition: angle-estimator.h:82
dynamicgraph::sot::AngleEstimator::fromSensor
bool fromSensor() const
Definition: angle-estimator.h:111
X
X
Y
Y
M_PI
#define M_PI
dynamicgraph::sot::AngleEstimator::computeWaistWorldRotation
MatrixRotation & computeWaistWorldRotation(MatrixRotation &res, const sigtime_t &time)
Definition: angle-estimator.cpp:281
dynamicgraph::sot::AngleEstimator::xff_dotSOUT
dg::SignalTimeDependent< dynamicgraph::Vector, sigtime_t > xff_dotSOUT
Definition: angle-estimator.h:86
dynamicgraph::sot
dynamicgraph::sot::AngleEstimator::jacobianSIN
dg::SignalPtr< dynamicgraph::Matrix, sigtime_t > jacobianSIN
Definition: angle-estimator.h:84
dynamicgraph::Entity::signalRegistration
void signalRegistration(const SignalArray< int > &signals)
dynamicgraph::sot::MatrixRotation
Eigen::Matrix< double, 3, 3 > SOT_CORE_EXPORT MatrixRotation
dynamicgraph::sot::AngleEstimator::computeAngles
dynamicgraph::Vector & computeAngles(dynamicgraph::Vector &res, const sigtime_t &time)
Definition: angle-estimator.cpp:147
dynamicgraph::Entity::addCommand
void addCommand(const std::string &name, command::Command *command)
t
Transform3f t
dynamicgraph::sot::AngleEstimator::anglesSOUT
dg::SignalTimeDependent< dynamicgraph::Vector, sigtime_t > anglesSOUT
Definition: angle-estimator.h:70
dq
dq
command.h
dynamicgraph::sot::AngleEstimator::sensorWorldRotationSOUT
dg::SignalTimeDependent< MatrixRotation, sigtime_t > sensorWorldRotationSOUT
Definition: angle-estimator.h:76
dynamicgraph::sot::AngleEstimator::contactWorldPositionSIN
dg::SignalPtr< MatrixHomogeneous, sigtime_t > contactWorldPositionSIN
Definition: angle-estimator.h:66
compile.name
name
Definition: compile.py:22
dynamicgraph::sot::DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(DoubleConstant, "DoubleConstant")
Z
Z
dynamicgraph::sot::AngleEstimator::computeFlexibilityFromAngles
MatrixRotation & computeFlexibilityFromAngles(MatrixRotation &res, const sigtime_t &time)
Definition: angle-estimator.cpp:212
sotDEBUG
#define sotDEBUG(level)


sot-dynamic-pinocchio
Author(s): Olivier Stasse
autogenerated on Fri Jul 28 2023 02:10:01