main.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. #include <QCoreApplication>
  2. #include <QMutex>
  3. #include <QUdpSocket>
  4. #include <QNetworkDatagram>
  5. #include <thread>
  6. #include <iostream>
  7. #include <memory>
  8. #include <math.h>
  9. #include "modulecomm.h"
  10. #include "xmlparam.h"
  11. #include "gpsimu.pb.h"
  12. #include "ndtgpspos.pb.h"
  13. #include "fusiongpslidar.pb.h"
  14. #include "chassis.pb.h"
  15. #include "ivbacktrace.h"
  16. #include "ivfault.h"
  17. #include "ivlog.h"
  18. #include "ivexit.h"
  19. #include "ivversion.h"
  20. iv::Ivfault *gfault = nullptr;
  21. iv::Ivlog *givlog = nullptr;
  22. bool gbinit = false;
  23. bool gbGPSFix = false;
  24. bool gbfusionrun = true;
  25. bool gbGPSNewData = false;
  26. bool gbNDTNewData = false;
  27. bool gbUseLidarOnly = false;
  28. bool gbShareUDP = true;
  29. bool gbShareGPSIMU = true;
  30. std::thread * gfusionthread;
  31. iv::gps::gpsimu ggpsimu;
  32. iv::lidar::ndtgpspos gndtgpspos;
  33. iv::fusion::fusiongpslidar gfusiongpslidar;
  34. QMutex mMutexgps;
  35. QMutex mMutexndt;
  36. void * gpa,* gpb, * gpc, * gpd,* gpe;
  37. std::string gstrgpsmsg;
  38. std::string gstrndtmsg;
  39. std::string gstrfusionmsg;
  40. std::string gstrlidaronly;
  41. std::string gstrfusiongpsimumsg;
  42. std::string gstrshareudp;
  43. std::string gstrsharegpsimu;
  44. QUdpSocket * gudpSocketGPSIMU;
  45. static int64_t glastchassitime = 0;
  46. static double gfChassisVelSpeed;
  47. void UpdateChassis(const char *strdata, const unsigned int nSize, const unsigned int index, const QDateTime *dt, const char *strmemname)
  48. {
  49. (void)index;
  50. (void)dt;
  51. (void)strmemname;
  52. iv::chassis xchassis;
  53. // static int ncount = 0;
  54. if(!xchassis.ParseFromArray(strdata,nSize))
  55. {
  56. std::cout<<"iv::decition::BrainDecition::UpdateChassis ParseFrom Array Error."<<std::endl;
  57. return;
  58. }
  59. if(xchassis.has_vel())
  60. {
  61. gfChassisVelSpeed = xchassis.vel();
  62. glastchassitime = std::chrono::system_clock::now().time_since_epoch().count()/1000000;
  63. // std::cout<<" gf Veh speed : "<<gfVehSpd<<std::endl;
  64. }
  65. }
  66. void ListenRaw(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
  67. {
  68. static unsigned int nFixCount = 0;
  69. iv::gps::gpsimu xgpsimu;
  70. if(!xgpsimu.ParseFromArray(strdata,nSize))
  71. {
  72. std::cout<<"ListenRaw Parse error."<<std::endl;
  73. }
  74. givlog->verbose("GPS","lat:%11.7f lon:%11.7f height:%6.3f heading:%6.3f rtk:%d",
  75. xgpsimu.lat(),xgpsimu.lon(),xgpsimu.height(),
  76. xgpsimu.heading(),xgpsimu.rtk_state());
  77. if(xgpsimu.rtk_state() == 6)
  78. {
  79. nFixCount++;
  80. }
  81. else
  82. {
  83. nFixCount = 0;
  84. }
  85. if(gbinit == false)
  86. {
  87. if(nFixCount > 0)
  88. {
  89. gbGPSFix = true;
  90. nFixCount = 300;
  91. }
  92. gbinit = true;
  93. }
  94. if(nFixCount < 300)gbGPSFix = false;
  95. else gbGPSFix = true;
  96. mMutexgps.lock();
  97. ggpsimu.CopyFrom(xgpsimu);
  98. mMutexgps.unlock();
  99. gbGPSNewData = true;
  100. }
  101. void ListenNDTGPS(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
  102. {
  103. iv::lidar::ndtgpspos xndtgpspos;
  104. if(!xndtgpspos.ParseFromArray(strdata,nSize))
  105. {
  106. std::cout<<"ListenNDTGPS Parse error."<<std::endl;
  107. return;
  108. }
  109. givlog->verbose("NDT","lat:%11.7f lon:%11.7f height:%6.3f heading:%6.3f trans_prob:%6.3f score:%6.3f",
  110. xndtgpspos.lat(),xndtgpspos.lon(),xndtgpspos.height(),
  111. xndtgpspos.heading(),xndtgpspos.tras_prob(),xndtgpspos.score());
  112. mMutexndt.lock();
  113. gndtgpspos.CopyFrom(xndtgpspos);
  114. mMutexndt.unlock();
  115. gbNDTNewData = true;
  116. }
  117. static void BroadCastData(iv::fusion::fusiongpslidar * pfusiongpslidar)
  118. {
  119. unsigned char strSend[72];
  120. int i;
  121. for(i=0;i<72;i++)strSend[i] = 0x0;
  122. strSend[0] = 0xE7;
  123. strSend[21] = 4;
  124. strSend[68] = pfusiongpslidar->state();
  125. strSend[67] = 0;
  126. strSend[62] = 62;
  127. double fV = pfusiongpslidar->lat();
  128. fV = fV/(180.0/M_PI);
  129. memcpy(strSend+23,&fV,8);
  130. fV = pfusiongpslidar->lon();fV = fV/(180.0/M_PI);memcpy(strSend+31,&fV,8);
  131. float fF =0;memcpy(strSend+39,&fF,4);
  132. int iV;
  133. char * piV = (char *)&iV;
  134. piV++;
  135. fV = pfusiongpslidar->ve();fV = fV*10000.0;iV = (int)fV;iV = iV*256;memcpy(strSend+43,piV,3);
  136. fV = pfusiongpslidar->vn();fV = fV*10000.0;iV = (int)fV;iV = iV*256;memcpy(strSend+46,piV,3);
  137. fV = pfusiongpslidar->vd();fV = fV*10000.0;iV = (int)fV;iV = iV*256;memcpy(strSend+49,piV,3);
  138. fV = pfusiongpslidar->heading()/(180.0/M_PI);fV = fV*1000000.0;iV = (int)fV;iV = iV*256;memcpy(strSend+52,piV,3);
  139. fV = pfusiongpslidar->pitch()/(180.0/M_PI);fV = fV*1000000.0;iV = (int)fV;iV = iV*256;memcpy(strSend+55,piV,3);
  140. fV = pfusiongpslidar->roll()/(180.0/M_PI);fV = fV*1000000.0;iV = (int)fV;iV = iV*256;memcpy(strSend+58,piV,3);
  141. char c;
  142. c = strSend[0];
  143. for(i=1;i<71;i++)c = c+strSend[i];
  144. strSend[71]= c;
  145. gudpSocketGPSIMU->writeDatagram((char *)strSend,72,QHostAddress::Broadcast, 3000);
  146. }
  147. static void sharefusiongpsimu(iv::fusion::fusiongpslidar * pfusiongpslidar)
  148. {
  149. iv::gps::gpsimu gpsimu;
  150. gpsimu.set_vd(pfusiongpslidar->vd());
  151. gpsimu.set_ve(pfusiongpslidar->ve());
  152. gpsimu.set_vn(pfusiongpslidar->vn());
  153. gpsimu.set_lat(pfusiongpslidar->lat());
  154. gpsimu.set_lon(pfusiongpslidar->lon());
  155. gpsimu.set_heading(pfusiongpslidar->heading());
  156. gpsimu.set_state(4);
  157. gpsimu.set_msgtime(QDateTime::currentMSecsSinceEpoch());
  158. gpsimu.set_roll(pfusiongpslidar->roll());
  159. gpsimu.set_pitch(pfusiongpslidar->pitch());
  160. gpsimu.set_rtk_state(pfusiongpslidar->state());
  161. gpsimu.set_ins_state(4);
  162. int64_t nmsnow = std::chrono::system_clock::now().time_since_epoch().count()/1000000;
  163. if(abs(nmsnow - glastchassitime) < 1000)
  164. {
  165. gpsimu.set_speed(gfChassisVelSpeed);
  166. std::cout<<"use chassis speed."<<std::endl;
  167. return;
  168. }
  169. char * strser;
  170. bool bser;
  171. int nbytesize;
  172. nbytesize = gpsimu.ByteSize();
  173. strser = new char[nbytesize];
  174. bser = gpsimu.SerializeToArray(strser,nbytesize);
  175. if(bser)
  176. iv::modulecomm::ModuleSendMsg(gpd,strser,nbytesize);
  177. else
  178. {
  179. // givlog->error("gpsimu serialize error.");
  180. // gfault->SetFaultState(1, 0, "gpsimu serialize err");
  181. }
  182. delete strser;
  183. }
  184. static void sharefusionres()
  185. {
  186. // std::cout<<"state is "<<gfusiongpslidar.state()<<std::endl;
  187. qDebug("lat %11.7f lon %11.7f heading %6.3f ve %6.3f vn %6.3f state %g",
  188. gfusiongpslidar.lat(),gfusiongpslidar.lon(),gfusiongpslidar.heading(),
  189. gfusiongpslidar.ve(),gfusiongpslidar.vn(),gfusiongpslidar.state());
  190. givlog->debug("FUSION_GPSNDT","lat %11.7f lon %11.7f heading %6.3f ve %6.3f vn %6.3f state %g",
  191. gfusiongpslidar.lat(),gfusiongpslidar.lon(),gfusiongpslidar.heading(),
  192. gfusiongpslidar.ve(),gfusiongpslidar.vn(),gfusiongpslidar.state());
  193. int ndatasize = gfusiongpslidar.ByteSize();
  194. char * strser = new char[ndatasize];
  195. std::shared_ptr<char> pstrser; pstrser.reset(strser);
  196. if(gfusiongpslidar.SerializeToArray(strser,ndatasize))
  197. {
  198. iv::modulecomm::ModuleSendMsg(gpc,strser,ndatasize);
  199. }
  200. else
  201. {
  202. std::cout<<"sharefusionres serialize error."<<std::endl;
  203. givlog->warn("sharefusionres serialize error.");
  204. }
  205. if(gbShareUDP)BroadCastData(&gfusiongpslidar);
  206. if(gbShareGPSIMU)sharefusiongpsimu(&gfusiongpslidar);
  207. }
  208. static void usegps(iv::gps::gpsimu * pgpsimu)
  209. {
  210. gfusiongpslidar.set_heading(pgpsimu->heading());
  211. gfusiongpslidar.set_height(pgpsimu->height());
  212. gfusiongpslidar.set_lat(pgpsimu->lat());
  213. gfusiongpslidar.set_lon(pgpsimu->lon());
  214. gfusiongpslidar.set_pitch(pgpsimu->pitch());
  215. gfusiongpslidar.set_roll(pgpsimu->roll());
  216. gfusiongpslidar.set_state(pgpsimu->rtk_state());
  217. gfusiongpslidar.set_timestamp(pgpsimu->time());
  218. gfusiongpslidar.set_vd(pgpsimu->vd());
  219. gfusiongpslidar.set_ve(pgpsimu->ve());
  220. gfusiongpslidar.set_vn(pgpsimu->vn());
  221. sharefusionres();
  222. }
  223. static void usendt(iv::lidar::ndtgpspos * pndtgpspos)
  224. {
  225. gfusiongpslidar.set_heading(pndtgpspos->heading());
  226. gfusiongpslidar.set_height(pndtgpspos->height());
  227. gfusiongpslidar.set_lat(pndtgpspos->lat());
  228. gfusiongpslidar.set_lon(pndtgpspos->lon());
  229. gfusiongpslidar.set_pitch(pndtgpspos->pitch());
  230. gfusiongpslidar.set_roll(pndtgpspos->roll());
  231. if(pndtgpspos->tras_prob() > 2.0)gfusiongpslidar.set_state(16);
  232. else gfusiongpslidar.set_state(15);
  233. // std::cout<<"state is "<<gfusiongpslidar.state()<<std::endl;
  234. gfusiongpslidar.set_timestamp(pndtgpspos->lidartime());
  235. gfusiongpslidar.set_vd(pndtgpspos->vd());
  236. gfusiongpslidar.set_ve(pndtgpspos->ve());
  237. gfusiongpslidar.set_vn(pndtgpspos->vn());
  238. sharefusionres();
  239. }
  240. void fusionthread()
  241. {
  242. unsigned int nnodatacount = 0;
  243. unsigned int nnogpsdata = 0;
  244. unsigned int nnondtdata = 0;
  245. int nstate = 0;
  246. int noldstate = 0;
  247. iv::gps::gpsimu xgpsimu;
  248. iv::lidar::ndtgpspos xndtgpspos;
  249. while(gbfusionrun)
  250. {
  251. std::this_thread::sleep_for(std::chrono::milliseconds(5));
  252. if(gbGPSNewData == false)
  253. {
  254. if(nnogpsdata < 1000000)nnogpsdata++;
  255. }
  256. else
  257. {
  258. nnogpsdata = 0;
  259. }
  260. if(gbNDTNewData == false)
  261. {
  262. if(nnondtdata < 1000000)nnondtdata++;
  263. }
  264. else
  265. {
  266. nnondtdata = 0;
  267. }
  268. if((gbNDTNewData == false)&&(gbGPSNewData == false))
  269. {
  270. if(nnodatacount < 1000000)nnodatacount++;
  271. }
  272. else
  273. {
  274. nnodatacount= 0;
  275. }
  276. if(gbUseLidarOnly)
  277. {
  278. // if() // trans ok use
  279. //Use NDT Data,if trans >0.5
  280. if(gndtgpspos.tras_prob() >0.5)
  281. {
  282. mMutexndt.lock();
  283. xndtgpspos.CopyFrom(gndtgpspos);
  284. mMutexndt.unlock();
  285. usendt(&xndtgpspos);
  286. }
  287. }
  288. else
  289. {
  290. if(gbGPSNewData && gbGPSFix)
  291. {
  292. //Use GPS Data;
  293. mMutexgps.lock();
  294. xgpsimu.CopyFrom(ggpsimu);
  295. mMutexgps.unlock();
  296. usegps(&xgpsimu);
  297. }
  298. else
  299. {
  300. if((nnondtdata > 200)&&(gbGPSNewData))
  301. {
  302. //Use GPS Data;
  303. mMutexgps.lock();
  304. xgpsimu.CopyFrom(ggpsimu);
  305. mMutexgps.unlock();
  306. usegps(&xgpsimu);
  307. }
  308. else
  309. {
  310. if(gbNDTNewData && ((gbGPSFix == false)||((gbGPSFix == true)&&(nnogpsdata > 100))))
  311. {
  312. // if() // trans ok use
  313. //Use NDT Data,if trans >0.5
  314. if(gndtgpspos.tras_prob() >0.5)
  315. {
  316. mMutexndt.lock();
  317. xndtgpspos.CopyFrom(gndtgpspos);
  318. mMutexndt.unlock();
  319. usendt(&xndtgpspos);
  320. }
  321. }
  322. }
  323. }
  324. }
  325. gbGPSNewData = false;
  326. gbNDTNewData = false;
  327. if(nnodatacount > 200)
  328. {
  329. nstate = 1;
  330. }
  331. if(nnodatacount > 1200)
  332. {
  333. nstate = 2;
  334. }
  335. if(nnodatacount < 30)
  336. {
  337. nstate = 0;
  338. }
  339. if(nstate != noldstate)
  340. {
  341. noldstate = nstate;
  342. switch (nstate) {
  343. case 0:
  344. gfault->SetFaultState(0,0,"OK");
  345. givlog->info("fusion gps ndt ok.");
  346. break;
  347. case 1:
  348. gfault->SetFaultState(1,1,"no data more than 1 second.");
  349. givlog->warn("no data more than 1 second.");
  350. break;
  351. case 2:
  352. gfault->SetFaultState(2,2,"no data more than 60 seconds.");
  353. givlog->error("no data more than 60 seconds.");
  354. break;
  355. default:
  356. break;
  357. }
  358. }
  359. }
  360. }
  361. void exitfunc()
  362. {
  363. std::cout<<"enter exitfunc."<<std::endl;
  364. gbfusionrun = false;
  365. gfusionthread->join();
  366. iv::modulecomm::Unregister(gpa);
  367. iv::modulecomm::Unregister(gpb);
  368. iv::modulecomm::Unregister(gpc);
  369. std::cout<<"Complete exitfunc."<<std::endl;
  370. }
  371. int main(int argc, char *argv[])
  372. {
  373. showversion("fusion_gpsndt");
  374. QCoreApplication a(argc, argv);
  375. gudpSocketGPSIMU = new QUdpSocket();
  376. QString strpath = QCoreApplication::applicationDirPath();
  377. if(argc < 2)
  378. strpath = strpath + "/fusion_gpsndt.xml";
  379. else
  380. strpath = argv[1];
  381. std::cout<<strpath.toStdString()<<std::endl;
  382. iv::xmlparam::Xmlparam xparam(strpath.toStdString());
  383. RegisterIVBackTrace();
  384. gfault = new iv::Ivfault("fusion_gpsndt");
  385. givlog = new iv::Ivlog("fusion_gpsndt");
  386. gfault->SetFaultState(0,0,"Initialize.");
  387. gstrfusionmsg = xparam.GetParam("fusionmsg","fusion_gpslidar");
  388. gstrgpsmsg = xparam.GetParam("gpsmsg","hcp2_gpsimu");
  389. gstrndtmsg = xparam.GetParam("ndtgpsposmsg","ndtgpspos");
  390. gstrlidaronly = xparam.GetParam("LidarOnly","false");
  391. gstrfusiongpsimumsg = xparam.GetParam("fusiongpsimumsg","fusion_gpsimu");
  392. gstrshareudp = xparam.GetParam("shareudp","true");
  393. gstrsharegpsimu = xparam.GetParam("sharegpsimu","true");
  394. if(gstrlidaronly == "true")
  395. {
  396. gbUseLidarOnly = true;
  397. }
  398. if(gstrshareudp == "false")
  399. {
  400. gbShareUDP = false;
  401. }
  402. if(gstrsharegpsimu == "false")
  403. {
  404. gbShareGPSIMU = false;
  405. }
  406. gpc = iv::modulecomm::RegisterSend(gstrfusionmsg.data(),1000,1);
  407. gpa = iv::modulecomm::RegisterRecv(gstrgpsmsg.data(),ListenRaw);
  408. gpb = iv::modulecomm::RegisterRecv(gstrndtmsg.data(),ListenNDTGPS);
  409. gpd = iv::modulecomm::RegisterSend(gstrfusiongpsimumsg.data(),10000,1);
  410. gpe = iv::modulecomm::RegisterRecv("chassis",UpdateChassis);
  411. std::cout<<"start fusion_gpsndt"<<std::endl;
  412. gfusionthread = new std::thread(fusionthread);
  413. iv::ivexit::RegIVExitCall(exitfunc);
  414. return a.exec();
  415. }