Controller.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 #include <mc_rtc/constants.h>
30 
33 
35 
36 namespace lipm_walking
37 {
38 
39 Controller::Controller(mc_rbdyn::RobotModulePtr robotModule,
40  double dt,
41  const mc_rtc::Configuration & config,
42  mc_control::ControllerParameters params)
43 : mc_control::fsm::Controller(robotModule, dt, config, params), planInterpolator(gui()), externalFootstepPlanner(*this),
44  halfSitPose(controlRobot().mbc().q)
45 {
46  auto robotConfig = config("robot_models")(controlRobot().name());
47  auto planConfig = config("plans")(controlRobot().name());
48  if(planConfig.has("external"))
49  {
50  externalFootstepPlanner.configure(planConfig("external"));
51  }
52 
53  mc_rtc::log::info("Loading default stabilizer configuration");
54  defaultStabilizerConfig_ = robot().module().defaultLIPMStabilizerConfiguration();
55  if(robotConfig.has("stabilizer"))
56  {
57  mc_rtc::log::info("Loading additional stabilizer configuration");
58  defaultStabilizerConfig_.load(robotConfig("stabilizer"));
59  // mc_rtc::log::info("Stabilizer Configuration:\n{}", defaultStabilizerConfig_.save().dump(true));
60  }
61 
62  // Patch CoM height and step width in all plans
63  std::vector<std::string> plans = planConfig.keys();
64  double comHeight = defaultStabilizerConfig_.comHeight;
65  for(const auto & p : plans)
66  {
67  auto plan = planConfig(p);
68  if(!plan.has("com_height"))
69  {
70  plan.add("com_height", comHeight);
71  }
72  }
73 
74  double postureStiffness = config("tasks")("posture")("stiffness");
75  double postureWeight = config("tasks")("posture")("weight");
76  postureTask = getPostureTask(robot().name());
77  postureTask->stiffness(postureStiffness);
78  postureTask->weight(postureWeight);
79 
80  // Set half-sitting pose for posture task
81  const auto & halfSit = robotModule->stance();
82  const auto & refJointOrder = robot().refJointOrder();
83  for(unsigned i = 0; i < refJointOrder.size(); ++i)
84  {
85  if(robot().hasJoint(refJointOrder[i]))
86  {
87  halfSitPose[robot().jointIndexByName(refJointOrder[i])] = halfSit.at(refJointOrder[i]);
88  }
89  }
90 
91  // Read sole properties from robot model and configuration file
92  sva::PTransformd X_0_lfc = controlRobot().surfacePose("LeftFootCenter");
93  sva::PTransformd X_0_rfc = controlRobot().surfacePose("RightFootCenter");
94  sva::PTransformd X_0_lf = controlRobot().surfacePose("LeftFoot");
95  sva::PTransformd X_lfc_lf = X_0_lf * X_0_lfc.inv();
96  sva::PTransformd X_rfc_lfc = X_0_lfc * X_0_rfc.inv();
97  double stepWidth = X_rfc_lfc.translation().y();
98  sole_ = robotConfig("sole");
99 
100  // If an ankle offset is specified use it, otherwise compute it
101  if(robotConfig("sole").has("leftAnkleOffset"))
102  {
103  sole_.leftAnkleOffset = robotConfig("sole")("leftAnkleOffset");
104  }
105  else
106  {
107  sole_.leftAnkleOffset = X_lfc_lf.translation().head<2>();
108  }
109 
110  // Configure MPC solver
111  mpcConfig_ = config("mpc");
112  mpc_.sole(sole_);
113 
114  // ====================
115  // Create Stabilizer
116  // - Default configuration from the robot module
117  // - Additional configuration from the configuration, in section robot_models/robot_name/stabilizer
118  // ====================
119  // clang-format off
120  stabilizer_.reset(
121  new mc_tasks::lipm_stabilizer::StabilizerTask(
122  solver().robots(),
123  solver().realRobots(),
124  robot().robotIndex(),
125  defaultStabilizerConfig_.leftFootSurface,
126  defaultStabilizerConfig_.rightFootSurface,
127  defaultStabilizerConfig_.torsoBodyName,
128  solver().dt()));
129  // clang-format on
130  stabilizer_->configure(defaultStabilizerConfig_);
131 
132  // Read footstep plans from configuration
133  planInterpolator.configure(planConfig);
134  planInterpolator.stepWidth(stepWidth);
135  std::string initialPlan = planInterpolator.availablePlans()[0];
136  config("initial_plan", initialPlan);
137  loadFootstepPlan(initialPlan);
138 
139  // =========================
140  // Create Swing foot tasks
141  // =========================
142  double swingWeight = 1000;
143  double swingStiffness = 500;
144  if(robotConfig.has("swingfoot"))
145  {
146  robotConfig("swingfoot")("weight", swingWeight);
147  robotConfig("swingfoot")("stiffness", swingStiffness);
148  }
149  swingFootTaskRight_.reset(new mc_tasks::SurfaceTransformTask("RightFootCenter", robots(), robots().robotIndex(),
150  swingWeight, swingStiffness));
151  swingFootTaskLeft_.reset(new mc_tasks::SurfaceTransformTask("LeftFootCenter", robots(), robots().robotIndex(),
152  swingWeight, swingStiffness));
153 
154  addLogEntries(logger());
155  mpc_.addLogEntries(logger());
156 
157  if(gui_)
158  {
159  addGUIElements(gui_);
160  mpc_.addGUIElements(gui_);
161  }
162 
163  // Update observers
164  datastore().make_call("KinematicAnchorFrame::" + robot().name(),
165  [this](const mc_rbdyn::Robot & robot)
166  {
167  return sva::interpolate(robot.surfacePose("RightFootCenter"),
168  robot.surfacePose("LeftFootCenter"), leftFootRatio_);
169  });
170 
171  mc_rtc::log::success("LIPMWalking controller init done.");
172 }
173 
174 void Controller::addLogEntries(mc_rtc::Logger & logger)
175 {
176  logger.addLogEntry("controlRobot_LeftFoot", [this]() { return controlRobot().surfacePose("LeftFoot"); });
177  logger.addLogEntry("controlRobot_LeftFootCenter", [this]() { return controlRobot().surfacePose("LeftFootCenter"); });
178  logger.addLogEntry("controlRobot_RightFoot", [this]() { return controlRobot().surfacePose("RightFoot"); });
179  logger.addLogEntry("controlRobot_RightFootCenter",
180  [this]() { return controlRobot().surfacePose("RightFootCenter"); });
181  logger.addLogEntry("mpc_failures", [this]() { return nbMPCFailures_; });
182  logger.addLogEntry("left_foot_ratio", [this]() { return leftFootRatio_; });
183  logger.addLogEntry("left_foot_ratio_measured", [this]() { return measuredLeftFootRatio(); });
184  logger.addLogEntry("plan_com_height", [this]() { return plan.comHeight(); });
185  logger.addLogEntry("plan_double_support_duration", [this]() { return plan.doubleSupportDuration(); });
186  logger.addLogEntry("plan_final_dsp_duration", [this]() { return plan.finalDSPDuration(); });
187  logger.addLogEntry("plan_init_dsp_duration", [this]() { return plan.initDSPDuration(); });
188  logger.addLogEntry("plan_landing_duration", [this]() { return plan.landingDuration(); });
189  logger.addLogEntry("plan_landing_pitch", [this]() { return plan.landingPitch(); });
190  logger.addLogEntry("plan_ref_vel", [this]() { return plan.supportContact().refVel; });
191  logger.addLogEntry("plan_single_support_duration", [this]() { return plan.singleSupportDuration(); });
192  logger.addLogEntry("plan_swing_height", [this]() { return plan.swingHeight(); });
193  logger.addLogEntry("plan_takeoff_duration", [this]() { return plan.takeoffDuration(); });
194  logger.addLogEntry("plan_takeoff_offset", [this]() { return plan.takeoffOffset(); });
195  logger.addLogEntry("plan_takeoff_pitch", [this]() { return plan.takeoffPitch(); });
196  logger.addLogEntry("realRobot_LeftFoot", [this]() { return realRobot().surfacePose("LeftFoot"); });
197  logger.addLogEntry("realRobot_LeftFootCenter", [this]() { return realRobot().surfacePose("LeftFootCenter"); });
198  logger.addLogEntry("realRobot_RightFoot", [this]() { return realRobot().surfacePose("RightFoot"); });
199  logger.addLogEntry("realRobot_RightFootCenter", [this]() { return realRobot().surfacePose("RightFootCenter"); });
200  logger.addLogEntry("realRobot_posW", [this]() { return realRobot().posW(); });
201 }
202 
203 void Controller::addGUIElements(std::shared_ptr<mc_rtc::gui::StateBuilder> gui)
204 {
205  using namespace mc_rtc::gui;
206 
207  gui->addElement(
208  {"Markers", "Sole"},
209  mc_rtc::gui::Point3D("Target Ankle Pos", [this]() { return this->targetContact().anklePos(sole_); }),
210  mc_rtc::gui::Point3D("Support Ankle Pos", [this]() { return this->supportContact().anklePos(sole_); }));
211 
212  gui->addElement({"Walking", "Main"},
213  Button("# EMERGENCY STOP",
214  [this]()
215  {
216  mc_rtc::log::error("EMERGENCY STOP!");
217  emergencyStop = true;
218  this->interrupt();
219  }),
220  Button("Reset",
221  [this]()
222  {
223  mc_rtc::log::warning("Reset to Initial state");
224  this->resume("Initial");
225  }));
226 
227  gui->addElement({"Walking", "CoM"}, Label("Plan name", [this]() { return plan.name; }));
228 
229  gui->addElement({"Walking", "Swing"}, Label("Plan name", [this]() { return plan.name; }),
230  NumberInput(
231  "Swing height [m]", [this]() { return plan.swingHeight(); },
232  [this](double height) { plan.swingHeight(height); }),
233  NumberInput(
234  "Takeoff duration [s]", [this]() { return plan.takeoffDuration(); },
235  [this](double duration) { plan.takeoffDuration(duration); }),
236  NumberInput(
237  "Takeoff pitch [rad]", [this]() { return plan.takeoffPitch(); },
238  [this](double pitch) { plan.takeoffPitch(pitch); }),
239  NumberInput(
240  "Landing duration [s]", [this]() { return plan.landingDuration(); },
241  [this](double duration) { plan.landingDuration(duration); }),
242  NumberInput(
243  "Landing pitch [rad]", [this]() { return plan.landingPitch(); },
244  [this](double pitch) { plan.landingPitch(pitch); }));
245 
246  gui->addElement({"Walking", "Timings"}, Label("Plan name", [this]() { return plan.name; }),
247  NumberInput(
248  "Initial DSP duration [s]", [this]() { return plan.initDSPDuration(); },
249  [this](double duration) { plan.initDSPDuration(duration); }),
250  NumberInput(
251  "SSP duration [s]", [this]() { return plan.singleSupportDuration(); },
252  [this](double duration)
253  {
254  constexpr double T = ModelPredictiveControl::SAMPLING_PERIOD;
255  duration = std::round(duration / T) * T;
256  plan.singleSupportDuration(duration);
257  }),
258  NumberInput(
259  "DSP duration [s]", [this]() { return plan.doubleSupportDuration(); },
260  [this](double duration)
261  {
262  constexpr double T = ModelPredictiveControl::SAMPLING_PERIOD;
263  duration = std::round(duration / T) * T;
264  plan.doubleSupportDuration(duration);
265  }),
266  NumberInput(
267  "Final DSP duration [s]", [this]() { return plan.finalDSPDuration(); },
268  [this](double duration) { plan.finalDSPDuration(duration); }));
269  gui->addElement(
270  {"Walking", "Sole"},
271  mc_rtc::gui::Label("Ankle offset",
272  []()
273  {
274  return std::string{
275  "position of ankle w.r.t to left foot center. The corresponding offset for the right "
276  "foot is computed assuming that the feet are symetrical in the lateral direction"};
277  }),
278  mc_rtc::gui::ArrayInput(
279  "Left Ankle Offset", [this]() -> const Eigen::Vector2d & { return sole_.leftAnkleOffset; },
280  [this](const Eigen::Vector2d & offset)
281  {
282  sole_.leftAnkleOffset = offset;
283  mpc_.sole(sole_);
284  }),
285  mc_rtc::gui::ArrayLabel("Right Ankle Offset",
286  [this]() -> Eigen::Vector2d {
287  return {sole_.leftAnkleOffset.x(), -sole_.leftAnkleOffset.y()};
288  }),
289  mc_rtc::gui::ArrayLabel("Sole half width/length",
290  [this]() {
291  return Eigen::Vector2d{sole_.halfWidth, sole_.halfLength};
292  })
293 
294  );
295 }
296 
297 void Controller::reset(const mc_control::ControllerResetData & data)
298 {
299  config()("observerPipelineName", observerPipelineName_);
300  if(!hasObserverPipeline(observerPipelineName_))
301  {
302  mc_rtc::log::error_and_throw<std::runtime_error>("LIPMWalking requires an observer pipeline named \"{}\"",
303  observerPipelineName_);
304  }
305 
306  mc_control::fsm::Controller::reset(data);
307 
308  stabilizer_->reset();
309  setContacts({{ContactState::Left, supportContact().pose}, {ContactState::Right, targetContact().pose}}, true);
310 
311  if(gui_)
312  {
313  gui_->removeCategory({"Contacts"});
314  }
315 }
316 
318  const std::vector<std::pair<mc_tasks::lipm_stabilizer::ContactState, sva::PTransformd>> & contacts,
319  bool fullDoF)
320 {
321  stabilizer()->setContacts(contacts);
322  auto rName = robot().name();
323  auto gName = "ground";
324  auto gSurface = "AllGround";
325  auto friction = stabilizer()->config().friction;
326  removeContact({rName, gName, stabilizer()->footSurface(mc_tasks::lipm_stabilizer::ContactState::Left), gSurface});
327  removeContact({rName, gName, stabilizer()->footSurface(mc_tasks::lipm_stabilizer::ContactState::Right), gSurface});
328  for(const auto & contact : contacts)
329  {
330  const auto & rSurface = stabilizer()->footSurface(contact.first);
331  Eigen::Vector6d dof = Eigen::Vector6d::Ones();
332  if(!fullDoF)
333  {
334  dof(0) = 0;
335  dof(1) = 0;
336  dof(5) = 0;
337  }
338  addContact({rName, gName, rSurface, gSurface, friction, dof});
339  }
340 }
341 
342 void Controller::leftFootRatio(double ratio)
343 {
344  double maxRatioVar = 1.5 * timeStep / plan.doubleSupportDuration();
345  if(std::abs(ratio - leftFootRatio_) > maxRatioVar)
346  {
347  mc_rtc::log::warning("Left foot ratio jumped from {} to {}", leftFootRatio_, ratio);
348  }
349  leftFootRatio_ = clamp(ratio, 0., 1., "leftFootRatio");
350 }
351 
353 {
354  const auto & observerp = observerPipeline(observerPipelineName_);
355  if(!observerp.success())
356  {
357  mc_rtc::log::error("Required pipeline \"{}\" for real robot observation failed to run!", observerPipelineName_);
358  for(const auto & observer : observerp.observers())
359  {
360  if(!observer.success())
361  {
362  mc_rtc::log::error("Observer \"{}\" failed with error \"{}\"", observer.observer().name(),
363  observer.observer().error());
364  }
365  }
366  return false;
367  }
368  if(emergencyStop)
369  {
370  return false;
371  }
373  {
375  }
376  if(!mc_control::fsm::Controller::running())
377  {
378  return mc_control::fsm::Controller::run();
379  }
380 
381  ctlTime_ += timeStep;
382 
384 
385  bool ret = mc_control::fsm::Controller::run();
386  // if(mc_control::fsm::Controller::running())
387  //{
388  // postureTask->posture(halfSitPose); // reset posture in case the FSM updated it
389  //}
390  return ret;
391 }
392 
394 {
395  constexpr double MAX_HEIGHT_DIFF = 0.02; // [m]
396  if(pauseWalking)
397  {
398  mc_rtc::log::warning("Already pausing, how did you get there?");
399  return;
400  }
401  else if(std::abs(supportContact().z() - targetContact().z()) > MAX_HEIGHT_DIFF)
402  {
403  if(!pauseWalkingRequested || verbose)
404  {
405  mc_rtc::log::warning("Cannot pause on uneven ground, will pause later");
406  }
407  gui()->removeElement({"Walking", "Main"}, "Pause walking");
408  pauseWalkingRequested = true;
409  }
410  else if(pauseWalkingRequested)
411  {
412  mc_rtc::log::warning("Pausing now that contacts are at same level");
413  pauseWalkingRequested = false;
414  pauseWalking = true;
415  }
416  else // (!pauseWalkingRequested)
417  {
418  gui()->removeElement({"Walking", "Main"}, "Pause walking");
419  pauseWalking = true;
420  }
421 }
422 
424 {
425  static bool isInTheAir = false;
426  constexpr double CONTACT_THRESHOLD = 30.; // [N]
427  double leftFootForce = realRobot().forceSensor("LeftFootForceSensor").force().z();
428  double rightFootForce = realRobot().forceSensor("RightFootForceSensor").force().z();
429  if(leftFootForce < CONTACT_THRESHOLD && rightFootForce < CONTACT_THRESHOLD)
430  {
431  if(!isInTheAir)
432  {
433  mc_rtc::log::warning("Robot is in the air");
434  isInTheAir = true;
435  }
436  }
437  else
438  {
439  if(isInTheAir)
440  {
441  mc_rtc::log::info("Robot is on the ground again");
442  isInTheAir = false;
443  }
444  }
445 }
446 
447 void Controller::loadFootstepPlan(std::string name)
448 {
449  bool loadingNewPlan = (plan.name != name);
450  double initHeight = (plan.name.length() > 0) ? plan.supportContact().p().z() : 0.;
451  FootstepPlan defaultPlan = planInterpolator.getPlan(name);
452  if(loadingNewPlan)
453  {
454  plan.removeGUIElements(*gui());
455  plan = defaultPlan;
456  plan.name = name;
457  mpc_.configure(mpcConfig_);
458  if(!plan.mpcConfig.empty())
459  {
460  mpc_.configure(plan.mpcConfig);
461  }
462  }
463  else if(plan.name != "external") // only reload contacts
464  {
465  plan.resetContacts(defaultPlan.contacts());
466  }
467  plan.complete(sole_);
468  const sva::PTransformd & X_0_lf = controlRobot().surfacePose("LeftFootCenter");
469  const sva::PTransformd & X_0_rf = controlRobot().surfacePose("RightFootCenter");
470  plan.updateInitialTransform(X_0_lf, X_0_rf, initHeight);
472  planInterpolator.updateSupportPath(X_0_lf, X_0_rf);
473  plan.rewind();
474 
475  double torsoPitch = plan.hasTorsoPitch() ? plan.torsoPitch() : defaultStabilizerConfig_.torsoPitch;
476  stabilizer_->torsoPitch(torsoPitch);
477 
478  if(loadingNewPlan)
479  {
480  plan.addGUIElements(*gui());
481  mc_rtc::log::info("Loaded footstep plan \"{}\"", name);
482  }
483 }
484 
485 void Controller::updatePlan(const std::string & name)
486 {
487  if(name == "external")
488  {
491  loadFootstepPlan(name);
492  return;
493  }
494  if(plan.name == "external")
495  {
497  }
498 
500  if(name.find("custom") != std::string::npos)
501  {
503  if(name.find("backward") != std::string::npos)
504  {
506  }
507  else if(name.find("forward") != std::string::npos)
508  {
510  }
511  else if(name.find("lateral") != std::string::npos)
512  {
514  }
516  }
517  else // new plan is not custom
518  {
519  loadFootstepPlan(name);
520  }
521 }
522 
523 void Controller::startLogSegment(const std::string & label)
524 {
525  if(segmentName_.length() > 0)
526  {
527  stopLogSegment();
528  }
529  segmentName_ = "t_" + std::to_string(++nbLogSegments_).erase(0, 1) + "_" + label;
530  logger().addLogEntry(segmentName_, [this]() { return ctlTime_; });
531 }
532 
534 {
535  logger().removeLogEntry(segmentName_);
536  segmentName_ = "";
537 }
538 
540 {
541  mpc_.initState(pendulum());
542  mpc_.comHeight(plan.comHeight());
543  if(mpc_.buildAndSolve())
544  {
545  preview = mpc_.solution();
546  return true;
547  }
548  else
549  {
550  nbMPCFailures_++;
551  return false;
552  }
553 }
554 
556 {
557  return gui()->hasElement({"Ticker"}, "Stop") && !datastore().has("Log::Replay");
558 }
559 
560 } // namespace lipm_walking
mc_rtc::gui::Color Color
Definition: Controller.cpp:34
double clamp(double v, double vMin, double vMax)
Definition: clamp.h:47
Eigen::Vector3d refVel
Definition: Contact.h:307
sva::PTransformd pose
Definition: Contact.h:314
Eigen::Vector3d anklePos(const Sole &sole) const
Definition: Contact.h:114
const Eigen::Vector3d & p() const
Definition: Contact.h:104
mc_rbdyn::Robot & controlRobot()
Definition: Controller.h:159
double measuredLeftFootRatio()
Definition: Controller.h:209
const Contact & targetContact()
Definition: Controller.h:299
virtual bool run() override
Definition: Controller.cpp:352
EIGEN_MAKE_ALIGNED_OPERATOR_NEW Controller(mc_rbdyn::RobotModulePtr robot, double dt, const mc_rtc::Configuration &config, mc_control::ControllerParameters params={})
Definition: Controller.cpp:39
std::shared_ptr< mc_tasks::lipm_stabilizer::StabilizerTask > stabilizer()
Definition: Controller.h:279
void updatePlan(const std::string &name)
Definition: Controller.cpp:485
const Contact & supportContact()
Definition: Controller.h:291
std::vector< std::vector< double > > halfSitPose
Definition: Controller.h:319
void loadFootstepPlan(std::string name)
Definition: Controller.cpp:447
void addGUIElements(std::shared_ptr< mc_rtc::gui::StateBuilder > gui)
Definition: Controller.cpp:203
bool isInOpenLoopTicker() const
Definition: Controller.cpp:555
std::shared_ptr< mc_tasks::SurfaceTransformTask > swingFootTaskLeft_
Definition: Controller.h:321
std::shared_ptr< Preview > preview
Definition: Controller.h:317
void pauseWalkingCallback(bool verbose=false)
Definition: Controller.cpp:393
void setContacts(const std::vector< std::pair< mc_tasks::lipm_stabilizer::ContactState, sva::PTransformd >> &contacts, bool fullDoF=false)
Definition: Controller.cpp:317
void addLogEntries(mc_rtc::Logger &logger)
Definition: Controller.cpp:174
mc_planning::Pendulum & pendulum()
Definition: Controller.h:247
void startLogSegment(const std::string &label)
Definition: Controller.cpp:523
void reset(const mc_control::ControllerResetData &data) override
Definition: Controller.cpp:297
PlanInterpolator planInterpolator
Definition: Controller.h:310
std::shared_ptr< mc_tasks::SurfaceTransformTask > swingFootTaskRight_
Definition: Controller.h:322
ExternalPlanner externalFootstepPlanner
Handle requesting/receiving plans from an external planner.
Definition: Controller.h:312
void configure(const mc_rtc::Configuration &config)
External planning configuration.
double landingDuration() const
Definition: FootstepPlan.h:224
double landingPitch() const
Definition: FootstepPlan.h:246
double takeoffPitch() const
Definition: FootstepPlan.h:390
mc_rtc::Configuration mpcConfig
Definition: FootstepPlan.h:452
double doubleSupportDuration() const
Definition: FootstepPlan.h:154
void addGUIElements(mc_rtc::gui::StateBuilder &gui)
Display the footstep plan in the GUI.
void updateInitialTransform(const sva::PTransformd &X_0_lf, const sva::PTransformd &X_0_rf, double initHeight)
EIGEN_MAKE_ALIGNED_OPERATOR_NEW void complete(const Sole &sole)
double singleSupportDuration() const
Definition: FootstepPlan.h:294
double swingHeight() const
Definition: FootstepPlan.h:326
const sva::PTransformd & initPose()
Definition: FootstepPlan.h:216
const std::vector< Contact > & contacts() const
Definition: FootstepPlan.h:146
double takeoffDuration() const
Definition: FootstepPlan.h:348
void resetContacts(const std::vector< Contact > &contacts)
Definition: FootstepPlan.h:286
Eigen::Vector3d takeoffOffset() const
Definition: FootstepPlan.h:370
double initDSPDuration() const
Definition: FootstepPlan.h:198
double finalDSPDuration() const
Definition: FootstepPlan.h:172
const Contact & supportContact() const
Definition: FootstepPlan.h:310
void removeGUIElements(mc_rtc::gui::StateBuilder &gui)
Remove the footstep plan from the GUI.
void addLogEntries(mc_rtc::Logger &logger)
void addGUIElements(std::shared_ptr< mc_rtc::gui::StateBuilder > gui)
const std::shared_ptr< Preview > solution() const
void initState(const mc_planning::Pendulum &pendulum)
static constexpr EIGEN_MAKE_ALIGNED_OPERATOR_NEW double SAMPLING_PERIOD
void configure(const mc_rtc::Configuration &)
void configure(const mc_rtc::Configuration &config)
const sva::PTransformd & worldReference() const
FootstepPlan getPlan(std::string name)
std::vector< std::string > availablePlans() const
void updateSupportPath(const sva::PTransformd &X_0_lf, const sva::PTransformd &X_0_rf)
const std::string & customPlanName() const
EIGEN_MAKE_ALIGNED_OPERATOR_NEW Eigen::Vector2d leftAnkleOffset
Definition: Sole.h:42