|
@@ -0,0 +1,376 @@
|
|
|
+#include "collectconvert.h"
|
|
|
+
|
|
|
+#include "gnss_coordinate_convert.h"
|
|
|
+#include "geofit.h"
|
|
|
+
|
|
|
+int groadid = 10001;
|
|
|
+CollectConvert::CollectConvert(iv::map::collectveh & xcollectveh,OpenDrive * pxodr)
|
|
|
+{
|
|
|
+ mcollectveh.CopyFrom(xcollectveh);
|
|
|
+ mpxodr = pxodr;
|
|
|
+}
|
|
|
+
|
|
|
+void CollectConvert::StartConvert()
|
|
|
+{
|
|
|
+ threadconvert();
|
|
|
+}
|
|
|
+
|
|
|
+void CollectConvert::threadconvert()
|
|
|
+{
|
|
|
+ OpenDrive * pxodr = mpxodr;
|
|
|
+ pxodr->SetHeader(1,1,"adc",1.1,"2022",0,0,0,0,mcollectveh.mlat0(),mcollectveh.mlon0(),360);
|
|
|
+ int i;
|
|
|
+ for(i=0;i<mcollectveh.mroads_size();i++)
|
|
|
+ {
|
|
|
+ iv::map::collectvehroad * proad = mcollectveh.mutable_mroads(i);
|
|
|
+ ConvertRoad(proad,pxodr);
|
|
|
+
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void CollectConvert::ConvertRoad(iv::map::collectvehroad *proad, OpenDrive *pxodr)
|
|
|
+{
|
|
|
+ if(proad->mpoints_size() == 0)return;
|
|
|
+ double flon0,flat0;
|
|
|
+ pxodr->GetHeader()->GetLat0Lon0(flat0,flon0);
|
|
|
+// pxodr->GetHeader()->GetLat0Lon0(flon0,flat0);
|
|
|
+ double x0,y0;
|
|
|
+ GaussProjCal(flon0,flat0,&x0,&y0);
|
|
|
+ int i;
|
|
|
+ std::vector<iv::collectxy> xvectorcollectxy;
|
|
|
+ for(i=0;i<proad->mpoints_size();i++)
|
|
|
+ {
|
|
|
+ iv::map::collectvehroadpoint * ppoint = proad->mutable_mpoints(i);
|
|
|
+ double x,y;
|
|
|
+// double fl1 = ppoint->mflon();
|
|
|
+// double fl2 = ppoint->mflat();
|
|
|
+ GaussProjCal(ppoint->mflon(),ppoint->mflat(),&x,&y);
|
|
|
+ iv::collectxy xc;
|
|
|
+ xc.height = 0;
|
|
|
+ xc.width = ppoint->mflanewidth();
|
|
|
+ xc.fhdg = (90 -ppoint->mfheading())*M_PI/180.0;
|
|
|
+ xc.x = x-x0 + ppoint->mfdis_left()*cos(xc.fhdg +M_PI/2.0);
|
|
|
+ xc.y = y-y0 + ppoint->mfdis_left()*sin(xc.fhdg +M_PI/2.0);
|
|
|
+ xvectorcollectxy.push_back(xc);
|
|
|
+ if(i>0)
|
|
|
+ {
|
|
|
+ double fdis =sqrt(pow(xvectorcollectxy[i].x - xvectorcollectxy[i-1].x,2)+pow(xvectorcollectxy[i].y-xvectorcollectxy[i-1].y,2));
|
|
|
+ xvectorcollectxy[i].fdistolast = fdis;
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ double LINE_ERROR = 0.20;
|
|
|
+
|
|
|
+
|
|
|
+ std::vector<geobase> xvectorgeo;
|
|
|
+
|
|
|
+ bool bComplete = false;
|
|
|
+ int j;
|
|
|
+ int ncurpos = 0;
|
|
|
+ int nrange = xvectorcollectxy.size();
|
|
|
+ bool bHaveLastxyhdg = false;
|
|
|
+ double fLastX,fLastY,fLastHdg;
|
|
|
+ double fEndX,fEndY,fEndHdg;
|
|
|
+ double fStartX,fStartY,fStartHdg;
|
|
|
+ while(bComplete == false)
|
|
|
+ {
|
|
|
+
|
|
|
+ VectorXd x_veh(nrange);
|
|
|
+ VectorXd y_veh(nrange);
|
|
|
+ for(j=0;j<nrange;j++)
|
|
|
+ {
|
|
|
+ x_veh[j] =xvectorcollectxy[j+ncurpos].x;// xvectorvehicle[xvectorvl[j+ncurpos].mvehindex].fx;//mvectorrtkdata.at(j+ncurpos).mfrelx;
|
|
|
+ y_veh[j] = xvectorcollectxy[j+ncurpos].y;//xvectorvehicle[xvectorvl[j+ncurpos].mvehindex].fy;//mvectorrtkdata.at(j+ncurpos).mfrely;
|
|
|
+ }
|
|
|
+
|
|
|
+ bool bArcOk = false;
|
|
|
+ bool bLineOk = false;
|
|
|
+ double dismax = 0;
|
|
|
+ QPointF sp,ep;
|
|
|
+ double fR,flen;
|
|
|
+ double fhdgstart,fhdgend;
|
|
|
+ if(nrange >= 3)
|
|
|
+ {
|
|
|
+
|
|
|
+ geofit::Inst().arcfitanddis(x_veh,y_veh,dismax,fR,sp,ep,fhdgstart,fhdgend,flen);
|
|
|
+
|
|
|
+ if(dismax < LINE_ERROR)
|
|
|
+ {
|
|
|
+ bArcOk = true;
|
|
|
+ std::cout<<" a arc is ok "<<"pos is "<<ncurpos<<" range is "<<nrange<<" error is "<<dismax<<std::endl;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ auto coeffs = polyfit(x_veh, y_veh, 1);
|
|
|
+
|
|
|
+ dismax = 0;
|
|
|
+ for(j=0;j<nrange;j++)
|
|
|
+ {
|
|
|
+ double A = coeffs[1];
|
|
|
+ double B = -1;
|
|
|
+ double C = coeffs[0];
|
|
|
+ double dis = fabs(A*x_veh[j] + B*y_veh[j] +C )/sqrt(pow(A,2)+pow(B,2));
|
|
|
+ if(dis>dismax)dismax = dis;
|
|
|
+ }
|
|
|
+ if(dismax < LINE_ERROR)
|
|
|
+ {
|
|
|
+ bLineOk = true;
|
|
|
+ std::cout<<" a line is ok "<<"pos is "<<ncurpos<<" range is "<<nrange<<" error is "<<dismax<<std::endl;
|
|
|
+ }
|
|
|
+
|
|
|
+ if((nrange <= 2)||bLineOk||bArcOk)
|
|
|
+ {
|
|
|
+ if((bLineOk)||(nrange<=2))
|
|
|
+ {
|
|
|
+ std::cout<<"use line"<<std::endl;
|
|
|
+ geobase xgeo;
|
|
|
+ xgeo.mnStartPoint = ncurpos;
|
|
|
+ xgeo.mnEndPoint = ncurpos + nrange -1 ;
|
|
|
+
|
|
|
+ double x0,y0,x1,y1;
|
|
|
+ geofit::Inst().getcrosspoint(coeffs[1],-1,coeffs[0],x_veh[0],
|
|
|
+ y_veh[0],x0,y0);
|
|
|
+ geofit::Inst().getcrosspoint(coeffs[1],-1,coeffs[0],x_veh[nrange -1],
|
|
|
+ y_veh[nrange - 1],x1,y1);
|
|
|
+ xgeo.mfA = coeffs[1];
|
|
|
+ xgeo.mfB = -1;
|
|
|
+ xgeo.mfC = coeffs[0];
|
|
|
+ xgeo.mfHdg = geofit::Inst().CalcHdg(x0,y0,x1,y1);
|
|
|
+ xgeo.mfX = x0;
|
|
|
+ xgeo.mfY = y0;
|
|
|
+ xgeo.mfLen = sqrt(pow(x1-x0,2)+pow(y1-y0,2));
|
|
|
+ xgeo.mnType = 0;
|
|
|
+ fStartX = x0;
|
|
|
+ fStartY = y0;
|
|
|
+ fStartHdg = xgeo.mfHdg;
|
|
|
+ fEndX = x1;
|
|
|
+ fEndY = y1;
|
|
|
+ fEndHdg = xgeo.mfHdg;
|
|
|
+
|
|
|
+ xvectorgeo.push_back(xgeo);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if(bArcOk)
|
|
|
+ {
|
|
|
+ std::cout<<"use arc"<<std::endl;
|
|
|
+ geobase xgeo;
|
|
|
+ xgeo.mnStartPoint = ncurpos;
|
|
|
+ xgeo.mnEndPoint = ncurpos + nrange -1;
|
|
|
+ xgeo.mfHdg = fhdgstart;
|
|
|
+ xgeo.mfHdgStart = fhdgstart;
|
|
|
+ xgeo.mfHdgEnd = fhdgend;
|
|
|
+ xgeo.mfX = sp.x();
|
|
|
+ xgeo.mfY = sp.y();
|
|
|
+ xgeo.mfLen = flen;
|
|
|
+ xgeo.mnType = 1;
|
|
|
+ xgeo.mfEndX = ep.x();
|
|
|
+ xgeo.mfEndY = ep.y();
|
|
|
+ xgeo.mR = fR;
|
|
|
+ fStartX = xgeo.mfX;
|
|
|
+ fStartY = xgeo.mfY;
|
|
|
+ fStartHdg = xgeo.mfHdgStart;
|
|
|
+ fEndX = xgeo.mfEndX;
|
|
|
+ fEndY = xgeo.mfEndY;
|
|
|
+ fEndHdg = xgeo.mfHdgEnd;
|
|
|
+ xvectorgeo.push_back(xgeo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // std::cout<<" a line is ok "<<"pos is "<<ncurpos<<" range is "<<nrange<<" error is "<<dismax<<std::endl;
|
|
|
+
|
|
|
+ if(bHaveLastxyhdg)
|
|
|
+ {
|
|
|
+ std::vector<geobase> xvectorgeobe = geofit::CreateBezierGeo(fLastX,fLastY,
|
|
|
+ fLastHdg,fStartX,fStartY,fStartHdg);
|
|
|
+ if(xvectorgeobe.size()>0)
|
|
|
+ {
|
|
|
+ xvectorgeobe[0].mnStartPoint = ncurpos-1;
|
|
|
+ xvectorgeobe[0].mnEndPoint = ncurpos;
|
|
|
+ xvectorgeo.insert(xvectorgeo.begin()+(xvectorgeo.size()-1),xvectorgeobe[0]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ bHaveLastxyhdg = true;
|
|
|
+ fLastX = fEndX;
|
|
|
+ fLastY = fEndY;
|
|
|
+ fLastHdg = fEndHdg;
|
|
|
+
|
|
|
+
|
|
|
+ // ncurpos = ncurpos + nrange -1;
|
|
|
+ ncurpos = ncurpos + nrange; //Skip 1 point, use bezier
|
|
|
+ nrange = xvectorcollectxy.size() - ncurpos;
|
|
|
+
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if(nrange > 30)
|
|
|
+ nrange = nrange/2;
|
|
|
+ else
|
|
|
+ nrange = nrange -1;
|
|
|
+ if(nrange<2)nrange = 2;
|
|
|
+ }
|
|
|
+ if(ncurpos>=(int)(xvectorcollectxy.size()-1))
|
|
|
+ {
|
|
|
+ if(ncurpos == (int)(xvectorcollectxy.size()-1))
|
|
|
+ {
|
|
|
+ std::cout<<"Last section, 2 Points, use line."<<std::endl;
|
|
|
+ VectorXd x_veh1(2);
|
|
|
+ VectorXd y_veh1(2);
|
|
|
+ x_veh1[0] = fLastX;
|
|
|
+ y_veh1[0] = fLastY;
|
|
|
+ x_veh1[1] = xvectorcollectxy[ncurpos].x;// xvectorvehicle[xvectorvl[ncurpos].mvehindex].fx;
|
|
|
+ y_veh1[1] = xvectorcollectxy[ncurpos].y;// xvectorvehicle[xvectorvl[ncurpos].mvehindex].fy;
|
|
|
+ auto coeffs = polyfit(x_veh1, y_veh1, 1);
|
|
|
+
|
|
|
+ geobase xgeo;
|
|
|
+ xgeo.mnStartPoint = ncurpos-1;
|
|
|
+ xgeo.mnEndPoint = ncurpos;
|
|
|
+
|
|
|
+ xgeo.mfA = coeffs[1];
|
|
|
+ xgeo.mfB = -1;
|
|
|
+ xgeo.mfC = coeffs[0];
|
|
|
+ xgeo.mfHdg = geofit::Inst().CalcHdg(x_veh1[0],y_veh1[0],x_veh1[1],y_veh1[1]);
|
|
|
+ xgeo.mfX = x_veh1[0];
|
|
|
+ xgeo.mfY = y_veh1[0];
|
|
|
+ xgeo.mfLen = sqrt(pow(x_veh1[1]-x_veh1[0],2)+pow(y_veh1[1]-y_veh1[0],2));
|
|
|
+ xgeo.mnType = 0;
|
|
|
+ xvectorgeo.push_back(xgeo);
|
|
|
+ }
|
|
|
+ bComplete = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ double snow = 0;
|
|
|
+ for(i=0;i<(int)xvectorgeo.size();i++)
|
|
|
+ {
|
|
|
+ geobase * pgeo = &xvectorgeo[i];
|
|
|
+// std::cout<<"geo len: "<<pgeo->mfLen<<" type"<<pgeo->mnType<<std::endl;
|
|
|
+ double tems = 0;
|
|
|
+ for(j=(pgeo->mnStartPoint+1);j<=pgeo->mnEndPoint;j++)
|
|
|
+ {
|
|
|
+ xvectorcollectxy[j].s = snow + tems+xvectorcollectxy[j].fdistolast;
|
|
|
+ // xvectorvehicle[xvectorvl[j].mvehindex].s = snow + tems + xvectorvehicle[xvectorvl[j].mvehindex].fdistolast;
|
|
|
+ tems = tems + xvectorcollectxy[j].fdistolast;
|
|
|
+ }
|
|
|
+ snow = snow + pgeo->mfLen;
|
|
|
+ }
|
|
|
+
|
|
|
+ std::vector<iv::widthabcd> xvectorwidthabcd;
|
|
|
+ bComplete = false;
|
|
|
+ ncurpos = 0;
|
|
|
+ nrange = xvectorcollectxy.size();
|
|
|
+ double flanewidtherror = 0.1; //1cm
|
|
|
+ while(bComplete == false)
|
|
|
+ {
|
|
|
+ double ele_coff[4];
|
|
|
+ for(j=0;j<4;j++)ele_coff[j] = 0;
|
|
|
+ if(nrange>0)ele_coff[0] = xvectorcollectxy[ncurpos].width;// xvectorvehicle[xvectorvl[ncurpos].mvehindex].flanewidth;
|
|
|
+ int M = nrange;
|
|
|
+ VectorXd x_vehhg(M);
|
|
|
+ VectorXd y_vehhg(M);
|
|
|
+ for(j=0;j<M;j++)
|
|
|
+ {
|
|
|
+ x_vehhg[j] = xvectorcollectxy[ncurpos+j].s - xvectorcollectxy[ncurpos].s;// xvectorvehicle[xvectorvl[ncurpos+j].mvehindex].s - xvectorvehicle[xvectorvl[ncurpos].mvehindex].s;
|
|
|
+ y_vehhg[j] = xvectorcollectxy[ncurpos+j].width;// xvectorvehicle[xvectorvl[ncurpos+j].mvehindex].flanewidth;
|
|
|
+ }
|
|
|
+ int MX = 3;
|
|
|
+ if(M<4)MX = M -1;
|
|
|
+ if(MX>3)MX = 3;
|
|
|
+ if(MX>0)
|
|
|
+ {
|
|
|
+ VectorXd coeffs = polyfit(x_vehhg, y_vehhg, MX);
|
|
|
+ for(j=0;j<=MX;j++)
|
|
|
+ {
|
|
|
+ ele_coff[j] = coeffs[j];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ double ferror = 0;
|
|
|
+ for(j=0;j<M;j++)
|
|
|
+ {
|
|
|
+ double s = x_vehhg[j];
|
|
|
+ double fvalue = fabs(ele_coff[0] + ele_coff[1]*s + ele_coff[2]*s*s+ele_coff[3]*s*s*s - y_vehhg[j]);
|
|
|
+ if(fvalue>ferror)ferror = fvalue;
|
|
|
+ }
|
|
|
+ if(ferror>flanewidtherror)
|
|
|
+ {
|
|
|
+ if(nrange>10)nrange = nrange/2;
|
|
|
+ else nrange = nrange -1;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ iv::widthabcd xabcd;
|
|
|
+ xabcd.s = xvectorcollectxy[ncurpos].s;// xvectorvehicle[xvectorvl[ncurpos].mvehindex].s;
|
|
|
+ xabcd.A = ele_coff[0];
|
|
|
+ xabcd.B = ele_coff[1];
|
|
|
+ xabcd.C = ele_coff[2];
|
|
|
+ xabcd.D = ele_coff[3];
|
|
|
+ xvectorwidthabcd.push_back(xabcd);
|
|
|
+ ncurpos = ncurpos + nrange-1;
|
|
|
+ nrange = xvectorcollectxy.size() - ncurpos;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(ncurpos>=(int)(xvectorcollectxy.size()-1))
|
|
|
+ {
|
|
|
+ bComplete = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ pxodr->AddRoad(proad->strroadname(),xvectorcollectxy[xvectorcollectxy.size()-1].s, QString::number(groadid).toStdString(),"-1");
|
|
|
+ Road * p = pxodr->GetRoad(pxodr->GetRoadCount() - 1);
|
|
|
+ groadid++;
|
|
|
+
|
|
|
+ // p->AddElevation(0,xlaneheightcoff.A,xlaneheightcoff.B,xlaneheightcoff.C,xlaneheightcoff.D);
|
|
|
+
|
|
|
+ double s = 0;
|
|
|
+ j= 0;
|
|
|
+// for(j=0;j<4;j++)
|
|
|
+ for(j=0;j<xvectorgeo.size();j++)
|
|
|
+ {
|
|
|
+
|
|
|
+ p->AddGeometryBlock();
|
|
|
+ GeometryBlock * pgb = p->GetGeometryBlock(j);
|
|
|
+
|
|
|
+ geobase * pline;
|
|
|
+ geobase * pbez;
|
|
|
+ geobase * parc;
|
|
|
+
|
|
|
+ switch(xvectorgeo[j].mnType)
|
|
|
+ {
|
|
|
+ case 0:
|
|
|
+ pline = &xvectorgeo[j];
|
|
|
+ pgb->AddGeometryLine(s,pline->mfX,pline->mfY,pline->mfHdg,pline->mfLen);
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ parc = &xvectorgeo[j];
|
|
|
+ pgb->AddGeometryArc(s,parc->mfX,parc->mfY,parc->mfHdgStart,parc->mfLen,1.0/parc->mR);
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ pbez = &xvectorgeo[j];
|
|
|
+ std::cout<<"u0:"<<pbez->mfu[0]<<std::endl;
|
|
|
+ pgb->AddGeometryParamPoly3(s,pbez->mfX,pbez->mfY,
|
|
|
+ pbez->mfHdg,pbez->mfLen,pbez->mfu[0],
|
|
|
+ pbez->mfu[1],pbez->mfu[2],pbez->mfu[3],pbez->mfv[0],
|
|
|
+ pbez->mfv[1],pbez->mfv[2],pbez->mfv[3]);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ s = s + xvectorgeo[j].mfLen;
|
|
|
+ }
|
|
|
+
|
|
|
+ p->AddLaneSection(0);
|
|
|
+
|
|
|
+ LaneSection * pLS = p->GetLaneSection(0);
|
|
|
+
|
|
|
+ pLS->AddLane(0,0,"none",false);
|
|
|
+ pLS->AddLane(-1,(-1)*(pLS->GetRightLaneCount()+1),"driving",false);
|
|
|
+ Lane * pLane = pLS->GetLastRightLane();
|
|
|
+ for(j=0;j<(int)xvectorwidthabcd.size();j++)
|
|
|
+ {
|
|
|
+ iv::widthabcd * pwa = &xvectorwidthabcd[j];
|
|
|
+ pLane->AddWidthRecord(pwa->s,pwa->A,pwa->B,pwa->C,pwa->D);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|