SetupCollisionPair.cpp
Go to the documentation of this file.
1 // -*- C++ -*-
10 #include <iomanip>
11 #include <hrpModel/Link.h>
12 #include <hrpModel/ModelLoaderUtil.h>
13 #include <hrpModel/JointPath.h>
14 #include <hrpUtil/Eigen3d.h>
15 #include <hrpUtil/Eigen4d.h>
17 #include "CollisionDetector.h"
18 extern "C" {
19 #if (defined __APPLE__)
20 #include <pcl/surface/qhull.h>
21 #else
22 #include <qhull/qhull_a.h>
23 #endif
24 }
25 
26 #define deg2rad(x) ((x)*M_PI/180)
27 #define rad2deg(x) ((x)*180/M_PI)
28 
29 std::vector<hrp::ColdetLinkPairPtr> m_pair;
30 std::vector<std::string> blacklist;
32 
33 RTC::ReturnCode_t setupCollisionModel(hrp::BodyPtr m_robot, const char *url, OpenHRP::BodyInfo_var binfo) {
34  // do qhull
35  OpenHRP::ShapeInfoSequence_var sis = binfo->shapes();
36  OpenHRP::LinkInfoSequence_var lis = binfo->links();
37  for(unsigned int i = 0; i < m_robot->numLinks(); i++ ) {
38  const OpenHRP::LinkInfo& i_li = lis[i];
39  const OpenHRP::TransformedShapeIndexSequence& tsis = i_li.shapeIndices;
40  // setup
41  int numTriangles = 0;
42  for (unsigned int l=0; l<tsis.length(); l++) {
43  OpenHRP::ShapeInfo& si = sis[tsis[l].shapeIndex];
44  const OpenHRP::LongSequence& triangles = si.triangles;
45  numTriangles += triangles.length();
46  }
47  double points[numTriangles*3];
48  int points_i = 0;
49  hrp::Matrix44 Rs44; // inv
50  hrp::Matrix33 Rs33 = m_robot->link(i)->Rs;
51 
52  Rs44 << Rs33(0,0),Rs33(0,1), Rs33(0,2), 0,
53  Rs33(1,0),Rs33(1,1), Rs33(1,2), 0,
54  Rs33(2,0),Rs33(2,1), Rs33(2,2), 0,
55  0.0, 0.0, 0.0, 1.0;
56  for (unsigned int l=0; l<tsis.length(); l++) {
57  const OpenHRP::DblArray12& M = tsis[l].transformMatrix;
58  hrp::Matrix44 T0;
59  T0 << M[0], M[1], M[2], M[3],
60  M[4], M[5], M[6], M[7],
61  M[8], M[9], M[10], M[11],
62  0.0, 0.0, 0.0, 1.0;
63  hrp::Matrix44 T(Rs44 * T0);
64  const OpenHRP::ShapeInfo& si = sis[tsis[l].shapeIndex];
65  const OpenHRP::LongSequence& triangles = si.triangles;
66  const float *vertices = si.vertices.get_buffer();
67 
68  for(unsigned int j=0; j < triangles.length() / 3; ++j){
69  for(int k=0; k < 3; ++k){
70  long orgVertexIndex = si.triangles[j * 3 + k];
71  int p = orgVertexIndex * 3;
72 
73  hrp::Vector4 v(T * hrp::Vector4(vertices[p+0], vertices[p+1], vertices[p+2], 1.0));
74  points[points_i++] = v[0];
75  points[points_i++] = v[1];
76  points[points_i++] = v[2];
77  }
78  }
79  }
80 
81  hrp::ColdetModelPtr coldetModel(new hrp::ColdetModel());
82  coldetModel->setName(std::string(i_li.name));
83  // qhull
84  int vertexIndex = 0;
85  int triangleIndex = 0;
86  int num = 0;
87  char flags[250];
88  boolT ismalloc = False;
89  sprintf(flags,"qhull Qt Tc");
90  if (! qh_new_qhull (3,numTriangles,points,ismalloc,flags,NULL,stderr) ) {
91 
92  qh_triangulate();
93  qh_vertexneighbors();
94 
95  vertexT *vertex,**vertexp;
96  coldetModel->setNumVertices(qh num_vertices);
97  coldetModel->setNumTriangles(qh num_facets);
98  int index[qh num_vertices];
99  FORALLvertices {
100  int p = qh_pointid(vertex->point);
101  index[p] = vertexIndex;
102  coldetModel->setVertex(vertexIndex++, points[p*3+0], points[p*3+1], points[p*3+2]);
103  }
104  facetT *facet;
105  num = qh num_facets;;
106  {
107  FORALLfacets {
108  int j = 0, p[3];
109  setT *vertices = qh_facet3vertex (facet);
110  FOREACHvertexreverse12_ (vertices) {
111  if (j<3) {
112  p[j] = index[qh_pointid(vertex->point)];
113  } else {
114  fprintf(stderr, "extra vertex %d\n",j);
115  }
116  j++;
117  }
118  coldetModel->setTriangle(triangleIndex++, p[0], p[1], p[2]);
119  }
120  }
121  } // qh_new_qhull
122 
123  coldetModel->build();
124  m_robot->link(i)->coldetModel = coldetModel;
125 
126  qh_freeqhull(!qh_ALL);
127  int curlong, totlong;
128  qh_memfreeshort (&curlong, &totlong);
129  if (curlong || totlong) {
130  fprintf(stderr, "convhulln: did not free %d bytes of long memory (%d pieces)\n", totlong, curlong);
131  }
132  //
133  std::cerr << std::setw(16) << i_li.name << " reduce triangles from " << std::setw(5) << numTriangles << " to " << std::setw(4) << num << std::endl;
134  }
135 
136  return RTC::RTC_OK;
137 }
138 
139 bool checkCollisionForAllJointRange(int i, hrp::JointPathPtr jointPath, std::vector<hrp::ColdetLinkPairPtr> &collisionPairs)
140 {
141  if ( i >= (int)jointPath->numJoints() ) return false;
142  if ( collisionPairs.size() == 0 ) return true;
143  hrp::Link *l = jointPath->joint(i);
144 
145  if ( l->jointType == hrp::Link::FIXED_JOINT ) {
146  checkCollisionForAllJointRange(i+1, jointPath, collisionPairs);
147  } else {
148  double step = (l->ulimit - l->llimit)/2;
149  for(float angle = l->llimit; angle <= l->ulimit; angle += step)
150  {
151  l->q = angle;
152  m_robot->calcForwardKinematics(false,false);
153  m_robot->updateLinkColdetModelPositions();
154 
155  //std::cerr << " " << collisionPair->link(0)->name << ":" << collisionPair->link(1)->name << " ";
156  //for(int j = 0; j < jointPath->numJoints(); j++) std::cerr << rad2deg(jointPath->joint(j)->q) << " ";
157  // std::cerr << "id = " << i << "/" << jointPath->numJoints() << ", " << l->name << " " << rad2deg(angle) << " (" << rad2deg(l->llimit) << "," << rad2deg(l->ulimit) << ") " << collisionPair->detectIntersection() << " " << collisionPair->link(0)->name << ":" << collisionPair->link(1)->name << std::endl;
158  for(std::vector<hrp::ColdetLinkPairPtr>::iterator it = collisionPairs.begin(); it != collisionPairs.end(); ) {
159  if ( (*it)->detectIntersection() ) {
160  std::cerr << "Find collision for " << (*it)->link(0)->name << " " << (*it)->link(1)->name << std::endl;
161  it = collisionPairs.erase(it);
162  continue;
163  }
164  it++;
165  }
166  checkCollisionForAllJointRange(i+1, jointPath, collisionPairs);
167  }
168  }
169  return false;
170 }
171 
173  for(std::vector<std::string>::iterator it = blacklist.begin(); it != blacklist.end(); it++ ) {
174  if (l->name == (*it)) return true;
175  }
176  return false;
177 }
178 
180  for(std::vector<std::string>::iterator it = blacklist.begin(); it != blacklist.end(); it++ ) {
181  if ((l1->name + ":" + l2->name) == (*it) ||
182  (l2->name + ":" + l1->name) == (*it)) return true;
183  }
184  return false;
185 }
186 
188  return (m_robot->getJointPath(p1->link(0),p1->link(1))->numJoints()) > (m_robot->getJointPath(p2->link(0),p2->link(1))->numJoints());
189 }
190 
192 {
193  std::vector<hrp::ColdetLinkPairPtr> tmp_pair;
194 
195  std::cerr << "Setup Initial collision pair without " << std::endl;
196  for(std::vector<std::string>::iterator it = blacklist.begin(); it != blacklist.end(); it++ ) {
197  std::cerr << *it << " ";
198  }
199  std::cerr << std::endl;
200  // find link to be ignored as the link is included in the parent link
201  // need AABBCollision?
202  //
203  // set all collisoin pair
204  for (unsigned int i=0; i<m_robot->numLinks(); i++) {
205  hrp::Link *l1 = m_robot->link(i);
206  for (unsigned int j=i+1; j<m_robot->numLinks(); j++) {
207  hrp::Link *l2 = m_robot->link(j);
208  if ( l1->coldetModel && l2->coldetModel
210  ) {
211  tmp_pair.push_back(new hrp::ColdetLinkPair(l1, l2));
212  }
213  }
214  }
215 
216  std::cerr << "Initial collision pair size " << tmp_pair.size() << std::endl;
217  std::vector<hrp::ColdetLinkPairPtr>::iterator it;
218  // Remove collision pair if the pair always collides
219  std::cerr << "step 0: Remove collision pair if they are adjacent pair" << std::endl;
220  it = tmp_pair.begin();
221  while ( it != tmp_pair.end() ) {
222  hrp::JointPathPtr jointPath = m_robot->getJointPath((*it)->link(0),(*it)->link(1));
223  if ( jointPath->numJoints() == 1 ) {
224  hrp::Link *l = jointPath->joint(0);
225  bool always_collide = true; // true if always collide
226  bool never_collide = true; // true if never collide ( crrect )
227  l->llimit = -M_PI;l->ulimit = M_PI;
228  std::cerr << l->name << " ulimit - " << l->llimit << " " << l->ulimit << std::endl;
229  for(float angle = l->llimit; angle <= l->ulimit; angle += deg2rad(5)) {
230  l->q = angle;
231  m_robot->calcForwardKinematics(false,false);
232  m_robot->updateLinkColdetModelPositions();
233  if ( (*it)->detectIntersection() ) {
234  never_collide = false;
235  } else {
236  always_collide = false;
237  }
238  //std::cerr << l->name << " " << deg2rad(l->q) << " intersect:" << (*it)->detectIntersection() << " check:" << (*it)->checkCollision() << std::endl;
239  (*it)->clearCollisions();
240  }
241  std::cerr << " pair (" << jointPath->numJoints() << ") " << (*it)->link(0)->name << "/" << (*it)->link(1)->name << (always_collide?" always collide":"") << (never_collide?" never collide":"") << std::endl;
242  it = tmp_pair.erase(it);
243  continue;
244  }
245  it++;
246  }
247  //
248  std::cerr << "step 1: Remove complex (2 or 3 distance) collision pair if they never/always collide" << std::endl;
249  it = tmp_pair.begin();
250  while ( it != tmp_pair.end() ) {
251  hrp::JointPathPtr jointPath = m_robot->getJointPath((*it)->link(0),(*it)->link(1));
252  if ( jointPath->numJoints() == 2 || jointPath->numJoints() == 3 ) {
253  hrp::Link *l = jointPath->joint(0);
254  bool always_collide = true; // true if always collide
255  bool never_collide = true; // true if never collide ( crrect )
256  for(float angle = l->llimit; angle <= l->ulimit; angle += deg2rad(5)) {
257  l->q = angle;
258  m_robot->calcForwardKinematics(false,false);
259  m_robot->updateLinkColdetModelPositions();
260  if ( (*it)->detectIntersection() ) {
261  never_collide = false;
262  } else {
263  always_collide = false;
264  }
265  //std::cerr << l->name << " " << deg2rad(l->q) << " intersect:" << (*it)->detectIntersection() << " check:" << (*it)->checkCollision() << std::endl;
266  (*it)->clearCollisions();
267  }
268  std::cerr << " pair (" << jointPath->numJoints() << ") " << (*it)->link(0)->name << "/" << (*it)->link(1)->name << " always:" << always_collide << ", never:" << never_collide << " " << (( always_collide || never_collide )?"remove from list":"") << std::endl;
269  if ( always_collide || never_collide ) {
270  it = tmp_pair.erase(it);
271  continue;
272  } else {
273  m_pair.push_back(*it);
274  }
275  }
276  it++;
277  }
278  std::cerr << " Remove always/never collide pair for a length of 1,2,3 ... " << tmp_pair.size() << std::endl;
279 
280  // setup data structure for check collision pair
281  // pair_tree[<pair:L1,L2,L3,L4>, [ <pair:L1,L2,L3,L4>, <pair:L1,L2,L3>, <pair:L1,L2> ]]
282  // pair_tree[<pair:L2,L3,L4,L5>, [ <pair:L2,L3,L4,L5>, <pair:L2,L3,L4>, <pair:L2,L3> ]]
283  std::map<hrp::ColdetLinkPairPtr, std::vector<hrp::ColdetLinkPairPtr> > pair_tree;
284  std::sort(tmp_pair.begin(), tmp_pair.end(), compare_joint_path_length);
285  int i = 0;
286  it = tmp_pair.begin();
287  while ( it != tmp_pair.end() ) {
288  hrp::JointPathPtr jointPath1 = m_robot->getJointPath((*it)->link(0),(*it)->link(1));
289  //std::cerr << " " << i << "/" << tmp_pair.size() << " pair (" << jointPath1->numJoints() << ") " << (*it)->link(0)->name << " " << (*it)->link(1)->name <<std::endl;
290  // check if JointPath1 is included in some of the pair_tree (jointPath2)
291  bool is_new_key = true;
292  for (std::map<hrp::ColdetLinkPairPtr, std::vector<hrp::ColdetLinkPairPtr> >::iterator ii=pair_tree.begin(); ii != pair_tree.end(); ++ii) {
293  hrp::JointPathPtr jointPath2 = m_robot->getJointPath(((*ii).first)->link(0),((*ii).first)->link(1));
294  // check if JointPath1 is included in jointPath2
295  bool find_key = true;
296  for (unsigned int j = 0; j < jointPath1->numJoints() ; j++ ) {
297  if ( jointPath1->joint(j)->name != jointPath2->joint(j)->name ) {
298  find_key = false;
299  break;
300  }
301  }
302  if ( find_key ) {
303  (*ii).second.push_back(*it);
304  is_new_key = false;
305  }
306  }
307  if (is_new_key) {
308  pair_tree[*it] = std::vector<hrp::ColdetLinkPairPtr>(1,*it)
309 ;
310  }
311  it++; i++;
312  }
313  // remove non-collisin pair from tmp_pair
314  std::cerr << "step 2: Remove collision pair if they never collide" << std::endl;
315  i = 0;
316  for (std::map<hrp::ColdetLinkPairPtr, std::vector<hrp::ColdetLinkPairPtr> >::iterator ii=pair_tree.begin(); ii != pair_tree.end(); ++ii) {
317  hrp::ColdetLinkPairPtr key_pair = (*ii).first;
318  std::vector<hrp::ColdetLinkPairPtr> sub_pairs = (*ii).second;
319  hrp::JointPathPtr jointPath = m_robot->getJointPath(key_pair->link(0),key_pair->link(1));
320  std::sort(sub_pairs.begin(), sub_pairs.end(), compare_joint_path_length);
321  //
322  std::cerr << " " << i << "/" << tmp_pair.size() << " pair (" << jointPath->numJoints() << ") " << (*ii).first->link(0)->name << " " << (*ii).first->link(1)->name <<std::endl;
323  i += (*ii).second.size();
324  for(std::vector<hrp::ColdetLinkPairPtr>::iterator it = sub_pairs.begin(); it != sub_pairs.end(); it++ ) {
325  hrp::JointPathPtr jointPath = m_robot->getJointPath((*it)->link(0),(*it)->link(1));
326  for ( unsigned int j = 0; j < jointPath->numJoints(); j++ ) {
327  std::cerr << jointPath->joint(j)->name << " ";
328  }
329  std::cerr << std::endl;
330  }
331  // rmeove non-collision pair from sub_paris
332  checkCollisionForAllJointRange(0, jointPath, sub_pairs);
333  for(std::vector<hrp::ColdetLinkPairPtr>::iterator p = sub_pairs.begin(); p != sub_pairs.end(); p++ ) {
334  for(std::vector<hrp::ColdetLinkPairPtr>::iterator it = tmp_pair.begin(); it != tmp_pair.end(); ) {
335  if ( (*p)->link(0) == (*it)->link(0) && (*p)->link(1) == (*it)->link(1) ) {
336  tmp_pair.erase(it);
337  continue;
338  }
339  it++;
340  }
341  //tmp_pair.erase(it); // does not work???
342  }
343  }
344  it = tmp_pair.begin();
345  while ( it != tmp_pair.end() ) {
346  m_pair.push_back(*it);
347  it++;
348  }
349  std::cerr << "Reduced collision pair size " << m_pair.size() << std::endl;
350 }
351 
352 int main (int argc, char** argv)
353 {
354  std::string url;
355 
356  for (int i = 1; i < argc; ++ i) {
357  std::string arg(argv[i]);
358  coil::normalize(arg);
359  if ( arg == "--model" ) {
360  if (++i < argc) url = argv[i];
361  } else if ( arg == "-o" ) {
362  ++i;
363  } else if ( arg[0] == '-' || arg[0] == '_' ) {
364  std::cerr << argv[0] << " : Unknwon arguments " << arg << std::endl;
365  } else {
366  blacklist.push_back(argv[i]);
367  }
368  }
369  if (argc < 2) {
370  std::cerr << "usage: " << argv[0] << " --model <model file> <blacklist : R_HAND_J0 L_HAND_J0 EYEBROW_P EYELID_P EYE_Y EYE_P MOUTH_P UPPERLIP_P LOWERLIP_P CHEEK_P>" << std::endl;
371  exit(1);
372  }
373 
374  m_robot = hrp::BodyPtr(new hrp::Body());
375  OpenHRP::BodyInfo_var binfo = hrp::loadBodyInfo(url.c_str(), argc, argv);
376  if (CORBA::is_nil(binfo)){
377  std::cerr << "failed to load model[" << url << "]" << std::endl;
378  return 1;
379  }
380  if (!loadBodyFromBodyInfo(m_robot, binfo)) {
381  std::cerr << "failed to load model[" << url << "]" << std::endl;
382  return 1;
383  }
384  setupCollisionModel(m_robot, url.c_str(), binfo);
386 
387  std::string fname = "/tmp/"+m_robot->name()+"collision_pair.conf";
388  std::ofstream ofs(fname.c_str());
389  ofs << "collision_pair:";
390  for (std::vector<hrp::ColdetLinkPairPtr>::iterator it = m_pair.begin(); it != m_pair.end(); it++) {
391  ofs << " " << (*it)->link(0)->name << ":" << (*it)->link(1)->name;
392  std::cerr << (*it)->link(0)->name << ":" << (*it)->link(1)->name << std::endl;
393  }
394  ofs << std::endl;
395  ofs.close();
396  std::cerr << "Write collision pair conf file to " << fname << std::endl;
397 
398  return 0;
399 }
bool compare_joint_path_length(const hrp::ColdetLinkPairPtr &p1, const hrp::ColdetLinkPairPtr &p2)
std::string normalize(std::string &str)
bool checkBlackListJointPair(hrp::Link *l1, hrp::Link *l2)
HRPMODEL_API OpenHRP::BodyInfo_var loadBodyInfo(const char *url, int &argc, char *argv[])
#define deg2rad(x)
png_uint_32 i
Eigen::Matrix4d Matrix44
png_uint_32 int flags
boost::shared_ptr< Body > BodyPtr
RTC::ReturnCode_t setupCollisionModel(hrp::BodyPtr m_robot, const char *url, OpenHRP::BodyInfo_var binfo)
Eigen::Matrix3d Matrix33
std::vector< hrp::ColdetLinkPairPtr > m_pair
def j(str, encoding="cp932")
list index
bool checkBlackListJoint(hrp::Link *l)
void setupCollisionLinkPair()
Eigen::Vector4d Vector4
#define M_PI
std::string sprintf(char const *__restrict fmt,...)
bool checkCollisionForAllJointRange(int i, hrp::JointPathPtr jointPath, std::vector< hrp::ColdetLinkPairPtr > &collisionPairs)
hrp::BodyPtr m_robot
int loadBodyFromBodyInfo(::World *world, const char *_name, BodyInfo_ptr bodyInfo)
int main(int argc, char **argv)
int num
char * arg
boost::intrusive_ptr< ColdetLinkPair > ColdetLinkPairPtr
boost::intrusive_ptr< ColdetModel > ColdetModelPtr
std::vector< std::string > blacklist


hrpsys
Author(s): AIST, Fumio Kanehiro
autogenerated on Thu May 6 2021 02:41:51