Contact.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_rbdyn/Robot.h>
31 #include <mc_rtc/Configuration.h>
32 #include <mc_rtc/constants.h>
33 #include <mc_rtc/logging.h>
34 #include <mc_tasks/lipm_stabilizer/Contact.h>
35 
36 #include <SpaceVecAlg/SpaceVecAlg>
37 
38 #include <cmath>
39 #include <lipm_walking/Sole.h>
40 
41 namespace lipm_walking
42 {
43 
44 using HrepXd = std::pair<Eigen::MatrixXd, Eigen::VectorXd>;
45 
47 
51 struct Contact
52 {
53  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
54 
60  Contact() {}
61 
67  Contact(const sva::PTransformd & pose) : pose(pose) {}
68 
72  Eigen::Vector3d sagittal() const
73  {
74  return pose.rotation().row(0);
75  }
76 
80  Eigen::Vector3d lateral() const
81  {
82  return pose.rotation().row(1);
83  }
84 
88  Eigen::Vector3d normal() const
89  {
90  return pose.rotation().row(2);
91  }
92 
96  const Eigen::Vector3d & position() const
97  {
98  return pose.translation();
99  }
100 
104  const Eigen::Vector3d & p() const
105  {
106  return position();
107  }
108 
114  Eigen::Vector3d anklePos(const Sole & sole) const
115  {
116  if(surfaceName == "LeftFootCenter")
117  {
118  return p() + sole.leftAnkleOffset.x() * sagittal() + sole.leftAnkleOffset.y() * lateral();
119  }
120  else if(surfaceName == "RightFootCenter")
121  {
122  return p() + sole.leftAnkleOffset.x() * sagittal() - sole.leftAnkleOffset.y() * lateral();
123  }
124  else
125  {
126  mc_rtc::log::error("Cannot compute anklePos for surface {}", surfaceName);
127  return p();
128  }
129  }
130 
136  sva::PTransformd anklePose(const Sole & sole) const
137  {
138  return {pose.rotation(), anklePos(sole)};
139  }
140 
144  double x() const
145  {
146  return position()(0);
147  }
148 
152  double y() const
153  {
154  return position()(1);
155  }
156 
160  double z() const
161  {
162  return position()(2);
163  }
164 
168  Eigen::Vector3d vertex0() const
169  {
170  return position() + halfLength * sagittal() + halfWidth * lateral();
171  }
172 
176  Eigen::Vector3d vertex1() const
177  {
178  return position() + halfLength * sagittal() - halfWidth * lateral();
179  }
180 
184  Eigen::Vector3d vertex2() const
185  {
186  return position() - halfLength * sagittal() - halfWidth * lateral();
187  }
188 
192  Eigen::Vector3d vertex3() const
193  {
194  return position() - halfLength * sagittal() + halfWidth * lateral();
195  }
196 
200  template<int i>
201  double minCoord() const
202  {
203  return std::min(std::min(vertex0()(i), vertex1()(i)), std::min(vertex2()(i), vertex3()(i)));
204  }
205 
209  template<int i>
210  double maxCoord() const
211  {
212  return std::max(std::max(vertex0()(i), vertex1()(i)), std::max(vertex2()(i), vertex3()(i)));
213  }
214 
218  double xmin() const
219  {
220  return minCoord<0>();
221  }
222 
226  double xmax() const
227  {
228  return maxCoord<0>();
229  }
230 
234  double ymin() const
235  {
236  return minCoord<1>();
237  }
238 
242  double ymax() const
243  {
244  return maxCoord<1>();
245  }
246 
250  double zmin() const
251  {
252  return minCoord<2>();
253  }
254 
258  double zmax() const
259  {
260  return maxCoord<2>();
261  }
262 
266  HrepXd hrep() const
267  {
268  Eigen::Matrix<double, 4, 2> localHrepMat, worldHrepMat;
269  Eigen::Matrix<double, 4, 1> localHrepVec, worldHrepVec;
270  // clang-format off
271  localHrepMat <<
272  +1, 0,
273  -1, 0,
274  0, +1,
275  0, -1;
276  localHrepVec <<
277  halfLength,
278  halfLength,
279  halfWidth,
280  halfWidth;
281  // clang-format on
282  if((normal() - mc_rtc::constants::vertical).norm() > 1e-3)
283  {
284  mc_rtc::log::warning("Contact is not horizontal");
285  }
286  const sva::PTransformd & X_0_c = pose;
287  worldHrepMat = localHrepMat * X_0_c.rotation().topLeftCorner<2, 2>();
288  worldHrepVec = worldHrepMat * X_0_c.translation().head<2>() + localHrepVec;
289  return HrepXd(worldHrepMat, worldHrepVec);
290  }
291 
297  inline sva::PTransformd robotTransform(const mc_rbdyn::Robot & robot) const
298  {
299  const sva::PTransformd & X_0_c = pose;
300  const sva::PTransformd & X_0_fb = robot.posW();
301  sva::PTransformd X_s_0 = robot.surfacePose(surfaceName).inv();
302  sva::PTransformd X_s_fb = X_0_fb * X_s_0;
303  return X_s_fb * X_0_c;
304  }
305 
306 public:
307  Eigen::Vector3d refVel =
308  Eigen::Vector3d::Zero();
309  double halfLength = 0.;
310  double halfWidth = 0.;
311  mc_rtc::Configuration
313  std::string surfaceName = "";
314  sva::PTransformd pose;
315  unsigned id = 0;
316 };
317 
325 inline Contact operator*(const sva::PTransformd & X, const Contact & contact)
326 {
327  Contact result = contact;
328  result.pose = X * contact.pose;
329  return result;
330 }
331 } // namespace lipm_walking
332 
333 namespace mc_rtc
334 {
335 template<>
336 struct ConfigurationLoader<lipm_walking::Contact>
337 {
338  static lipm_walking::Contact load(const mc_rtc::Configuration & config)
339  {
340  lipm_walking::Contact contact;
341  contact.pose = config("pose");
342  config("half_length", contact.halfLength);
343  config("half_width", contact.halfWidth);
344  config("ref_vel", contact.refVel);
345  config("surface", contact.surfaceName);
346  if(config.has("swing"))
347  {
348  contact.swingConfig = config("swing");
349  }
350  return contact;
351  }
352 
353  static mc_rtc::Configuration save(const lipm_walking::Contact & contact)
354  {
355  mc_rtc::Configuration config;
356  config.add("half_length", contact.halfLength);
357  config.add("half_width", contact.halfWidth);
358  config.add("pose", contact.pose);
359  config.add("ref_vel", contact.refVel);
360  config.add("surface", contact.surfaceName);
361  if(!contact.swingConfig.empty())
362  {
363  config("swing") = contact.swingConfig;
364  }
365  return config;
366  }
367 };
368 
369 } // namespace mc_rtc
std::pair< Eigen::MatrixXd, Eigen::VectorXd > HrepXd
Definition: Contact.h:44
Contact operator*(const sva::PTransformd &X, const Contact &contact)
Definition: Contact.h:325
mc_tasks::lipm_stabilizer::ContactState ContactState
Definition: Contact.h:46
std::string surfaceName
Definition: Contact.h:313
Eigen::Vector3d refVel
Definition: Contact.h:307
sva::PTransformd robotTransform(const mc_rbdyn::Robot &robot) const
Definition: Contact.h:297
double ymin() const
Definition: Contact.h:234
double z() const
Definition: Contact.h:160
sva::PTransformd pose
Definition: Contact.h:314
double y() const
Definition: Contact.h:152
Eigen::Vector3d normal() const
Definition: Contact.h:88
Eigen::Vector3d vertex1() const
Definition: Contact.h:176
Eigen::Vector3d vertex0() const
Definition: Contact.h:168
Contact(const sva::PTransformd &pose)
Definition: Contact.h:67
double minCoord() const
Definition: Contact.h:201
double x() const
Definition: Contact.h:144
mc_rtc::Configuration swingConfig
Definition: Contact.h:312
Eigen::Vector3d sagittal() const
Definition: Contact.h:72
Eigen::Vector3d lateral() const
Definition: Contact.h:80
double zmax() const
Definition: Contact.h:258
double zmin() const
Definition: Contact.h:250
EIGEN_MAKE_ALIGNED_OPERATOR_NEW Contact()
Definition: Contact.h:60
Eigen::Vector3d vertex3() const
Definition: Contact.h:192
Eigen::Vector3d vertex2() const
Definition: Contact.h:184
double maxCoord() const
Definition: Contact.h:210
double xmax() const
Definition: Contact.h:226
double xmin() const
Definition: Contact.h:218
Eigen::Vector3d anklePos(const Sole &sole) const
Definition: Contact.h:114
double ymax() const
Definition: Contact.h:242
const Eigen::Vector3d & position() const
Definition: Contact.h:96
HrepXd hrep() const
Definition: Contact.h:266
sva::PTransformd anklePose(const Sole &sole) const
Definition: Contact.h:136
const Eigen::Vector3d & p() const
Definition: Contact.h:104
EIGEN_MAKE_ALIGNED_OPERATOR_NEW Eigen::Vector2d leftAnkleOffset
Definition: Sole.h:42
static lipm_walking::Contact load(const mc_rtc::Configuration &config)
Definition: Contact.h:338
static mc_rtc::Configuration save(const lipm_walking::Contact &contact)
Definition: Contact.h:353