dialogroadoptimize.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. #include "dialogroadoptimize.h"
  2. #include "ui_dialogroadoptimize.h"
  3. #include <math.h>
  4. #include <memory>
  5. #include "geofit.h"
  6. DialogRoadOptimize::DialogRoadOptimize(Road * pRoad,OpenDrive * pxodr,QWidget *parent) :
  7. QDialog(parent),
  8. ui(new Ui::DialogRoadOptimize)
  9. {
  10. ui->setupUi(this);
  11. ui->lineEdit_disthresh->setText("0.1");
  12. ui->lineEdit_hdgthresh->setText("0.01");
  13. ui->lineEdit_arcbezel->setText("3.0");
  14. ui->lineEdit_linebezel->setText("10.0");
  15. ui->lineEdit_roadoffthresh->setText("0.5");
  16. mpRoad = pRoad;
  17. mpxodr = pxodr;
  18. std::vector<double> fvectordis,fvectorhdg;
  19. int nrtn = CheckRoadQuality(pRoad,fvectordis,fvectorhdg);
  20. const int noutbufsize = 100000;
  21. std::shared_ptr<char> pstrout_ptr = std::shared_ptr<char>(new char[noutbufsize]);
  22. char strline[1000];
  23. snprintf(pstrout_ptr.get(),noutbufsize,"Check point:%d\n",nrtn);
  24. if(nrtn > 0)
  25. {
  26. int i;
  27. for(i=0;i<nrtn;i++)
  28. {
  29. RoadGeometry * pg = pRoad->GetGeometryBlock(i)->GetGeometryAt(0);
  30. snprintf(strline,1000,"%d distance:%f hdgdiff:%f geo type:%d s:%f length %f\n",
  31. i,fvectordis[i],fvectorhdg[i],pg->GetGeomType(),pg->GetS(),pg->GetLength());
  32. strncat(pstrout_ptr.get(),strline,noutbufsize);
  33. }
  34. }
  35. ui->plainTextEdit->setPlainText(pstrout_ptr.get());
  36. setWindowTitle("Road Optimize");
  37. }
  38. DialogRoadOptimize::~DialogRoadOptimize()
  39. {
  40. delete ui;
  41. }
  42. int DialogRoadOptimize::CheckRoadQuality(Road *pRoad, std::vector<double> & fvectordis,
  43. std::vector<double> & fvectorhdg)
  44. {
  45. if(pRoad->GetGeometryBlockCount() <=1)
  46. {
  47. return 0;
  48. }
  49. int nrtn = 0;
  50. unsigned int i;
  51. for(i=0;i<(pRoad->GetGeometryBlockCount()-1);i++)
  52. {
  53. GeometryBlock * pgeob1 = pRoad->GetGeometryBlock(i);
  54. GeometryBlock * pgeob2 = pRoad->GetGeometryBlock(i+1);
  55. double x1,y1,hdg1;
  56. double x2,y2,hdg2;
  57. pgeob1->GetGeometryAt(0)->GetCoords(pgeob1->GetGeometryAt(0)->GetS() + pgeob1->GetGeometryAt(0)->GetLength(),
  58. x1,y1,hdg1);
  59. pgeob2->GetGeometryAt(0)->GetCoords(pgeob2->GetGeometryAt(0)->GetS() ,
  60. x2,y2,hdg2);
  61. double fdis = sqrt(pow(x2-x1,2)+pow(y2-y1,2));
  62. double fhdgdiff = hdg2 - hdg1;
  63. while (fhdgdiff>M_PI)fhdgdiff = fhdgdiff -2.0*M_PI;
  64. while(fhdgdiff<=(-M_PI))fhdgdiff = fhdgdiff + 2.0*M_PI;
  65. fvectordis.push_back(fdis);
  66. fvectorhdg.push_back(fhdgdiff);
  67. nrtn++;
  68. }
  69. return nrtn;
  70. }
  71. void DialogRoadOptimize::on_pushButton_Optimize_clicked()
  72. {
  73. double fdisthresh = ui->lineEdit_disthresh->text().toDouble();
  74. double fhdgthresh = ui->lineEdit_hdgthresh->text().toDouble();
  75. double flinebezel = ui->lineEdit_linebezel->text().toDouble();
  76. double farcbezel = ui->lineEdit_arcbezel->text().toDouble();
  77. double froadoffthresh = ui->lineEdit_roadoffthresh->text().toDouble();
  78. if(fdisthresh<0.00001)
  79. {
  80. fdisthresh = 0.00001;
  81. std::cout<<"fdisthresh change to "<<fdisthresh<<std::endl;
  82. }
  83. if(fhdgthresh<0.001)
  84. {
  85. fhdgthresh = 0.001;
  86. std::cout<<"fhdgthesh change to "<<fhdgthresh<<std::endl;
  87. }
  88. if(flinebezel<1.0)
  89. {
  90. flinebezel = 1.0;
  91. std::cout<<"flinebezel change to "<<flinebezel<<std::endl;
  92. }
  93. if(farcbezel<1.0)
  94. {
  95. farcbezel = 1.0;
  96. std::cout<<"farcbezel change to "<<farcbezel<<std::endl;
  97. }
  98. if(froadoffthresh<0.05)
  99. {
  100. froadoffthresh = 0.05;
  101. std::cout<<"froadoffthresh change to "<<froadoffthresh<<std::endl;
  102. }
  103. std::vector<double> fvectordis,fvectorhdg;
  104. Road * pRoad = mpRoad;
  105. int nrtn = CheckRoadQuality(pRoad,fvectordis,fvectorhdg);
  106. if(nrtn == 0)
  107. {
  108. QMessageBox::information(this,"Info","Not Need Optimize",QMessageBox::YesAll);
  109. return;
  110. }
  111. int nmsgbufsize = 100000;
  112. std::shared_ptr<char> strmsg_ptr = std::shared_ptr<char>(new char[nmsgbufsize]);
  113. snprintf(strmsg_ptr.get(),nmsgbufsize,"Change pos: \n");
  114. int nchange = 0;
  115. Road * pnewroad = mpRoad;
  116. int i;
  117. int nowgeobpos = 0;
  118. GeometryBlock * pgeobnow = pnewroad->GetGeometryBlock(0);
  119. std::vector<GeometryBlock > * pvectorgeo = pnewroad->GetGeometryBlockVector();
  120. for(i=0;i<nrtn;i++)
  121. {
  122. if((fvectordis[i]>fdisthresh)||(fabs(fvectorhdg[i])>fhdgthresh))
  123. {
  124. pgeobnow = pnewroad->GetGeometryBlock(nowgeobpos);
  125. RoadGeometry * pgeo = pgeobnow->GetGeometryAt(0);
  126. int ngeotype = pgeo->GetGeomType();
  127. std::cout<<"geo type : "<<ngeotype<<std::endl;
  128. if((pgeo->GetGeomType() ==0) ||(pgeo->GetGeomType() == 2))
  129. {
  130. double fthresh = flinebezel;
  131. if(ngeotype == 2)fthresh = farcbezel;
  132. if(pgeo->GetLength()>(fthresh+1.0))
  133. {
  134. double xkeeplen = pgeo->GetLength() - fthresh;
  135. double x_start,y_start,hdg_start,x_end,y_end,hdg_end;
  136. pgeo->GetCoords(pgeo->GetS()+xkeeplen,x_start,y_start,hdg_start);
  137. pnewroad->GetGeometryBlock(nowgeobpos+1)->GetGeometryAt(0)->GetCoords(pgeo->GetS() + pgeo->GetLength(),
  138. x_end,y_end,hdg_end);
  139. std::vector<geobase> xvectorgeo = geofit::CreateBezierGeo(x_start,y_start,
  140. hdg_start,x_end,y_end,hdg_end);
  141. GeometryBlock xgb;
  142. qDebug("be len: %f ",xvectorgeo[0].mfLen);
  143. xgb.AddGeometryParamPoly3(pgeo->GetS() + xkeeplen,x_start,y_start,hdg_start,xvectorgeo[0].mfLen,
  144. xvectorgeo[0].mfu[0],xvectorgeo[0].mfu[1],
  145. xvectorgeo[0].mfu[2],xvectorgeo[0].mfu[3],
  146. xvectorgeo[0].mfv[0],xvectorgeo[0].mfv[1],
  147. xvectorgeo[0].mfv[2],xvectorgeo[0].mfv[3],false);
  148. double fdisgeo = GetGeo1toGeo2MaxDis(&xgb,&(pvectorgeo->at(nowgeobpos)));
  149. if(fdisgeo<= froadoffthresh)
  150. {
  151. pgeo->SetLength(xkeeplen);
  152. pvectorgeo->insert(pvectorgeo->begin() + nowgeobpos+1,xgb);
  153. nowgeobpos = nowgeobpos+2;
  154. char strout[1000];
  155. snprintf(strout,1000,"geo %d to geo %d. Insert a bezel.geo off:%f.\n",i,i+1,fdisgeo);
  156. strncat(strmsg_ptr.get(),strout,nmsgbufsize);
  157. nchange++;
  158. }
  159. else
  160. {
  161. char strout[1000];
  162. snprintf(strout,1000,"geo %d to geo %d. Optimize off %f exceed thresh.\n",i,i+1,fdisgeo);
  163. strncat(strmsg_ptr.get(),strout,nmsgbufsize);
  164. nchange++;
  165. nowgeobpos++;
  166. }
  167. }
  168. else
  169. {
  170. double x_start,y_start,hdg_start,x_end,y_end,hdg_end;
  171. pgeo->GetCoords(pgeo->GetS(),x_start,y_start,hdg_start);
  172. pnewroad->GetGeometryBlock(nowgeobpos+1)->GetGeometryAt(0)->GetCoords(pgeo->GetS() + pgeo->GetLength(),
  173. x_end,y_end,hdg_end);
  174. std::vector<geobase> xvectorgeo = geofit::CreateBezierGeo(x_start,y_start,
  175. hdg_start,x_end,y_end,hdg_end);
  176. qDebug("be len: %f ",xvectorgeo[0].mfLen);
  177. GeometryBlock xgb;
  178. xgb.AddGeometryParamPoly3(pgeo->GetS(),x_start,y_start,hdg_start,xvectorgeo[0].mfLen,
  179. xvectorgeo[0].mfu[0],xvectorgeo[0].mfu[1],
  180. xvectorgeo[0].mfu[2],xvectorgeo[0].mfu[3],
  181. xvectorgeo[0].mfv[0],xvectorgeo[0].mfv[1],
  182. xvectorgeo[0].mfv[2],xvectorgeo[0].mfv[3],false);
  183. double fdisgeo = GetGeo1toGeo2MaxDis(&xgb,&(pvectorgeo->at(nowgeobpos)));
  184. if(fdisgeo <= froadoffthresh)
  185. {
  186. pvectorgeo->erase(pvectorgeo->begin()+nowgeobpos);
  187. pvectorgeo->insert(pvectorgeo->begin()+nowgeobpos,xgb);
  188. nowgeobpos = nowgeobpos+1;
  189. char strout[1000];
  190. snprintf(strout,1000,"geo %d to geo %d. geo %d replace by a bezel. geo off:%f.\n",i,i+1,i,fdisgeo);
  191. strncat(strmsg_ptr.get(),strout,nmsgbufsize);
  192. nchange++;
  193. }
  194. else
  195. {
  196. char strout[1000];
  197. snprintf(strout,1000,"geo %d to geo %d. Optimize off %f exceed thresh.\n",i,i+1,fdisgeo);
  198. strncat(strmsg_ptr.get(),strout,nmsgbufsize);
  199. nchange++;
  200. nowgeobpos++;
  201. }
  202. // break;
  203. }
  204. unsigned int j;
  205. for(j=1;j<pvectorgeo->size();j++)
  206. {
  207. pvectorgeo->at(j).GetGeometryAt(0)->SetS(pvectorgeo->at(j-1).GetGeometryAt(0)->GetS()
  208. +pvectorgeo->at(j-1).GetGeometryAt(0)->GetLength());
  209. }
  210. }
  211. else
  212. {
  213. nowgeobpos++;
  214. }
  215. }
  216. else
  217. {
  218. char strout[1000];
  219. snprintf(strout,1000,"geo %d to geo %d. Not Need Optimize.\n",i,i+1);
  220. strncat(strmsg_ptr.get(),strout,nmsgbufsize);
  221. nowgeobpos++;
  222. }
  223. }
  224. if(nchange > 0)
  225. {
  226. RoadGeometry * pgeolast = pvectorgeo->at(pvectorgeo->size()-1).GetGeometryAt(0);
  227. pnewroad->SetRoadLength(pgeolast->GetS() + pgeolast->GetLength());
  228. }
  229. char strout[1000];
  230. snprintf(strout,1000,"Optimize %d position.",nchange);
  231. strncat(strmsg_ptr.get(),strout,nmsgbufsize);
  232. QMessageBox::information(this,"Optimize Result",strmsg_ptr.get(),QMessageBox::YesAll);
  233. }
  234. double DialogRoadOptimize::GetGeo1toGeo2MaxDis(GeometryBlock *pgeob1, GeometryBlock *pgeob2)
  235. {
  236. RoadGeometry * prg1,*prg2;
  237. prg1 = pgeob1->GetGeometryAt(0);
  238. prg2 = pgeob2->GetGeometryAt(0);
  239. double fstep = 0.1;
  240. int nCount = (int)(prg1->GetLength()/fstep);
  241. if(nCount == 0)
  242. {
  243. return sqrt(pow(prg1->GetX() - prg2->GetX(),2)+pow(prg1->GetY() - prg2->GetY(),2));
  244. }
  245. int i;
  246. double rg1_s = prg1->GetS();
  247. double rg2_s = prg2->GetS();
  248. // double rg1_len = prg1->GetLength();
  249. double rg2_len = prg2->GetLength();
  250. double fdismax = 0;
  251. double fsmax = 0;
  252. for(i=0;i<nCount;i++)
  253. {
  254. double s = fstep * i;
  255. double x1,y1,hdg1;
  256. double fstep2 = 0.5;
  257. prg1->GetCoords(rg1_s+s,x1,y1,hdg1);
  258. int nCount2 =(int)( rg2_len/fstep2);
  259. double snear = 0;
  260. double sdis = 1000.0;
  261. if(nCount2 == 0)
  262. {
  263. snear = 0;
  264. }
  265. else
  266. {
  267. int j;
  268. for(j=0;j<nCount2;j++)
  269. {
  270. double x2,y2,hdg2;
  271. double s2 = j*fstep2;
  272. prg2->GetCoords(rg2_s +s2,x2,y2,hdg2);
  273. double fdis = sqrt(pow(x2-x1,2)+pow(y2-y1,2));
  274. if(fdis <sdis)
  275. {
  276. snear = s2;
  277. sdis = fdis;
  278. }
  279. }
  280. }
  281. double snear_low = snear - fstep2;
  282. double snear_high = snear + fstep2;
  283. if(snear_low<0)snear_low = 0;
  284. if(snear_high > rg2_len)snear_high = rg2_len;
  285. double s3 = snear_low;
  286. while(s3<=snear_high)
  287. {
  288. double x3,y3,hdg3;
  289. prg2->GetCoords(rg2_s+s3,x3,y3,hdg3);
  290. double fdis = sqrt(pow(x3-x1,2)+pow(y3-y1,2));
  291. if(fdis < sdis)
  292. {
  293. snear = s3;
  294. sdis = fdis;
  295. }
  296. s3 = s3 +0.01;
  297. }
  298. if(sdis > fdismax)
  299. {
  300. fdismax = sdis;
  301. fsmax = snear;
  302. }
  303. }
  304. // std::cout<<"dismax : "<<fdismax<<std::endl;
  305. return fdismax;
  306. }