ModelPredictiveControl.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_rtc/GUIState.h>
31 
32 #include <copra/LMPC.h>
33 #include <copra/PreviewSystem.h>
34 #include <copra/constraints.h>
35 #include <copra/costFunctions.h>
36 #include <lipm_walking/Contact.h>
37 #include <lipm_walking/Pendulum.h>
38 #include <lipm_walking/Preview.h>
39 #include <lipm_walking/Sole.h>
41 
42 namespace lipm_walking
43 {
44 
53 {
54  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
55 
56  static constexpr double SAMPLING_PERIOD = 0.1;
57  static constexpr unsigned INPUT_SIZE = 2;
58  static constexpr unsigned NB_STEPS = 16;
59  static constexpr unsigned STATE_SIZE = 6;
65 
71  void addGUIElements(std::shared_ptr<mc_rtc::gui::StateBuilder> gui);
72 
78  void addLogEntries(mc_rtc::Logger & logger);
79 
83  void configure(const mc_rtc::Configuration &);
84 
104  void phaseDurations(double initSupportDuration, double doubleSupportDuration, double targetSupportDuration);
105 
111  bool buildAndSolve();
112 
118  void comHeight(double height)
119  {
120  double zeta = height / world::GRAVITY;
121  double omegaInv = std::sqrt(zeta);
122  // clang-format off
123  dcmFromState_ <<
124  1, 0, omegaInv, 0, 0, 0,
125  0, 1, 0, omegaInv, 0, 0;
126  zmpFromState_ <<
127  1, 0, 0, 0, -zeta, 0,
128  0, 1, 0, 0, 0, -zeta;
129  // clang-format on
130  }
131 
142  {
143  initContact_ = initContact;
144  nextContact_ = nextContact;
145  targetContact_ = targetContact;
146  }
147 
153  void initState(const Pendulum & pendulum)
154  {
155  initState_ = Eigen::VectorXd(STATE_SIZE);
156  initState_ << pendulum.com().head<2>(), pendulum.comd().head<2>(), pendulum.comdd().head<2>();
157  }
158 
169  unsigned indexToHrep(unsigned i) const
170  {
171  return indexToHrep_[i];
172  }
173 
177  const Contact & initContact() const
178  {
179  return initContact_;
180  }
181 
186  unsigned nbInitSupportSteps() const
187  {
188  return nbInitSupportSteps_;
189  }
190 
196  unsigned nbDoubleSupportSteps() const
197  {
198  return nbDoubleSupportSteps_;
199  }
200 
204  const Contact & nextContact() const
205  {
206  return nextContact_;
207  }
208 
214  void sole(const Sole & sole)
215  {
216  sole_ = sole;
217  }
218 
222  const std::shared_ptr<Preview> solution() const
223  {
224  return solution_;
225  }
226 
230  const Contact & targetContact() const
231  {
232  return targetContact_;
233  }
234 
235 private:
236  void computeZMPRef();
237 
238  void updateTerminalConstraint();
239 
240  void updateZMPConstraint();
241 
242  void updateJerkCost();
243 
244  void updateVelCost();
245 
246  void updateZMPCost();
247 
248 public:
249  Eigen::Vector2d velWeights = {10., 10.};
250  double jerkWeight = 1.;
251  double zmpWeight = 1000.;
253 private:
254  using RefVector = Eigen::Matrix<double, 2 * (NB_STEPS + 1), 1>;
255  using StateMatrix = Eigen::Matrix<double, 2, STATE_SIZE>;
256 
257  Contact initContact_;
258  Contact nextContact_;
259  Contact targetContact_;
260  RefVector velRef_ = RefVector::Zero();
261  RefVector zmpRef_ = RefVector::Zero();
262  Eigen::Matrix<double, 2 * (NB_STEPS + 1), STATE_SIZE *(NB_STEPS + 1)> velCostMat_;
263  StateMatrix dcmFromState_ = StateMatrix::Zero();
264  StateMatrix zmpFromState_ = StateMatrix::Zero();
265  Eigen::VectorXd initState_;
266  HrepXd hreps_[4];
267  copra::SolverFlag solver_ = copra::SolverFlag::QLD;
268  double buildAndSolveTime_ = 0.;
269  double solveTime_ = 0.;
270  std::shared_ptr<Preview> solution_ = nullptr;
271  std::shared_ptr<copra::ControlCost> jerkCost_ = nullptr;
272  std::shared_ptr<copra::PreviewSystem> previewSystem_ = nullptr;
273  std::shared_ptr<copra::TrajectoryConstraint> termDCMCons_ = nullptr;
274  std::shared_ptr<copra::TrajectoryConstraint> termZMPCons_ = nullptr;
275  std::shared_ptr<copra::TrajectoryConstraint> zmpCons_ = nullptr;
276  std::shared_ptr<copra::TrajectoryCost> velCost_ = nullptr;
277  std::shared_ptr<copra::TrajectoryCost> zmpCost_ = nullptr;
278  unsigned indexToHrep_[NB_STEPS + 1];
279  unsigned nbDoubleSupportSteps_ = 0;
280  Sole sole_;
281  unsigned nbInitSupportSteps_ = 0;
282  unsigned nbNextDoubleSupportSteps_ = 0;
283  unsigned nbTargetSupportSteps_ = 0;
284 };
285 
286 } // namespace lipm_walking
unsigned nbInitSupportSteps() const
Number of sampling steps in the preview spent in the first single-support phase.
static constexpr unsigned INPUT_SIZE
Input is the 2D horizontal CoM jerk.
const Contact & initContact() const
Support contact in the first single-support phase.
Eigen::Vector2d velWeights
Weights of CoM velocity tracking cost.
const Contact & targetContact() const
Support contact in the second single-support phase.
const Eigen::Vector3d & comdd() const
CoM acceleration in the world frame.
Definition: Pendulum.h:128
State of the inverted pendulum model.
Definition: Pendulum.h:40
constexpr double GRAVITY
Definition: world.h:38
const Contact & nextContact() const
Support contact in the third single-support phase.
const Eigen::Vector3d & comd() const
CoM velocity in the world frame.
Definition: Pendulum.h:120
static constexpr unsigned NB_STEPS
Number of sampling steps.
double zmpWeight
Weight of reference ZMP tracking cost.
static EIGEN_MAKE_ALIGNED_OPERATOR_NEW constexpr double SAMPLING_PERIOD
Duration of each sampling step in [s].
unsigned nbDoubleSupportSteps() const
Number of sampling steps in the preview spent in the first double-support phase.
void contacts(Contact initContact, Contact targetContact, Contact nextContact)
Reset contacts.
void initState(const Pendulum &pendulum)
Set the initial CoM state.
ModelPredictiveControl()
Initialize new problem.
static constexpr unsigned STATE_SIZE
State is the 6D stacked vector of CoM positions, velocities and accelerations.
Model predictive control problem.
double jerkWeight
Weight of CoM jerk regularization cost.
void addLogEntries(mc_rtc::Logger &logger)
Log stabilizer entries.
void configure(const mc_rtc::Configuration &)
Read configuration from dictionary.
unsigned indexToHrep(unsigned i) const
Get index of inequality constraints.
bool buildAndSolve()
Build and solve the model predictive control quadratic program.
Main controller namespace.
Definition: build.dox:1
const Eigen::Vector3d & com() const
CoM position in the world frame.
Definition: Pendulum.h:112
Contacts wrap foot frames with extra info from the footstep plan.
Definition: Contact.h:58
Foot sole properties.
Definition: Sole.h:38
void sole(const Sole &sole)
Set model sole properties.
std::pair< Eigen::MatrixXd, Eigen::VectorXd > HrepXd
Definition: Contact.h:43
void comHeight(double height)
Set CoM height.
void phaseDurations(double initSupportDuration, double doubleSupportDuration, double targetSupportDuration)
Set duration of the initial single-support phase.
void addGUIElements(std::shared_ptr< mc_rtc::gui::StateBuilder > gui)
Add GUI panel.
const std::shared_ptr< Preview > solution() const
Get solution vector.