globalrelocation.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484
  1. #include "globalrelocation.h"
  2. #include <pcl/filters/voxel_grid.h>
  3. #include <tf/tf.h>
  4. #include <pcl/io/pcd_io.h>
  5. GlobalRelocation::GlobalRelocation()
  6. {
  7. // std::cout<<" run hear."<<std::endl;
  8. if(mnThreadNum > MAX_NDT)mnThreadNum = MAX_NDT;
  9. int i;
  10. for(i=0;i<MAX_NDT;i++)mpthread[i] = NULL;
  11. }
  12. void GlobalRelocation::threadtest(int n,iv::Reloc & xReloc)
  13. {
  14. }
  15. void GlobalRelocation::threadReloc(int nThread,cpu::NormalDistributionsTransform<pcl::PointXYZ, pcl::PointXYZ> * pndt,
  16. pcl::PointCloud<pcl::PointXYZ>::Ptr raw_scan,
  17. iv::Reloc xReloc)
  18. {
  19. xReloc.x_calc = xReloc.x_guess;
  20. xReloc.y_calc = xReloc.y_guess;
  21. xReloc.z_calc = xReloc.z_guess;
  22. xReloc.yaw_calc = xReloc.yaw_guess;
  23. xReloc.pitch_calc = 0;// xReloc.pitch_guess;
  24. xReloc.roll_calc = 0;//xReloc.roll_guess;
  25. xReloc.trans_prob = 0;
  26. Eigen::Matrix4f tf_btol;
  27. Eigen::Translation3f tl_btol(0, 0, 0); // tl: translation
  28. Eigen::AngleAxisf rot_x_btol(0, Eigen::Vector3f::UnitX()); // rot: rotation
  29. Eigen::AngleAxisf rot_y_btol(0, Eigen::Vector3f::UnitY());
  30. Eigen::AngleAxisf rot_z_btol(0, Eigen::Vector3f::UnitZ());
  31. tf_btol = (tl_btol * rot_z_btol * rot_y_btol * rot_x_btol).matrix();
  32. double fLastProb = 0.0;
  33. int i;
  34. for(i=0;i<50;i++)
  35. {
  36. double voxel_leaf_size = 2.0;
  37. pcl::PointCloud<pcl::PointXYZ>::Ptr filtered_scan(new pcl::PointCloud<pcl::PointXYZ>());
  38. pcl::VoxelGrid<pcl::PointXYZ> voxel_grid_filter;
  39. voxel_grid_filter.setLeafSize(voxel_leaf_size, voxel_leaf_size, voxel_leaf_size);
  40. voxel_grid_filter.setInputCloud(raw_scan);
  41. voxel_grid_filter.filter(*filtered_scan);
  42. pcl::PointCloud<pcl::PointXYZ>::Ptr filtered_scan_ptr(new pcl::PointCloud<pcl::PointXYZ>(*filtered_scan));
  43. pndt->setInputSource(filtered_scan_ptr);
  44. Eigen::Translation3f init_translation(xReloc.x_calc,xReloc.y_calc, xReloc.z_calc);
  45. Eigen::AngleAxisf init_rotation_x(xReloc.roll_calc, Eigen::Vector3f::UnitX());
  46. Eigen::AngleAxisf init_rotation_y(xReloc.pitch_calc, Eigen::Vector3f::UnitY());
  47. Eigen::AngleAxisf init_rotation_z(xReloc.yaw_calc, Eigen::Vector3f::UnitZ());
  48. Eigen::Matrix4f init_guess = (init_translation * init_rotation_z * init_rotation_y * init_rotation_x) * tf_btol;
  49. pcl::PointCloud<pcl::PointXYZ>::Ptr aligned(new pcl::PointCloud<pcl::PointXYZ>());
  50. pndt->align(*aligned,init_guess);
  51. bool has_converged;
  52. int iteration = 0;
  53. double fitness_score = 0.0;
  54. double trans_probability = 0.0;
  55. Eigen::Matrix4f t(Eigen::Matrix4f::Identity());
  56. Eigen::Matrix4f t2(Eigen::Matrix4f::Identity());
  57. has_converged = pndt->hasConverged();
  58. t = pndt->getFinalTransformation();
  59. iteration = pndt->getFinalNumIteration();
  60. fitness_score = pndt->getFitnessScore();
  61. trans_probability = pndt->getTransformationProbability();
  62. t2 = t * tf_btol.inverse();
  63. double x,y,z,yaw,pitch,roll;
  64. tf::Matrix3x3 mat_b; // base_link
  65. mat_b.setValue(static_cast<double>(t2(0, 0)), static_cast<double>(t2(0, 1)), static_cast<double>(t2(0, 2)),
  66. static_cast<double>(t2(1, 0)), static_cast<double>(t2(1, 1)), static_cast<double>(t2(1, 2)),
  67. static_cast<double>(t2(2, 0)), static_cast<double>(t2(2, 1)), static_cast<double>(t2(2, 2)));
  68. // Update ndt_pose
  69. x = t2(0, 3);
  70. y = t2(1, 3);
  71. z = t2(2, 3);
  72. // ndt_pose.x = localizer_pose.x;
  73. // ndt_pose.y = localizer_pose.y;
  74. // ndt_pose.z = localizer_pose.z;
  75. mat_b.getRPY(roll, pitch, yaw, 1);
  76. xReloc.x_calc = x;
  77. xReloc.y_calc = y;
  78. xReloc.z_calc = z;
  79. xReloc.roll_calc = roll;
  80. xReloc.pitch_calc = pitch;
  81. xReloc.yaw_calc =yaw;
  82. xReloc.trans_prob = trans_probability;
  83. // std::cout<<"guass x:"<<xReloc.x_guess<<" res:"<<" x: "<<xReloc.x_calc<<" y: "<<xReloc.y_calc<<" prob: "<<xReloc.trans_prob<<" step: "<<i<<std::endl;
  84. if((i>=10)&&(xReloc.trans_prob<1.0))
  85. {
  86. break;
  87. }
  88. if((xReloc.trans_prob>3.0) && ((xReloc.trans_prob - fLastProb)<0.01) && (i>20))
  89. {
  90. break;
  91. }
  92. if((xReloc.trans_prob<1.5) && ((xReloc.trans_prob - fLastProb)<0.01) && (i>20))
  93. {
  94. break;
  95. }
  96. fLastProb = xReloc.trans_prob;
  97. }
  98. mmutexReloc.lock();
  99. mvectorReloc.push_back(xReloc);
  100. mmutexReloc.unlock();
  101. std::cout<<"guass x:"<<xReloc.x_guess<<" y:"<<xReloc.y_guess<<" res:"<<" x: "<<xReloc.x_calc<<" y: "<<xReloc.y_calc<<" prob: "<<xReloc.trans_prob<<std::endl;
  102. mthreadcomplete[nThread] = true;
  103. }
  104. void GlobalRelocation::RunReloc(std::vector<iv::ndttracepoint> & xtrace,pcl::PointCloud<pcl::PointXYZ>::Ptr raw_scan,bool bCheckComplete)
  105. {
  106. int i;
  107. bool bComplete = false;
  108. bool bHaveTask = true;
  109. int ntracesize = static_cast<int>(xtrace.size());
  110. int j = 0;
  111. if(j == ntracesize)bHaveTask = false;
  112. while(bComplete == false)
  113. {
  114. if(bHaveTask)
  115. {
  116. for(i=0;i<mnThreadNum;i++)
  117. {
  118. if((mthreadcomplete[i] == true) &&(bHaveTask))
  119. {
  120. if(mpthread[i] != NULL)
  121. {
  122. mpthread[i]->join();
  123. delete mpthread[i];
  124. mpthread[i] = NULL;
  125. }
  126. iv::Reloc xReloc;
  127. xReloc.x_guess = xtrace[j].x;
  128. xReloc.y_guess = xtrace[j].y;
  129. xReloc.z_guess = xtrace[j].z;
  130. xReloc.yaw_guess = xtrace[j].yaw;
  131. xReloc.pitch_guess = 0;
  132. xReloc.roll_guess = 0;
  133. if(j == ntracesize)bHaveTask = false;
  134. // std::thread * pthread = new std::thread(&GlobalRelocation::threadtest,this,i,xReloc);
  135. mthreadcomplete[i] = false;
  136. mpthread[i] = new std::thread(&GlobalRelocation::threadReloc,this,i,&mndt[i],raw_scan,xReloc);
  137. j++;
  138. if(j == ntracesize)bHaveTask = false;
  139. }
  140. }
  141. }
  142. else
  143. {
  144. for(i=0;i<mnThreadNum;i++)
  145. {
  146. if((mthreadcomplete[i] == true))
  147. {
  148. if(mpthread[i] != NULL)
  149. {
  150. mpthread[i]->join();
  151. delete mpthread[i];
  152. mpthread[i] = NULL;
  153. }
  154. }
  155. else
  156. {
  157. break;
  158. }
  159. }
  160. if(i == mnThreadNum)
  161. {
  162. bComplete = true;
  163. break;
  164. }
  165. }
  166. if(bCheckComplete)
  167. {
  168. for(i=0;i<mvectorReloc.size();i++)
  169. {
  170. if(mvectorReloc[i].trans_prob >= 3.0)
  171. {
  172. bHaveTask = false;
  173. std::cout<<" Complete. "<<std::endl;
  174. }
  175. }
  176. }
  177. std::this_thread::sleep_for(std::chrono::milliseconds(1));
  178. }
  179. }
  180. iv::Reloc GlobalRelocation::pointreloc(pcl::PointCloud<pcl::PointXYZ>::Ptr raw_scan)
  181. {
  182. iv::Reloc xreloczero;
  183. xreloczero.trans_prob = 0.0;
  184. if(mvectorndtmap.size() > 1)
  185. {
  186. std::cout<<" only one map, can use relocation."<<std::endl;
  187. return xreloczero;
  188. }
  189. if(mvectorndtmap.size() == 0)
  190. {
  191. std::cout<<" no map."<<std::endl;
  192. return xreloczero;
  193. }
  194. mvectorReloc.clear();
  195. int i;
  196. int j;
  197. for(i=0;i<mnThreadNum;i++)
  198. {
  199. mthreadcomplete[i] = true;
  200. }
  201. std::vector<iv::ndttracepoint> xtrace = mvectorseedpoint;
  202. RunReloc(xtrace,raw_scan,false);
  203. int nrelocsize = mvectorReloc.size();
  204. int indexmax = 0;
  205. double fMaxProb = 0.0;
  206. for(i=0;i<nrelocsize;i++)
  207. {
  208. if(mvectorReloc[i].trans_prob>fMaxProb)
  209. {
  210. fMaxProb = mvectorReloc[i].trans_prob;
  211. indexmax = i;
  212. }
  213. }
  214. if(fMaxProb > 2.0)
  215. {
  216. return mvectorReloc[indexmax];
  217. }
  218. std::cout<<" use diff yaw"<<std::endl;
  219. std::vector<iv::ndttracepoint> xtraceraw = mvectorseedpoint;
  220. xtrace.clear();
  221. for(i=0;i<xtraceraw.size();i++)
  222. {
  223. iv::ndttracepoint ntp = xtraceraw[i];
  224. for(j=1;j<mnCirclDivide;j++)
  225. {
  226. double yawadd = M_PI*2.0/mnCirclDivide;
  227. yawadd = yawadd * j;
  228. iv::ndttracepoint ntpyaw = ntp;
  229. ntpyaw.yaw = ntp.yaw + yawadd;
  230. if(ntpyaw.yaw >= 2.0*M_PI)ntpyaw.yaw = ntpyaw.yaw - 2.0*M_PI;
  231. xtrace.push_back(ntpyaw);
  232. }
  233. }
  234. RunReloc(xtrace,raw_scan,false);
  235. nrelocsize = mvectorReloc.size();
  236. indexmax = 0;
  237. fMaxProb = 0.0;
  238. for(i=0;i<nrelocsize;i++)
  239. {
  240. if(mvectorReloc[i].trans_prob>fMaxProb)
  241. {
  242. fMaxProb = mvectorReloc[i].trans_prob;
  243. indexmax = i;
  244. }
  245. }
  246. if(fMaxProb > 2.0)
  247. {
  248. return mvectorReloc[indexmax];
  249. }
  250. std::cout<<" use dis yaw"<<std::endl;
  251. xtraceraw = mvectorseedpoint;
  252. xtrace.clear();
  253. int k;
  254. for(k=1;k<10;k++)
  255. {
  256. for(i=0;i<xtraceraw.size();i++)
  257. {
  258. iv::ndttracepoint ntpraw = xtraceraw[i];
  259. iv::ndttracepoint ntp = ntpraw;
  260. ntp.x = ntpraw.x + k*mfSeedDisThresh * cos(ntpraw.yaw + M_PI/2.0);
  261. ntp.y = ntpraw.y + k*mfSeedDisThresh * sin(ntpraw.yaw + M_PI/2.0);
  262. for(j=0;j<mnCirclDivide;j++)
  263. {
  264. double yawadd = M_PI*2.0/mnCirclDivide;
  265. yawadd = yawadd * j;
  266. iv::ndttracepoint ntpyaw = ntp;
  267. ntpyaw.yaw = ntp.yaw + yawadd;
  268. if(ntpyaw.yaw >= 2.0*M_PI)ntpyaw.yaw = ntpyaw.yaw - 2.0*M_PI;
  269. xtrace.push_back(ntpyaw);
  270. }
  271. ntp = ntpraw;
  272. ntp.x = ntpraw.x + k*mfSeedDisThresh * cos(ntpraw.yaw - M_PI/2.0);
  273. ntp.y = ntpraw.y + k*mfSeedDisThresh * sin(ntpraw.yaw - M_PI/2.0);
  274. for(j=0;j<mnCirclDivide;j++)
  275. {
  276. double yawadd = M_PI*2.0/mnCirclDivide;
  277. yawadd = yawadd * j;
  278. iv::ndttracepoint ntpyaw = ntp;
  279. ntpyaw.yaw = ntp.yaw + yawadd;
  280. if(ntpyaw.yaw >= 2.0*M_PI)ntpyaw.yaw = ntpyaw.yaw - 2.0*M_PI;
  281. xtrace.push_back(ntpyaw);
  282. }
  283. }
  284. }
  285. RunReloc(xtrace,raw_scan,true);
  286. nrelocsize = mvectorReloc.size();
  287. indexmax = 0;
  288. fMaxProb = 0.0;
  289. for(i=0;i<nrelocsize;i++)
  290. {
  291. if(mvectorReloc[i].trans_prob>fMaxProb)
  292. {
  293. fMaxProb = mvectorReloc[i].trans_prob;
  294. indexmax = i;
  295. }
  296. }
  297. if(fMaxProb > 2.0)
  298. {
  299. std::cout<<" find pos."<<std::endl;
  300. return mvectorReloc[indexmax];
  301. }
  302. if(mvectorReloc.size() > 0)
  303. {
  304. return mvectorReloc[indexmax];
  305. }
  306. return xreloczero;
  307. }
  308. void GlobalRelocation::setndtmap(std::vector<iv::ndtmaptrace> & xvectorndtmap)
  309. {
  310. mvectorndtmap = xvectorndtmap;
  311. if(mvectorndtmap.size() == 0)
  312. {
  313. return;
  314. }
  315. int i;
  316. for(i=0;i<mnThreadNum;i++)
  317. {
  318. pcl::PointCloud<pcl::PointXYZ>::Ptr xmap;
  319. xmap = boost::shared_ptr<pcl::PointCloud<pcl::PointXYZ>>(new pcl::PointCloud<pcl::PointXYZ>);
  320. QTime xTime;
  321. xTime.start();
  322. if(0 == pcl::io::loadPCDFile(mvectorndtmap[0].mstrpcdpath.data(),*xmap))
  323. {
  324. }
  325. else
  326. {
  327. std::cout<<"map size is 0"<<std::endl;
  328. return;
  329. }
  330. mbRelocAvail = true;
  331. mndt[i].setInputTarget(xmap);
  332. mthreadcomplete[i] = true;
  333. }
  334. int npointsize = mvectorndtmap[0].mvector_trace.size();
  335. if(npointsize == 0)
  336. {
  337. return;
  338. }
  339. mvectorseedpoint.clear();
  340. std::cout<<" load trace seed."<<std::endl;
  341. iv::ndttracepoint ntp = mvectorndtmap[0].mvector_trace[0];
  342. mvectorseedpoint.push_back(ntp);
  343. for(i=1;i<npointsize;i++)
  344. {
  345. iv::ndttracepoint ntpnow = mvectorndtmap[0].mvector_trace[i];
  346. iv::ndttracepoint ntplast = mvectorseedpoint[mvectorseedpoint.size() -1];
  347. double fdis = sqrt(pow(ntpnow.x - ntplast.x,2) + pow(ntpnow.y - ntplast.y,2));
  348. double fyawdiff = ntpnow.yaw - ntplast.yaw;
  349. while(fyawdiff<(-M_PI))fyawdiff = fyawdiff + 2.0*M_PI;
  350. while(fyawdiff >(M_PI))fyawdiff = fyawdiff - 2.0*M_PI;
  351. if(fdis>=mfSeedDisThresh)
  352. {
  353. mvectorseedpoint.push_back(ntpnow);
  354. }
  355. else
  356. {
  357. if(fabs(fyawdiff)>0.1)
  358. {
  359. mvectorseedpoint.push_back(ntpnow);
  360. }
  361. else
  362. {
  363. if(i== (npointsize -1))
  364. {
  365. mvectorseedpoint.push_back(ntpnow);
  366. }
  367. }
  368. }
  369. }
  370. if(mvectorseedpoint.size()>0)
  371. {
  372. const int nfrontadd = 3;
  373. const int nrearadd = 3;
  374. iv::ndttracepoint ntpfirst = mvectorseedpoint[0];
  375. iv::ndttracepoint ntplast = mvectorseedpoint[mvectorseedpoint.size() -1];
  376. for(i=0;i<nfrontadd;i++)
  377. {
  378. iv::ndttracepoint ntpnow = ntpfirst;
  379. double foff = (i+1)*mfSeedDisThresh;
  380. ntpnow.x = ntpfirst.x + foff*cos(ntpfirst.yaw + M_PI);
  381. ntpnow.y = ntpfirst.y + foff*sin(ntpfirst.yaw + M_PI);
  382. mvectorseedpoint.insert(mvectorseedpoint.begin(),ntpnow);
  383. }
  384. for(i=0;i<nrearadd;i++)
  385. {
  386. iv::ndttracepoint ntpnow = ntplast;
  387. double foff = (i+1)*mfSeedDisThresh;
  388. ntpnow.x = ntplast.x + foff*cos(ntpfirst.yaw);
  389. ntpnow.y = ntplast.y + foff*sin(ntpfirst.yaw );
  390. mvectorseedpoint.push_back(ntpnow);
  391. }
  392. }
  393. // for(i=0;i<mvectorseedpoint.size();i++)
  394. // {
  395. // mvectorseedpoint[i].yaw = mvectorseedpoint[i].yaw + M_PI;
  396. // mvectorseedpoint[i].y = mvectorseedpoint[i].y + 10.0;
  397. // }
  398. }