Collision Checker
fcl_collision_requests.h
Go to the documentation of this file.
1 #ifndef COLLISION_FCL_FCL_COLLISION_REQUESTS_H_
2 #define COLLISION_FCL_FCL_COLLISION_REQUESTS_H_
3 
5 
6 #include <fcl/broadphase/broadphase_dynamic_AABB_tree.h>
7 #include <fcl/math/constants.h>
8 #include <fcl/narrowphase/collision.h>
9 #include <fcl/narrowphase/collision_object.h>
10 
13 
14 #include <set>
15 
16 namespace collision {
17 class CollisionChecker;
18 typedef std::shared_ptr<CollisionChecker> CollisionCheckerPtr;
19 typedef std::shared_ptr<const CollisionChecker> CollisionCheckerConstPtr;
20 
21 namespace solvers {
22 namespace solverFCL {
23 CollisionObject *getParentPointerFromFclObj(
25 
27 
29  public:
31  std::vector<CollisionObjectConstPtr> &ret_obstacles,
32  const std::unordered_map<const CollisionObject *,
33  std::list<CollisionObjectConstPtr>> &parent_map,
34  int max_obstacles)
35  : m_obstacles(ret_obstacles),
36  m_parent_map(parent_map),
37  m_max_obstacles(max_obstacles){
38 
39  };
40 
41  bool addRequestResultObstacle(const CollisionObject *obst);
42 
43  bool testPair(std::pair<fcl::CollisionObject<FCL_PRECISION> *,
45  pair);
46 
47  void setMaxObstacles(int max_obstacles) { m_max_obstacles = max_obstacles; }
48 
49  int getMaxObstacles() const { return m_max_obstacles; }
50 
52  m_subject_group_size = -1; // only for comparison to determine object order
53  // in broadphase callback
54  }
56  fcl::BroadPhaseCollisionManager<FCL_PRECISION> *mngr) {
57  m_subject_group_size = mngr->size();
58  }
59 
60  void setTargetMngrSize(int size) { m_target_mngr_size = size; }
61 
63  m_obstacle_callback_first = m_target_mngr_size < m_subject_group_size;
64  }
65 
66  bool getObstacleCallbackOrder(void) const {
67  return !m_obstacle_callback_first;
68  }
69 
70  void setUngroupShapeGroups(bool val) { m_ungroup_sg = val; }
71  void setUngroupTvObstacles(bool val) { m_ungroup_tvobst = val; }
72 
73  void setAllObst_added(void) { m_finished = true; }
74 
75  bool getAllObstAdded(void) const { return m_finished; }
76 
77  private:
78  bool addRequestResultObstacleObject(CollisionObjectConstPtr obj);
79  std::vector<CollisionObjectConstPtr> &m_obstacles;
80  int m_subject_group_size;
81  int m_target_mngr_size;
82  const std::unordered_map<const CollisionObject *,
83  std::list<CollisionObjectConstPtr>> &m_parent_map;
84  std::unordered_map<const CollisionObject *, bool> m_added_map;
85  std::unordered_map<const CollisionObject *, bool> m_added_map_parent;
86  std::set<std::pair<fcl::CollisionObject<FCL_PRECISION> *,
88  checkedPairs;
89  bool m_obstacle_callback_first = false;
90  bool m_ungroup_tvobst = false;
91  bool m_ungroup_sg = false;
92  bool m_finished = false;
93  int m_max_obstacles;
94 };
95 
97  public:
100  std::vector<const CollisionObject *> &result,
101  const std::unordered_map<const collision::CollisionObject *,
102  std::list<CollisionObjectConstPtr>> &parent_map)
103  : m_subject_object(subject_object),
104  m_result(result),
105  m_parent_map(parent_map){};
106 
107  void addRequestResultObstacle(const CollisionObject *obst);
108 
110  return m_subject_object;
111  }
112 
113  private:
114  fcl::CollisionObject<FCL_PRECISION> *m_subject_object;
115  std::vector<const CollisionObject *> &m_result;
116  const std::unordered_map<const CollisionObject *,
117  std::list<CollisionObjectConstPtr>> &m_parent_map;
118  std::unordered_map<const CollisionObject *, bool> m_added_map;
119 };
120 
122  public:
124  const ICollisionContainer *cont_2)
125  : m_cont_1(cont_1), m_cont_2(cont_2){};
126 
127  void addRequestResultPair(int o1, int o2);
128 
129  void addRequestResultList(std::list<int> list1, std::list<int> list2);
130 
131  std::set<std::pair<int, int>> getRequestResultPairs() const;
132 
133  int set_debug_pairs(std::vector<std::pair<int, int>> pairs_in) {
134  m_Debug_Pairs = pairs_in;
135  return 0;
136  }
137 
138  int get_debug_pairs(std::vector<std::pair<int, int>> &pairs_out) const {
139  pairs_out = m_Debug_Pairs;
140  return 0;
141  }
142 
143  const ICollisionContainer *get_cont_1(void) const { return m_cont_1; }
144  const ICollisionContainer *get_cont_2(void) const { return m_cont_2; }
145 
146  std::set<std::pair<fcl::CollisionObject<FCL_PRECISION> *,
149 
150  private:
151  const ICollisionContainer *m_cont_1;
152  const ICollisionContainer *m_cont_2;
153 
154  std::vector<std::pair<int, int>> m_Debug_Pairs;
155 
156  std::set<std::pair<int, int>> m_ResultPairs;
157 };
158 
161 // CollisionData struct MUST not be changed
162 template <typename S>
164  CollisionData() { done = false; }
165 
167  fcl::CollisionRequest<S> request;
168 
170  fcl::CollisionResult<S> result;
171 
173  bool done;
174 };
175 
176 template <typename S>
177 struct CollisionDataEx : public CollisionData<S> {
178  CollisionDataEx() { m_bool_result = false; }
179  void set_result(bool res) { m_bool_result = res; }
180  bool get_result(void) { return m_bool_result; }
181 
182  private:
183  bool m_bool_result;
184 };
185 
186 template <typename S>
189 
191  : self_reqData(reqData) {}
192 };
193 
194 template <typename S>
197 
199  : self_reqData(reqData) {}
200 };
201 template <typename S>
204 
206  : self_reqData(reqData) {}
207 };
208 
209 template <typename S>
212  void *cdata_) {
213  auto *cdata = static_cast<CollisionDataWindowQuery<S> *>(cdata_);
214  const auto &request = cdata->request;
215 
216  if (cdata->done) return true;
217 
218  const fcl::CollisionObject<S> *subj_obj =
219  cdata->self_reqData.getSubjectObject();
220 
221  if (o1 == subj_obj)
222 
223  {
224  cdata->self_reqData.addRequestResultObstacle(
226  } else if (o2 == subj_obj) {
227  cdata->self_reqData.addRequestResultObstacle(
229  }
230 
231  return cdata->done;
232 }
233 /*
234 template <typename S>
235 bool defaultprimitveCollisionFunction(solverFCL::CollisionObject<S>* o1,
236 solverFCL::CollisionObject<S>* o2, void* cdata_)
237 {
238 auto* cdata = static_cast<CollisionData<S>*>(cdata_);
239 const auto& request = cdata->request;
240 auto& result = cdata->result;
241 const CollisionObject* obj1_entity=getParentPointerFromFclObj(o1);
242 const CollisionObject* obj2_entity=getParentPointerFromFclObj(o2);
243 if(obj1_entity->collide(*obj2_entity,CollisionRequest(COL_PRIMITIVE)))
244 {
245 solverFCL::Contact<double> cont;
246 result.addContact(cont);
247 return true;
248 }
249 else
250 return false;
251 //cdata->result.addContact();
252 
253 }
254 */
255 
256 template <typename S>
258  fcl::CollisionObject<S> *o2, void *cdata_) {
259  auto *cdata = static_cast<CollisionData<S> *>(cdata_);
260  const auto &request = cdata->request;
261  auto &result = cdata->result;
262 
263  if (cdata->done) return true;
264 
265  collide(o1, o2, request, result);
266 
267  if (!request.enable_cost && (result.isCollision()) &&
268  (result.numContacts() >= request.num_max_contacts))
269  cdata->done = true;
270 
271  return cdata->done;
272 }
273 
274 template <typename S>
277  void *cdata_) {
278  CollisionDataOverlap<S> *cdata =
279  static_cast<CollisionDataOverlap<S> *>(cdata_);
280  fcl::CollisionRequest<S> *request = &(cdata->request);
281  fcl::CollisionResult<S> *result = &(cdata->result);
282 
283  if (cdata->done) return true;
284 
285  const auto &pair_obj =
286  std::pair<fcl::CollisionObject<S> *, fcl::CollisionObject<S> *>(o1, o2);
287 
288  // TODO: if collision detected earlier - don't check again!
289  auto &checked_pairs = cdata->self_reqData.checkedPairs;
290  auto search = checked_pairs.find(pair_obj);
291  if (search != checked_pairs.end()) return false;
292 
293  fcl::collide(o1, o2, *request, *result);
294 
295  checked_pairs.emplace(pair_obj);
296 
297  if (cdata->result.isCollision()) {
298  (cdata->result).clear();
299  const CollisionObject *obj1_entity = getParentPointerFromFclObj(o1);
300  const CollisionObject *obj2_entity = getParentPointerFromFclObj(o2);
301 
302  if (obj1_entity && obj2_entity) {
303  std::list<int> cont1_obj1_list;
304  std::list<int> cont1_obj2_list;
305  std::list<int> cont2_obj1_list;
306  std::list<int> cont2_obj2_list;
307 
308  int res_cont1_obj1 =
309  cdata->self_reqData.get_cont_1()->queryContainedObjectIndexList(
310  obj1_entity, cont1_obj1_list);
311  int res_cont1_obj2 =
312  cdata->self_reqData.get_cont_1()->queryContainedObjectIndexList(
313  obj2_entity, cont1_obj2_list);
314 
315  int res_cont2_obj1 =
316  cdata->self_reqData.get_cont_2()->queryContainedObjectIndexList(
317  obj1_entity, cont2_obj1_list);
318  int res_cont2_obj2 =
319  cdata->self_reqData.get_cont_2()->queryContainedObjectIndexList(
320  obj2_entity, cont2_obj2_list);
321 
322  if (!res_cont1_obj1 && !res_cont2_obj1) // obj1 is in both containers
323  {
324  cdata->self_reqData.addRequestResultList(cont1_obj1_list,
325  cont2_obj1_list);
326  }
327 
328  if (!res_cont1_obj2 && !res_cont2_obj2) // obj2 is in both containers
329  {
330  cdata->self_reqData.addRequestResultList(cont1_obj2_list,
331  cont2_obj2_list);
332  }
333  if (!res_cont1_obj1 &&
334  !res_cont2_obj2) // obj1 in container 1, obj2 in container 2
335  {
336  cdata->self_reqData.addRequestResultList(cont1_obj1_list,
337  cont2_obj2_list);
338  }
339 
340  if (!res_cont1_obj2 &&
341  !res_cont2_obj1) // obj1 in container 1, obj2 in container 2
342  {
343  cdata->self_reqData.addRequestResultList(cont1_obj2_list,
344  cont2_obj1_list);
345  }
346  }
347  }
348 
349  return cdata->done;
350 }
351 
352 template <typename S>
355  void *cdata_) {
356  auto *cdata = static_cast<CollisionDataListOfObstacles<S> *>(cdata_);
357  const auto &request = cdata->request;
358 
359  if (cdata->done) return true;
360 
361  fcl::CollisionObject<S> *obst = 0;
362 
363  fcl::CollisionObject<S> *subj = 0;
364 
365  // TODO: if collision detected earlier - don't check again!
366  if (cdata->self_reqData.getObstacleCallbackOrder()) {
367  obst = o1;
368  subj = o2;
369  } else {
370  subj = o1;
371  obst = o2;
372  }
373 
374  const auto &pair_obj =
375  std::pair<fcl::CollisionObject<S> *, fcl::CollisionObject<S> *>(obst,
376  subj);
377 
378  if (!(cdata->self_reqData.testPair(pair_obj))) return false;
379 
380  collide(obst, subj, request, cdata->result);
381 
382  if (cdata->result.isCollision()) {
383  cdata->set_result(true);
384 
385  cdata->result.clear();
386 
387  const CollisionObject *obst_entity = getParentPointerFromFclObj(obst);
388  const CollisionObject *subj_entity = getParentPointerFromFclObj(subj);
389 
390  // try to add both, as the order in the callback is undefined
391  if (cdata->self_reqData.addRequestResultObstacle(obst_entity)) {
392  cdata->self_reqData.setAllObst_added();
393  return true;
394  }
395  if (cdata->self_reqData.addRequestResultObstacle(subj_entity)) {
396  cdata->self_reqData.setAllObst_added();
397  return true;
398  }
399  }
400 
401  return cdata->done;
402 }
403 
404 } // namespace solverFCL
405 } // namespace solvers
406 
407 } // namespace collision
408 
409 #endif /* COLLISION_FCL_FCL_COLLISION_REQUESTS_H_ */
int get_debug_pairs(std::vector< std::pair< int, int >> &pairs_out) const
std::shared_ptr< const CollisionChecker > CollisionCheckerConstPtr
bool defaultCollisionFunctionListOfObstacles(fcl::CollisionObject< S > *o1, fcl::CollisionObject< S > *o2, void *cdata_)
CollisionDataListOfObstacles(CollisionRequestDataMultipleObstacles &reqData)
fcl::CollisionResult< S > result
Collision result.
bool done
Whether the collision iteration can stop.
void setSubjectEntitySize(fcl::BroadPhaseCollisionManager< FCL_PRECISION > *mngr)
void setSubjectEntitySize(fcl::CollisionObject< FCL_PRECISION > *obj)
int set_debug_pairs(std::vector< std::pair< int, int >> pairs_in)
std::shared_ptr< const CollisionObject > CollisionObjectConstPtr
fcl::CollisionObject< FCL_PRECISION > * getSubjectObject(void) const
std::shared_ptr< CollisionChecker > CollisionCheckerPtr
CollisionDataOverlap(CollisionRequestDataOverlap &reqData)
bool defaultCollisionFunctionOverlap(fcl::CollisionObject< S > *o1, fcl::CollisionObject< S > *o2, void *cdata_)
bool defaultCollisionFunctionWindowQuery(fcl::CollisionObject< S > *o1, fcl::CollisionObject< S > *o2, void *cdata_)
CollisionDataWindowQuery(CollisionRequestDataWindowQuery &reqData)
fcl::CollisionRequest< S > request
Collision request.
CollisionRequestDataOverlap(const ICollisionContainer *cont_1, const ICollisionContainer *cont_2)
std::set< std::pair< fcl::CollisionObject< FCL_PRECISION > *, fcl::CollisionObject< FCL_PRECISION > * > > checkedPairs
bool defaultCollisionFunction(fcl::CollisionObject< S > *o1, fcl::CollisionObject< S > *o2, void *cdata_)
CollisionObject * getParentPointerFromFclObj(fcl::CollisionObject< FCL_PRECISION > *fcl_obj)
CollisionRequestDataMultipleObstacles(std::vector< CollisionObjectConstPtr > &ret_obstacles, const std::unordered_map< const CollisionObject *, std::list< CollisionObjectConstPtr >> &parent_map, int max_obstacles)
Base class for CollisionObjects and some of their groups.
Collision data stores the collision request and the result given by collision algorithm.
CollisionRequestDataWindowQuery(fcl::CollisionObject< FCL_PRECISION > *subject_object, std::vector< const CollisionObject *> &result, const std::unordered_map< const collision::CollisionObject *, std::list< CollisionObjectConstPtr >> &parent_map)