ExternalPlanner.cpp
Go to the documentation of this file.
1 #include <mc_control/MCController.h>
2 #include <mc_rtc/gui.h>
3 
4 #include <boost/optional.hpp>
5 
6 #include <ExternalFootstepPlanner/Plan.h>
8 
9 namespace lipm_walking
10 {
11 
12 using SE2d = utils::SE2d;
13 
14 ExternalPlanner::ExternalPlanner(mc_control::MCController & ctl) : ctl_(ctl) {}
15 
16 void ExternalPlanner::configure(const mc_rtc::Configuration & config)
17 {
18  auto planningConf = config("allowed_planning_time");
19  planningConf("single_support", allowedTimeSingleSupport_);
20  planningConf("standing", allowedTimeStanding_);
21 
22  if(config.has("leftFootLandingOffset"))
23  {
24  Eigen::Vector3d offset = config("leftFootLandingOffset");
25  leftFootLandingOffset_ = utils::SE2d{offset.x(), offset.y(), offset.z()};
26  }
27  if(config.has("rightFootLandingOffset"))
28  {
29  Eigen::Vector3d offset = config("rightFootLandingOffset");
30  rightFootLandingOffset_ = utils::SE2d{offset.x(), offset.y(), offset.z()};
31  }
32 }
33 
35  const Foot supportFoot,
36  const utils::SE2d & start_lf,
37  const utils::SE2d & start_rf,
38  double allowed_time)
39 {
40  bool worldTargetChanged = ctl_.datastore().call<bool>("ExternalFootstepPlanner::WorldPositionTargetChanged");
41  bool localVelocityTargetChanged = ctl_.datastore().call<bool>("ExternalFootstepPlanner::LocalPositionTargetChanged");
42  if(worldTargetChanged && localVelocityTargetChanged)
43  {
44  mc_rtc::log::warning(
45  "[ExternalPlanner] Both target position (world) and velocity target (world) changed, using target position");
46  return;
47  }
48  if(worldTargetChanged)
49  { // world position target
50  const auto & target = ctl_.datastore().call<const mc_plugin::ExternalFootstepPlanner::SE2d &>(
51  "ExternalFootstepPlanner::WorldPositionTarget");
52  const auto goal = utils::SE2d{target.x, target.y, target.theta};
53  requestPlanWorldPositionTarget(state, supportFoot, start_lf, start_rf, goal, allowed_time);
54  }
55  else
56  { // local target
57  const auto & local = ctl_.datastore().call<const mc_plugin::ExternalFootstepPlanner::SE2d &>(
58  "ExternalFootstepPlanner::LocalPositionTarget");
59  const auto local_goal = utils::SE2d{local.x, local.y, local.theta};
60  requestPlanLocalPositionTarget(state, supportFoot, start_lf, start_rf, local_goal, allowed_time);
61  }
62 }
63 
65  const Foot supportFoot,
66  const utils::SE2d & start_lf,
67  const utils::SE2d & start_rf,
68  const utils::SE2d & targetWorld,
69  double allowed_time)
70 {
71  Request request;
72  request.start_left_foot = {start_lf.x, start_lf.y, start_lf.theta};
73  request.start_right_foot = {start_rf.x, start_rf.y, start_rf.theta};
74 
75  // Compute goal with nominal foot standing width
76  auto lfGoal = utils::SE2d(leftFootLandingOffset_.asPTransform() * targetWorld.asPTransform());
77  auto rfGoal = utils::SE2d(rightFootLandingOffset_.asPTransform() * targetWorld.asPTransform());
78 
79  request.goal_left_foot = {lfGoal.x, lfGoal.y, lfGoal.theta};
80  request.goal_right_foot = {rfGoal.x, rfGoal.y, rfGoal.theta};
81  request.support_foot = supportFoot;
82  request.allowed_time = allowed_time;
83 
84  ctl_.datastore().call<void>("ExternalFootstepPlanner::RequestPlan", static_cast<const Request &>(request));
85  state_ = state;
86  requested_ = true;
87 }
88 
90  const Foot supportFoot,
91  const utils::SE2d & start_lf,
92  const utils::SE2d & start_rf,
93  const utils::SE2d & local_velocity,
94  double allowed_time)
95 {
96  // Convert local velocity to global target
97  // What should the choice of local frame be here?
98  // For now we assume the support foot as the reference local frame
99  auto worldSupportFrame = SE2d{sva::interpolate(start_lf.asPTransform(), start_rf.asPTransform(), 0.5)};
100  auto goal = utils::SE2d(local_velocity.asPTransform() * worldSupportFrame.asPTransform());
101  requestPlanWorldPositionTarget(state, supportFoot, start_lf, start_rf, goal, allowed_time);
102 }
103 
104 std::vector<lipm_walking::Contact> ExternalPlanner::plan()
105 {
106  auto convertPlan = [](const mc_plugin::ExternalFootstepPlanner::Plan & ext_plan)
107  {
108  std::vector<lipm_walking::Contact> contacts;
109  unsigned i = 0;
110  for(const auto & ext_contact : ext_plan.contacts)
111  {
112  auto contact = lipm_walking::Contact{};
113  // contact.
114  // plan.contacts.push_back()
115  contact.surfaceName = (ext_contact.foot == Foot::Right ? "RightFootCenter" : "LeftFootCenter");
116  utils::SE2d pose2D = {ext_contact.pose.x, ext_contact.pose.y, ext_contact.pose.theta};
117  contact.pose = pose2D.asPTransform();
118  contact.id = i++;
119  contacts.push_back(contact);
120  }
121  return contacts;
122  };
123 
124  requested_ = false;
125  auto plan = ctl_.datastore().call<mc_plugin::ExternalFootstepPlanner::Plan>("ExternalFootstepPlanner::PopPlan");
126  return convertPlan(plan);
127 }
128 
129 } // namespace lipm_walking
utils::SE2d SE2d
std::string surfaceName
Definition: Contact.h:313
void requestPlanLocalPositionTarget(const State state, const Foot supportFoot, const utils::SE2d &start_lf, const utils::SE2d &start_rf, const utils::SE2d &localTarget, double allowed_time)
Request a plan in local frame.
void requestPlan(const State state, const Foot supportFoot, const utils::SE2d &start_lf, const utils::SE2d &start_rf, double allowed_time)
Request a plan to the plugin.
ExternalPlanner(mc_control::MCController &ctl)
mc_plugin::ExternalFootstepPlanner::Request Request
void configure(const mc_rtc::Configuration &config)
External planning configuration.
mc_control::MCController & ctl_
void requestPlanWorldPositionTarget(const State state, const Foot supportFoot, const utils::SE2d &start_lf, const utils::SE2d &start_rf, const utils::SE2d &targetWorld, double allowed_time)
Request a plan with a target expressed in world frame.
mc_plugin::ExternalFootstepPlanner::Foot Foot
std::vector< lipm_walking::Contact > plan()
Convert plugin's plan to lipm_walking plan format.
SE2d leftFootLandingOffset_
Landing offset of the feet w.r.t target frame, expressed in target frame.
sva::PTransformd asPTransform() const
Definition: SE2d.h:89