xodrfunc.cpp 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096
  1. #include "xodrfunc.h"
  2. #include "limits"
  3. #include <iostream>
  4. #include <Eigen/Dense>
  5. #include <Eigen/Cholesky>
  6. #include <Eigen/LU>
  7. #include <Eigen/QR>
  8. #include <Eigen/SVD>
  9. #include <QDebug>
  10. #include <QPointF>
  11. xodrfunc::xodrfunc()
  12. {
  13. }
  14. inline double xodrfunc::calcpointdis(QPointF p1,QPointF p2)
  15. {
  16. return sqrt(pow(p1.x()-p2.x(),2)+pow(p1.y()-p2.y(),2));
  17. }
  18. bool xodrfunc::pointinarc(GeometryArc * parc,QPointF poingarc,QPointF point1)
  19. {
  20. double hdg = CalcHdg(poingarc,point1);
  21. if(parc->GetCurvature() >0)hdg = hdg + M_PI/2.0;
  22. else hdg = hdg - M_PI/2.0;
  23. if(hdg >= 2.0*M_PI)hdg = hdg - 2.0*M_PI;
  24. if(hdg < 0)hdg = hdg + 2.0*M_PI;
  25. double hdgrange = parc->GetLength()/(1.0/parc->GetCurvature());
  26. double hdgdiff = hdg - parc->GetHdg();
  27. if(hdgrange >= 0 )
  28. {
  29. if(hdgdiff < 0)hdgdiff = hdgdiff + M_PI*2.0;
  30. }
  31. else
  32. {
  33. if(hdgdiff > 0)hdgdiff = hdgdiff - M_PI*2.0;
  34. }
  35. if(fabs(hdgdiff ) < fabs(hdgrange))return true;
  36. return false;
  37. }
  38. /**
  39. * @brief CalcHdg
  40. * 计算点0到点1的航向
  41. * @param p0 Point 0
  42. * @param p1 Point 1
  43. **/
  44. double xodrfunc::CalcHdg(QPointF p0, QPointF p1)
  45. {
  46. double x0,y0,x1,y1;
  47. x0 = p0.x();
  48. y0 = p0.y();
  49. x1 = p1.x();
  50. y1 = p1.y();
  51. if(x0 == x1)
  52. {
  53. if(y0 < y1)
  54. {
  55. return M_PI/2.0;
  56. }
  57. else
  58. return M_PI*3.0/2.0;
  59. }
  60. double ratio = (y1-y0)/(x1-x0);
  61. double hdg = atan(ratio);
  62. if(ratio > 0)
  63. {
  64. if(y1 > y0)
  65. {
  66. }
  67. else
  68. {
  69. hdg = hdg + M_PI;
  70. }
  71. }
  72. else
  73. {
  74. if(y1 > y0)
  75. {
  76. hdg = hdg + M_PI;
  77. }
  78. else
  79. {
  80. hdg = hdg + 2.0*M_PI;
  81. }
  82. }
  83. return hdg;
  84. }
  85. /**
  86. * @brief GetParamPoly3Dis 获得点到贝塞尔曲线的距离。
  87. * @param parc
  88. * @param xnow
  89. * @param ynow
  90. * @param nearx
  91. * @param neary
  92. * @param nearhead
  93. * @return
  94. */
  95. double xodrfunc::GetParamPoly3Dis(GeometryParamPoly3 * parc,double xnow,double ynow,double & nearx,
  96. double & neary,double & nearhead,double & frels)
  97. {
  98. double s = 0.1;
  99. double fdismin = 100000.0;
  100. frels = 0;
  101. double xold,yold;
  102. xold = parc->GetX();
  103. yold = parc->GetY();
  104. double fdis = calcpointdis(QPointF(parc->GetX(),parc->GetY()),QPointF(xnow,ynow));
  105. if(fdis<fdismin)
  106. {
  107. fdismin = fdis;
  108. nearhead = parc->GetHdg();
  109. nearx = parc->GetX();
  110. neary = parc->GetY();
  111. }
  112. while(s < parc->GetLength())
  113. {
  114. double x, y,xtem,ytem;
  115. xtem = parc->GetuA() + parc->GetuB() * s + parc->GetuC() * s*s + parc->GetuD() * s*s*s;
  116. ytem = parc->GetvA() + parc->GetvB() * s + parc->GetvC() * s*s + parc->GetvD() * s*s*s;
  117. x = xtem*cos(parc->GetHdg()) - ytem * sin(parc->GetHdg()) + parc->GetX();
  118. y = xtem*sin(parc->GetHdg()) + ytem * cos(parc->GetHdg()) + parc->GetY();
  119. double hdg = CalcHdg(QPointF(xold,yold),QPointF(x,y));
  120. double fdis = calcpointdis(QPointF(x,y),QPointF(xnow,ynow));
  121. if(fdis<fdismin)
  122. {
  123. fdismin = fdis;
  124. nearhead = hdg;
  125. nearx = x;
  126. neary = y;
  127. frels = s;
  128. }
  129. xold = x;
  130. yold = y;
  131. s = s+ 0.1;
  132. }
  133. return fdismin;
  134. }
  135. /**
  136. * @brief GetArcDis
  137. * 计算点到圆弧的最短距离,首先用点和圆弧中心点的直线与圆的交点,计算点到交点的距离,如果交点在圆弧上,则最短距离是交点之一,否则计算点到圆弧两个端点的距离。
  138. * @param parc pointer to a arc geomery
  139. * @param x current x
  140. * @param y current y
  141. * @param nearx near x
  142. * @param neary near y
  143. * @param nearhead nearhead
  144. **/
  145. double xodrfunc::GetArcDis(GeometryArc * parc,double x,double y,double & nearx,
  146. double & neary,double & nearhead,double & frels)
  147. {
  148. if((parc->GetS()>370)&&(parc->GetS()<370.1))
  149. {
  150. int a = 1;
  151. }
  152. if(parc->GetCurvature() == 0.0)return 1000.0;
  153. double R = fabs(1.0/parc->GetCurvature());
  154. frels = 0.0;
  155. //calculate arc center
  156. double x_center,y_center;
  157. if(parc->GetCurvature() > 0)
  158. {
  159. x_center = parc->GetX() + R * cos(parc->GetHdg() + M_PI/2.0);
  160. y_center = parc->GetY() + R * sin(parc->GetHdg()+ M_PI/2.0);
  161. }
  162. else
  163. {
  164. x_center = parc->GetX() + R * cos(parc->GetHdg() - M_PI/2.0);
  165. y_center = parc->GetY() + R * sin(parc->GetHdg() - M_PI/2.0);
  166. }
  167. double hdgltoa = CalcHdg(QPointF(x,y),QPointF(x_center,y_center));
  168. QPointF arcpoint;
  169. arcpoint.setX(x_center);arcpoint.setY(y_center);
  170. QPointF pointnow;
  171. pointnow.setX(x);pointnow.setY(y);
  172. QPointF point1,point2;
  173. point1.setX(x_center + (R * cos(hdgltoa)));
  174. point1.setY(y_center + (R * sin(hdgltoa)));
  175. point2.setX(x_center + (R * cos(hdgltoa + M_PI)));
  176. point2.setY(y_center + (R * sin(hdgltoa + M_PI)));
  177. //calculat dis
  178. bool bp1inarc,bp2inarc;
  179. bp1inarc =pointinarc(parc,arcpoint,point1);
  180. bp2inarc =pointinarc(parc,arcpoint,point2);
  181. double fdis[4];
  182. fdis[0] = calcpointdis(pointnow,point1);
  183. fdis[1] = calcpointdis(pointnow,point2);
  184. fdis[2] = calcpointdis(pointnow,QPointF(parc->GetX(),parc->GetY()));
  185. QPointF pointend;
  186. double hdgrange = parc->GetLength()*parc->GetCurvature();
  187. double hdgend = parc->GetHdg() + hdgrange;
  188. while(hdgend <0.0)hdgend = hdgend + 2.0 *M_PI;
  189. while(hdgend >= 2.0*M_PI) hdgend = hdgend -2.0*M_PI;
  190. if(parc->GetCurvature() >0)
  191. {
  192. pointend.setX(arcpoint.x() + R*cos(hdgend -M_PI/2.0 ));
  193. pointend.setY(arcpoint.y() + R*sin(hdgend -M_PI/2.0) );
  194. }
  195. else
  196. {
  197. pointend.setX(arcpoint.x() + R*cos(hdgend +M_PI/2.0 ));
  198. pointend.setY(arcpoint.y() + R*sin(hdgend +M_PI/2.0) );
  199. }
  200. fdis[3] = calcpointdis(pointnow,pointend);
  201. int indexmin = -1;
  202. double fdismin = 1000000.0;
  203. if(bp1inarc)
  204. {
  205. indexmin = 0;fdismin = fdis[0];
  206. }
  207. if(bp2inarc)
  208. {
  209. if(indexmin == -1)
  210. {
  211. indexmin = 1;fdismin = fdis[1];
  212. }
  213. else
  214. {
  215. if(fdis[1]<fdismin)
  216. {
  217. indexmin = 1;fdismin = fdis[1];
  218. }
  219. }
  220. }
  221. if(indexmin == -1)
  222. {
  223. indexmin = 2;fdismin = fdis[2];
  224. }
  225. else
  226. {
  227. if(fdis[2]<fdismin)
  228. {
  229. indexmin = 2;fdismin = fdis[2];
  230. }
  231. }
  232. if(fdis[3]<fdismin)
  233. {
  234. indexmin = 3;fdismin = fdis[3];
  235. }
  236. double hdgdiff;
  237. switch (indexmin) {
  238. case 0:
  239. nearx = point1.x();
  240. neary = point1.y();
  241. if(parc->GetCurvature()<0)
  242. {
  243. nearhead = CalcHdg(arcpoint,point1) - M_PI/2.0;
  244. }
  245. else
  246. {
  247. nearhead = CalcHdg(arcpoint,point1) + M_PI/2.0;
  248. }
  249. while(nearhead>2.0*M_PI)nearhead = nearhead -2.0*M_PI;
  250. while(nearhead<0)nearhead = nearhead + 2.0*M_PI;
  251. hdgdiff = (nearhead-parc->GetHdg())*(parc->GetCurvature()/abs(parc->GetCurvature()));
  252. if(hdgdiff>=2.0*M_PI)hdgdiff = hdgdiff - 2.0*M_PI;
  253. if(hdgdiff<0)hdgdiff = hdgdiff + 2.0*M_PI;
  254. frels = hdgdiff * R;
  255. break;
  256. case 1:
  257. nearx = point2.x();
  258. neary = point2.y();
  259. if(parc->GetCurvature()<0)
  260. {
  261. nearhead = CalcHdg(arcpoint,point2) - M_PI/2.0;
  262. }
  263. else
  264. {
  265. nearhead = CalcHdg(arcpoint,point2) + M_PI/2.0;
  266. }
  267. while(nearhead>2.0*M_PI)nearhead = nearhead -2.0*M_PI;
  268. while(nearhead<0)nearhead = nearhead + 2.0*M_PI;
  269. hdgdiff = (nearhead-parc->GetHdg())*(parc->GetCurvature()/abs(parc->GetCurvature()));
  270. if(hdgdiff>=2.0*M_PI)hdgdiff = hdgdiff - 2.0*M_PI;
  271. if(hdgdiff<0)hdgdiff = hdgdiff + 2.0*M_PI;
  272. frels = hdgdiff * R;
  273. break;
  274. case 2:
  275. nearx = parc->GetX();
  276. neary = parc->GetY();
  277. nearhead = parc->GetHdg();
  278. frels = 0;
  279. break;
  280. case 3:
  281. nearx = pointend.x();
  282. neary = pointend.y();
  283. nearhead = hdgend;
  284. frels = parc->GetLength();
  285. break;
  286. default:
  287. std::cout<<"error in arcdis "<<std::endl;
  288. break;
  289. }
  290. while(nearhead>2.0*M_PI)nearhead = nearhead -2.0*M_PI;
  291. while(nearhead<0)nearhead = nearhead + 2.0*M_PI;
  292. return fdismin;
  293. }
  294. double xodrfunc::GetPoly3Dis(GeometryPoly3 * ppoly,double xnow,double ynow,double & nearx,
  295. double & neary,double & nearhead,double & frels)
  296. {
  297. double x,y,hdg;
  298. // double s = 0.0;
  299. double fdismin = 100000.0;
  300. // double s0 = ppoly->GetS();
  301. x = ppoly->GetX();
  302. y = ppoly->GetY();
  303. double A,B,C,D;
  304. A = ppoly->GetA();
  305. B = ppoly->GetB();
  306. C = ppoly->GetC();
  307. D = ppoly->GetD();
  308. const double steplim = 0.3;
  309. double du = steplim;
  310. double u = 0;
  311. double v = 0;
  312. double oldx,oldy;
  313. oldx = x;
  314. oldy = y;
  315. double xstart,ystart;
  316. xstart = x;
  317. ystart = y;
  318. frels = 0;
  319. double hdgstart = ppoly->GetHdg();
  320. double flen = 0;
  321. u = u+du;
  322. while(flen < ppoly->GetLength())
  323. {
  324. double fdis = 0;
  325. v = A + B*u + C*u*u + D*u*u*u;
  326. x = xstart + u*cos(hdgstart) - v*sin(hdgstart);
  327. y = ystart + u*sin(hdgstart) + v*cos(hdgstart);
  328. fdis = sqrt(pow(x- oldx,2)+pow(y-oldy,2));
  329. if(fdis>(steplim*2.0))du = du/2.0;
  330. flen = flen + fdis;
  331. u = u + du;
  332. hdg = xodrfunc::CalcHdg(QPointF(oldx,oldy),QPointF(x,y));
  333. double fdisnow = calcpointdis(QPointF(x,y),QPointF(xnow,ynow));
  334. if(fdisnow<fdismin)
  335. {
  336. fdismin = fdisnow;
  337. nearhead = hdg;
  338. nearx = x;
  339. neary = y;
  340. frels = flen;
  341. }
  342. oldx = x;
  343. oldy = y;
  344. }
  345. return fdismin;
  346. }
  347. double xodrfunc::GetSpiralDis(GeometrySpiral * pspiral,double xnow,double ynow,double & nearx,
  348. double & neary,double & nearhead,double & frels)
  349. {
  350. double x,y,hdg;
  351. double s = 0.0;
  352. double fdismin = 100000.0;
  353. double s0 = pspiral->GetS();
  354. frels = 0;
  355. while(s<pspiral->GetLength())
  356. {
  357. pspiral->GetCoords(s0+s,x,y,hdg);
  358. double fdis = calcpointdis(QPointF(x,y),QPointF(xnow,ynow));
  359. if(fdis<fdismin)
  360. {
  361. fdismin = fdis;
  362. nearhead = hdg;
  363. nearx = x;
  364. neary = y;
  365. frels = s;
  366. }
  367. s = s+0.1;
  368. }
  369. return fdismin;
  370. }
  371. /**
  372. * @brief GetLineDis 获得点到直线Geometry的距离。
  373. * @param pline
  374. * @param x
  375. * @param y
  376. * @param nearx
  377. * @param neary
  378. * @param nearhead
  379. * @return
  380. */
  381. double xodrfunc::GetLineDis(GeometryLine * pline,const double x,const double y,double & nearx,
  382. double & neary,double & nearhead,double & frels)
  383. {
  384. double fRtn = 1000.0;
  385. double a1,a2,a3,a4,b1,b2;
  386. double ratio = pline->GetHdg();
  387. while(ratio >= 2.0* M_PI)ratio = ratio-2.0*M_PI;
  388. while(ratio<0)ratio = ratio+2.0*M_PI;
  389. double dis1,dis2,dis3;
  390. double x1,x2,x3,y1,y2,y3;
  391. x1 = pline->GetX();y1=pline->GetY();
  392. if((ratio == 0)||(ratio == M_PI))
  393. {
  394. a1 = 0;a4=0;
  395. a2 = 1;b1= pline->GetY();
  396. a3 = 1;b2= x;
  397. }
  398. else
  399. {
  400. if((ratio == 0.5*M_PI)||(ratio == 1.5*M_PI))
  401. {
  402. a2=0;a3=0;
  403. a1=1,b1=pline->GetX();
  404. a4 = 1;b2 = y;
  405. }
  406. else
  407. {
  408. a1 = tan(ratio) *(-1.0);
  409. a2 = 1;
  410. a3 = tan(ratio+M_PI/2.0)*(-1.0);
  411. a4 = 1;
  412. b1 = a1*pline->GetX() + a2 * pline->GetY();
  413. b2 = a3*x+a4*y;
  414. }
  415. }
  416. y2 = y1 + pline->GetLength() * sin(ratio);
  417. x2 = x1 + pline->GetLength() * cos(ratio);
  418. Eigen::Matrix2d A;
  419. A<<a1,a2,
  420. a3,a4;
  421. Eigen::Vector2d B(b1,b2);
  422. Eigen::Vector2d opoint = A.lu().solve(B);
  423. x3 = opoint(0);
  424. y3 = opoint(1);
  425. dis1 = sqrt(pow(x1-x,2)+pow(y1-y,2));
  426. dis2 = sqrt(pow(x2-x,2)+pow(y2-y,2));
  427. dis3 = sqrt(pow(x3-x,2)+pow(y3-y,2));
  428. if((dis1>pline->GetLength())||(dis2>pline->GetLength())) //Outoff line
  429. {
  430. // std::cout<<" out line"<<std::endl;
  431. if(dis1<dis2)
  432. {
  433. fRtn = dis1;
  434. nearx = x1;neary=y1;nearhead = pline->GetHdg();
  435. }
  436. else
  437. {
  438. fRtn = dis2;
  439. nearx = x2;neary=y2;nearhead = pline->GetHdg();
  440. }
  441. }
  442. else
  443. {
  444. fRtn = dis3;
  445. nearx = x3;neary=y3;nearhead = pline->GetHdg();
  446. }
  447. frels = sqrt(pow(nearx - pline->GetX(),2)+pow(neary - pline->GetY(),2));
  448. return fRtn;
  449. }
  450. namespace iv {
  451. struct nearoption
  452. {
  453. Road * pRoad;
  454. GeometryBlock * pgeob;
  455. double fdis;
  456. double nearx;
  457. double neary;
  458. double nearhead;
  459. double fs;
  460. int nlane;
  461. double fgeodis;
  462. };
  463. }
  464. int xodrfunc::GetNearPoint(const double x, const double y, OpenDrive *pxodr, Road **pObjRoad, GeometryBlock **pgeo,
  465. double &fdis, double &nearx, double &neary, double &nearhead,
  466. const double nearthresh,double * pfs,int * pnlane,bool bnotuselane)
  467. {
  468. double dismin = std::numeric_limits<double>::infinity();
  469. fdis = dismin;
  470. unsigned int i;
  471. *pObjRoad = 0;
  472. std::vector<iv::nearoption> xvectornearopt;
  473. for(i=0;i<pxodr->GetRoadCount();i++)
  474. {
  475. unsigned int j;
  476. Road * proad = pxodr->GetRoad(i);
  477. double nx,ny,nh,frels;
  478. for(j=0;j<proad->GetGeometryBlockCount();j++)
  479. {
  480. GeometryBlock * pgb = proad->GetGeometryBlock(j);
  481. double dis;
  482. RoadGeometry * pg;
  483. int nlane = 1000;
  484. pg = pgb->GetGeometryAt(0);
  485. if((sqrt(pow(x-pg->GetX(),2)+pow(y- pg->GetY(),2))-pg->GetLength())>nearthresh)
  486. {
  487. continue;
  488. }
  489. switch (pg->GetGeomType()) {
  490. case 0: //line
  491. dis = GetLineDis((GeometryLine *) pg,x,y,nx,ny,nh,frels);
  492. break;
  493. case 1:
  494. dis = GetSpiralDis((GeometrySpiral *)pg,x,y,nx,ny,nh,frels);
  495. break;
  496. case 2: //arc
  497. dis = GetArcDis((GeometryArc *)pg,x,y,nx,ny,nh,frels);
  498. break;
  499. case 3:
  500. dis = GetPoly3Dis((GeometryPoly3 *)pg,x,y,nx,ny,nh,frels);
  501. break;
  502. case 4:
  503. dis = GetParamPoly3Dis((GeometryParamPoly3 *)pg,x,y,nx,ny,nh,frels);
  504. break;
  505. default:
  506. dis = 100000.0;
  507. break;
  508. }
  509. double fgeodis;
  510. fgeodis = dis;
  511. if((dis < 100)&&(bnotuselane == false))
  512. {
  513. double faccuratedis;
  514. faccuratedis = GetAcurateDis(x,y,proad,frels+pg->GetS(),nx,ny,nh,&nlane);
  515. if(faccuratedis < dis)dis = faccuratedis;
  516. }
  517. if(dis == 0)
  518. {
  519. iv::nearoption xopt;
  520. xopt.fdis = dis;
  521. xopt.fgeodis = fgeodis;
  522. xopt.fs = frels +pg->GetS();
  523. xopt.nearhead = nh;
  524. xopt.nearx = nx;
  525. xopt.neary = ny;
  526. xopt.nlane = nlane;
  527. xopt.pgeob = pgb;
  528. xopt.pRoad = proad;
  529. xvectornearopt.push_back(xopt);
  530. }
  531. if(dis < dismin)
  532. {
  533. dismin = dis;
  534. nearx = nx;
  535. neary = ny;
  536. nearhead = nh;
  537. fdis = dis;
  538. *pObjRoad = proad;
  539. *pgeo = pgb;
  540. if(pfs != 0)*pfs = frels +pg->GetS();
  541. if(pnlane != 0)*pnlane = nlane;
  542. }
  543. }
  544. }
  545. if(xvectornearopt.size() > 1)
  546. {
  547. double fgeodismin = 1000;
  548. int nindex = 0;
  549. for(i=0;i<xvectornearopt.size();i++)
  550. {
  551. if(xvectornearopt.at(i).fgeodis < fgeodismin)
  552. {
  553. fgeodismin = xvectornearopt.at(i).fgeodis;
  554. nindex = i;
  555. }
  556. }
  557. dismin = xvectornearopt.at(nindex).fdis;
  558. nearx = xvectornearopt.at(nindex).nearx;
  559. neary = xvectornearopt.at(nindex).neary;
  560. nearhead = xvectornearopt.at(nindex).nearhead;
  561. fdis = dismin;
  562. *pObjRoad = xvectornearopt.at(nindex).pRoad;
  563. *pgeo = xvectornearopt.at(nindex).pgeob;
  564. if(pfs != 0)*pfs = xvectornearopt.at(nindex).fs;
  565. if(pnlane != 0)*pnlane = xvectornearopt.at(nindex).nlane;
  566. }
  567. if(fdis > nearthresh)return -1;
  568. return 0;
  569. }
  570. std::vector<iv::LanePoint> xodrfunc::GetAllLanePoint(Road *pRoad, const double s,const double x, const double y,const double fhdg)
  571. {
  572. int i;
  573. int nLSCount = pRoad->GetLaneSectionCount();
  574. double s_section = 0;
  575. std::vector<iv::LanePoint> xvectorlanepoint;
  576. for(i=0;i<nLSCount;i++)
  577. {
  578. // if((pRoad->GetRoadId() == "30012")&&(s>35))
  579. // {
  580. // int a= 1;
  581. // }
  582. LaneSection * pLS = pRoad->GetLaneSection(i);
  583. if(i<(nLSCount -1))
  584. {
  585. if(pRoad->GetLaneSection(i+1)->GetS()<s)
  586. {
  587. continue;
  588. }
  589. }
  590. s_section = pLS->GetS();
  591. int nlanecount = pLS->GetLaneCount();
  592. int j;
  593. for(j=0;j<nlanecount;j++)
  594. {
  595. Lane * pLane = pLS->GetLane(j);
  596. int nlanemarktype = -1; //default no lanetype
  597. int nlanetype = 2; //driving
  598. int nlanecolor = 0;
  599. int k;
  600. double s_lane = s-s_section;
  601. for(k=0;k<pLane->GetLaneRoadMarkCount();k++)
  602. {
  603. LaneRoadMark * plrm = pLane->GetLaneRoadMark(k);
  604. if(k<(pLane->GetLaneRoadMarkCount()-1))
  605. {
  606. if(pLane->GetLaneRoadMark(k+1)->GetS()<s_lane)
  607. {
  608. continue;
  609. }
  610. }
  611. else
  612. {
  613. if(s_lane<plrm->GetS())
  614. {
  615. continue;
  616. }
  617. }
  618. if(plrm->GetType() == "solid")
  619. {
  620. nlanemarktype = 0;
  621. }
  622. if(plrm->GetType() == "broken")
  623. {
  624. nlanemarktype = 1;
  625. }
  626. if(plrm->GetType() == "solid solid")
  627. {
  628. nlanemarktype = 2;
  629. }
  630. if(plrm->GetType() == "solid broken")
  631. {
  632. nlanemarktype = 3;
  633. }
  634. if(plrm->GetType() == "broken solid")
  635. {
  636. nlanemarktype = 4;
  637. }
  638. if(plrm->GetType() == "broken broken")
  639. {
  640. nlanemarktype = 5;
  641. }
  642. if(plrm->GetColor() == "standard")nlanecolor = 0;
  643. if(plrm->GetColor() == "blue")nlanecolor = 1;
  644. if(plrm->GetColor() == "green")nlanecolor = 2;
  645. if(plrm->GetColor() == "red")nlanecolor = 3;
  646. if(plrm->GetColor() == "white")nlanecolor = 4;
  647. if(plrm->GetColor() == "yellow")nlanecolor = 5;
  648. if(plrm->GetColor() == "orange")nlanecolor = 6;
  649. break;
  650. }
  651. if(pLane->GetType() == "shoulder")
  652. {
  653. nlanetype = 0;
  654. }
  655. if(pLane->GetType() == "border")
  656. {
  657. nlanetype = 1;
  658. }
  659. if(pLane->GetType() == "driving")
  660. {
  661. nlanetype = 2;
  662. }
  663. if(pLane->GetType() == "none")
  664. {
  665. nlanetype = 4;
  666. }
  667. if(pLane->GetType() == "biking")
  668. {
  669. nlanetype = 8;
  670. }
  671. if(pLane->GetType() == "sidewalk")
  672. {
  673. nlanetype = 9;
  674. }
  675. if(pLane->GetId() != 0)
  676. {
  677. // if((pRoad->GetRoadId() == "10012")&&(pLane->GetId()==1))
  678. // {
  679. // int a= 1;
  680. // }
  681. // int k;
  682. // double s_lane = 0;
  683. for(k=0;k<pLane->GetLaneWidthCount();k++)
  684. {
  685. if(k<(pLane->GetLaneWidthCount()-1))
  686. {
  687. if((pLane->GetLaneWidth(k+1)->GetS()+s_section)<s)
  688. {
  689. continue;
  690. }
  691. }
  692. s_lane = pLane->GetLaneWidth(k)->GetS();
  693. break;
  694. }
  695. LaneWidth * pLW = pLane->GetLaneWidth(k);
  696. if(pLW == 0)
  697. {
  698. std::cout<<"not find LaneWidth"<<std::endl;
  699. break;
  700. }
  701. iv::LanePoint lp;
  702. lp.mnlanetype = nlanetype;
  703. lp.mnlanemarktype = nlanemarktype;
  704. lp.mnlanecolor = nlanecolor;
  705. lp.mnlane = pLane->GetId();
  706. lp.mnLaneSection = i;
  707. double fds = s - s_lane - s_section;
  708. lp.mflanewidth = pLW->GetA() + pLW->GetB() * fds
  709. +pLW->GetC() * pow(fds,2) + pLW->GetD() * pow(fds,3);
  710. lp.mflanetocenter = 0;
  711. lp.mnlanetype = nlanetype;
  712. lp.mfhdg = fhdg;
  713. lp.mS = s;
  714. lp.mfGeoX = x;
  715. lp.mfGeoY = y;
  716. xvectorlanepoint.push_back(lp);
  717. }
  718. else
  719. {
  720. iv::LanePoint lp;
  721. lp.mnlanetype = nlanetype;
  722. lp.mnlanemarktype = nlanemarktype;
  723. lp.mnlanecolor = nlanecolor;
  724. lp.mnlane = 0;
  725. lp.mnLaneSection = i;
  726. lp.mflanewidth = 0;
  727. lp.mflanetocenter = 0;
  728. lp.mfhdg = fhdg;
  729. lp.mS = s;
  730. lp.mfGeoX = x;
  731. lp.mfGeoY = y;
  732. xvectorlanepoint.push_back(lp);
  733. }
  734. }
  735. for(j=0;j<xvectorlanepoint.size();j++)
  736. {
  737. int k;
  738. for(k=0;k<xvectorlanepoint.size();k++)
  739. {
  740. if(abs(xvectorlanepoint[k].mnlane)>abs((xvectorlanepoint[j].mnlane)))
  741. {
  742. continue;
  743. }
  744. if(xvectorlanepoint[k].mnlane * xvectorlanepoint[j].mnlane <= 0)
  745. {
  746. continue;
  747. }
  748. xvectorlanepoint[j].mflanetocenter = xvectorlanepoint[j].mflanetocenter + xvectorlanepoint[k].mflanewidth;
  749. }
  750. }
  751. for(j=0;j<xvectorlanepoint.size();j++)
  752. {
  753. if(xvectorlanepoint[j].mnlane < 0)
  754. {
  755. xvectorlanepoint[j].mfX = x + xvectorlanepoint[j].mflanetocenter * cos(fhdg-M_PI/2.0);
  756. xvectorlanepoint[j].mfY = y + xvectorlanepoint[j].mflanetocenter * sin(fhdg-M_PI/2.0);
  757. }
  758. else
  759. {
  760. xvectorlanepoint[j].mfX = x + xvectorlanepoint[j].mflanetocenter * cos(fhdg+M_PI/2.0);
  761. xvectorlanepoint[j].mfY = y + xvectorlanepoint[j].mflanetocenter * sin(fhdg+M_PI/2.0);
  762. }
  763. }
  764. break;
  765. }
  766. std::vector<iv::LanePoint> xvectorlanepointrtn;
  767. bool bIsSort = true;
  768. for(i=0;i<(xvectorlanepoint.size()-1);i++)
  769. {
  770. if(xvectorlanepoint[i].mnlane < xvectorlanepoint[i+1].mnlane)
  771. {
  772. bIsSort = false;
  773. break;
  774. }
  775. }
  776. if(bIsSort == false)
  777. {
  778. while(xvectorlanepoint.size() > 0)
  779. {
  780. int nlanemin;
  781. nlanemin = 0;
  782. int nlanenum = xvectorlanepoint[0].mnlane;
  783. for(i=1;i<xvectorlanepoint.size();i++)
  784. {
  785. if(xvectorlanepoint[i].mnlane >= nlanenum)
  786. {
  787. nlanenum = xvectorlanepoint[i].mnlane;
  788. nlanemin = i;
  789. }
  790. }
  791. xvectorlanepointrtn.push_back(xvectorlanepoint[nlanemin]);
  792. xvectorlanepoint.erase(xvectorlanepoint.begin() + nlanemin);
  793. }
  794. }
  795. else
  796. {
  797. xvectorlanepointrtn = xvectorlanepoint;
  798. }
  799. return xvectorlanepointrtn;
  800. }
  801. double xodrfunc::GetAcurateDis(const double x, const double y, Road *pRoad, const double s, const double nearx, const double neary, const double nearhead,int * pnlane)
  802. {
  803. double fdismin = 1000;
  804. if(pRoad->GetLaneSectionCount() < 1)return 1000;
  805. std::vector<iv::LanePoint> xvectorlanepoint = GetAllLanePoint(pRoad,s,nearx,neary,nearhead);
  806. double fdistoref = sqrt(pow(x-nearx,2)+pow(y-neary,2));
  807. int i;
  808. std::vector<double> xvectordis;
  809. int nsize = xvectorlanepoint.size();
  810. for(i=0;i<nsize;i++)
  811. {
  812. double fdis = sqrt(pow(x-xvectorlanepoint[i].mfX,2)+pow(y-xvectorlanepoint[i].mfY,2));
  813. xvectordis.push_back(fdis);
  814. if(fdismin>fdis)fdismin = fdis;
  815. }
  816. int nlane = -1000;
  817. for(i=0;i<nsize;i++)
  818. {
  819. if((xvectordis[i]<=xvectorlanepoint[i].mflanewidth)&&(fdistoref <= xvectorlanepoint[i].mflanetocenter))
  820. {
  821. nlane = xvectorlanepoint[i].mnlane;
  822. fdismin = 0; //On Lane, is very near.
  823. break;
  824. }
  825. }
  826. if(pnlane != 0)*pnlane = nlane;
  827. return fdismin;
  828. }
  829. int xodrfunc::GetLineXY(GeometryLine *pline, double soff, double &x, double &y, double &hdg)
  830. {
  831. if(soff<0)return -1;
  832. hdg = pline->GetHdg();
  833. x = pline->GetX() + soff*cos(hdg);
  834. y = pline->GetY() + soff*sin(hdg);
  835. return 0;
  836. }
  837. Road * xodrfunc::GetRoadByID(OpenDrive * pxodr,std::string strroadid)
  838. {
  839. Road * pRoad = 0;
  840. int nroadcount = pxodr->GetRoadCount();
  841. int i;
  842. for(i=0;i<nroadcount;i++)
  843. {
  844. if(pxodr->GetRoad(i)->GetRoadId() == strroadid)
  845. {
  846. pRoad = pxodr->GetRoad(i);
  847. break;
  848. }
  849. }
  850. return pRoad;
  851. }
  852. int xodrfunc::GetSpiralXY(GeometrySpiral *pspira, double soff, double &x, double &y, double &hdg)
  853. {
  854. pspira->GetCoords(pspira->GetS() + soff,x,y,hdg);
  855. return 0;
  856. }
  857. int xodrfunc::GetArcXY(GeometryArc *parc, double soff, double &x, double &y, double &hdg)
  858. {
  859. if(parc->GetCurvature() == 0)return -1;
  860. double R = fabs(1.0/parc->GetCurvature());
  861. //calculate arc center
  862. double x_center = parc->GetX() + (1.0/parc->GetCurvature()) * cos(parc->GetHdg() + M_PI/2.0);
  863. double y_center = parc->GetY() + (1.0/parc->GetCurvature()) * sin(parc->GetHdg()+ M_PI/2.0);
  864. double arcdiff = soff/R;
  865. if(parc->GetCurvature() > 0)
  866. {
  867. x = x_center + R * cos(parc->GetHdg() + arcdiff - M_PI/2.0);
  868. y = y_center + R * sin(parc->GetHdg() + arcdiff - M_PI/2.0);
  869. hdg = parc->GetHdg() + arcdiff;
  870. }
  871. else
  872. {
  873. x = x_center + R * cos(parc->GetHdg() -arcdiff + M_PI/2.0);
  874. y = y_center + R * sin(parc->GetHdg() -arcdiff + M_PI/2.0);
  875. hdg = parc->GetHdg() - arcdiff;
  876. }
  877. return 0;
  878. }
  879. int xodrfunc::GetParamPoly3XY(GeometryParamPoly3 *pparam3d, double soff, double &x, double &y, double &hdg)
  880. {
  881. double xtem,ytem;
  882. double ua,ub,uc,ud,va,vb,vc,vd;
  883. ua = pparam3d->GetuA();ub= pparam3d->GetuB();uc= pparam3d->GetuC();ud = pparam3d->GetuD();
  884. va = pparam3d->GetvA();vb= pparam3d->GetvB();vc= pparam3d->GetvC();vd = pparam3d->GetvD();
  885. // xtem = parc->GetuA() + parc->GetuB() * s * len + parc->GetuC() * s*s *pow(len,2) + parc->GetuD() * s*s*s *pow(len,3);
  886. // ytem = parc->GetvA() + parc->GetvB() * s* len + parc->GetvC() * s*s *pow(len,2) + parc->GetvD() * s*s*s *pow(len,3);
  887. xtem = ua + ub * soff + uc * soff * soff + ud * soff *soff*soff ;
  888. ytem = va + vb * soff + vc * soff*soff + vd * soff*soff*soff ;
  889. x = xtem*cos(pparam3d->GetHdg()) - ytem * sin(pparam3d->GetHdg()) + pparam3d->GetX();
  890. y = xtem*sin(pparam3d->GetHdg()) + ytem * cos(pparam3d->GetHdg()) + pparam3d->GetY();
  891. if(soff<0.3)hdg = pparam3d->GetHdg();
  892. else
  893. {
  894. double soff1 = soff - 0.1;
  895. double x1,y1;
  896. xtem = ua + ub * soff1 + uc * soff1 * soff1 + ud * soff1 *soff1*soff1 ;
  897. ytem = va + vb * soff1 + vc * soff1*soff1 + vd * soff1*soff1*soff1 ;
  898. x1 = xtem*cos(pparam3d->GetHdg()) - ytem * sin(pparam3d->GetHdg()) + pparam3d->GetX();
  899. y1 = xtem*sin(pparam3d->GetHdg()) + ytem * cos(pparam3d->GetHdg()) + pparam3d->GetY();
  900. hdg = CalcHdg(QPointF(x1,y1),QPointF(x,y));
  901. }
  902. return 0;
  903. }
  904. int xodrfunc::GetRoadXYByS(Road *pRoad, const double s, double &x, double &y, double &hdg)
  905. {
  906. if(s<0)return -1;
  907. if(s>(pRoad->GetRoadLength()+0.1))return -2;
  908. if(pRoad == 0)return -3;
  909. if(pRoad->GetGeometryBlockCount()<1)return -4;
  910. int i;
  911. int nroadgeosize = pRoad->GetGeometryBlockCount();
  912. RoadGeometry * pgeosel = pRoad->GetGeometryBlock(nroadgeosize -1)->GetGeometryAt(0);
  913. for(i=0;i<(nroadgeosize-1);i++)
  914. {
  915. if(s<pRoad->GetGeometryBlock(i+1)->GetGeometryAt(0)->GetS())
  916. {
  917. pgeosel = pRoad->GetGeometryBlock(0)->GetGeometryAt(0);
  918. break;
  919. }
  920. }
  921. switch (pgeosel->GetGeomType()) {
  922. case 0:
  923. return GetLineXY((GeometryLine *)pgeosel,(s-pgeosel->GetS()),x,y,hdg);
  924. break;
  925. case 1:
  926. return GetSpiralXY((GeometrySpiral *)pgeosel,(s-pgeosel->GetS()),x,y,hdg);
  927. break;
  928. case 2:
  929. return GetArcXY((GeometryArc *)pgeosel,(s-pgeosel->GetS()),x,y,hdg);
  930. break;
  931. case 3:
  932. break;
  933. case 4:
  934. return GetParamPoly3XY((GeometryParamPoly3 *)pgeosel,(s-pgeosel->GetS()),x,y,hdg);
  935. break;
  936. default:
  937. break;
  938. }
  939. return -5;
  940. }
  941. int xodrfunc::GetRoadIndex(OpenDrive * pxodr, Road *pRoad)
  942. {
  943. int nroadcount = pxodr->GetRoadCount();
  944. int i;
  945. for(i=0;i<nroadcount;i++)
  946. {
  947. if(pxodr->GetRoad(i) == pRoad)
  948. {
  949. return i;
  950. }
  951. }
  952. return -1;
  953. }