state_space.cpp
Go to the documentation of this file.
2 
3 #include <vigir_footstep_planning_lib/math.h>
4 
5 #include <vigir_footstep_planning_plugins/plugin_aggregators/robot_model.h>
6 #include <vigir_footstep_planning_plugins/plugin_aggregators/post_processor.h>
7 #include <vigir_footstep_planning_plugins/plugin_aggregators/step_cost_estimator.h>
8 #include <vigir_footstep_planning_plugins/plugin_aggregators/heuristic.h>
9 
10 
11 
13 {
14 StateSpace::StateSpace(const EnvironmentParameters& params, std::vector<int*>& state_ID2_index_mapping)
15  : params(params)
16  , frame_id("/world")
17  , ivIdPlanningStart(-1)
18  , ivIdPlanningGoal(-1)
19  , ivIdStartFootLeft(-1)
20  , ivIdStartFootRight(-1)
21  , ivIdGoalFootLeft(-1)
22  , ivIdGoalFootRight(-1)
23  , state_ID2_index_mapping(state_ID2_index_mapping)
24  , ivpStateHash2State(new std::vector<PlanningState*>[params.hash_table_size])
25  , ivHeuristicExpired(false)
26  , ivRandomNodeDist(params.random_node_distance / params.cell_size)
27 {
28 }
29 
31 {
33  {
34  delete[] ivpStateHash2State;
35  ivpStateHash2State = NULL;
36  }
37 }
38 
40 {
41  for(unsigned int i = 0; i < ivStateId2State.size(); ++i)
42  {
43  if (ivStateId2State[i])
44  {
45  delete ivStateId2State[i];
46  }
47  }
48  ivStateId2State.clear();
49 
51  {
52  for(int i = 0; i < params.hash_table_size; ++i)
53  ivpStateHash2State[i].clear();
54  }
55 
57 
58  ivRandomStates.clear();
59 
60  ivIdPlanningStart = -1;
61  ivIdPlanningGoal = -1;
62 
63  ivIdGoalFootLeft = -1;
64  ivIdGoalFootRight = -1;
65  ivIdStartFootLeft = -1;
66  ivIdStartFootRight = -1;
67 
68  ivHeuristicExpired = true;
69 }
70 
71 void StateSpace::setFrameId(const std::string& frame_id)
72 {
73  this->frame_id = frame_id;
74 }
75 
76 std::pair<int, int> StateSpace::updateGoal(const State& foot_left, const State& foot_right)
77 {
78  // keep the old IDs
79  int goal_foot_id_left = ivIdGoalFootLeft;
80  int goal_foot_id_right = ivIdGoalFootRight;
81 
82  // update the states for both feet (if necessary)
83  goal_foot_left = getHashEntry(foot_left);
84  if (goal_foot_left == NULL)
86  goal_foot_right = getHashEntry(foot_right);
87  if (goal_foot_right == NULL)
88  goal_foot_right = createNewHashEntry(foot_right);
91  // check if everything has been set correctly
92  assert(ivIdGoalFootLeft != -1);
93  assert(ivIdGoalFootRight != -1);
94 
95  // if using the forward search a change of the goal states involves an
96  // update of the heuristic
98  {
99  // check if the goal states have been changed
100  if (goal_foot_id_left != ivIdGoalFootLeft || goal_foot_id_right != ivIdGoalFootRight)
101  {
102  ivHeuristicExpired = true;
103  //setStateArea(*goal_foot_left, *goal_foot_right);
104  }
105  }
106 
107  return std::pair<int, int>(ivIdGoalFootLeft, ivIdGoalFootRight);
108 }
109 
110 std::pair<int, int> StateSpace::updateStart(const State& foot_left, const State& foot_right)
111 {
112  // keep the old IDs
113  int start_foot_id_left = ivIdStartFootLeft;
114  int start_foot_id_right = ivIdStartFootRight;
115 
116  // update the states for both feet (if necessary)
117  start_foot_left = getHashEntry(foot_left);
118  if (start_foot_left == NULL)
119  start_foot_left = createNewHashEntry(foot_left);
120  start_foot_right = getHashEntry(foot_right);
121  if (start_foot_right == NULL)
122  start_foot_right = createNewHashEntry(foot_right);
125  // check if everything has been set correctly
126  assert(ivIdStartFootLeft != -1);
127  assert(ivIdStartFootRight != -1);
128 
129  // if using the backward search a change of the start states involves an
130  // update of the heuristic
131  if (!params.forward_search)
132  {
133  // check if the start states have been changed
134  if (start_foot_id_left != ivIdStartFootLeft || start_foot_id_right != ivIdStartFootRight)
135  {
136  ivHeuristicExpired = true;
137  //setStateArea(*start_foot_left, *start_foot_right);
138  }
139  }
140 
141  return std::pair<int, int>(ivIdStartFootLeft, ivIdStartFootRight);
142 }
143 
144 void StateSpace::setPlannerStartAndGoal(unsigned int start_foot_selection)
145 {
146  if (start_foot_selection == msgs::StepPlanRequest::AUTO)
147  {
148  State robot_start;
149  getStartState(robot_start);
150 
151  State robot_goal;
152  getGoalState(robot_goal);
153 
154  tf::Transform direction = robot_start.getPose().inverse() * robot_goal.getPose();
155  if (direction.getOrigin().getY() > 0.0)
156  start_foot_selection = msgs::StepPlanRequest::RIGHT;
157  else
158  start_foot_selection = msgs::StepPlanRequest::LEFT;
159  }
160 
161  if (start_foot_selection == msgs::StepPlanRequest::LEFT) // move first right foot
162  {
164  start_foot_right->setSuccState(start_foot_left);
165  start_foot_left->setPredState(start_foot_right);
166 
168  goal_foot_right->setSuccState(goal_foot_left);
169  goal_foot_left->setPredState(goal_foot_right);
170  }
171  else if (start_foot_selection == msgs::StepPlanRequest::RIGHT) // move first left foot
172  {
174  start_foot_left->setSuccState(start_foot_right);
175  start_foot_right->setPredState(start_foot_left);
176 
178  goal_foot_left->setSuccState(goal_foot_right);
179  goal_foot_right->setPredState(goal_foot_left);
180  }
181  else
182  ROS_ERROR("[setPlannerStartAndGoal] Unknown selection mode: %u", start_foot_selection);
183 }
184 
185 bool StateSpace::getState(unsigned int id, State &s) const
186 {
187  if (id >= ivStateId2State.size())
188  return false;
189 
190  s = ivStateId2State[id]->getState();
191  return true;
192 }
193 
194 bool StateSpace::getStartState(State &left, State &right) const
195 {
196  if (!getState(ivIdStartFootLeft, left))
197  return false;
198  if (!getState(ivIdStartFootRight, right))
199  return false;
200  return true;
201 }
202 
203 bool StateSpace::getStartState(State &robot) const
204 {
205  State left;
206  State right;
207 
208  if (!getState(ivIdStartFootLeft, left))
209  return false;
210  if (!getState(ivIdStartFootRight, right))
211  return false;
212 
213  robot.setX(0.5*(left.getX()+right.getX()));
214  robot.setY(0.5*(left.getY()+right.getY()));
215  robot.setZ(0.5*(left.getZ()+right.getZ()));
216  robot.setYaw(0.5*(left.getYaw()+right.getYaw()));
217  return true;
218 }
219 
220 bool StateSpace::getGoalState(State &left, State &right) const
221 {
222  if (!getState(ivIdGoalFootLeft, left))
223  return false;
224  if (!getState(ivIdGoalFootRight, right))
225  return false;
226  return true;
227 }
228 
229 bool StateSpace::getGoalState(State &robot) const
230 {
231  State left;
232  State right;
233 
234  if (!getState(ivIdGoalFootLeft, left))
235  return false;
236  if (!getState(ivIdGoalFootRight, right))
237  return false;
238 
239  robot.setX(0.5*(left.getX()+right.getX()));
240  robot.setY(0.5*(left.getY()+right.getY()));
241  robot.setZ(0.5*(left.getZ()+right.getZ()));
242  robot.setYaw(0.5*(left.getYaw()+right.getYaw()));
243  return true;
244 }
245 
246 PlanningState *StateSpace::createNewHashEntry(const State& s)
247 {
249  return createNewHashEntry(tmp);
250 }
251 
252 PlanningState* StateSpace::createNewHashEntry(const PlanningState& s)
253 {
254  unsigned int state_hash = s.getHashTag();
255  PlanningState* new_state = new PlanningState(s);
256 
257  boost::unique_lock<boost::shared_mutex> lock(hash_table_shared_mutex);
258 
259  size_t state_id = ivStateId2State.size();
260  assert(state_id < (size_t)std::numeric_limits<int>::max());
261 
262  // insert the ID of the new state into the corresponding map
263  new_state->setId(state_id);
264  ivStateId2State.push_back(new_state);
265 
266  // insert the new state into the hash map at the corresponding position
267  ivpStateHash2State[state_hash].push_back(new_state);
268 
269  int* entry = new int[NUMOFINDICES_STATEID2IND];
270  state_ID2_index_mapping.push_back(entry);
271 
272  for(int i = 0; i < NUMOFINDICES_STATEID2IND; ++i)
273  state_ID2_index_mapping[state_id][i] = -1;
274 
275  assert(state_ID2_index_mapping.size() - 1 == state_id);
276 
277  return new_state;
278 }
279 
280 PlanningState* StateSpace::getHashEntry(const State& s)
281 {
283  return getHashEntry(tmp);
284 }
285 
286 PlanningState* StateSpace::getHashEntry(const PlanningState& s)
287 {
288  unsigned int state_hash = s.getHashTag();
289  std::vector<PlanningState*>::const_iterator state_iter;
290  boost::shared_lock<boost::shared_mutex> lock(hash_table_shared_mutex);
291  for (state_iter = ivpStateHash2State[state_hash].begin(); state_iter != ivpStateHash2State[state_hash].end(); ++state_iter)
292  {
293  if (*(*state_iter) == s)
294  return *state_iter;
295  }
296 
297  return NULL;
298 }
299 
300 PlanningState* StateSpace::createHashEntryIfNotExists(const PlanningState& s)
301 {
302  PlanningState* hash_entry = getHashEntry(s);
303  if (hash_entry == NULL)
304  hash_entry = createNewHashEntry(s);
305 
306  return hash_entry;
307 }
308 
309 bool StateSpace::closeToStart(const PlanningState& from) const
310 {
311  if (from.getLeg() == ivStateId2State[ivIdPlanningStart]->getLeg())
312  return false;
313 
314  assert(from.getSuccState() != nullptr);
315 
316  // check if first goal pose can be reached
317  State left_foot = (from.getLeg() == LEFT) ? from.getState() : from.getSuccState()->getState();
318  State right_foot = (from.getLeg() == RIGHT) ? from.getState() : from.getSuccState()->getState();
319  State start_foot = ivStateId2State[ivIdPlanningStart]->getState();
320 
321  PostProcessor::instance().postProcessBackward(left_foot, right_foot, start_foot);
322  if (!RobotModel::instance().isReachable(left_foot, right_foot, start_foot))
323  return false;
324 
325  // check if second (final) goal can be reached
326  if (start_foot.getLeg() == LEFT)
327  {
328  left_foot = start_foot;
329  start_foot = start_foot_right->getState();
330  }
331  else
332  {
333  right_foot = start_foot;
334  start_foot = start_foot_left->getState();
335  }
336 
337  PostProcessor::instance().postProcessBackward(left_foot, right_foot, start_foot);
338  start_foot.setBodyVelocity(geometry_msgs::Vector3()); // set velocity to zero
339  if (!RobotModel::instance().isReachable(left_foot, right_foot, start_foot))
340  return false;
341 
342  return true;
343 }
344 
345 bool StateSpace::closeToGoal(const PlanningState& from) const
346 {
347  if (from.getLeg() == ivStateId2State[ivIdPlanningGoal]->getLeg())
348  return false;
349 
350  assert(from.getPredState() != nullptr);
351 
352  // check if first goal pose can be reached
353  State left_foot = (from.getLeg() == LEFT) ? from.getState() : from.getPredState()->getState();
354  State right_foot = (from.getLeg() == RIGHT) ? from.getState() : from.getPredState()->getState();
355  State goal_foot = ivStateId2State[ivIdPlanningGoal]->getState();
356 
357  PostProcessor::instance().postProcessForward(left_foot, right_foot, goal_foot);
358  if (!RobotModel::instance().isReachable(left_foot, right_foot, goal_foot))
359  return false;
360 
361  // check if second (final) goal can be reached
362  if (goal_foot.getLeg() == LEFT)
363  {
364  left_foot = goal_foot;
365  goal_foot = goal_foot_right->getState();
366  }
367  else
368  {
369  right_foot = goal_foot;
370  goal_foot = goal_foot_left->getState();
371  }
372 
373  PostProcessor::instance().postProcessForward(left_foot, right_foot, goal_foot);
374  goal_foot.setBodyVelocity(geometry_msgs::Vector3()); // set velocity to zero
375  if (!RobotModel::instance().isReachable(left_foot, right_foot, goal_foot))
376  return false;
377 
378  return true;
379 }
380 
381 bool StateSpace::getStepCost(const State& stand_foot, const State& swing_foot_before, const State& swing_foot_after, double& cost, double& risk) const
382 {
383  cost = 0.0;
384  risk = 0.0;
385 
386  if (stand_foot.getLeg() == swing_foot_before.getLeg())
387  {
388  ROS_ERROR("Can't compute step cost: No standing foot is same leg as swing foot!");
389  return false;
390  }
391 
392  if (swing_foot_before.getLeg() != swing_foot_after.getLeg())
393  {
394  ROS_ERROR("Can't compute step cost: Swing foot states have not same leg!");
395  return false;
396  }
397 
398  const State& left_foot = stand_foot.getLeg() == LEFT ? stand_foot : swing_foot_before;
399  const State& right_foot = stand_foot.getLeg() == RIGHT ? stand_foot : swing_foot_before;
400 
401  if (!StepCostEstimator::instance().getCost(left_foot, right_foot, swing_foot_after, cost, risk))
402  return false;
403 
404  if (risk >= params.max_risk)
405  return false;
406 
407  return true;
408 }
409 
410 bool StateSpace::getStepCost(const State& stand_foot, const State& swing_foot_before, const State& swing_foot_after, int& cost, int& risk) const
411 {
412  double cost_d, risk_d;
413  if (!getStepCost(stand_foot, swing_foot_before, swing_foot_after, cost_d, risk_d))
414  return false;
415 
416  cost = static_cast<int>(cvMmScale * cost_d + 0.5);
417  risk = static_cast<int>(cvMmScale * risk_d + 0.5);
418 
419  return true;
420 }
421 
422 bool StateSpace::getStepCost(const State& stand_foot, const State& swing_foot_before, const State& swing_foot_after, int& cost) const
423 {
424  int risk = 0;
425  return getStepCost(stand_foot, swing_foot_before, swing_foot_after, cost, risk);
426 }
427 }
boost::shared_mutex hash_table_shared_mutex
Definition: state_space.h:209
std::vector< const PlanningState * > ivStateId2State
Maps from an ID to the corresponding PlanningState. (Used in the SBPL to access a certain PlanningSta...
Definition: state_space.h:192
void setFrameId(const std::string &frame_id)
Definition: state_space.cpp:71
int ivIdPlanningStart
ID of Start and Goal foot chosen by planner.
Definition: state_space.h:169
bool getState(unsigned int id, State &s) const
Try to receive a state with a certain ID.
TFSIMD_FORCE_INLINE const tfScalar & getY() const
bool closeToStart(const PlanningState &from) const
exp_states_t ivRandomStates
random intermediate states for R*
Definition: state_space.h:207
PlanningState * createHashEntryIfNotExists(const PlanningState &s)
StateSpace(const EnvironmentParameters &params, std::vector< int * > &state_ID2_index_mapping)
Definition: state_space.cpp:14
std::vector< int * > & state_ID2_index_mapping
Definition: state_space.h:186
PlanningState * getHashEntry(const State &s)
Wrapper for footstep_planner_environment::getHashEntry(PlanningState).
std::pair< int, int > updateGoal(const State &foot_left, const State &foot_right)
Definition: state_space.cpp:76
bool getGoalState(State &left, State &right) const
Transform inverse() const
std::pair< int, int > updateStart(const State &foot_left, const State &right_right)
bool getStepCost(const State &stand_foot, const State &swing_foot_before, const State &swing_foot_after, double &cost, double &risk) const
TFSIMD_FORCE_INLINE Vector3 & getOrigin()
const EnvironmentParameters & params
Definition: state_space.h:165
void setPlannerStartAndGoal(unsigned int start_foot_selection)
std::vector< PlanningState * > * ivpStateHash2State
Maps from a hash tag to a list of corresponding planning states. (Used in footstep_planner_environmen...
Definition: state_space.h:199
bool closeToGoal(const PlanningState &from) const
bool getStartState(State &left, State &right) const
PlanningState * createNewHashEntry(const State &s)
Wrapper for footstep_planner_environment::createNewHashEntry(PlanningState).
#define ROS_ERROR(...)
bool ivHeuristicExpired
The heuristic function used by the planner.
Definition: state_space.h:202


vigir_footstep_planner
Author(s): Alexander Stumpf
autogenerated on Sun Nov 17 2019 03:29:59