SingleSupport.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 "SingleSupport.h"
29 
30 namespace lipm_walking
31 {
32 
34 {
35  auto & ctl = controller();
36  auto & supportContact = ctl.supportContact();
37  auto & targetContact = ctl.targetContact();
38 
39  duration_ = ctl.singleSupportDuration();
40  hasUpdatedMPCOnce_ = false;
41  remTime_ = ctl.singleSupportDuration();
42  stateTime_ = 0.;
43  timeSinceLastPreviewUpdate_ = 0.; // don't update at transition
44 
45  if(supportContact.surfaceName == "LeftFootCenter")
46  {
47  ctl.leftFootRatio(1.);
49  supportFootTask = stabilizer().leftFootTask;
50  swingFootTask = stabilizer().rightFootTask;
51  }
52  else // (ctl.supportContact.surfaceName == "RightFootCenter")
53  {
54  ctl.leftFootRatio(0.);
56  supportFootTask = stabilizer().rightFootTask;
57  swingFootTask = stabilizer().leftFootTask;
58  }
59 
60  swingFoot_.landingDuration(ctl.plan.landingDuration());
61  swingFoot_.landingPitch(ctl.plan.landingPitch());
62  swingFoot_.takeoffDuration(ctl.plan.takeoffDuration());
63  swingFoot_.takeoffOffset(ctl.plan.takeoffOffset());
64  swingFoot_.takeoffPitch(ctl.plan.takeoffPitch());
65  swingFoot_.reset(swingFootTask->surfacePose(), targetContact.pose, duration_, ctl.plan.swingHeight());
66  stabilizer().setContact(supportFootTask, supportContact);
67  stabilizer().setSwingFoot(swingFootTask);
68  stabilizer().addTasks(ctl.solver());
69 
70  logger().addLogEntry("rem_phase_time", [this]() { return remTime_; });
71  logger().addLogEntry("support_xmax", [&ctl]() { return ctl.supportContact().xmax(); });
72  logger().addLogEntry("support_xmin", [&ctl]() { return ctl.supportContact().xmin(); });
73  logger().addLogEntry("support_ymax", [&ctl]() { return ctl.supportContact().ymax(); });
74  logger().addLogEntry("support_ymin", [&ctl]() { return ctl.supportContact().ymin(); });
75  logger().addLogEntry("support_zmax", [&ctl]() { return ctl.supportContact().zmax(); });
76  logger().addLogEntry("support_zmin", [&ctl]() { return ctl.supportContact().zmin(); });
77  logger().addLogEntry("walking_phase", []() { return 1.; });
78  swingFoot_.addLogEntries(logger());
79 
80  runState(); // don't wait till next cycle to update reference and tasks
81 }
82 
84 {
85  stabilizer().removeTasks(controller().solver());
86 
87  logger().removeLogEntry("contact_impulse");
88  logger().removeLogEntry("rem_phase_time");
89  logger().removeLogEntry("support_xmax");
90  logger().removeLogEntry("support_xmin");
91  logger().removeLogEntry("support_ymax");
92  logger().removeLogEntry("support_ymin");
93  logger().removeLogEntry("support_zmax");
94  logger().removeLogEntry("support_zmin");
95  logger().removeLogEntry("walking_phase");
96  swingFoot_.removeLogEntries(logger());
97 }
98 
100 {
101  if(remTime_ < 0.)
102  {
103  output("DoubleSupport");
104  return true;
105  }
106  return false;
107 }
108 
110 {
111  auto & ctl = controller();
112  double dt = ctl.timeStep;
113 
114  updateSwingFoot();
115  if(timeSinceLastPreviewUpdate_ > PREVIEW_UPDATE_PERIOD)
116  {
117  updatePreview();
118  }
119 
120  ctl.preview->integrate(pendulum(), dt);
121  if(hasUpdatedMPCOnce_)
122  {
123  pendulum().resetCoMHeight(ctl.plan.comHeight(), ctl.supportContact());
124  pendulum().completeIPM(ctl.supportContact());
125  }
126  else // still in DSP of preview
127  {
128  pendulum().completeIPM(ctl.prevContact());
129  }
130  stabilizer().run();
131 
132  remTime_ -= dt;
133  stateTime_ += dt;
134  timeSinceLastPreviewUpdate_ += dt;
135 }
136 
138 {
139  auto & ctl = controller();
140  auto & targetContact = ctl.targetContact();
141  double dt = ctl.timeStep;
142 
143  if(stabilizer().contactState() != ContactState::DoubleSupport)
144  {
145  bool liftPhase = (remTime_ > duration_ / 3.);
146  bool touchdownDetected = stabilizer().detectTouchdown(swingFootTask, targetContact);
147  if(liftPhase || !touchdownDetected)
148  {
149  swingFoot_.integrate(dt);
150  swingFootTask->targetPose(swingFoot_.pose());
151  swingFootTask->refVelB(swingFoot_.vel());
152  swingFootTask->refAccel(swingFoot_.accel());
153  }
154  else // (stabilizer().contactState() != ContactState::DoubleSupport)
155  {
157  stabilizer().setContact(swingFootTask, targetContact);
158  }
159  }
160 }
161 
163 {
164  auto & ctl = controller();
165  ctl.mpc().contacts(ctl.supportContact(), ctl.targetContact(), ctl.nextContact());
166  if(ctl.isLastSSP() || ctl.pauseWalking)
167  {
168  ctl.nextDoubleSupportDuration(ctl.plan.finalDSPDuration());
169  ctl.mpc().phaseDurations(remTime_, ctl.plan.finalDSPDuration(), 0.);
170  }
171  else
172  {
173  ctl.mpc().phaseDurations(remTime_, ctl.doubleSupportDuration(), ctl.singleSupportDuration());
174  }
175  if(ctl.updatePreview())
176  {
177  timeSinceLastPreviewUpdate_ = 0.;
178  hasUpdatedMPCOnce_ = true;
179  }
180 }
181 
182 } // namespace lipm_walking
183 
184 EXPORT_SINGLE_STATE("SingleSupport", lipm_walking::states::SingleSupport)
void updateSwingFoot()
Update swing foot target.
ContactState contactState()
Get contact state.
Definition: Stabilizer.h:200
Pendulum & pendulum()
Get pendulum reference.
Definition: State.h:82
void integrate(double dt)
Progress by dt along the swing foot trajectory.
Definition: SwingFoot.cpp:95
void addTasks(mc_solver::QPSolver &solver)
Add tasks to QP solver.
Definition: Stabilizer.cpp:358
void landingPitch(double pitch)
Upward pitch angle before landing.
Definition: SwingFoot.h:111
EIGEN_MAKE_ALIGNED_OPERATOR_NEW void addLogEntries(mc_rtc::Logger &logger)
Add swing foot entries to log.
Definition: SwingFoot.cpp:77
void completeIPM(const Contact &plane)
Complete inverted pendulum inputs (ZMP and natural frequency) from contact plane. ...
Definition: Pendulum.cpp:88
void run()
Update QP task targets.
Definition: Stabilizer.cpp:490
sva::MotionVecd accel() const
Get current acceleration as motion vector.
Definition: SwingFoot.h:83
Stabilizer & stabilizer()
Get stabilizer.
Definition: State.h:115
void teardown() override
Teardown state.
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
void runState() override
Main state function, called if no transition at this cycle.
Single support phase while walking.
Definition: SingleSupport.h:46
void resetCoMHeight(double height, const Contact &contact)
Reset CoM height above a given contact plane.
Definition: Pendulum.cpp:79
constexpr double PREVIEW_UPDATE_PERIOD
Preview update period, same as MPC sampling period.
Definition: Controller.h:62
void start() override
Start state.
std::shared_ptr< mc_tasks::force::CoPTask > leftFootTask
Left foot hybrid position/force control task.
Definition: Stabilizer.h:390
void takeoffPitch(double pitch)
Downward pitch angle after takeoff.
Definition: SwingFoot.h:157
std::shared_ptr< mc_tasks::force::CoPTask > rightFootTask
Right foot hybrid position/force control task.
Definition: Stabilizer.h:391
mc_rtc::Logger & logger()
Get logger.
Definition: State.h:72
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
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
void takeoffOffset(const Eigen::Vector3d &offset)
Offset applied to horizontal position after takeoff.
Definition: SwingFoot.h:147
bool checkTransitions() override
Check transitions at beginning of control cycle.
sva::PTransformd pose() const
Get current pose as Plucker transform.
Definition: SwingFoot.h:119
void landingDuration(double duration)
Duration of landing phase.
Definition: SwingFoot.h:101
Controller & controller()
Get controller.
Definition: State.h:52
void takeoffDuration(double duration)
Set duration of takeoff phase.
Definition: SwingFoot.h:137
void updatePreview()
Update horizontal MPC preview.
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