RoadGeometry.cpp 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234
  1. #include "RoadGeometry.h"
  2. #define _USE_MATH_DEFINES
  3. #include <math.h>
  4. //#define PI 3.14159265358979323846264338327950288
  5. extern int fresnl( double , double *, double * );
  6. //***********************************************************************************
  7. //Road Geometry Base Class
  8. //***********************************************************************************
  9. /**
  10. * Constructor that initializes the base properties of teh record
  11. */
  12. RoadGeometry::RoadGeometry(double s, double x, double y, double hdg, double length)
  13. {
  14. mS=s; mX=x; mY=y, mHdg=hdg, mLength=length;
  15. mS2=s+length;
  16. }
  17. /**
  18. * Computes the required vars
  19. */
  20. void RoadGeometry::ComputeVars()
  21. {}
  22. /**
  23. * Clones and returns the new geometry record
  24. */
  25. RoadGeometry* RoadGeometry::Clone() const
  26. {
  27. return new RoadGeometry(mS,mX,mY, mHdg, mLength);
  28. }
  29. //-------------------------------------------------
  30. /**
  31. * Sets the type of the geometry
  32. * 0: Line, 1: Arc, 2: Spiral
  33. */
  34. void RoadGeometry::SetGeomType(short int geomType)
  35. {
  36. mGeomType = geomType;
  37. }
  38. double RoadGeometry::CalcHdg(double x0, double y0, double x1, double y1)
  39. {
  40. if(x0 == x1)
  41. {
  42. if(y0 < y1)
  43. {
  44. return M_PI/2.0;
  45. }
  46. else
  47. return M_PI*3.0/2.0;
  48. }
  49. double ratio = (y1-y0)/(x1-x0);
  50. double hdg = atan(ratio);
  51. if(ratio > 0)
  52. {
  53. if(y1 > y0)
  54. {
  55. }
  56. else
  57. {
  58. hdg = hdg + M_PI;
  59. }
  60. }
  61. else
  62. {
  63. if(y1 > y0)
  64. {
  65. hdg = hdg + M_PI;
  66. }
  67. else
  68. {
  69. hdg = hdg + 2.0*M_PI;
  70. }
  71. }
  72. return hdg;
  73. }
  74. /**
  75. * Setter for the base properties
  76. */
  77. void RoadGeometry::SetBase(double s, double x, double y, double hdg, double length, bool recalculate)
  78. {
  79. mS=s;
  80. mX=x;
  81. mY=y;
  82. mHdg=hdg;
  83. mLength=length;
  84. mS2=mS+mLength;
  85. if(recalculate) ComputeVars();
  86. }
  87. void RoadGeometry::SetS(double s)
  88. {
  89. mS=s;
  90. mS2=mS+mLength;
  91. ComputeVars();
  92. }
  93. void RoadGeometry::SetX(double x)
  94. {
  95. mX=x;
  96. }
  97. void RoadGeometry::SetY(double y)
  98. {
  99. mY=y;
  100. }
  101. void RoadGeometry::SetHdg(double hdg)
  102. {
  103. mHdg=hdg;
  104. ComputeVars();
  105. }
  106. void RoadGeometry::SetLength(double length)
  107. {
  108. mLength=length;
  109. mS2=mS+mLength;
  110. ComputeVars();
  111. }
  112. //-------------------------------------------------
  113. /**
  114. * Getter for the geometry type
  115. */
  116. short int RoadGeometry::GetGeomType()
  117. {
  118. return mGeomType;
  119. }
  120. /**
  121. * Getter for the base properties
  122. */
  123. double RoadGeometry::GetS()
  124. {
  125. return mS;
  126. }
  127. double RoadGeometry::GetS2()
  128. {
  129. return mS2;
  130. }
  131. double RoadGeometry::GetX()
  132. {
  133. return mX;
  134. }
  135. double RoadGeometry::GetY()
  136. {
  137. return mY;
  138. }
  139. double RoadGeometry::GetHdg()
  140. {
  141. return mHdg;
  142. }
  143. double RoadGeometry::GetLength()
  144. {
  145. return mLength;
  146. }
  147. //-------------------------------------------------
  148. /**
  149. * Checks if the sample S gets in the current block interval
  150. */
  151. bool RoadGeometry::CheckInterval (double s_check)
  152. {
  153. // if ((s_check >= mS) && (s_check<=mS2))
  154. if ((s_check >= mS) && (s_check<=(mS2+0.00001))) //Solve End Problem.
  155. return true;
  156. else
  157. return false;
  158. }
  159. /**
  160. * Gets the coordinates at the sample S offset
  161. */
  162. void RoadGeometry::GetCoords(double s_check, double &retX, double &retY)
  163. {
  164. double tmp;
  165. GetCoords(s_check, retX, retY, tmp);
  166. }
  167. void RoadGeometry::GetCoords(double s_check, double &retX, double &retY, double &retHDG)
  168. {}
  169. //***********************************************************************************
  170. //Line geometry
  171. //***********************************************************************************
  172. /**
  173. * Constructor that initializes the base properties of the record
  174. */
  175. GeometryLine::GeometryLine (double s, double x, double y, double hdg, double length): RoadGeometry(s, x, y, hdg, length)
  176. {
  177. SetGeomType(0);
  178. }
  179. /**
  180. * Clones and returns the new geometry record
  181. */
  182. RoadGeometry* GeometryLine::Clone() const
  183. {
  184. GeometryLine* ret=new GeometryLine(mS,mX,mY, mHdg, mLength);
  185. return ret;
  186. }
  187. //-------------------------------------------------
  188. /**
  189. * Setter for the base properties
  190. */
  191. void GeometryLine::SetAll(double s, double x, double y, double hdg, double length)
  192. {
  193. SetBase(s,x,y,hdg,length,false);
  194. ComputeVars();
  195. }
  196. //-------------------------------------------------
  197. /**
  198. * Gets the coordinates at the sample S offset
  199. */
  200. void GeometryLine::GetCoords(double s_check, double &retX, double &retY, double &retHDG)
  201. {
  202. double newLength=s_check-mS;
  203. //find the end of the chord line
  204. retX=mX+cos(mHdg)*newLength;
  205. retY=mY+sin(mHdg)*newLength;
  206. retHDG=mHdg;
  207. }
  208. //***********************************************************************************
  209. //Arc geometry
  210. //***********************************************************************************
  211. /**
  212. * Constructor that initializes the base properties of the record
  213. */
  214. GeometryArc::GeometryArc (double s, double x, double y, double hdg, double length, double curvature): RoadGeometry(s, x, y, hdg, length)
  215. {
  216. SetGeomType(2);
  217. mCurvature=curvature;
  218. ComputeVars();
  219. }
  220. /**
  221. * Computes the required vars
  222. */
  223. void GeometryArc::ComputeVars()
  224. {
  225. double radius=0.0;
  226. //if curvature is 0, radius is also 0, otherwise, radius is 1/curvature
  227. if (fabs(mCurvature)>1.00e-15)
  228. {
  229. radius = fabs(1.0/mCurvature);
  230. }
  231. //calculate the start angle for the arc plot
  232. if (mCurvature<=0)
  233. mStartAngle=mHdg+M_PI_2;
  234. else
  235. mStartAngle=mHdg-M_PI_2;
  236. mCircleX=mX+cos(mStartAngle-M_PI)*radius;
  237. mCircleY=mY+sin(mStartAngle-M_PI)*radius;
  238. }
  239. /**
  240. * Clones and returns the new geometry record
  241. */
  242. RoadGeometry* GeometryArc::Clone() const
  243. {
  244. GeometryArc* ret=new GeometryArc(mS,mX,mY, mHdg, mLength, mCurvature);
  245. return ret;
  246. }
  247. //-------------------------------------------------
  248. /**
  249. * Setter for the base properties
  250. */
  251. void GeometryArc::SetAll(double s, double x, double y, double hdg, double length, double curvature)
  252. {
  253. SetBase(s,x,y,hdg,length,false);
  254. mCurvature=curvature;
  255. ComputeVars();
  256. }
  257. void GeometryArc::SetCurvature(double curvature)
  258. {
  259. mCurvature=curvature;
  260. ComputeVars();
  261. }
  262. //-------------------------------------------------
  263. /**
  264. * Getter for the base properties
  265. */
  266. double GeometryArc::GetCurvature()
  267. {
  268. return mCurvature;
  269. }
  270. //-------------------------------------------------
  271. /**
  272. * Gets the coordinates at the sample S offset
  273. */
  274. void GeometryArc::GetCoords(double s_check, double &retX, double &retY, double &retHDG)
  275. {
  276. //s from the beginning of the segment
  277. double currentLength = s_check - mS;
  278. double endAngle=mStartAngle;
  279. double radius=0.0;
  280. //if curvature is 0, radius is also 0, so don't add anything to the initial radius,
  281. //otherwise, radius is 1/curvature so the central angle can be calculated and added to the initial direction
  282. if (fabs(mCurvature)>1.00e-15)
  283. {
  284. endAngle+= currentLength/(1.0/mCurvature);
  285. radius = fabs(1.0/mCurvature);
  286. }
  287. //coords on the arc for given s value
  288. retX=mCircleX+cos(endAngle)*radius;
  289. retY=mCircleY+sin(endAngle)*radius;
  290. //heading at the given position
  291. if (mCurvature<=0)
  292. retHDG=endAngle-M_PI_2;
  293. else
  294. retHDG=endAngle+M_PI_2;
  295. }
  296. //***********************************************************************************
  297. //Spiral geometry
  298. //***********************************************************************************
  299. const double GeometrySpiral::sqrtPiO2=sqrt(M_PI_2);
  300. /**
  301. * Constructor that initializes the base properties of the record
  302. */
  303. GeometrySpiral::GeometrySpiral (double s, double x, double y, double hdg, double length, double curvatureStart,double curvatureEnd): RoadGeometry(s, x, y, hdg, length)
  304. {
  305. SetGeomType(1);
  306. mCurvatureStart=curvatureStart;
  307. mCurvatureEnd=curvatureEnd;
  308. ComputeVars();
  309. }
  310. /**
  311. * Computes the required vars
  312. */
  313. void GeometrySpiral::ComputeVars()
  314. {
  315. mA=0;
  316. //if the curvatureEnd is the non-zero curvature, then the motion is in normal direction along the spiral
  317. if ((fabs(mCurvatureEnd)>1.00e-15)&&(fabs(mCurvatureStart)<=1.00e-15))
  318. {
  319. mNormalDir=true;
  320. mCurvature=mCurvatureEnd;
  321. //Calculate the normalization term : a = 1.0/sqrt(2*End_Radius*Total_Curve_Length)
  322. mA=1.0/sqrt(2*1.0/fabs(double(mCurvature))*mLength);
  323. //Denormalization Factor
  324. mDenormalizeFactor=1.0/mA;
  325. //Calculate the sine and cosine of the heading angle used to rotate the spiral according to the heading
  326. mRotCos=cos(mHdg);
  327. mRotSin=sin(mHdg);
  328. }
  329. //else the motion is in the inverse direction along the spiral
  330. else
  331. {
  332. mNormalDir=false;
  333. mCurvature=mCurvatureStart;
  334. //Calculate the normalization term : a = 1.0/sqrt(2*End_Radius*Total_Curve_Length)
  335. mA=1.0/sqrt(2*1.0/fabs(mCurvature)*mLength);
  336. //Because we move in the inverse direction, we need to rotate the curve according to the heading
  337. //around the last point of the normalized spiral
  338. //Calculate the total length, normalize it and divide by sqrtPiO2, then, calculate the position of the final point.
  339. double L=(mS2-mS)*mA/sqrtPiO2;
  340. fresnl(L,&mEndY,&mEndX);
  341. //Invert the curve if the curvature is negative
  342. if (mCurvature<0)
  343. mEndY=-mEndY;
  344. //Denormalization factor
  345. mDenormalizeFactor=1.0/mA;
  346. //Find the x,y coords of the final point of the curve in local curve coordinates
  347. mEndX*=mDenormalizeFactor*sqrtPiO2;
  348. mEndY*=mDenormalizeFactor*sqrtPiO2;
  349. //Calculate the tangent angle
  350. differenceAngle=L*L*(sqrtPiO2*sqrtPiO2);
  351. double diffAngle;
  352. //Calculate the tangent and heading angle difference that will be used to rotate the spiral
  353. if (mCurvature<0)
  354. {
  355. diffAngle=mHdg-differenceAngle-M_PI;
  356. }
  357. else
  358. {
  359. diffAngle=mHdg+differenceAngle-M_PI;
  360. }
  361. //Calculate the sine and cosine of the difference angle
  362. mRotCos=cos(diffAngle);
  363. mRotSin=sin(diffAngle);
  364. }
  365. }
  366. /**
  367. * Clones and returns the new geometry record
  368. */
  369. RoadGeometry* GeometrySpiral::Clone() const
  370. {
  371. GeometrySpiral* ret=new GeometrySpiral(mS,mX,mY, mHdg, mLength, mCurvatureStart, mCurvatureEnd);
  372. return ret;
  373. }
  374. //-------------------------------------------------
  375. /**
  376. * Setter for the base properties
  377. */
  378. void GeometrySpiral::SetAll(double s, double x, double y, double hdg, double length, double curvatureStart,double curvatureEnd)
  379. {
  380. SetBase(s,x,y,hdg,length,false);
  381. mCurvatureStart=curvatureStart;
  382. mCurvatureEnd=curvatureEnd;
  383. ComputeVars();
  384. }
  385. void GeometrySpiral::SetCurvatureStart(double curvature)
  386. {
  387. mCurvatureStart=curvature;
  388. ComputeVars();
  389. }
  390. void GeometrySpiral::SetCurvatureEnd(double curvature)
  391. {
  392. mCurvatureEnd=curvature;
  393. ComputeVars();
  394. }
  395. //-------------------------------------------------
  396. /**
  397. * Getter for the base properties
  398. */
  399. double GeometrySpiral::GetCurvatureStart()
  400. {
  401. return mCurvatureStart;
  402. }
  403. double GeometrySpiral::GetCurvatureEnd()
  404. {
  405. return mCurvatureEnd;
  406. }
  407. //-------------------------------------------------
  408. /**
  409. * Gets the coordinates at the sample S offset
  410. */
  411. void GeometrySpiral::GetCoords(double s_check, double &retX, double &retY, double &retHDG)
  412. {
  413. double l=0.0;
  414. double tmpX=0.0, tmpY=0.0;
  415. //Depending on the moving direction, calculate the length of the curve from its beginning to the current point and normalize
  416. //it by multiplying with the "a" normalization term
  417. //Cephes lib for solving Fresnel Integrals, uses cos/sin (PI/2 * X^2) format in its function.
  418. //So, in order to use the function, transform the argument (which is just L) by dividing it by the sqrt(PI/2) factor and multiply the results by it.
  419. if (mNormalDir)
  420. {
  421. l=(s_check-mS)*mA/sqrtPiO2;
  422. }
  423. else
  424. {
  425. l=(mS2-s_check)*mA/sqrtPiO2;
  426. }
  427. //Solve the Fresnel Integrals
  428. fresnl(l,&tmpY,&tmpX);
  429. //If the curvature is negative, invert the curve on the Y axis
  430. if (mCurvature<0)
  431. tmpY=-tmpY;
  432. //Denormalize the results and multiply by the sqrt(PI/2) term
  433. tmpX*=mDenormalizeFactor*sqrtPiO2;
  434. tmpY*=mDenormalizeFactor*sqrtPiO2;
  435. //Calculate the heading at the found position. Kill the sqrt(PI/2) term that was added to the L
  436. l=(s_check-mS)*mA;
  437. double tangentAngle = l*l;
  438. if (mCurvature<0)
  439. tangentAngle=-tangentAngle;
  440. retHDG=mHdg+tangentAngle;
  441. if (!mNormalDir)
  442. {
  443. //If we move in the inverse direction, translate the spiral in order to rotate around its final point
  444. tmpX-=mEndX;
  445. tmpY-=mEndY;
  446. //also invert the spiral in the y axis
  447. tmpY=-tmpY;
  448. }
  449. //Translate the curve to the required position and rotate it according to the heading
  450. retX=mX+ tmpX*mRotCos-tmpY*mRotSin;
  451. retY=mY+ tmpY*mRotCos+tmpX*mRotSin;
  452. }
  453. //***********************************************************************************
  454. //Cubic Polynom geometry. Has to be implemented
  455. //***********************************************************************************
  456. /**
  457. * Constructor that initializes the base properties of the record
  458. */
  459. GeometryPoly3::GeometryPoly3 (double s, double x, double y, double hdg, double length, double a, double b,double c, double d ): RoadGeometry(s, x, y, hdg, length)
  460. {
  461. SetGeomType(3); mA=a; mB=b; mC=c; mD=d;
  462. UpdateSamplePoint();
  463. }
  464. void GeometryPoly3::UpdateSamplePoint()
  465. {
  466. double u = 0.0;
  467. double du = 0.1;
  468. geosamplepoint gsp;
  469. gsp.s = 0;
  470. gsp.x = mA;
  471. gsp.y = 0.0;
  472. vector<geosamplepoint> xvectorgeosample;
  473. xvectorgeosample.clear();
  474. xvectorgeosample.push_back(gsp);
  475. u = du;
  476. double v;
  477. double flen = 0.0;
  478. double oldu,oldv;
  479. oldu = xvectorgeosample[0].x;
  480. oldv = xvectorgeosample[0].y;
  481. while(flen <= mLength)
  482. {
  483. double fdis = 0;
  484. v = mA + mB*u + mC*u*u + mD*u*u*u;
  485. fdis = sqrt(pow(u- oldu,2)+pow(v-oldv,2));
  486. oldu = u;
  487. oldv = v;
  488. flen = flen + fdis;
  489. gsp.s = flen;
  490. gsp.x = u;
  491. gsp.y = v;
  492. xvectorgeosample.push_back(gsp);
  493. if(fdis < 0.05)
  494. {
  495. if(fdis > 0)
  496. {
  497. du = du * 0.1/fdis;
  498. }
  499. }
  500. if(fdis > 0.2)
  501. {
  502. du = du * 0.1/fdis;
  503. }
  504. u = u + du;
  505. }
  506. if(xvectorgeosample.size() < 2)
  507. {
  508. mvectorgeosample.clear();
  509. gsp.s = 0;
  510. gsp.x = mX;
  511. gsp.y = mY;
  512. gsp.fHdg = mHdg;
  513. mvectorgeosample.push_back(gsp);
  514. return;
  515. }
  516. double ds = 0.1;
  517. double s =0;
  518. int ipos1 = 0;
  519. int ipos2= 1;
  520. mvectorgeosample.clear();
  521. while(s<mLength)
  522. {
  523. while(xvectorgeosample[ipos2].s<=s)
  524. {
  525. if(ipos2 == (xvectorgeosample.size()-1))
  526. {
  527. ipos1 = ipos2;
  528. break;
  529. }
  530. else
  531. {
  532. ipos2++;
  533. ipos1 = ipos2 -1;
  534. }
  535. }
  536. gsp.s = s;
  537. if(ipos1 == ipos2)
  538. {
  539. gsp.x = xvectorgeosample[ipos1].x;
  540. gsp.y = xvectorgeosample[ipos1].y;
  541. if(ipos1 == 0)
  542. {
  543. gsp.fHdg = mHdg;
  544. }
  545. else
  546. {
  547. gsp.fHdg = CalcHdg(xvectorgeosample[ipos1-1].x,xvectorgeosample[ipos1-1].y,
  548. xvectorgeosample[ipos1].x,xvectorgeosample[ipos1].y);
  549. }
  550. }
  551. else
  552. {
  553. double fratio = 0.5;
  554. double x1,y1,x2,y2;
  555. x1 = xvectorgeosample[ipos1].x;
  556. y1 = xvectorgeosample[ipos1].y;
  557. x2 = xvectorgeosample[ipos2].x;
  558. y2 = xvectorgeosample[ipos2].y;
  559. if(xvectorgeosample[ipos1].s != xvectorgeosample[ipos2].s)
  560. {
  561. fratio = (s - xvectorgeosample[ipos1].s)/(xvectorgeosample[ipos2].s - xvectorgeosample[ipos1].s);
  562. }
  563. gsp.x = x1 + fratio * (x2 - x1);
  564. gsp.y = y1 + fratio * (y2 - y1);
  565. if(mvectorgeosample.size() == 0)
  566. {
  567. gsp.fHdg = mHdg;
  568. }
  569. else
  570. {
  571. gsp.fHdg = (mvectorgeosample[mvectorgeosample.size() -1].x,mvectorgeosample[mvectorgeosample.size() -1].y,
  572. gsp.x,gsp.y);
  573. }
  574. }
  575. mvectorgeosample.push_back(gsp);
  576. s = s+ ds;
  577. }
  578. // vector<geosamplepoint> * pxvectorgeosample = &mvectorgeosample;
  579. mbHaveSample = true;
  580. }
  581. /**
  582. * Clones and returns the new geometry record
  583. */
  584. RoadGeometry* GeometryPoly3::Clone() const
  585. {
  586. GeometryPoly3* ret=new GeometryPoly3(mS,mX,mY, mHdg, mLength, mA, mB, mC, mD);
  587. return ret;
  588. }
  589. //-------------------------------------------------
  590. /**
  591. * Setter for the base properties
  592. */
  593. void GeometryPoly3::SetAll(double s, double x, double y, double hdg, double length, double a,double b,double c,double d)
  594. {
  595. SetBase(s,x,y,hdg,length,false);
  596. mA=a;
  597. mB=b;
  598. mC=c;
  599. mD=d;
  600. ComputeVars();
  601. UpdateSamplePoint();
  602. }
  603. //GetA to GetD, Added by Yuchuli
  604. double GeometryPoly3::GetA()
  605. {
  606. return mA;
  607. }
  608. double GeometryPoly3::GetB()
  609. {
  610. return mB;
  611. }
  612. double GeometryPoly3::GetC()
  613. {
  614. return mC;
  615. }
  616. double GeometryPoly3::GetD()
  617. {
  618. return mD;
  619. }
  620. void GeometryPoly3::GetCoords(double s_check, double &retX, double &retY, double &retHDG)
  621. {
  622. if(mbHaveSample &&(mvectorgeosample.size() > 1))
  623. {
  624. double fpos = (s_check - mS)/0.1;
  625. unsigned int ipos = fpos;
  626. double temX,temY,temHDG;
  627. if(ipos<=0)
  628. {
  629. temX = mvectorgeosample[ipos].x;
  630. temY = mvectorgeosample[ipos].y;
  631. temHDG = mHdg;
  632. }
  633. else
  634. {
  635. if(ipos>=(mvectorgeosample.size()-1))
  636. {
  637. temX = mvectorgeosample[mvectorgeosample.size()-1].x;
  638. temY = mvectorgeosample[mvectorgeosample.size()-1].y;
  639. temHDG = mvectorgeosample[mvectorgeosample.size() -1].fHdg;
  640. }
  641. else
  642. {
  643. temX = mvectorgeosample[ipos].x;
  644. temY = mvectorgeosample[ipos].y;
  645. temHDG = mvectorgeosample[ipos].fHdg;
  646. }
  647. }
  648. retX = mX + temX*cos(mHdg) - temY*sin(mHdg);
  649. retY = mY + temX*sin(mHdg) + temY*cos(mHdg);
  650. retHDG = mHdg + temHDG;
  651. if(retHDG >= 2.0*M_PI)retHDG = retHDG - 2.0*M_PI;
  652. return;
  653. }
  654. double currentLength = s_check - mS;
  655. double flen = 0;
  656. double u=0;
  657. double v;
  658. double x,y;
  659. double oldx,oldy;
  660. oldx = mX;
  661. oldy = mY;
  662. double du =0.1;
  663. retHDG = mHdg;
  664. if(currentLength<du)
  665. {
  666. retX = mX;
  667. retY = mY;
  668. retHDG = mHdg;
  669. return;
  670. }
  671. u = du;
  672. while(flen <= currentLength)
  673. {
  674. double fdis = 0;
  675. v = mA + mB*u + mC*u*u + mD*u*u*u;
  676. x = mX + u*cos(mHdg) - v*sin(mHdg);
  677. y = mY + u*sin(mHdg) + v*cos(mHdg);
  678. fdis = sqrt(pow(x- oldx,2)+pow(y-oldy,2));
  679. oldx = x;
  680. oldy = y;
  681. flen = flen + fdis;
  682. u = u + du;
  683. retHDG = CalcHdg(oldx,oldy,x,y);
  684. }
  685. }
  686. //***********************************************************************************
  687. //Cubic Polynom geometry. Has to be implemented. Added By Yuchuli
  688. //***********************************************************************************
  689. /**
  690. * Constructor that initializes the base properties of the record
  691. */
  692. GeometryParamPoly3::GeometryParamPoly3 (double s, double x, double y, double hdg, double length,double ua,double ub,double uc,double ud,double va, double vb, double vc,double vd,bool bNormal ): RoadGeometry(s, x, y, hdg, length)
  693. {
  694. SetGeomType(4); muA=ua; muB=ub; muC=uc; muD=ud;mvA=va; mvB=vb; mvC=vc; mvD=vd;mbNormal = bNormal;
  695. }
  696. /**
  697. * Clones and returns the new geometry record
  698. */
  699. RoadGeometry* GeometryParamPoly3::Clone() const
  700. {
  701. GeometryParamPoly3* ret=new GeometryParamPoly3(mS,mX,mY, mHdg, mLength, muA, muB, muC, muD,mvA,mvB,mvC,mvD,mbNormal);
  702. return ret;
  703. }
  704. void GeometryParamPoly3::UpdateSamplePoint()
  705. {
  706. }
  707. //-------------------------------------------------
  708. /**
  709. * Setter for the base properties
  710. */
  711. void GeometryParamPoly3::SetAll(double s, double x, double y, double hdg, double length, double ua,double ub,double uc,double ud,double va, double vb, double vc,double vd )
  712. {
  713. SetBase(s,x,y,hdg,length,false);
  714. muA=ua;
  715. muB=ub;
  716. muC=uc;
  717. muD=ud;
  718. mvA=va;
  719. mvB=vb;
  720. mvC=vc;
  721. mvD=vd;
  722. ComputeVars();
  723. }
  724. double GeometryParamPoly3::GetuA(){return muA;}
  725. double GeometryParamPoly3::GetuB(){return muB;}
  726. double GeometryParamPoly3::GetuC(){return muC;}
  727. double GeometryParamPoly3::GetuD(){return muD;}
  728. double GeometryParamPoly3::GetvA(){return mvA;}
  729. double GeometryParamPoly3::GetvB(){return mvB;}
  730. double GeometryParamPoly3::GetvC(){return mvC;}
  731. double GeometryParamPoly3::GetvD(){return mvD;}
  732. bool GeometryParamPoly3::GetNormal(){return mbNormal;}
  733. void GeometryParamPoly3::GetCoords(double s_check, double &retX, double &retY, double &retHDG)
  734. {
  735. double pRange = 1.0;
  736. if(mLength == 0)
  737. {
  738. retX = mX;
  739. retY = mY;
  740. retHDG = mHdg;
  741. }
  742. if(mbNormal)
  743. {
  744. pRange = (s_check - mS)/mLength;
  745. if(pRange<0)pRange = 0.0;
  746. if(pRange>1.0)pRange = 1.0;
  747. }
  748. else
  749. {
  750. pRange = (s_check -mS);
  751. }
  752. double xtem,ytem;
  753. xtem = muA + muB * pRange + muC * pRange*pRange + muD * pRange*pRange*pRange;
  754. ytem = mvA + mvB * pRange + mvC * pRange*pRange + mvD * pRange*pRange*pRange;
  755. retX = xtem*cos(mHdg) - ytem * sin(mHdg) + mX;
  756. retY = xtem*sin(mHdg) + ytem * cos(mHdg) + mY;
  757. if(s_check<0.1)
  758. {
  759. retHDG = mHdg;
  760. }
  761. else
  762. {
  763. if(mbNormal)
  764. {
  765. pRange = (s_check -mS)/mLength;
  766. if(pRange<0)pRange = 0.0;
  767. if(pRange>1.0)pRange = 1.0;
  768. }
  769. else
  770. {
  771. pRange = s_check-mS;
  772. }
  773. double a,b;
  774. a = muB + 2 * muC*pRange + 3*muD*pRange*pRange;
  775. b = mvB + 2 * mvC*pRange + 3*mvD*pRange*pRange;
  776. if(a == 0)
  777. {
  778. if(b>0)
  779. {
  780. retHDG = M_PI/2.0;
  781. }
  782. else
  783. {
  784. retHDG = M_PI*3.0/2.0;
  785. }
  786. }
  787. else
  788. {
  789. double ratio = b/a;
  790. double hdg = atan(ratio);
  791. if(ratio > 0)
  792. {
  793. if(b>0)
  794. {
  795. }
  796. else
  797. {
  798. hdg = hdg + M_PI;
  799. }
  800. }
  801. else
  802. {
  803. if(b>0)
  804. {
  805. hdg = hdg + M_PI;
  806. }
  807. else
  808. {
  809. hdg = hdg + 2.0*M_PI;
  810. }
  811. }
  812. retHDG = hdg;
  813. }
  814. retHDG = retHDG + mHdg;
  815. while(retHDG<0)retHDG = retHDG + 2.0*M_PI;
  816. while(retHDG>=2.0*M_PI)retHDG = retHDG - 2.0*M_PI;
  817. // if(mbNormal)
  818. // {
  819. // pRange = (s_check -mS-0.001)/mLength;
  820. // if(pRange<0)pRange = 0.0;
  821. // if(pRange>1.0)pRange = 1.0;
  822. // }
  823. // else
  824. // {
  825. // pRange = s_check-mS - 0.001;
  826. // }
  827. // xtem = muA + muB * pRange + muC * pRange*pRange + muD * pRange*pRange*pRange;
  828. // ytem = mvA + mvB * pRange + mvC * pRange*pRange + mvD * pRange*pRange*pRange;
  829. // double x = xtem*cos(mHdg) - ytem * sin(mHdg) + mX;
  830. // double y = xtem*sin(mHdg) + ytem * cos(mHdg) + mY;
  831. // retHDG = CalcHdg(x,y,retX,retY);
  832. }
  833. }
  834. //***********************************************************************************
  835. //Base class for Geometry blocks
  836. //***********************************************************************************
  837. /**
  838. * Constructor
  839. */
  840. GeometryBlock::GeometryBlock()
  841. {}
  842. /**
  843. * Copy constructor
  844. */
  845. GeometryBlock::GeometryBlock(const GeometryBlock& geomBlock)
  846. {
  847. for (vector<RoadGeometry*>::const_iterator member = geomBlock.mGeometryBlockElement.begin(); member != geomBlock.mGeometryBlockElement.end(); member++)
  848. mGeometryBlockElement.push_back((*member)->Clone());
  849. }
  850. /**
  851. * Assignment operator overload
  852. */
  853. const GeometryBlock& GeometryBlock::operator=(const GeometryBlock& otherGeomBlock)
  854. {
  855. if (this!= &otherGeomBlock)
  856. {
  857. for (vector<RoadGeometry*>::iterator member = mGeometryBlockElement.begin(); member != mGeometryBlockElement.end(); member++)
  858. {
  859. if(GeometryLine *line = dynamic_cast<GeometryLine *>(*member))
  860. {
  861. delete line;
  862. }
  863. else if(GeometryArc *arc = dynamic_cast<GeometryArc *>(*member))
  864. {
  865. delete arc;
  866. }
  867. else if(GeometrySpiral *spiral = dynamic_cast<GeometrySpiral *>(*member))
  868. {
  869. delete spiral;
  870. }
  871. else if(GeometryPoly3 *poly = dynamic_cast<GeometryPoly3 *>(*member))
  872. {
  873. delete poly;
  874. }
  875. else if(GeometryParamPoly3 * parampoly = dynamic_cast<GeometryParamPoly3 *>(*member) )
  876. {
  877. delete parampoly;
  878. }
  879. }
  880. mGeometryBlockElement.clear();
  881. for (vector<RoadGeometry*>::const_iterator member = otherGeomBlock.mGeometryBlockElement.begin(); member != otherGeomBlock.mGeometryBlockElement.end(); member++)
  882. mGeometryBlockElement.push_back((*member)->Clone());
  883. }
  884. return *this;
  885. }
  886. //-------------------------------------------------
  887. /**
  888. * Methods used to add geometry recors to the geometry record vector
  889. */
  890. void GeometryBlock::AddGeometryLine(double s, double x, double y, double hdg, double length)
  891. {
  892. mGeometryBlockElement.push_back(new GeometryLine(s, x, y, hdg, length));
  893. }
  894. void GeometryBlock::AddGeometryArc(double s, double x, double y, double hdg, double length, double curvature)
  895. {
  896. mGeometryBlockElement.push_back(new GeometryArc(s, x, y, hdg, length, curvature));
  897. }
  898. void GeometryBlock::AddGeometrySpiral(double s, double x, double y, double hdg, double length, double curvatureStart,double curvatureEnd)
  899. {
  900. mGeometryBlockElement.push_back(new GeometrySpiral(s, x, y, hdg, length, curvatureStart, curvatureEnd));
  901. }
  902. void GeometryBlock::AddGeometryPoly3(double s, double x, double y, double hdg, double length, double a,double b,double c,double d)
  903. {
  904. mGeometryBlockElement.push_back(new GeometryPoly3(s, x, y, hdg, length, a, b, c, d));
  905. }
  906. void GeometryBlock::AddGeometryParamPoly3(double s, double x, double y, double hdg, double length, double ua, double ub, double uc, double ud, double va, double vb, double vc, double vd,bool bNormal)
  907. {
  908. mGeometryBlockElement.push_back(new GeometryParamPoly3(s,x,y,hdg,length,ua,ub,uc,ud,va,vb,vc,vd,bNormal));
  909. }
  910. //-------------------------------------------------
  911. /**
  912. * Getter for the geometry record at a given index position of the vector
  913. */
  914. RoadGeometry* GeometryBlock::GetGeometryAt(int index)
  915. {
  916. return mGeometryBlockElement.at(index);
  917. }
  918. /**
  919. * Getter for the overal block length (summ of geometry record lengths)
  920. */
  921. double GeometryBlock::GetBlockLength()
  922. {
  923. double lTotal=0;
  924. for (unsigned int i=0;i<mGeometryBlockElement.size();i++)
  925. {
  926. lTotal+=mGeometryBlockElement.at(i)->GetLength();
  927. }
  928. return lTotal;
  929. }
  930. /**
  931. * Checks if the block is a straight line block or a turn
  932. */
  933. bool GeometryBlock::CheckIfLine()
  934. {
  935. if(mGeometryBlockElement.size()>1) return false;
  936. else return true;
  937. }
  938. //-------------------------------------------------
  939. /**
  940. * Recalculates the geometry blocks when one of the geometry records is modified
  941. * Makes sure that every geometry records starts where the previous record ends
  942. */
  943. void GeometryBlock::Recalculate(double s, double x, double y, double hdg)
  944. {
  945. double lS=s;
  946. double lX=x;
  947. double lY=y;
  948. double lHdg=hdg;
  949. if(mGeometryBlockElement.size()==1)
  950. {
  951. GeometryLine *lGeometryLine = static_cast<GeometryLine*>(mGeometryBlockElement.at(0));
  952. if(lGeometryLine!=NULL)
  953. {
  954. // Updates the line to reflect the changes of the previous block
  955. lGeometryLine->SetBase(lS,lX,lY,lHdg,lGeometryLine->GetLength());
  956. }
  957. }
  958. else if(mGeometryBlockElement.size()==3)
  959. {
  960. GeometrySpiral *lGeometrySpiral1 = static_cast<GeometrySpiral*>(mGeometryBlockElement.at(0));
  961. GeometryArc *lGeometryArc = static_cast<GeometryArc*>(mGeometryBlockElement.at(1));
  962. GeometrySpiral *lGeometrySpiral2 = static_cast<GeometrySpiral*>(mGeometryBlockElement.at(2));
  963. if(lGeometrySpiral1!=NULL && lGeometryArc!=NULL && lGeometrySpiral2!=NULL)
  964. {
  965. // Updates the first spiral to reflect the changes of the previous block
  966. lGeometrySpiral1->SetBase(lS,lX,lY,lHdg,lGeometrySpiral1->GetLength());
  967. // Reads the new coords of the spiral
  968. lS=lGeometrySpiral1->GetS2();
  969. lGeometrySpiral1->GetCoords(lS,lX,lY,lHdg);
  970. // Updates the arc to reflect the changes to the first spiral
  971. lGeometryArc->SetBase(lS,lX,lY,lHdg,lGeometryArc->GetLength());
  972. // Reads the new coords of the arc
  973. lS=lGeometryArc->GetS2();
  974. lGeometryArc->GetCoords(lS,lX,lY,lHdg);
  975. // Updates the second spiral to reflect hte changes to the arc
  976. lGeometrySpiral2->SetBase(lS,lX,lY,lHdg,lGeometrySpiral2->GetLength());
  977. }
  978. }
  979. }
  980. //-------------------------------------------------
  981. /**
  982. * Gets the S at the end of the block
  983. */
  984. double GeometryBlock::GetLastS2()
  985. {
  986. if(mGeometryBlockElement.size()>0)
  987. return mGeometryBlockElement.at(mGeometryBlockElement.size()-1)->GetS2();
  988. else
  989. return 0;
  990. }
  991. /**
  992. * Gets the last geometry in the geometry vector
  993. */
  994. RoadGeometry* GeometryBlock::GetLastGeometry()
  995. {
  996. return mGeometryBlockElement.at(mGeometryBlockElement.size()-1);
  997. }
  998. /**
  999. * Gets the coordinates at the end of the last geometry
  1000. */
  1001. short int GeometryBlock::GetLastCoords(double &s, double &retX, double &retY, double &retHDG)
  1002. {
  1003. int lSize = mGeometryBlockElement.size();
  1004. if(lSize>0)
  1005. {
  1006. RoadGeometry* lGeometry = mGeometryBlockElement.at(lSize-1);
  1007. s = lGeometry->GetS2();
  1008. lGeometry->GetCoords(s, retX, retY, retHDG);
  1009. }
  1010. else
  1011. {
  1012. s=0;
  1013. retX=0;
  1014. retY=0;
  1015. retHDG=0;
  1016. }
  1017. return 0;
  1018. }
  1019. /**
  1020. * Check if sample S belongs to this block
  1021. */
  1022. bool GeometryBlock::CheckInterval(double s_check)
  1023. {
  1024. for (unsigned int i=0;i<mGeometryBlockElement.size();i++)
  1025. {
  1026. //if the s_check belongs to one of the geometries
  1027. if (mGeometryBlockElement.at(i)->CheckInterval(s_check))
  1028. return true;
  1029. }
  1030. return false;
  1031. }
  1032. /**
  1033. * Gets the coordinates at the sample S offset
  1034. */
  1035. short int GeometryBlock::GetCoords(double s_check, double &retX, double &retY)
  1036. {
  1037. double tmp;
  1038. return GetCoords(s_check, retX, retY, tmp);
  1039. }
  1040. /**
  1041. * Gets the coordinates and heading at the end of the last geometry
  1042. */
  1043. short int GeometryBlock::GetCoords(double s_check, double &retX, double &retY, double &retHDG)
  1044. {
  1045. // go through all the elements
  1046. for (unsigned int i=0;i<mGeometryBlockElement.size();i++)
  1047. {
  1048. //if the s_check belongs to one of the geometries
  1049. if (mGeometryBlockElement.at(i)->CheckInterval(s_check))
  1050. {
  1051. //get the x,y coords and return the type of the geometry
  1052. mGeometryBlockElement.at(i)->GetCoords(s_check, retX, retY, retHDG);
  1053. return mGeometryBlockElement.at(i)->GetGeomType();
  1054. }
  1055. }
  1056. //if nothing found, return -999
  1057. return -999;
  1058. }
  1059. //-------------------------------------------------
  1060. /**
  1061. * Destructor
  1062. */
  1063. GeometryBlock::~GeometryBlock()
  1064. {
  1065. // Clears the geometry record vector
  1066. for (vector<RoadGeometry*>::iterator member = mGeometryBlockElement.begin(); member != mGeometryBlockElement.end(); member++)
  1067. {
  1068. if(GeometryLine *line = dynamic_cast<GeometryLine *>(*member))
  1069. {
  1070. delete line;
  1071. }
  1072. else if(GeometryArc *arc = dynamic_cast<GeometryArc *>(*member))
  1073. {
  1074. delete arc;
  1075. }
  1076. else if(GeometrySpiral *spiral = dynamic_cast<GeometrySpiral *>(*member))
  1077. {
  1078. delete spiral;
  1079. }
  1080. else if(GeometryPoly3 *poly = dynamic_cast<GeometryPoly3 *>(*member))
  1081. {
  1082. delete poly;
  1083. }
  1084. else if(GeometryParamPoly3 *parampoly = dynamic_cast<GeometryParamPoly3 *>(*member))
  1085. {
  1086. delete parampoly;
  1087. }
  1088. }
  1089. mGeometryBlockElement.clear();
  1090. }
  1091. //----------------------------------------------------------------------------------