main.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. #include <QCoreApplication>
  2. #include "modulecomm.h"
  3. #include <pcl/io/pcd_io.h>
  4. #include <pcl/point_types.h>
  5. #include <QTime>
  6. #include <QDir>
  7. #include <QFile>
  8. #include <thread>
  9. #include "ivfault.h"
  10. #include "ivlog.h"
  11. #include "ndt_matching.h"
  12. #include "gpsimu.pb.h"
  13. #include "ivexit.h"
  14. #include "ivbacktrace.h"
  15. #include "xmlparam.h"
  16. #include "ivversion.h"
  17. extern bool gbuseanh;
  18. QTime gTime; //a Time function. use calculate elapsed.
  19. int gndttime; //ndt calculate time
  20. void * gpa,* gpb ,* gpc, * gpd; //Modulecomm pointer
  21. iv::Ivfault *gfault = nullptr; //fault diag
  22. iv::Ivlog *givlog = nullptr; //log
  23. std::vector<iv::ndtmaptrace> gvector_trace; //trace and map origin. use shift map
  24. iv::gpspos glastndtgpspos; //last ndt pos(convert to gps)
  25. iv::gpspos gcurndtgpspos; //cur ndt pos(conver to gps)
  26. iv::gpspos gcurgpsgpspos; //cur gps pos
  27. bool gbGPSFix = false; //GPS is Fix. If 300 times report rtk 6.
  28. int64_t gnLastGPSTime = 0; //ms
  29. std::thread * gpthread; //State thread pointer.
  30. std::string gstr_lidarmsgname; //lidar message name
  31. std::string gstr_gpsmsgname; // gps message name
  32. std::string gstr_ndtposmsgname; //ndtpos message name
  33. std::string gstr_ndtgpsposmsgname; //gpspos message name
  34. std::string gstr_ndtmainsensormsgname;
  35. std::string gstr_arm_x;
  36. std::string gstr_arm_y;
  37. std::string gstr_yawcorrect; //lidar yaw correct.
  38. std::string gstr_heightcorrect; //gps height correct.
  39. double gyawcorrect = 0.0; //lidar yaw correct.
  40. double gheightcorrect = 0.0; //gps height correct.
  41. std::string gstr_savelastpos; //set save last pos. default true
  42. bool gbSaveLastPos = true;
  43. double garm_x = 0.0;
  44. double garm_y = 0.0;
  45. QFile * gpFileLastPos = 0;//Save Last Positin
  46. /**
  47. * @brief readtrace read trace
  48. * @param pFile
  49. * @return
  50. */
  51. std::vector<iv::ndttracepoint> readtrace(QFile * pFile)
  52. {
  53. std::vector<iv::ndttracepoint> ntp;
  54. QByteArray ba;
  55. ba = pFile->readLine();
  56. do
  57. {
  58. QString str;
  59. str = ba;
  60. QStringList strlist;
  61. strlist = str.split("\t");
  62. if(strlist.size() == 6)
  63. {
  64. iv::ndttracepoint tp;
  65. QString strx;
  66. int j;
  67. double fv[6];
  68. for(j=0;j<6;j++)
  69. {
  70. strx = strlist.at(j);
  71. fv[j] = strx.toDouble();
  72. }
  73. tp.x = fv[0];
  74. tp.y = fv[1];
  75. tp.z = fv[2];
  76. tp.pitch = fv[3];
  77. tp.roll = fv[4];
  78. tp.yaw = fv[5];
  79. ntp.push_back(tp);
  80. }
  81. else
  82. {
  83. qDebug("len is %d, %d",ba.length(),strlist.size());
  84. }
  85. ba = pFile->readLine();
  86. }while(ba.length()>0);
  87. return ntp;
  88. }
  89. /**
  90. * @brief readndtorigin read .pcd file's origin gps position.
  91. * @param pFile
  92. * @param pnori
  93. * @return
  94. */
  95. int readndtorigin(QFile * pFile,iv::gpspos * pnori)
  96. {
  97. int nrtn = -1;
  98. QByteArray ba;
  99. ba = pFile->readLine();
  100. QString str;
  101. str = ba;
  102. QStringList strlist;
  103. strlist = str.split("\t");
  104. if(strlist.size() == 6)
  105. {
  106. QString xstr[6];
  107. int i;
  108. for(i=0;i<6;i++)xstr[i] = strlist.at(i);
  109. pnori->lon = xstr[0].toDouble();
  110. pnori->lat = xstr[1].toDouble();
  111. pnori->height = xstr[2].toDouble();
  112. pnori->heading = xstr[3].toDouble();
  113. pnori->pitch = xstr[4].toDouble();
  114. pnori->roll = xstr[5].toDouble();
  115. nrtn = 0;
  116. }
  117. return nrtn;
  118. }
  119. /**
  120. * @brief LoadLastPos Load last position
  121. * @param strlastposfilepath
  122. */
  123. static void LoadLastPos(const char * strlastposfilepath)
  124. {
  125. QFile * xFile = new QFile();
  126. xFile->setFileName(strlastposfilepath);
  127. if(xFile->open(QIODevice::ReadWrite))
  128. {
  129. int nrtn = readndtorigin(xFile,&glastndtgpspos);
  130. if(nrtn < 0)
  131. {
  132. givlog->warn("load last pos fail.");
  133. }
  134. if(gbSaveLastPos)gpFileLastPos = xFile;
  135. else
  136. {
  137. gpFileLastPos = 0;
  138. xFile->close();
  139. }
  140. }
  141. }
  142. /**
  143. * @brief LoadTrace
  144. */
  145. static void LoadTrace()
  146. {
  147. std::string strpath = getenv("HOME");
  148. strpath = strpath + "/map/";
  149. std::string strlastposfile = strpath;
  150. strlastposfile = strlastposfile + "lastpos.txt";
  151. LoadLastPos(strlastposfile.data());
  152. QString strpathdir = strpath.data();
  153. QDir dir(strpath.data());
  154. QStringList xfilter;
  155. xfilter<<"*.pcd";
  156. foreach(QString strfilename,dir.entryList(xfilter,QDir::Files))
  157. {
  158. qDebug(strfilename.toLatin1().data());
  159. QString stroripath;
  160. QString strtracepath;
  161. QString strpcdpath;
  162. stroripath = strfilename;
  163. stroripath = stroripath.left(stroripath.length() - 4);
  164. stroripath = strpathdir + stroripath + ".ori";
  165. strtracepath = strfilename;
  166. strtracepath = strtracepath.left(strtracepath.length() - 4);
  167. strtracepath = strpathdir + strtracepath + ".txt";
  168. strpcdpath = strfilename;
  169. strpcdpath = strpathdir + strpcdpath;
  170. QFile xFileori,xFile,xFilepcd;
  171. xFileori.setFileName(stroripath);
  172. xFilepcd.setFileName(strpcdpath);
  173. xFile.setFileName(strtracepath);
  174. if(xFileori.exists() && xFile.exists())
  175. {
  176. qDebug("file name ok.");
  177. if(xFile.open(QIODevice::ReadOnly) && xFileori.open(QIODevice::ReadOnly))
  178. {
  179. std::vector<iv::ndttracepoint> xv = readtrace(&xFile);
  180. iv::gpspos xnori;
  181. int nrtn = readndtorigin(&xFileori,&xnori);
  182. if((xv.size() > 0)&&(nrtn == 0))
  183. {
  184. iv::ndtmaptrace nmt;
  185. nmt.mvector_trace = xv;
  186. nmt.mstrpcdpath = strpcdpath.toLatin1().data();
  187. nmt.mndtorigin = xnori;
  188. gvector_trace.push_back(nmt);
  189. qDebug("this is ok.");
  190. }
  191. }
  192. xFile.close();
  193. xFileori.close();
  194. }
  195. else
  196. {
  197. qDebug(" file not ok.");
  198. }
  199. }
  200. return;
  201. }
  202. int gnothavedatatime = 0;
  203. /**
  204. * @brief ListenPointCloud
  205. * @param strdata
  206. * @param nSize
  207. * @param index
  208. * @param dt
  209. * @param strmemname
  210. */
  211. void ListenPointCloud(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
  212. {
  213. QTime xTime;
  214. xTime.start();
  215. gnothavedatatime = 0;
  216. if(nSize <=16)return;
  217. unsigned int * pHeadSize = (unsigned int *)strdata;
  218. if(*pHeadSize > nSize)
  219. {
  220. std::cout<<"ListenPointCloud data is small headsize ="<<*pHeadSize<<" data size is"<<nSize<<std::endl;
  221. }
  222. pcl::PointCloud<pcl::PointXYZ>::Ptr point_cloud(
  223. new pcl::PointCloud<pcl::PointXYZ>());
  224. int nNameSize;
  225. nNameSize = *pHeadSize - 4-4-8;
  226. char * strName = new char[nNameSize+1];strName[nNameSize] = 0;
  227. memcpy(strName,(char *)((char *)strdata +4),nNameSize);
  228. point_cloud->header.frame_id = strName;
  229. memcpy(&point_cloud->header.seq,(char *)strdata+4+nNameSize,4);
  230. memcpy(&point_cloud->header.stamp,(char *)strdata+4+nNameSize+4,8);
  231. int nPCount = (nSize - *pHeadSize)/sizeof(pcl::PointXYZI);
  232. int i;
  233. pcl::PointXYZI * p;
  234. p = (pcl::PointXYZI *)((char *)strdata + *pHeadSize);
  235. for(i=0;i<nPCount;i++)
  236. {
  237. pcl::PointXYZ xp;
  238. xp.x = p->y;
  239. xp.y = p->x * (-1.0);
  240. xp.z = p->z;
  241. if(gyawcorrect != 0.0)
  242. {
  243. double yaw = gyawcorrect;
  244. double x1,y1;
  245. x1 = xp.x;
  246. y1 = xp.y;
  247. xp.x = x1*cos(yaw) -y1*sin(yaw);
  248. xp.y = x1*sin(yaw) + y1*cos(yaw);
  249. }
  250. // xp.intensity = p->intensity;
  251. point_cloud->push_back(xp);
  252. p++;
  253. }
  254. givlog->verbose("point cloud size is %d",
  255. point_cloud->size());
  256. point_ndt(point_cloud);
  257. gndttime = xTime.elapsed();
  258. givlog->verbose("ndt time is %d, gtime is %d", xTime.elapsed(), gTime.elapsed());
  259. // return;
  260. // gw->UpdatePointCloud(point_cloud);
  261. // DBSCAN_PC(point_cloud);
  262. gfault->SetFaultState(0, 0, "ok");
  263. }
  264. /**
  265. * @brief ListenMapUpdate
  266. * @param strdata
  267. * @param nSize
  268. * @param index
  269. * @param dt
  270. * @param strmemname
  271. */
  272. void ListenMapUpdate(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
  273. {
  274. char * strpath = new char[nSize+1];
  275. memcpy(strpath,strdata,nSize);
  276. strpath[nSize] = 0;
  277. pcl::PointCloud<pcl::PointXYZ>::Ptr mapx = boost::shared_ptr<pcl::PointCloud<pcl::PointXYZ>>(new pcl::PointCloud<pcl::PointXYZ>);;
  278. if(0 == pcl::io::loadPCDFile(strpath,*mapx))
  279. {
  280. int size = mapx->size();
  281. givlog->verbose("mapx size = %d", size);
  282. ndt_match_SetMap(mapx);
  283. }
  284. gfault->SetFaultState(0, 0, "ok");
  285. delete strpath;
  286. }
  287. /**
  288. * @brief ListenNDTRunstate
  289. * @param strdata
  290. * @param nSize
  291. * @param index
  292. * @param dt
  293. * @param strmemname
  294. */
  295. void ListenNDTRunstate(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
  296. {
  297. bool bState;
  298. if(nSize < sizeof(bool))
  299. {
  300. gfault->SetFaultState(1, 0, "ListenNDTRunstate data size is small");
  301. givlog->error("ListenNDTRunstate data size is small");
  302. return;
  303. }
  304. memcpy(&bState,strdata,sizeof(bool));
  305. SetRunState(bState);
  306. gfault->SetFaultState(0, 0, "ok");
  307. }
  308. /**
  309. * @brief pausecomm
  310. */
  311. void pausecomm()
  312. {
  313. iv::modulecomm::PauseComm(gpa);
  314. iv::modulecomm::PauseComm(gpb);
  315. iv::modulecomm::PauseComm(gpc);
  316. iv::modulecomm::PauseComm(gpd);
  317. }
  318. /**
  319. * @brief continuecomm
  320. */
  321. void continuecomm()
  322. {
  323. iv::modulecomm::ContintuComm(gpa);
  324. iv::modulecomm::ContintuComm(gpb);
  325. iv::modulecomm::ContintuComm(gpc);
  326. iv::modulecomm::ContintuComm(gpd);
  327. }
  328. /**
  329. * @brief ListenRaw
  330. * @param strdata
  331. * @param nSize
  332. * @param index
  333. * @param dt
  334. * @param strmemname
  335. */
  336. void ListenRaw(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
  337. {
  338. static unsigned int nFixCount = 0;
  339. iv::gps::gpsimu xgpsimu;
  340. if(!xgpsimu.ParseFromArray(strdata,nSize))
  341. {
  342. std::cout<<"ListenRaw Parse error."<<std::endl;
  343. }
  344. gcurgpsgpspos.lat = xgpsimu.lat();
  345. gcurgpsgpspos.lon = xgpsimu.lon();
  346. gcurgpsgpspos.height = xgpsimu.height() + gheightcorrect;
  347. gcurgpsgpspos.heading = xgpsimu.heading();
  348. gcurgpsgpspos.pitch = xgpsimu.pitch();
  349. gcurgpsgpspos.roll = xgpsimu.roll();
  350. gcurgpsgpspos.ve = xgpsimu.ve();
  351. gcurgpsgpspos.vn = xgpsimu.vn();
  352. givlog->verbose("gps lat:%11.7f lon:%11.7f heading:%11.7f height:%6.3f rtk:%d",
  353. xgpsimu.lat(),xgpsimu.lon(),xgpsimu.heading(),
  354. xgpsimu.height(),xgpsimu.rtk_state());
  355. if(xgpsimu.has_acce_x())
  356. {
  357. setuseimu(true);
  358. imu_update(xgpsimu.time(),
  359. xgpsimu.roll(),xgpsimu.pitch(),
  360. xgpsimu.heading(),xgpsimu.acce_x(),
  361. xgpsimu.acce_y(),xgpsimu.acce_z());
  362. }
  363. if(xgpsimu.rtk_state() == 6)
  364. {
  365. nFixCount++;
  366. }
  367. else
  368. {
  369. nFixCount = 0;
  370. }
  371. if(nFixCount < 300)gbGPSFix = false;
  372. else gbGPSFix = true;
  373. gnLastGPSTime = std::chrono::system_clock::now().time_since_epoch().count()/1000000;
  374. }
  375. bool gbstate = true;
  376. /**
  377. * @brief statethread Monitor ndt state thread.
  378. */
  379. void statethread()
  380. {
  381. int nstate = 0;
  382. int nlaststate = 0;
  383. while(gbstate)
  384. {
  385. std::this_thread::sleep_for(std::chrono::milliseconds(10));
  386. if(gnothavedatatime < 100000) gnothavedatatime++;
  387. if(gnothavedatatime < 100)
  388. {
  389. nstate = 0;
  390. }
  391. if(gnothavedatatime > 1000)
  392. {
  393. nstate = 1;
  394. }
  395. if(gnothavedatatime > 6000)
  396. {
  397. nstate = 2;
  398. }
  399. if(nstate != nlaststate)
  400. {
  401. nlaststate = nstate;
  402. switch (nstate) {
  403. case 0:
  404. givlog->info("ndt matching is ok");
  405. gfault->SetFaultState(0,0,"data is ok.");
  406. break;
  407. case 1:
  408. givlog->warn("more than 10 seconds not have lidar pointcloud.");
  409. gfault->SetFaultState(1,1,"more than 10 seconds not have lidar pointcloud.");
  410. break;
  411. case 2:
  412. givlog->error("more than 60 seconds not have lidar pointcloud.");
  413. gfault->SetFaultState(2,2,"more than 60 seconds not have lidar pointcloud.");
  414. break;
  415. default:
  416. break;
  417. }
  418. }
  419. }
  420. }
  421. /**
  422. * @brief exitfunc when receive exit command.
  423. */
  424. void exitfunc()
  425. {
  426. std::cout<<"enter exitfunc."<<std::endl;
  427. gbstate = false;
  428. gpthread->join();
  429. iv::modulecomm::Unregister(gpa);
  430. iv::modulecomm::Unregister(gpb);
  431. iv::modulecomm::Unregister(gpc);
  432. iv::modulecomm::Unregister(gpd);
  433. if(gpFileLastPos != 0)gpFileLastPos->close();
  434. std::cout<<"Complete exitfunc."<<std::endl;
  435. }
  436. int main(int argc, char *argv[])
  437. {
  438. showversion("detection_ndt_matching");
  439. QCoreApplication a(argc, argv);
  440. QString strpath = QCoreApplication::applicationDirPath();
  441. if(argc < 2)
  442. strpath = strpath + "/detection_ndt_matching.xml";
  443. else
  444. strpath = argv[1];
  445. std::cout<<strpath.toStdString()<<std::endl;
  446. iv::xmlparam::Xmlparam xparam(strpath.toStdString());
  447. gstr_lidarmsgname = xparam.GetParam("lidarmsg","lidar_pc");
  448. gstr_gpsmsgname = xparam.GetParam("gpsmsg","hcp2_gpsimu");
  449. gstr_ndtposmsgname = xparam.GetParam("ndtposmsg","ndtpos");
  450. gstr_ndtgpsposmsgname = xparam.GetParam("ndtgpsposmsg","ndtgpspos");
  451. gstr_ndtmainsensormsgname = xparam.GetParam("mainsensor","gps");
  452. gstr_yawcorrect = xparam.GetParam("AngleCorrect","0.0");
  453. gstr_heightcorrect = xparam.GetParam("HeightCorrect","0.0");
  454. gstr_savelastpos = xparam.GetParam("SaveLastPos","true");
  455. gstr_arm_x = xparam.GetParam("Arm_LidarGPSBase_x","0.0");
  456. gstr_arm_y = xparam.GetParam("Arm_LidarGPSBase_y","0.0");
  457. gbuseanh = xparam.GetParam("useanh",false);
  458. gyawcorrect = atof(gstr_yawcorrect.data()) * M_PI/180.0;
  459. gheightcorrect = atof(gstr_heightcorrect.data());
  460. if(gstr_savelastpos == "true")gbSaveLastPos = true;
  461. else gbSaveLastPos = false;
  462. garm_x = atof(gstr_arm_x.data());
  463. garm_y = atof(gstr_arm_y.data());
  464. std::cout<<"lidar message is "<<gstr_lidarmsgname<<std::endl;
  465. std::cout<<"gps message is "<<gstr_gpsmsgname<<std::endl;
  466. std::cout<<"ndtpos message is "<<gstr_ndtposmsgname<<std::endl;
  467. std::cout<<"ndtgpspos message is "<<gstr_ndtgpsposmsgname<<std::endl;
  468. std::cout<<"AngleCorrect is "<<gstr_yawcorrect<<std::endl;
  469. std::cout<<"HeightCorrect is "<<gstr_heightcorrect<<std::endl;
  470. std::cout<<"SaveLastPos is "<<gstr_savelastpos<<std::endl;
  471. std::cout<<"Arm_LidarGPSBase_x is "<<gstr_arm_x<<std::endl;
  472. std::cout<<"Arm_LidarGPSBase_x is "<<gstr_arm_y<<std::endl;
  473. gfault = new iv::Ivfault("detection_ndt_matching_gpu");
  474. givlog = new iv::Ivlog("detection_ndt_matching_gpu");
  475. gfault->SetFaultState(0,0,"Initialize.");
  476. glastndtgpspos.lat = 39;
  477. glastndtgpspos.lon = 119;
  478. glastndtgpspos.heading = 0;
  479. glastndtgpspos.height = 0;
  480. glastndtgpspos.pitch = 0;
  481. glastndtgpspos.roll = 0;
  482. gcurndtgpspos = glastndtgpspos;
  483. iv::gpspos xpos = glastndtgpspos;
  484. xpos.lat = 39.1;
  485. xpos.heading = 90;
  486. pose xp = CalcPose(glastndtgpspos,xpos);
  487. iv::gpspos xx = PoseToGPS(glastndtgpspos,xp);
  488. LoadTrace();
  489. std::cout<<"trace size is "<<gvector_trace.size()<<std::endl;
  490. gpa = iv::modulecomm::RegisterRecv(gstr_lidarmsgname.data(),ListenPointCloud);
  491. gpb = iv::modulecomm::RegisterRecv(gstr_gpsmsgname.data(),ListenRaw);
  492. gpc = iv::modulecomm::RegisterSend(gstr_ndtposmsgname.data(),10000,1);
  493. gpd = iv::modulecomm::RegisterSend(gstr_ndtgpsposmsgname.data(),10000,1);
  494. ndt_match_Init_nomap();
  495. iv::ivexit::RegIVExitCall(exitfunc);
  496. RegisterIVBackTrace();
  497. gpthread = new std::thread(statethread);
  498. // gpb = iv::modulecomm::RegisterRecv("ndt_mappath",ListenMapUpdate);
  499. // gpc = iv::modulecomm::RegisterRecv("ndt_runstate",ListenNDTRunstate);
  500. return a.exec();
  501. }