SwingFoot.cpp
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 #include <mc_rbdyn/rpy_utils.h>
29 
30 #include <lipm_walking/SwingFoot.h>
32 
33 namespace lipm_walking
34 {
35 
36 void SwingFoot::reset(const sva::PTransformd & initPose,
37  const sva::PTransformd & targetPose,
38  double duration,
39  double height)
40 {
41  assert(0. <= takeoffDuration_ && takeoffDuration_ <= 0.5 * duration);
42  assert(0. <= landingDuration_ && landingDuration_ <= 0.5 * duration);
43 
44  accel_ = Eigen::Vector3d::Zero();
45  aerialStart_ = takeoffDuration_;
46  duration_ = duration;
47  height_ = height;
48  initPose_ = initPose;
49  ori_ = initPose.rotation();
50  playback_ = 0.;
51  pos_ = initPose.translation();
52  targetPose_ = targetPose;
53  vel_ = Eigen::Vector3d::Zero();
54 
55  const Eigen::Vector3d & initPos = initPose_.translation();
56  const Eigen::Vector3d & targetPos = targetPose_.translation();
57  double aerialDuration = duration - takeoffDuration_ - landingDuration_;
58  double halfDuration = duration / 2;
59 
60  Eigen::Vector3d aerialStartPos = initPos + takeoffOffset_;
61  xyTakeoffChunk_.reset(initPos.head<2>(), aerialStartPos.head<2>(), takeoffDuration_);
62  xyAerialChunk_.reset(aerialStartPos.head<2>(), targetPos.head<2>(), aerialDuration);
63 
64  Eigen::Vector3d airPos = 0.5 * (initPose.translation() + targetPose.translation());
65  airPos.z() = std::min(initPose.translation().z(), targetPose.translation().z()) + height;
66  zFirstChunk_.reset(initPos.z(), airPos.z(), halfDuration);
67  zSecondChunk_.reset(airPos.z(), targetPos.z(), halfDuration);
68 
69  pitchTakeoffChunk_.reset(0., takeoffPitch_, takeoffDuration_);
70  pitchAerialChunk1_.reset(takeoffPitch_, 0., aerialDuration / 2);
71  pitchAerialChunk2_.reset(0., landingPitch_, aerialDuration / 2);
72  pitchLandingChunk_.reset(landingPitch_, 0., landingDuration_);
73 
74  updatePose(/* t = */ 0.);
75 }
76 
77 void SwingFoot::addLogEntries(mc_rtc::Logger & logger)
78 {
79  logger.addLogEntry("swing_foot_accel", [this]() { return accel(); });
80  logger.addLogEntry("swing_foot_offset", [this]() { return takeoffOffset_; });
81  logger.addLogEntry("swing_foot_pitch", [this]() { return pitch_; });
82  logger.addLogEntry("swing_foot_pose", [this]() { return pose(); });
83  logger.addLogEntry("swing_foot_vel", [this]() { return vel(); });
84 }
85 
86 void SwingFoot::removeLogEntries(mc_rtc::Logger & logger)
87 {
88  logger.removeLogEntry("swing_foot_accel");
89  logger.removeLogEntry("swing_foot_offset");
90  logger.removeLogEntry("swing_foot_pitch");
91  logger.removeLogEntry("swing_foot_pose");
92  logger.removeLogEntry("swing_foot_vel");
93 }
94 
95 void SwingFoot::integrate(double dt)
96 {
97  playback_ += dt;
98  updatePose(playback_);
99 }
100 
101 void SwingFoot::updatePose(double t)
102 {
103  updateZ(t);
104  updateXY(t);
105  updatePitch(t);
106 }
107 
108 void SwingFoot::updateZ(double t)
109 {
110  double t1 = t;
111  double t2 = t - zFirstChunk_.duration();
112  if(t1 <= zFirstChunk_.duration())
113  {
114  pos_.z() = zFirstChunk_.pos(t1);
115  vel_.z() = zFirstChunk_.vel(t1);
116  accel_.z() = zFirstChunk_.accel(t1);
117  }
118  else // (t2 > 0.)
119  {
120  pos_.z() = zSecondChunk_.pos(t2);
121  vel_.z() = zSecondChunk_.vel(t2);
122  accel_.z() = zSecondChunk_.accel(t2);
123  }
124 }
125 
126 void SwingFoot::updateXY(double t)
127 {
128  double t1 = t - 0.;
129  double t2 = t1 - xyTakeoffChunk_.duration();
130  if(t1 <= xyTakeoffChunk_.duration())
131  {
132  pos_.head<2>() = xyTakeoffChunk_.pos(t1);
133  vel_.head<2>() = xyTakeoffChunk_.vel(t1);
134  accel_.head<2>() = xyTakeoffChunk_.accel(t1);
135  }
136  else // (t2 > 0)
137  {
138  pos_.head<2>() = xyAerialChunk_.pos(t2);
139  vel_.head<2>() = xyAerialChunk_.vel(t2);
140  accel_.head<2>() = xyAerialChunk_.accel(t2);
141  }
142 }
143 
144 void SwingFoot::updatePitch(double t)
145 {
146  Eigen::Matrix3d baseOri;
147  double t1 = t - 0.;
148  double t2 = t1 - pitchTakeoffChunk_.duration();
149  double t3 = t2 - pitchAerialChunk1_.duration();
150  double t4 = t3 - pitchAerialChunk2_.duration();
151  double takeoffDuration = pitchTakeoffChunk_.duration();
152  double aerialDuration = xyAerialChunk_.duration();
153  if(t1 <= takeoffDuration)
154  {
155  baseOri = initPose_.rotation();
156  }
157  else if(t2 <= aerialDuration)
158  {
159  double s2 = xyAerialChunk_.s(t2);
160  baseOri = slerp(initPose_.rotation(), targetPose_.rotation(), s2);
161  }
162  else // (t2 > aerialDuration)
163  {
164  baseOri = targetPose_.rotation();
165  }
166  if(t1 <= pitchTakeoffChunk_.duration())
167  {
168  pitch_ = pitchTakeoffChunk_.pos(t1);
169  }
170  else if(t2 <= pitchAerialChunk1_.duration())
171  {
172  pitch_ = pitchAerialChunk1_.pos(t2);
173  }
174  else if(t3 <= pitchAerialChunk2_.duration())
175  {
176  pitch_ = pitchAerialChunk2_.pos(t3);
177  }
178  else // (t4 > 0)
179  {
180  pitch_ = pitchLandingChunk_.pos(t4);
181  }
182  ori_ = mc_rbdyn::rpyToMat(0., pitch_, 0.) * baseOri;
183 }
184 
185 } // namespace lipm_walking
void reset(const T &initPos, const T &targetPos, double duration)
Reset duration and boundary positions.
Definition: polynomials.h:697
T vel(double t) const
Velocity along the retimed trajectory.
Definition: polynomials.h:785
void integrate(double dt)
Progress by dt along the swing foot trajectory.
Definition: SwingFoot.cpp:95
T accel(double t) const
Acceleration along the retimed trajectory.
Definition: polynomials.h:795
EIGEN_MAKE_ALIGNED_OPERATOR_NEW void addLogEntries(mc_rtc::Logger &logger)
Add swing foot entries to log.
Definition: SwingFoot.cpp:77
sva::MotionVecd accel() const
Get current acceleration as motion vector.
Definition: SwingFoot.h:83
double duration() const
Get trajectory duration.
Definition: polynomials.h:683
T pos(double t) const
Position along the retimed trajectory.
Definition: polynomials.h:775
double height()
Get current swing foot height.
Definition: SwingFoot.h:91
Main controller namespace.
Definition: build.dox:1
Eigen::Matrix3d slerp(const Eigen::Matrix3d &from, const Eigen::Matrix3d &to, double t)
Spherical linear interpolation between two rotation matrices.
Definition: slerp.h:48
double s(double t) const
Mapping from to .
Definition: polynomials.h:756
sva::PTransformd pose() const
Get current pose as Plucker transform.
Definition: SwingFoot.h:119
void takeoffDuration(double duration)
Set duration of takeoff phase.
Definition: SwingFoot.h:137
sva::MotionVecd vel() const
Get current velocity as motion vector.
Definition: SwingFoot.h:165
void removeLogEntries(mc_rtc::Logger &logger)
Remove swing foot entries from log.
Definition: SwingFoot.cpp:86
void reset(const sva::PTransformd &initPose, const sva::PTransformd &targetPose, double duration, double height)
Recompute swing foot trajectory for a new pair of contacts.
Definition: SwingFoot.cpp:36