FootstepPlannerEnvironment.cpp
Go to the documentation of this file.
1 /*
2  * A footstep planner for humanoid robots
3  *
4  * Copyright 2010-2011 Johannes Garimort, Armin Hornung, University of Freiburg
5  * http://www.ros.org/wiki/footstep_planner
6  *
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, version 3.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
22 
23 
24 namespace footstep_planner
25 {
27  const environment_params& params)
28 : DiscreteSpaceInformation(),
29  ivIdPlanningGoal(-1),
30  ivIdStartFootLeft(-1),
31  ivIdStartFootRight(-1),
32  ivIdGoalFootLeft(-1),
33  ivIdGoalFootRight(-1),
34  ivpStateHash2State(
35  new std::vector<const PlanningState*>[params.hash_table_size]),
36  ivFootstepSet(params.footstep_set),
37  ivHeuristicConstPtr(params.heuristic),
38  ivFootsizeX(params.footsize_x),
39  ivFootsizeY(params.footsize_y),
40  ivOriginFootShiftX(params.foot_origin_shift_x),
41  ivOriginFootShiftY(params.foot_origin_shift_y),
42  ivMaxFootstepX(disc_val(params.max_footstep_x, params.cell_size)),
43  ivMaxFootstepY(disc_val(params.max_footstep_y, params.cell_size)),
44  ivMaxFootstepTheta(
45  angle_state_2_cell(params.max_footstep_theta, params.num_angle_bins)),
46  ivMaxInvFootstepX(disc_val(params.max_inverse_footstep_x, params.cell_size)),
47  ivMaxInvFootstepY(disc_val(params.max_inverse_footstep_y, params.cell_size)),
48  ivMaxInvFootstepTheta(
49  angle_state_2_cell(params.max_inverse_footstep_theta,
50  params.num_angle_bins)),
51  ivStepCost(cvMmScale * params.step_cost),
52  ivCollisionCheckAccuracy(params.collision_check_accuracy),
53  ivHashTableSize(params.hash_table_size),
54  ivCellSize(params.cell_size),
55  ivNumAngleBins(params.num_angle_bins),
56  ivForwardSearch(params.forward_search),
57  ivMaxStepWidth(double(disc_val(params.max_step_width, params.cell_size))),
58  ivNumRandomNodes(params.num_random_nodes),
59  ivRandomNodeDist(params.random_node_distance / ivCellSize),
60  ivHeuristicScale(params.heuristic_scale),
61  ivHeuristicExpired(true),
62  ivNumExpandedStates(0)
63 {
64  int num_angle_bins_half = ivNumAngleBins / 2;
65  if (ivMaxFootstepTheta >= num_angle_bins_half)
67  if (ivMaxInvFootstepTheta >= num_angle_bins_half)
69 
70  int num_x = ivMaxFootstepX - ivMaxInvFootstepX + 1;
71  ivpStepRange = new bool[num_x * (ivMaxFootstepY - ivMaxInvFootstepY + 1)];
72 
73  // determine whether a (x,y) translation can be performed by the robot by
74  // checking if it is within a certain area of performable steps
75  for (int j = ivMaxInvFootstepY; j <= ivMaxFootstepY; ++j)
76  {
77  for (int i = ivMaxInvFootstepX; i <= ivMaxFootstepX; ++i)
78  {
79  ivpStepRange[(j - ivMaxInvFootstepY) * num_x + (i - ivMaxInvFootstepX)] =
80  pointWithinPolygon(i, j, params.step_range);
81  }
82  }
83 }
84 
85 
87 {
88  reset();
90  {
91  delete[] ivpStateHash2State;
92  ivpStateHash2State = NULL;
93  }
94  if (ivpStepRange)
95  {
96  delete[] ivpStepRange;
97  ivpStepRange = NULL;
98  }
99 }
100 
101 
102 std::pair<int, int>
104  const State& foot_right)
105 {
106  // keep the old IDs
107  int goal_foot_id_left = ivIdGoalFootLeft;
108  int goal_foot_id_right = ivIdGoalFootRight;
109 
110  // update the states for both feet (if necessary)
111  const PlanningState* p_foot_left = getHashEntry(foot_left);
112  if (p_foot_left == NULL)
113  p_foot_left = createNewHashEntry(foot_left);
114  const PlanningState* p_foot_right = getHashEntry(foot_right);
115  if (p_foot_right == NULL)
116  p_foot_right = createNewHashEntry(foot_right);
117  ivIdGoalFootLeft = p_foot_left->getId();
118  ivIdGoalFootRight = p_foot_right->getId();
119  // check if everything has been set correctly
120  assert(ivIdGoalFootLeft != -1);
121  assert(ivIdGoalFootRight != -1);
122 
123  // if using the forward search a change of the goal states involves an
124  // update of the heuristic
125  if (ivForwardSearch)
126  {
127  // check if the goal states have been changed
128  if (goal_foot_id_left != ivIdGoalFootLeft &&
129  goal_foot_id_right != ivIdGoalFootRight)
130  {
131  ivHeuristicExpired = true;
132  setStateArea(*p_foot_left, *p_foot_right);
133  }
134  }
135 
136  return std::pair<int, int>(ivIdGoalFootLeft, ivIdGoalFootRight);
137 }
138 
139 
140 std::pair<int, int>
142  const State& foot_right)
143 {
144  // keep the old IDs
145  int start_foot_id_left = ivIdStartFootLeft;
146  int start_foot_id_right = ivIdStartFootRight;
147 
148  // update the states for both feet (if necessary)
149  const PlanningState* p_foot_left = getHashEntry(foot_left);
150  if (p_foot_left == NULL)
151  p_foot_left = createNewHashEntry(foot_left);
152  const PlanningState* p_foot_right = getHashEntry(foot_right);
153  if (p_foot_right == NULL)
154  p_foot_right = createNewHashEntry(foot_right);
155  ivIdStartFootLeft = p_foot_left->getId();
156  ivIdStartFootRight = p_foot_right->getId();
157  // check if everything has been set correctly
158  assert(ivIdStartFootLeft != -1);
159  assert(ivIdStartFootRight != -1);
160 
161  // if using the backward search a change of the start states involves an
162  // update of the heuristic
163  if (!ivForwardSearch)
164  {
165  // check if the start states have been changed
166  if (start_foot_id_left != ivIdStartFootLeft ||
167  start_foot_id_right != ivIdStartFootRight)
168  {
169  ivHeuristicExpired = true;
170  setStateArea(*p_foot_left, *p_foot_right);
171  }
172  }
173 
174  return std::pair<int, int>(ivIdStartFootLeft, ivIdStartFootRight);
175 }
176 
177 
178 const PlanningState*
180 {
182  return createNewHashEntry(tmp);
183 }
184 
185 
186 const PlanningState*
188 {
189  unsigned int state_hash = s.getHashTag();
190  PlanningState* new_state = new PlanningState(s);
191 
192  size_t state_id = ivStateId2State.size();
193  assert(state_id < (size_t)std::numeric_limits<int>::max());
194 
195  // insert the ID of the new state into the corresponding map
196  new_state->setId(state_id);
197  ivStateId2State.push_back(new_state);
198 
199  // insert the new state into the hash map at the corresponding position
200  ivpStateHash2State[state_hash].push_back(new_state);
201 
202  int* entry = new int[NUMOFINDICES_STATEID2IND];
203  StateID2IndexMapping.push_back(entry);
204  for(int i = 0; i < NUMOFINDICES_STATEID2IND; ++i)
205  {
206  StateID2IndexMapping[state_id][i] = -1;
207  }
208 
209  assert(StateID2IndexMapping.size() - 1 == state_id);
210 
211  return new_state;
212 }
213 
214 
215 const PlanningState*
217 {
219  return getHashEntry(tmp);
220 }
221 
222 
223 const PlanningState*
225 {
226  unsigned int state_hash = s.getHashTag();
227  std::vector<const PlanningState*>::const_iterator state_iter;
228  for (state_iter = ivpStateHash2State[state_hash].begin();
229  state_iter != ivpStateHash2State[state_hash].end();
230  ++state_iter)
231  {
232  if (*(*state_iter) == s)
233  return *state_iter;
234  }
235 
236  return NULL;
237 }
238 
239 const PlanningState*
241  const PlanningState& s)
242 {
243  const PlanningState* hash_entry = getHashEntry(s);
244  if (hash_entry == NULL)
245  hash_entry = createNewHashEntry(s);
246 
247  return hash_entry;
248 
249 }
250 
251 
252 int
254  const PlanningState& b)
255 {
256  if (a == b)
257  return 0;
258 
259  // NOTE: instead of using cont_val() the calculation is done directly
260  // here because cont_val() truncates the input length to int
261  double dist = euclidean_distance(
262  a.getX(), a.getY(), b.getX(), b.getY()) * ivCellSize;
263 
264  return int(cvMmScale * dist) + ivStepCost;
265 }
266 
267 
268 bool
270 {
272  ivHashTableSize));
273 }
274 
275 
276 bool
278 {
279  double x = cell_2_state(s.getX(), ivCellSize);
280  double y = cell_2_state(s.getY(), ivCellSize);
281  // collision check for the planning state
282  if (ivMapPtr->isOccupiedAt(x,y))
283  return true;
285  double theta_cos = cos(theta);
286  double theta_sin = sin(theta);
287 
288  // transform the planning state to the foot center
289  x += theta_cos*ivOriginFootShiftX - theta_sin*ivOriginFootShiftY;
290  if (s.getLeg() == LEFT)
291  y += theta_sin*ivOriginFootShiftX + theta_cos*ivOriginFootShiftY;
292  else // leg == RLEG
293  y += theta_sin*ivOriginFootShiftX - theta_cos*ivOriginFootShiftY;
294 
295  // collision check for the foot center
296  return collision_check(x, y, theta, ivFootsizeX, ivFootsizeY,
298 }
299 
300 
301 bool
303 {
304  if (id >= ivStateId2State.size())
305  return false;
306 
307  const PlanningState* planning_state = ivStateId2State[id];
308  s->setX(cell_2_state(planning_state->getX(), ivCellSize));
309  s->setY(cell_2_state(planning_state->getY(), ivCellSize));
311  planning_state->getTheta(), ivNumAngleBins)));
312  s->setLeg(planning_state->getLeg());
313 
314  return true;
315 }
316 
317 
318 void
320 {
321  ivMapPtr.reset();
322  ivMapPtr = map;
323 
324  if (ivHeuristicConstPtr->getHeuristicType() == Heuristic::PATH_COST)
325  {
327  boost::dynamic_pointer_cast<PathCostHeuristic>(
329  h->updateMap(map);
330 
331  ivHeuristicExpired = true;
332  }
333 }
334 
335 
336 void
338 {
339  // check if start and goal have been set
340  assert(ivIdGoalFootLeft != -1 && ivIdGoalFootRight != -1);
341  assert(ivIdStartFootLeft != -1 && ivIdStartFootRight != -1);
342 
343  if (!ivHeuristicExpired)
344  return;
345 
346  ROS_INFO("Updating the heuristic values.");
347 
348  if (ivHeuristicConstPtr->getHeuristicType() == Heuristic::PATH_COST)
349  {
351  boost::dynamic_pointer_cast<PathCostHeuristic>(
353  MDPConfig MDPCfg;
354  InitializeMDPCfg(&MDPCfg);
355  const PlanningState* start = ivStateId2State[MDPCfg.startstateid];
356  const PlanningState* goal = ivStateId2State[MDPCfg.goalstateid];
357 
358  // NOTE: start/goal state are set to left leg
359  bool success;
360  if (ivForwardSearch)
361  success = h->calculateDistances(*start, *goal);
362  else
363  success = h->calculateDistances(*goal, *start);
364  if (!success)
365  {
366  ROS_ERROR("Failed to calculate path cost heuristic.");
367  exit(1);
368  }
369  }
370 
371  ROS_DEBUG("Finished updating the heuristic values.");
372  ivHeuristicExpired = false;
373 }
374 
375 
376 void
378 {
379  for(unsigned int i = 0; i < ivStateId2State.size(); ++i)
380  {
381  if (ivStateId2State[i])
382  {
383  delete ivStateId2State[i];
384  }
385  }
386  ivStateId2State.clear();
387 
388  if (ivpStateHash2State)
389  {
390  for(int i = 0; i < ivHashTableSize; ++i)
391  ivpStateHash2State[i].clear();
392  }
393 
394  StateID2IndexMapping.clear();
395 
396  ivExpandedStates.clear();
398  ivRandomStates.clear();
399 
400  ivIdPlanningGoal = -1;
401 
402  ivIdGoalFootLeft = -1;
403  ivIdGoalFootRight = -1;
404  ivIdStartFootLeft = -1;
405  ivIdStartFootRight = -1;
406 
407  ivHeuristicExpired = true;
408 }
409 
410 
411 bool
413 {
414  // NOTE: "goal check" for backward planning
415  const PlanningState* start;
416  if (from.getLeg() == RIGHT)
418  else
420 
421  return reachable(*start, from);
422 }
423 
424 
425 bool
427 {
428  // NOTE: "goal check" for forward planning
429  const PlanningState* goal;
430  if (from.getLeg() == RIGHT)
432  else
434 
435  // TODO: check step if reachable == True
436  return reachable(from, *goal);
437 }
438 
439 
440 bool
442  const PlanningState& to)
443 {
444  if (euclidean_distance(from.getX(), from.getY(), to.getX(), to.getY()) >
446  {
447  return false;
448  }
449 
451  tf::Pose(
455  cell_2_state(from.getY(), ivCellSize),
456  0.0)).inverse() *
457  tf::Pose(
462  0.0));
463  int footstep_x = disc_val(step.getOrigin().x(), ivCellSize);
464  int footstep_y = disc_val(step.getOrigin().y(), ivCellSize);
465 
466  // calculate the footstep rotation
467  int footstep_theta = to.getTheta() - from.getTheta();
468  // transform the value into [-ivNumAngleBins/2..ivNumAngleBins/2)
469  int num_angle_bins_half = ivNumAngleBins / 2;
470  if (footstep_theta >= num_angle_bins_half)
471  footstep_theta -= ivNumAngleBins;
472  else if (footstep_theta < -num_angle_bins_half)
473  footstep_theta += ivNumAngleBins;
474 
475  // adjust for the left foot
476  if (from.getLeg() == LEFT)
477  {
478  footstep_y = -footstep_y;
479  footstep_theta = -footstep_theta;
480  }
481 
482  // check if footstep_x is not within the executable range
483  if (footstep_x > ivMaxFootstepX || footstep_x < ivMaxInvFootstepX)
484  return false;
485  // check if footstep_y is not within the executable range
486  if (footstep_y > ivMaxFootstepY || footstep_y < ivMaxInvFootstepY)
487  return false;
488  // check if footstep_theta is not within the executable range
489  if (footstep_theta > ivMaxFootstepTheta ||
490  footstep_theta < ivMaxInvFootstepTheta)
491  return false;
492  return ivpStepRange[(footstep_y - ivMaxInvFootstepY) *
494  (footstep_x - ivMaxInvFootstepX)];
495 
496 // // get the (continuous) orientation of state 'from'
497 // double orient = -(angle_cell_2_state(from.getTheta(), ivNumAngleBins));
498 // double orient_cos = cos(orient);
499 // double orient_sin = sin(orient);
500 //
501 // // calculate the footstep shift and rotate it into the 'from'-view
502 // int footstep_x = to.getX() - from.getX();
503 // int footstep_y = to.getY() - from.getY();
504 // double shift_x = footstep_x * orient_cos - footstep_y * orient_sin;
505 // double shift_y = footstep_x * orient_sin + footstep_y * orient_cos;
506 // footstep_x = round(shift_x);
507 // footstep_y = round(shift_y);
508 //
509 // // calculate the footstep rotation
510 // int footstep_theta = to.getTheta() - from.getTheta();
511 //
512 // // transform the value into [-ivNumAngleBins/2..ivNumAngleBins/2)
513 // int num_angle_bins_half = ivNumAngleBins / 2;
514 // if (footstep_theta >= num_angle_bins_half)
515 // footstep_theta -= ivNumAngleBins;
516 // else if (footstep_theta < -num_angle_bins_half)
517 // footstep_theta += ivNumAngleBins;
518 //
519 // // adjust for the left foot
520 // if (from.getLeg() == LEFT)
521 // {
522 // footstep_y = -footstep_y;
523 // footstep_theta = -footstep_theta;
524 // }
525 //
526 // return (footstep_x <= ivMaxFootstepX &&
527 // footstep_x >= ivMaxInvFootstepX &&
528 // footstep_y <= ivMaxFootstepY &&
529 // footstep_y >= ivMaxInvFootstepY &&
530 // footstep_theta <= ivMaxFootstepTheta &&
531 // footstep_theta >= ivMaxInvFootstepTheta);
532 }
533 
534 
535 void
537  const std::vector<State>& changed_states,
538  std::vector<int>* pred_ids)
539 {
540  pred_ids->clear();
541 
542  std::vector<State>::const_iterator state_iter;
543  for (state_iter = changed_states.begin();
544  state_iter != changed_states.end();
545  ++state_iter)
546  {
549  // generate predecessor planning states
550  std::vector<Footstep>::const_iterator footstep_set_iter;
551  for(footstep_set_iter = ivFootstepSet.begin();
552  footstep_set_iter != ivFootstepSet.end();
553  ++footstep_set_iter)
554  {
555  PlanningState pred = footstep_set_iter->reverseMeOnThisState(s);
556  // check if predecessor exists
557  const PlanningState* pred_hash_entry = getHashEntry(pred);
558  if (pred_hash_entry == NULL)
559  continue;
560  pred_ids->push_back(pred_hash_entry->getId());
561  }
562  }
563 }
564 
565 
566 void
568  const std::vector<State>& changed_states,
569  std::vector<int>* succ_ids)
570 {
571  succ_ids->clear();
572 
573  std::vector<State>::const_iterator state_iter;
574  for (state_iter = changed_states.begin();
575  state_iter != changed_states.end();
576  ++state_iter)
577  {
580  // generate successors
581  std::vector<Footstep>::const_iterator footstep_set_iter;
582  for(footstep_set_iter = ivFootstepSet.begin();
583  footstep_set_iter != ivFootstepSet.end();
584  ++footstep_set_iter)
585  {
586  PlanningState succ = footstep_set_iter->performMeOnThisState(s);
587  // check if successor exists
588  const PlanningState* succ_hash_entry = getHashEntry(succ);
589  if (succ_hash_entry == NULL)
590  continue;
591  succ_ids->push_back(succ_hash_entry->getId());
592  }
593  }
594 }
595 
596 
597 int
599  int ToStateID)
600 {
601  assert(FromStateID >= 0 && (unsigned int) FromStateID < ivStateId2State.size());
602  assert(ToStateID >= 0 && (unsigned int) ToStateID < ivStateId2State.size());
603 
604  if ((FromStateID == ivIdGoalFootLeft && ToStateID == ivIdGoalFootRight)
605  || (FromStateID == ivIdGoalFootRight && ToStateID == ivIdGoalFootLeft)){
606  return 0;
607  }
608 
609  const PlanningState* from = ivStateId2State[FromStateID];
610  const PlanningState* to = ivStateId2State[ToStateID];
611  // if (ivHeuristicConstPtr->getHeuristicType() == Heuristic::PATH_COST){
612  // boost::shared_ptr<PathCostHeuristic> pathCostHeuristic = boost::dynamic_pointer_cast<PathCostHeuristic>(ivHeuristicConstPtr);
613  // pathCostHeuristic->calculateDistances(*from, *to);
614  // }
615  return GetFromToHeuristic(*from, *to);
616 }
617 
618 int
620  const PlanningState& to)
621 {
622  return cvMmScale * ivHeuristicScale *
623  ivHeuristicConstPtr->getHValue(from, to);
624 }
625 
626 
627 int
629 {
630  return GetFromToHeuristic(stateID, ivIdGoalFootLeft);
631 }
632 
633 
634 void
636  std::vector<int> *PredIDV,
637  std::vector<int> *CostV)
638 {
639  PredIDV->clear();
640  CostV->clear();
641 
642  assert(TargetStateID >= 0 &&
643  (unsigned int) TargetStateID < ivStateId2State.size());
644 
645  // make goal state absorbing (only left!)
646  if (TargetStateID == ivIdStartFootLeft)
647  return;
648  // add cheap transition from right to left, so right becomes an equivalent
649  // goal
650  if (TargetStateID == ivIdStartFootRight)
651  {
652  PredIDV->push_back(ivIdStartFootLeft);
653  CostV->push_back(0.0);
654  return;
655  }
656 
657  const PlanningState* current = ivStateId2State[TargetStateID];
658 
659  // make sure goal state transitions are consistent with
660  // GetSuccs(some_state, goal_state) where goal_state is reachable by an
661  // arbitrary step from some_state
662  if (ivForwardSearch)
663  {
664  if (TargetStateID == ivIdGoalFootLeft || TargetStateID == ivIdGoalFootRight)
665  {
666  const PlanningState* s;
667  int cost;
668  std::vector<int>::const_iterator state_id_iter;
669  for(state_id_iter = ivStateArea.begin();
670  state_id_iter != ivStateArea.end();
671  ++state_id_iter)
672  {
673  s = ivStateId2State[*state_id_iter];
674  cost = stepCost(*current, *s);
675  PredIDV->push_back(s->getId());
676  CostV->push_back(cost);
677  }
678  return;
679  }
680  }
681 
682  ivExpandedStates.insert(std::pair<int,int>(current->getX(), current->getY()));
684 
685  if (closeToStart(*current))
686  {
687  // map to the start state id
688  PredIDV->push_back(ivIdStartFootLeft);
689  // get actual costs (dependent on whether the start foot is left or right)
690  int start_id;
691  if (current->getLeg() == RIGHT)
692  start_id = ivIdStartFootLeft;
693  else
694  start_id = ivIdStartFootRight;
695  CostV->push_back(stepCost(*current, *ivStateId2State[start_id]));
696 
697  return;
698  }
699 
700  PredIDV->reserve(ivFootstepSet.size());
701  CostV->reserve(ivFootstepSet.size());
702  std::vector<Footstep>::const_iterator footstep_set_iter;
703  for(footstep_set_iter = ivFootstepSet.begin();
704  footstep_set_iter != ivFootstepSet.end();
705  ++footstep_set_iter)
706  {
707  const PlanningState predecessor =
708  footstep_set_iter->reverseMeOnThisState(*current);
709  if (occupied(predecessor))
710  continue;
711 
712  const PlanningState* predecessor_hash = createHashEntryIfNotExists(
713  predecessor);
714 
715  int cost = stepCost(*current, *predecessor_hash);
716  PredIDV->push_back(predecessor_hash->getId());
717  CostV->push_back(cost);
718  }
719 }
720 
721 
722 int
724 {
725  return GetFromToHeuristic(stateID, ivIdStartFootLeft);
726 }
727 
728 
729 void
731  std::vector<int> *SuccIDV,
732  std::vector<int> *CostV)
733 {
734  SuccIDV->clear();
735  CostV->clear();
736 
737  assert(SourceStateID >= 0 &&
738  unsigned(SourceStateID) < ivStateId2State.size());
739 
740  // make goal state absorbing (only left!)
741  if (SourceStateID == ivIdGoalFootLeft)
742  {
743  return;
744  }
745  // add cheap transition from right to left, so right becomes an
746  // equivalent goal
747  if (SourceStateID == ivIdGoalFootRight)
748  {
749  SuccIDV->push_back(ivIdGoalFootLeft);
750  CostV->push_back(0.0);
751  return;
752  }
753 
754  const PlanningState* current = ivStateId2State[SourceStateID];
755 
756  // make sure start state transitions are consistent with
757  // GetPreds(some_state, start_state) where some_state is reachable by an
758  // arbitrary step from start_state
759  if (!ivForwardSearch)
760  {
761  if (SourceStateID == ivIdStartFootLeft ||
762  SourceStateID == ivIdStartFootRight)
763  {
764  const PlanningState* s;
765  int cost;
766  std::vector<int>::const_iterator state_id_iter;
767  for(state_id_iter = ivStateArea.begin();
768  state_id_iter != ivStateArea.end();
769  ++state_id_iter)
770  {
771  s = ivStateId2State[*state_id_iter];
772  cost = stepCost(*current, *s);
773  SuccIDV->push_back(s->getId());
774  CostV->push_back(cost);
775  }
776  return;
777  }
778  }
779 
780  ivExpandedStates.insert(std::pair<int,int>(current->getX(), current->getY()));
782 
783  if (closeToGoal(*current))
784  {
785  int goal_id;
786  assert(current->getLeg() != NOLEG);
787  if (current->getLeg() == RIGHT)
788  goal_id = ivIdGoalFootLeft;
789  else
790  goal_id = ivIdGoalFootRight;
791 
792  const PlanningState* goal = ivStateId2State[goal_id];
793  SuccIDV->push_back(goal_id);
794  CostV->push_back(stepCost(*current, *goal));
795 
796  return;
797  }
798 
799  SuccIDV->reserve(ivFootstepSet.size());
800  CostV->reserve(ivFootstepSet.size());
801  std::vector<Footstep>::const_iterator footstep_set_iter;
802  for(footstep_set_iter = ivFootstepSet.begin();
803  footstep_set_iter != ivFootstepSet.end();
804  ++footstep_set_iter)
805  {
806  PlanningState successor =
807  footstep_set_iter->performMeOnThisState(*current);
808  if (occupied(successor))
809  continue;
810 
811  const PlanningState* successor_hash_entry =
812  createHashEntryIfNotExists(successor);
813 
814  int cost = stepCost(*current, *successor_hash_entry);
815  SuccIDV->push_back(successor_hash_entry->getId());
816  CostV->push_back(cost);
817  }
818 }
819 
820 void
821 FootstepPlannerEnvironment::GetSuccsTo(int SourceStateID, int goalStateId,
822  std::vector<int> *SuccIDV,
823  std::vector<int> *CostV)
824 {
825  //return GetSuccs(SourceStateID, SuccIDV, CostV);
826 
827  SuccIDV->clear();
828  CostV->clear();
829 
830  assert(SourceStateID >= 0 &&
831  unsigned(SourceStateID) < ivStateId2State.size());
832 
833  // make goal state absorbing
834  if (SourceStateID == ivIdGoalFootLeft ){
835  return;
836  }
837 
838  const PlanningState* current = ivStateId2State[SourceStateID];
839  ivExpandedStates.insert(std::pair<int,int>(current->getX(), current->getY()));
841 
842  //ROS_INFO("GetSuccsTo %d -> %d: %f", SourceStateID, goalStateId, euclidean_distance(current->getX(), current->getY(), ivStateId2State[goalStateId]->getX(), ivStateId2State[goalStateId]->getY()));
843 
844  // add cheap transition from right to left, so right becomes an equivalent goal
845  if (goalStateId== ivIdGoalFootLeft && SourceStateID == ivIdGoalFootRight && current->getLeg() == RIGHT){
846  SuccIDV->push_back(ivIdGoalFootLeft);
847  CostV->push_back(ivStepCost);
848  return;
849  }
850 
851  if (closeToGoal(*current))
852  {
853  int goal_id;
854  assert(current->getLeg() != NOLEG);
855  if (current->getLeg() == RIGHT){
856  goal_id = ivIdGoalFootLeft;
857  } else {
858  goal_id = ivIdGoalFootRight;
859  }
860 
861  const PlanningState* goal = ivStateId2State[goal_id];
862  int cost = stepCost(*current, *goal);
863  SuccIDV->push_back(goal_id);
864  CostV->push_back(cost);
865 
866  return;
867  }
868 
869  // intermediate goal reachable (R*)?
870  assert(goalStateId >= 0 && unsigned(goalStateId) < ivStateId2State.size());
871  const PlanningState* randomGoal = ivStateId2State[goalStateId];
872  if (randomGoal->getLeg() != current->getLeg() && reachable(*current, *randomGoal)){
873  int cost = stepCost(*current, *randomGoal);
874  SuccIDV->push_back(goalStateId);
875  CostV->push_back(cost);
876  // ROS_INFO("%d %d", goalStateId, cost);
877 
878  // return;
879  }
880 
881 
882  SuccIDV->reserve(ivFootstepSet.size());
883  CostV->reserve(ivFootstepSet.size());
884  std::vector<Footstep>::const_iterator footstep_set_iter;
885  for(footstep_set_iter = ivFootstepSet.begin();
886  footstep_set_iter != ivFootstepSet.end();
887  ++footstep_set_iter)
888  {
889  PlanningState successor =
890  footstep_set_iter->performMeOnThisState(*current);
891  if (occupied(successor))
892  continue;
893 
894  const PlanningState* successor_hash = createHashEntryIfNotExists(successor);
895 
896  int cost = stepCost(*current, *successor_hash);
897  SuccIDV->push_back(successor_hash->getId());
898  CostV->push_back(cost);
899  }
900 }
901 
902 
903 void
905  std::vector<int>* SuccIDV, std::vector<int>* CLowV)
906 {
907 
908  assert(SourceStateID >= 0 && unsigned(SourceStateID) < ivStateId2State.size());
909  //goal state should be absorbing
910  if (SourceStateID == ivIdGoalFootLeft || SourceStateID == ivIdGoalFootRight )
911  return;
912 
913 
914  const PlanningState* currentState = ivStateId2State[SourceStateID];
915  // TODO: closeToGoal?
916  //
917  // if (closeToGoal(*currentState))
918  // return;
919 
920  //get the successors
921  GetRandomNeighs(currentState, SuccIDV, CLowV, ivNumRandomNodes,
922  ivRandomNodeDist, true);
923 }
924 
925 void
927  std::vector<int>* PredIDV, std::vector<int>* CLowV)
928 {
929 
930  assert(TargetStateID >= 0 &&
931  unsigned(TargetStateID) < ivStateId2State.size());
932 
933  // start state should be absorbing
934  if (TargetStateID == ivIdStartFootLeft || TargetStateID == ivIdStartFootRight)
935  return;
936 
937  const PlanningState* currentState = ivStateId2State[TargetStateID];
938 
939  // TODO: ???
940  // if(closeToStart(*currentState))
941  // return;
942 
943  //get the predecessors
944  GetRandomNeighs(currentState, PredIDV, CLowV, ivNumRandomNodes,
945  ivRandomNodeDist, false);
946 
947 }
948 
949 //generates nNumofNeighs random neighbors of cell <X,Y> at distance nDist_c (measured in cells)
950 //it will also generate goal if within this distance as an additional neighbor
951 //bSuccs is set to true if we are computing successor states, otherwise it is Preds
952 // (see fct. implemented in environment_nav2D)
953 void FootstepPlannerEnvironment::GetRandomNeighs(const PlanningState* currentState, std::vector<int>* NeighIDV, std::vector<int>* CLowV, int nNumofNeighs, int nDist_c, bool bSuccs)
954 {
955 
956  //clear the successor array
957  NeighIDV->clear();
958  CLowV->clear();
959 
960 
961  //get X, Y for the states
962  int X = currentState->getX();
963  int Y = currentState->getY();
964  //int theta = currentState->getTheta();
965 
966  //see if the goal/start belongs to the inside area and if yes then add it to Neighs as well
967  // NOTE: "goal check" for backward planning
968  const PlanningState* goal_left = NULL;
969  const PlanningState* goal_right = NULL;
970  if (bSuccs){
971  goal_left = ivStateId2State[ivIdGoalFootLeft];
972  goal_right = ivStateId2State[ivIdGoalFootRight];
973  } else {
974  goal_left = ivStateId2State[ivIdStartFootLeft];
975  goal_right = ivStateId2State[ivIdStartFootRight];
976  }
977 
978  int nDist_sq = nDist_c*nDist_c;
979 
980  //add left if within the distance
981  if (euclidean_distance_sq(X, Y, goal_left->getX(), goal_left->getY()) <= nDist_sq)
982  {
983  //compute clow
984  int clow;
985  if(bSuccs)
986  clow = GetFromToHeuristic(*currentState, *goal_left);
987  else
988  clow = GetFromToHeuristic(*goal_left, *currentState);
989 
990  NeighIDV->push_back(goal_left->getId());
991  CLowV->push_back(clow);
992  ivRandomStates.push_back(goal_left->getId());
993  }
994 
995  //add right if within the distance
996  if(euclidean_distance_sq(X, Y, goal_right->getX(), goal_right->getY()) <= nDist_sq)
997  {
998  //compute clow
999  int clow;
1000  if(bSuccs)
1001  clow = GetFromToHeuristic(*currentState, *goal_right);
1002  else
1003  clow = GetFromToHeuristic(*goal_right, *currentState);
1004 
1005  NeighIDV->push_back(goal_right->getId());
1006  CLowV->push_back(clow);
1007  ivRandomStates.push_back(goal_right->getId());
1008  }
1009 
1010  //iterate through random actions
1011  int nAttempts = 0;
1012  for (int i = 0; i < nNumofNeighs && nAttempts < 5*nNumofNeighs; ++i, ++nAttempts)
1013  {
1014 
1015  // pick goal in random direction
1016  float fDir = (float)(TWO_PI*(((double)rand())/RAND_MAX));
1017 
1018  int dX = (int)(nDist_c*cos(fDir));
1019  int dY = (int)(nDist_c*sin(fDir));
1020 
1021  //get the coords of the state
1022  int newX = X + dX;
1023  int newY = Y + dY;
1024 
1025  // TODO / FIXME x,y, can be negative! need offset
1026  // check if outside of map:
1027  // if (newX < 0 || newY < 0 || unsigned(newX) >= ivMapPtr->getInfo().width || unsigned(newY) >= ivMapPtr->getInfo().height){
1028  // i--;
1029  // ROS_INFO("Outside of map: %d %d", newX, newY);
1030  // continue;
1031  // }
1032 
1033  // direction of random exploration (facing forward):
1034  int newTheta = angle_state_2_cell(fDir, ivNumAngleBins);
1035 
1036  // random left/right
1037  Leg newLeg = Leg(rand() % 2);
1038 
1039  PlanningState randomState(newX, newY, newTheta, newLeg, ivHashTableSize);
1040 
1041  // add both left and right if available:
1042  // int sep = disc_val(0.07, ivCellSize);
1043  // int ddX = int(-sin(fDir) * sep);
1044  // int ddY = int(cos(fDir) * sep);
1045  // PlanningState randomState(newX+ddX, newY+ddY, newTheta, LEFT, ivHashTableSize);
1046  //
1047  // PlanningState randomStateR(newX-ddX, newY-ddY, newTheta, RIGHT, ivHashTableSize);
1048 
1049  if(!occupied(randomState))
1050  {
1051  const PlanningState* random_hash_entry = getHashEntry(randomState);
1052  if (random_hash_entry == NULL){
1053  random_hash_entry = createNewHashEntry(randomState);
1054  ivRandomStates.push_back(random_hash_entry->getId());
1055  }
1056 
1057  //compute clow
1058  int clow;
1059  if(bSuccs)
1060  clow = GetFromToHeuristic(currentState->getId(), random_hash_entry->getId());
1061 
1062  else
1063  clow = GetFromToHeuristic(random_hash_entry->getId(), currentState->getId());
1064 
1065  NeighIDV->push_back(random_hash_entry->getId());
1066  CLowV->push_back(clow);
1067 
1068  }else{
1069  i--;
1070  }
1071 
1072  // if(!occupied(randomStateR))
1073  // {
1074  // const PlanningState* random_hash_entry = getHashEntry(randomStateR);
1075  // if (random_hash_entry == NULL){
1076  // random_hash_entry = createNewHashEntry(randomStateR);
1077  // ivRandomStates.push_back(random_hash_entry->getId());
1078  // }
1079  //
1080  // //compute clow
1081  // int clow;
1082  // if(bSuccs)
1083  // clow = GetFromToHeuristic(currentState->getId(), random_hash_entry->getId());
1084  // else
1085  // clow = GetFromToHeuristic(random_hash_entry->getId(), currentState->getId());
1086  //
1087  // NeighIDV->push_back(random_hash_entry->getId());
1088  // CLowV->push_back(clow);
1089  //
1090  // }else{
1091  // i--;
1092  // }
1093 
1094 
1095  }
1096 
1097  if (NeighIDV->size() == 0){
1098  ROS_WARN("Could not create any random neighbor nodes (%d attempts) from id %d (%d %d)",
1099  nAttempts, currentState->getId(), X, Y);
1100  } else
1101 
1102  ROS_DEBUG("Created %zu random neighbors (%d attempts) from id %d "
1103  "(%d %d)", NeighIDV->size(), nAttempts, currentState->getId(),
1104  X, Y);
1105 }
1106 
1107 bool
1109 {
1110  assert(StateID1 >= 0 && StateID2 >= 0
1111  && unsigned(StateID1) < ivStateId2State.size() && unsigned(StateID2) < ivStateId2State.size());
1112 
1113 
1114  if (StateID1 == StateID2)
1115  return true;
1116 
1117  const PlanningState* s1 = ivStateId2State[StateID1];
1118  const PlanningState* s2 = ivStateId2State[StateID2];
1119 
1120  // // approximately compare, ignore theta:
1121  return (std::abs(s1->getX() - s2->getX()) < 1
1122  && std::abs(s1->getY() - s2->getY()) < 1
1123  // && std::abs(s1->getTheta() - s2->getTheta()) < 3
1124  && s1->getLeg() == s2->getLeg()
1125  );
1126 
1127 
1128 // compare the actual values (exact comparison)
1129 // return (*s1 == *s2);
1130 }
1131 
1132 
1133 
1134 bool
1136 {
1137 // ROS_ERROR("FootstepPlanerEnvironment::InitializeEnv: Hit unimplemented "
1138 // "function. Check this!");
1139  return true;
1140 }
1141 
1142 
1143 bool
1145 {
1146  // NOTE: The internal start and goal ids are set here to the left foot
1147  // (this affects the calculation of the heuristic values)
1148  MDPCfg->goalstateid = ivIdGoalFootLeft;
1149  MDPCfg->startstateid = ivIdStartFootLeft;
1150 
1151  assert(ivIdGoalFootLeft != -1);
1152  assert(ivIdStartFootLeft != -1);
1153 
1154  return true;
1155 }
1156 
1157 
1158 void
1160 {
1161  // NOTE: implement this if the planner needs to print out configurations
1162  ROS_ERROR("FootstepPlanerEnvironment::PrintEnv_Config: Hit "
1163  "unimplemented function. Check this!");
1164 }
1165 
1166 
1167 void
1168 FootstepPlannerEnvironment::PrintState(int stateID, bool bVerbose,
1169  FILE *fOut)
1170 {
1171  if(fOut == NULL)
1172  {
1173  fOut = stdout;
1174  }
1175 
1176  if(stateID == ivIdGoalFootLeft && bVerbose)
1177  {
1178  SBPL_FPRINTF(fOut, "the state is a goal state\n");
1179  }
1180 
1181  const PlanningState* s = ivStateId2State[stateID];
1182 
1183  if(bVerbose)
1184  {
1185  SBPL_FPRINTF(fOut, "X=%i Y=%i THETA=%i FOOT=%i\n",
1186  s->getX(), s->getY(), s->getTheta(), s->getLeg());
1187  }
1188  else
1189  {
1190  SBPL_FPRINTF(fOut, "%i %i %i %i\n",
1191  s->getX(), s->getY(), s->getTheta(), s->getLeg());
1192  }
1193 }
1194 
1195 
1196 void
1198 {
1199  // NOTE: not implemented so far
1200  // Description: Some searches may also use SetAllActionsandAllOutcomes
1201  // or SetAllPreds functions if they keep the pointers to successors
1202  // (predecessors) but most searches do not require this, so it is not
1203  // necessary to support this
1204 
1205  ROS_ERROR("FootstepPlannerEnvironment::SetAllActionsandAllOutcomes: Hit"
1206  " unimplemented function. Check this!");
1207 }
1208 
1209 
1210 void
1212 {
1213  // NOTE: not implemented so far
1214  // Description: Some searches may also use SetAllActionsandAllOutcomes
1215  // or SetAllPreds functions if they keep the pointers to successors
1216  // (predecessors) but most searches do not require this, so it is not
1217  // necessary to support this
1218 
1219  ROS_ERROR("FootstepPlannerEnvironment::SetAllPreds: Hit unimplemented "
1220  "function. Check this!");
1221 }
1222 
1223 
1224 int
1226 {
1227  return ivStateId2State.size();
1228 }
1229 
1230 
1231 void
1233  const PlanningState& right)
1234 {
1235  ivStateArea.clear();
1236 
1237  const PlanningState* p_state = getHashEntry(right);
1238  ivStateArea.push_back(p_state->getId());
1239 
1240  double cont_step_x, cont_step_y, cont_step_theta;
1241  for (int step_y = ivMaxInvFootstepY; step_y <= ivMaxFootstepY; ++step_y)
1242  {
1243  for (int step_x = ivMaxInvFootstepX; step_x <= ivMaxFootstepX; ++step_x)
1244  {
1245  for (int step_theta = ivMaxInvFootstepTheta;
1246  step_theta <= ivMaxFootstepTheta;
1247  ++step_theta)
1248  {
1249  cont_step_x = cont_val(step_x, ivCellSize);
1250  cont_step_y = cont_val(step_y, ivCellSize);
1251  cont_step_theta = angle_cell_2_state(step_theta, ivNumAngleBins);
1252  Footstep step(cont_step_x, cont_step_y, cont_step_theta,
1254  if (ivForwardSearch)
1255  {
1256  PlanningState pred = step.reverseMeOnThisState(left);
1257  if (occupied(pred) || !reachable(pred, left))
1258  continue;
1259  p_state = createHashEntryIfNotExists(pred);
1260  ivStateArea.push_back(p_state->getId());
1261 
1262  pred = step.reverseMeOnThisState(right);
1263  if (occupied(pred) || !reachable(pred, right))
1264  continue;
1265  p_state = createHashEntryIfNotExists(pred);
1266  ivStateArea.push_back(p_state->getId());
1267  }
1268  else
1269  {
1270  PlanningState succ = step.performMeOnThisState(left);
1271  if (occupied(succ) || !reachable(left, succ))
1272  continue;
1273  p_state = createHashEntryIfNotExists(succ);
1274  ivStateArea.push_back(p_state->getId());
1275 
1276  succ = step.performMeOnThisState(right);
1277  if (occupied(succ) || !reachable(right, succ))
1278  continue;
1279  p_state = createHashEntryIfNotExists(succ);
1280  ivStateArea.push_back(p_state->getId());
1281  }
1282  }
1283  }
1284  }
1285 }
1286 
1287 
1288 bool
1290  const PlanningState* b)
1291 const
1292 {
1293  if (a->getX() < b->getX())
1294  return true;
1295  else if (a->getY() < b->getY())
1296  return true;
1297  else
1298  return false;
1299 }
1300 }
1301 
void GetSuccsTo(int SourceStateID, int goalStateID, std::vector< int > *SuccIDV, std::vector< int > *CostV)
Testing, for R*.
const int ivStepCost
The costs for each step (discretized with the help of cvMmScale).
double cell_2_state(int value, double cell_size)
Calculate the respective (continuous) state value for a cell. (Should be used to get a State from a d...
Definition: helper.h:122
int GetFromToHeuristic(int FromStateID, int ToStateID)
const double ivOriginFootShiftX
Shift in x direction from the foot&#39;s center.
const std::vector< Footstep > & ivFootstepSet
The set of footsteps used for the path planning.
bool operator()(const PlanningState *a, const PlanningState *b) const
const int ivMaxFootstepX
The maximal translation in x direction (discretized in cell size).
void setTheta(double theta)
Definition: State.h:43
static const double TWO_PI
Definition: helper.h:37
void getSuccsOfGridCells(const std::vector< State > &changed_states, std::vector< int > *succ_ids)
std::pair< int, int > updateStart(const State &foot_left, const State &right_right)
Update the robot&#39;s feet poses in the start state.
bool getState(unsigned int id, State *s)
Try to receive a state with a certain ID.
std::vector< const PlanningState * > * ivpStateHash2State
Maps from a hash tag to a list of corresponding planning states. (Used in FootstepPlannerEnvironment ...
const double ivFootsizeX
Size of the foot in x direction.
Determining the heuristic value by calculating a 2D path from each grid cell of the map to the goal a...
const int ivMaxFootstepY
The maximal translation in y direction (discretized in cell size).
const double ivOriginFootShiftY
Shift in y direction from the foot&#39;s center.
PlanningState reverseMeOnThisState(const PlanningState &current) const
Reverse this footstep on a given planning state.
Definition: Footstep.cpp:106
XmlRpcServer s
double euclidean_distance_sq(int x1, int y1, int x2, int y2)
Definition: helper.h:48
const boost::shared_ptr< Heuristic > ivHeuristicConstPtr
The heuristic function used by the planner.
boost::shared_ptr< gridmap_2d::GridMap2D > ivMapPtr
Pointer to the map.
void getPredsOfGridCells(const std::vector< State > &changed_states, std::vector< int > *pred_ids)
int ivIdStartFootRight
ID of the start pose of the right foot.
double euclidean_distance(int x1, int y1, int x2, int y2)
Definition: helper.h:56
const PlanningState * createHashEntryIfNotExists(const PlanningState &s)
bool collision_check(double x, double y, double theta, double height, double width, int accuracy, const gridmap_2d::GridMap2D &distance_map)
Checks if a footstep (represented by its center and orientation) collides with an obstacle...
Definition: helper.cpp:26
tf::Vector3 Point
#define ROS_WARN(...)
FootstepPlannerEnvironment(const environment_params &params)
void GetSuccs(int SourceStateID, std::vector< int > *SuccIDV, std::vector< int > *CostV)
Calculates the successor states and the corresponding costs when performing the footstep set on the p...
void setId(unsigned int id)
Used to attach such an unique ID to the planning state. (This cannot be done in the constructor since...
Definition: PlanningState.h:94
const double ivFootsizeY
Size of the foot in y direction.
int ivIdPlanningGoal
ID of the planning goal, i.e. dependent on the planning direction (forward/backward) this ID is used ...
const int ivMaxInvFootstepY
The minimal translation in y direction (discretized in cell size).
std::vector< const PlanningState * > ivStateId2State
Maps from an ID to the corresponding PlanningState. (Used in the SBPL to access a certain PlanningSta...
TFSIMD_FORCE_INLINE const tfScalar & x() const
tf::Transform Pose
A class representing the robot&#39;s pose (i.e. position and orientation) in the (continuous) world view...
Definition: State.h:34
int ivMaxInvFootstepTheta
The minimal rotation (discretized into bins).
exp_states_t ivRandomStates
random intermediate states for R*
static Quaternion createQuaternionFromYaw(double yaw)
const int ivNumRandomNodes
number of random neighbors for R*
void setY(double y)
Definition: State.h:42
#define ROS_INFO(...)
int ivMaxFootstepTheta
The maximal rotation (discretized into bins).
int ivIdGoalFootLeft
ID of the goal pose of the left foot.
TFSIMD_FORCE_INLINE Quaternion inverse(const Quaternion &q)
int disc_val(double length, double cell_size)
Discretize a (continuous) value into cell size.
Definition: helper.h:130
std::pair< int, int > updateGoal(const State &foot_left, const State &foot_right)
Update the robot&#39;s feet poses in the goal state.
TFSIMD_FORCE_INLINE const tfScalar & y() const
int ivIdGoalFootRight
ID of the goal pose of the right foot.
bool ivHeuristicExpired
Indicates if heuristic has to be updated.
double angle_cell_2_state(int angle, int angle_bin_num)
Calculate the respective (continuous) angle for a bin.
Definition: helper.h:101
PlanningState performMeOnThisState(const PlanningState &current) const
Performs this footstep (translation and rotation) on a given planning state.
Definition: Footstep.cpp:69
const double ivCellSize
The size of each grid cell used to discretize the robot positions.
def normalize_angle(angle)
void updateHeuristicValues()
Update the heuristic values (e.g. after the map has changed). The environment takes care that the upd...
TFSIMD_FORCE_INLINE Vector3 & getOrigin()
const int ivHashTableSize
Size of the hash table storing the planning states expanded during the search. (Also referred to by m...
unsigned int step
virtual void GetRandomPredsatDistance(int TargetStateID, std::vector< int > *PredIDV, std::vector< int > *CLowV)
Used for RStar: generate succs/preds at some domain-dependent distance. The number of generated succs...
const PlanningState * createNewHashEntry(const State &s)
Wrapper for FootstepPlannerEnvironment::createNewHashEntry(PlanningState).
const int ivMaxInvFootstepX
The minimal translation in x direction (discretized in cell size).
std::vector< std::pair< int, int > > step_range
Defines the area of performable (discrete) steps.
void GetPreds(int TargetStateID, std::vector< int > *PredIDV, std::vector< int > *CostV)
Calculates the predecessor states and the corresponding costs when reversing the footstep set on the ...
const int ivCollisionCheckAccuracy
Whether to check just the foot&#39;s inner circle (0), the hole outer circle (1) or exactly the foot&#39;s bo...
void PrintState(int stateID, bool bVerbose, FILE *fOut)
static const int cvMmScale
Used to scale continuous values in meter to discrete values in mm.
void setLeg(Leg leg)
Definition: State.h:44
int angle_state_2_cell(double angle, int angle_bin_num)
Discretize a (continuous) angle into a bin.
Definition: helper.h:92
const PlanningState * getHashEntry(const State &s)
Wrapper for FootstepPlannerEnvironment::getHashEntry(PlanningState).
A class representing a footstep (i.e. a translation and rotation of a specific foot with respect to t...
Definition: Footstep.h:38
void reset()
Resets the current planning task (i.e. the start and goal poses).
const int ivRandomNodeDist
distance of random neighbors for R* (discretized in cells)
bool pointWithinPolygon(int x, int y, const std::vector< std::pair< int, int > > &edges)
Crossing number method to determine whether a point lies within a polygon or not. ...
Definition: helper.cpp:84
int stepCost(const PlanningState &a, const PlanningState &b)
unsigned int getHashTag() const
A class representing the robot&#39;s pose (i.e. position and orientation) in the underlying SBPL...
Definition: PlanningState.h:45
void setX(double x)
Definition: State.h:41
#define ROS_ERROR(...)
const int ivNumAngleBins
The number of bins used to discretize the robot orientations.
void GetRandomNeighs(const PlanningState *currentState, std::vector< int > *NeighIDV, std::vector< int > *CLowV, int nNumofNeighs, int nDist_c, bool bSuccs)
void setStateArea(const PlanningState &left, const PlanningState &right)
bool reachable(const PlanningState &from, const PlanningState &to)
const bool ivForwardSearch
Whether to use forward search (1) or backward search (0).
virtual void GetRandomSuccsatDistance(int SourceStateID, std::vector< int > *SuccIDV, std::vector< int > *CLowV)
Used for RStar: generate succs/preds at some domain-dependent distance. The number of generated succs...
double cont_val(int length, double cell_size)
Calculates the continuous value for a length discretized in cell size.
Definition: helper.h:141
int ivIdStartFootLeft
ID of the start pose of the left foot.
#define ROS_DEBUG(...)


footstep_planner
Author(s): Johannes Garimort, Armin Hornung
autogenerated on Mon Jun 10 2019 13:38:24