123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644 |
- #include "frenet_planner.h"
- #include <adc_tools/transfer.h>
- #include <common/car_status.h>
- #include <adc_tools/parameter_status.h>
- //#include <decide_gps_00.h>
- #include <adc_planner/lane_change_planner.h>
- #include<Eigen/Dense>
- using namespace std;
- using namespace Eigen;
- iv::decition::FrenetPlanner::FrenetPlanner(){
- this->planner_id = 1;
- this->planner_name = "Frenet";
- this->lidarGridPtr = NULL;
- }
- iv::decition::FrenetPlanner::~FrenetPlanner(){
- free(this->lidarGridPtr);
- }
- /**
- * @brief iv::decition::FrenetPlanner::getPath
- * 采用的基于frenet坐标系的最优局部路径生成方法,可实现从当前车道变换到另一车道之间的路径生成。还可实现车辆在路线旁起步的“有迹可循”。
- * 计算的是,在车辆到达 原始地图路径偏移offset距离的车道 之前,frenet下规划的路径。
- *
- * @param now_gps_ins 实时gps信息
- * @param gpsMapLine 地图数据点
- * @param PathPoint 地图路线中距离车辆位置最近的一个点的序号
- * @param offset 在车辆避障中,地图源路线所在车道 与 即将去往的车道 之间的距离差值。可以为负值。offset = -(roadNow - roadOri)*roadWidth
- * @param lidarGridPtr 激光雷达信息网格
- * @return 返回一条车辆坐标系下的路径
- */
- std::vector<iv::Point2D> iv::decition::FrenetPlanner::getPath(GPS_INS now_gps_ins, const std::vector<GPSData>& gpsMapLine, int PathPoint, double offset, iv::LidarGridPtr lidarGridPtr){
- this->roadNow = -1;
- this->now_gps_ins = now_gps_ins;
- this->gpsMapLine = gpsMapLine;
- this->PathPoint = PathPoint;
- this->lidarGridPtr = lidarGridPtr;
- LaneChangePlanner *lcp = new LaneChangePlanner();
- std::vector<iv::Point2D> gpsTrace = lcp->getPath(now_gps_ins,gpsMapLine,PathPoint,0,lidarGridPtr);
- delete lcp;
- double realSecSpeed = now_gps_ins.speed / 3.6;
- leftWidth = offset;
- rightWidth = offset;
- std::vector<iv::Point2D> trace = getGpsTrace_AfterCalcFrenetTrace(gpsTrace,realSecSpeed);
- return trace;
- }
- /**
- * @brief iv::decition::FrenetPlanner::chooseRoadByFrenet
- * 用frenet的方法对每条道路考察,选择一个最优的道路
- * @param now_gps_ins 实时gps信息
- * @param gpsMapLine 地图数据点
- * @param PathPoint 地图路线中距离车辆位置最近的一个点的序号
- * @param offsetL 在选择道路中,地图源路线左边的最大宽度。可以为负值。offsetL = -(roadSum - 1)*roadWidth
- * @param offsetR 在选择道路中,地图源路线右边的最大宽度。可以为非负值。offsetR = (roadOri - 0)*roadWidth
- * @param lidarGridPtr 激光雷达信息网格
- * @return
- */
- int iv::decition::FrenetPlanner::chooseRoadByFrenet(GPS_INS now_gps_ins, const std::vector<GPSData>& gpsMapLine, int PathPoint, double offsetL, double offsetR, iv::LidarGridPtr lidarGridPtr,int roadNow){
- this->roadNow = roadNow;
- this->aimRoadByFrenet = -1;
- this->now_gps_ins = now_gps_ins;
- this->gpsMapLine = gpsMapLine;
- this->PathPoint = PathPoint;
- this->lidarGridPtr = lidarGridPtr;
- LaneChangePlanner *lcp = new LaneChangePlanner();
- std::vector<iv::Point2D> gpsTrace = lcp->getPath(now_gps_ins,gpsMapLine,PathPoint,0,lidarGridPtr);
- delete lcp;
- double realSecSpeed = now_gps_ins.speed / 3.6;
- leftWidth = offsetL;
- rightWidth = offsetR;
- std::vector<iv::Point2D> trace = getGpsTrace_AfterCalcFrenetTrace(gpsTrace,realSecSpeed);
- return aimRoadByFrenet;
- }
- /**
- * @brief iv::decition::FrenetPlanner::getGpsTrace_AfterCalcFrenetTrace
- * 进行frenet规划的总函数,还包括了规划前的一些准备工作,比如frenet坐标系建立、车辆起始状态等。
- * @param gpsTrace 地图路线上从PathPoint开始的600个点
- * @param realsecSpeed 实时车速 [m/s]
- * @return 返回一条frenet规划后并转换到车辆坐标系下的路径
- */
- std::vector<iv::Point2D> iv::decition::FrenetPlanner::getGpsTrace_AfterCalcFrenetTrace(const std::vector<iv::Point2D>& gpsTrace,double realsecSpeed){
- vector<Point2D> trace;
- vector<FrenetPoint> frenet_s;
- double stp=0.0;
- //把gpsTrace里的点全部转为frenet坐标系下的点,存储在frenet_s中。相当于frenet坐标系的S轴。
- FrenetPoint tmp={.x=gpsTrace[0].x,.y=gpsTrace[0].y,.s=0.0,.d=0.0};
- frenet_s.push_back(tmp);
- for(int i=1; i<gpsTrace.size(); ++i){
- stp+=iv::decition::GetDistance(gpsTrace[i-1],gpsTrace[i]);
- tmp={.x=gpsTrace[i].x,.y=gpsTrace[i].y,.s=stp,.d=0.0};
- frenet_s.push_back(tmp);
- }
- //求出车辆当前位置在frenet坐标系下的坐标
- // FrenetPoint car_now_at_frenet = XY2Frenet(0,0,gpsTrace);
- FrenetPoint car_now_at_frenet = getFrenetfromXY(0,0,gpsTrace,this->gpsMapLine,this->PathPoint,this->now_gps_ins);
- double c_s_speed = realsecSpeed * cos(car_now_at_frenet.tangent_Ang-M_PI/2);
- double c_d_speed = realsecSpeed * sin(car_now_at_frenet.tangent_Ang-M_PI/2);
- double realAcc = ServiceCarStatus.mfCalAcc;
- double c_s_dd = realAcc * cos(car_now_at_frenet.tangent_Ang-M_PI/2);
- double c_d_dd = realAcc * sin(car_now_at_frenet.tangent_Ang-M_PI/2);
- vector<Point2D> path=frenet_optimal_planning(car_now_at_frenet,frenet_s,c_s_speed,c_d_speed,c_d_dd);
- return path;
- }
- /**
- * @brief iv::decition::FrenetPlanner::frenet_optimal_planning
- * 对frenet规划出的路径进行后续操作,并选出损失最小的一条路径作为最优路径
- * @param car_now_frenet_point 车辆当前位置在frenet坐标系下的坐标
- * @param frenet_s frenet坐标系的s轴
- * @param c_speed 车辆的纵向速度。沿s轴方向的速度。
- * @param c_d_d 车辆沿d方向的速度。
- * @param c_d_dd 车辆沿d方向的加速度。
- * @return 返回一条frenet规划的最优路径
- */
- vector<iv::Point2D> iv::decition::FrenetPlanner::frenet_optimal_planning(iv::decition::FrenetPoint car_now_frenet_point,
- const std::vector<FrenetPoint>& frenet_s, double c_speed, double c_d_d, double c_d_dd){
- double s0 = car_now_frenet_point.s;
- double c_d = car_now_frenet_point.d;
- vector<iv::Point2D> gpsTrace;
- vector<Frenet_path> fplist=calc_frenet_paths(c_speed, c_d, c_d_d, c_d_dd, s0); //frenet规划
- sort(fplist.begin(),fplist.end(),comp); //按损失度由小到大进行排序
- for(int i=0; i<fplist.size(); ++i){
- calc_global_single_path(fplist[i],frenet_s);
- if(check_single_path(fplist[i])){
- gpsTrace = frenet_path_to_gpsTrace(fplist[i]);
- aimRoadByFrenet = fplist[i].roadflag;
- return gpsTrace;
- }
- }
- return gpsTrace;
- /*
- // calc_global_paths(fplist, frenet_s); //生成frenet路径中每个点在车辆坐标系下的坐标
- // fplist = check_paths(fplist); //检验计算出的每条路径
- // //找到损失最小的轨迹
- // double min_cost = (numeric_limits<double>::max)();
- // Frenet_path bestpath;
- // for(int i=0; i<fplist.size(); ++i){
- // if(min_cost > fplist[i].cf){
- // min_cost = fplist[i].cf;
- // bestpath = fplist[i];
- // }
- // }
- // gpsTrace = frenet_path_to_gpsTrace(bestpath);
- // aimRoadByFrenet = bestpath.roadflag;
- // return gpsTrace;
- */
- }
- /**
- * @brief iv::decition::FrenetPlanner::calc_frenet_paths
- * 正式规划出不同的frenet路径,并统计相应的损失度。单从车辆行驶的平滑性计算而得,后续需检测是否有障碍物。
- * @param c_speed 车辆的纵向速度。沿s轴方向的速度
- * @param c_d 车辆的横向(d方向)偏移距离
- * @param c_d_d 车辆沿d方向的速度
- * @param c_d_dd 车辆沿d方向的加速度
- * @param s0 车辆沿s方向的坐标
- * @return 返回多条frenet路径
- */
- vector<iv::decition::Frenet_path> iv::decition::FrenetPlanner::calc_frenet_paths(double c_speed, double c_d, double c_d_d, double c_d_dd, double s0){
- vector<iv::decition::Frenet_path> frenet_paths;
- int roadNum = round(abs((leftWidth-rightWidth)/ServiceParameterStatus.D_ROAD_W)); //roadNum为frenet算法的起始道路序号
- //采样,并对每一个目标配置生成轨迹
- for(double di=leftWidth; di<=rightWidth; di+=ServiceParameterStatus.D_ROAD_W,roadNum--){
- if(roadNum == this->roadNow)
- continue;
- //横向动作规划
- for(double Ti=ServiceParameterStatus.MINT; Ti<ServiceParameterStatus.MAXT; Ti+=ServiceParameterStatus.DT){
- Frenet_path fp;
- fp.roadflag = roadNum;
- //计算出关于目标配置di,Ti的横向多项式
- Quintic_polynomial lat_qp = Quintic_polynomial(c_d, c_d_d, c_d_dd, di, 0.0, 0.0, Ti);
- for(double i=0; i<Ti; i+=ServiceParameterStatus.D_POINT_T)
- fp.t.push_back(i);
- for(int i=0; i<fp.t.size(); ++i){
- fp.d.push_back(lat_qp.calc_point(fp.t[i]));
- fp.d_d.push_back(lat_qp.calc_first_derivative(fp.t[i]));
- fp.d_dd.push_back(lat_qp.calc_second_derivative(fp.t[i]));
- fp.d_ddd.push_back(lat_qp.calc_third_derivative(fp.t[i]));
- }
- //纵向速度规划 (速度保持)
- for(double tv=ServiceParameterStatus.TARGET_SPEED - ServiceParameterStatus.D_T_S * ServiceParameterStatus.N_S_SAMPLE;
- tv<(ServiceParameterStatus.TARGET_SPEED + ServiceParameterStatus.D_T_S * ServiceParameterStatus.N_S_SAMPLE);
- tv+=ServiceParameterStatus.D_T_S){
- Frenet_path tfp = fp;
- Quartic_polynomial lon_qp = Quartic_polynomial(s0, c_speed, 0.0, tv, 0.0, Ti);
- for(int i=0; i<fp.t.size(); ++i){
- tfp.s.push_back(lon_qp.calc_point(fp.t[i]));
- tfp.s_d.push_back(lon_qp.calc_first_derivative(fp.t[i]));
- tfp.s_dd.push_back(lon_qp.calc_second_derivative(fp.t[i]));
- tfp.s_ddd.push_back(lon_qp.calc_third_derivative(fp.t[i]));
- }
- //square of jerk
- double Jp = inner_product(tfp.d_ddd.begin(), tfp.d_ddd.end(), tfp.d_ddd.begin(), 0);
- //square of jerk
- double Js = inner_product(tfp.s_ddd.begin(), tfp.s_ddd.end(), tfp.s_ddd.begin(), 0);
- //square of diff from target speed
- double ds = pow((ServiceParameterStatus.TARGET_SPEED - tfp.s_d.back()),2);
- //横向的损失函数
- tfp.cd = ServiceParameterStatus.KJ * Jp + ServiceParameterStatus.KT * Ti + ServiceParameterStatus.KD * tfp.d.back() * tfp.d.back();
- //纵向的损失函数
- tfp.cv = ServiceParameterStatus.KJ * Js + ServiceParameterStatus.KT * Ti + ServiceParameterStatus.KD * ds;
- //总的损失函数为d 和 s方向的损失函数乘对应的系数相加
- tfp.cf = ServiceParameterStatus.KLAT * tfp.cd + ServiceParameterStatus.KLON * tfp.cv;
- frenet_paths.push_back(tfp);
- }
- }
- }
- return frenet_paths;
- }
- /**
- * @brief iv::decition::FrenetPlanner::calc_global_paths
- * 计算出每条frenet路径中轨迹点的x,y坐标。x,y坐标是轨迹点在车辆坐标系下的横纵坐标。
- * 部分函数参数在第一种计算XY坐标的方法中没有使用,但在第二种方法中会用到。
- * @param fplist 多条frenet路径
- * @param frenet_s frenet坐标系的s轴
- * @return 通过引用传递返回带有x,y值的多条frenet路径
- */
- void iv::decition::FrenetPlanner::calc_global_paths(vector<Frenet_path>& fplist,const std::vector<FrenetPoint>& frenet_s){
- for(auto& fp:fplist){
- for(int i=0; i<fp.s.size(); ++i){
- double ix,iy;
- // Frenet2XY(&ix,&iy,fp.s[i],fp.d[i],frenet_s); //第一种方法
- getXYfromFrenet(&ix,&iy,fp.s[i],fp.d[i],frenet_s,this->gpsMapLine,this->PathPoint,this->now_gps_ins); //第二种方法
- fp.x.push_back(ix);
- fp.y.push_back(iy);
- }
- for(int i=0; i<(fp.x.size()-1); ++i){
- double dx = fp.x[i+1] - fp.x[i];
- double dy = fp.y[i+1] - fp.y[i];
- fp.yaw.push_back(atan2(dy,dx));
- fp.ds.push_back(sqrt(dx*dx + dy*dy));
- }
- fp.ds.push_back(fp.ds.back());
- fp.yaw.push_back(fp.yaw.back());
- for(int i = 0; i < (fp.yaw.size() - 1); ++i){
- fp.c.push_back((fp.yaw[i + 1] - fp.yaw[i]) / fp.ds[i]);
- }
- }
- }
- void iv::decition::FrenetPlanner::calc_global_single_path(Frenet_path &fp, const std::vector<FrenetPoint> &frenet_s){
- for(int i=0; i<fp.s.size(); ++i){
- double ix,iy;
- // Frenet2XY(&ix,&iy,fp.s[i],fp.d[i],frenet_s); //第一种方法
- getXYfromFrenet(&ix,&iy,fp.s[i],fp.d[i],frenet_s,this->gpsMapLine,this->PathPoint,this->now_gps_ins); //第二种方法
- fp.x.push_back(ix);
- fp.y.push_back(iy);
- }
- for(int i=0; i<(fp.x.size()-1); ++i){
- double dx = fp.x[i+1] - fp.x[i];
- double dy = fp.y[i+1] - fp.y[i];
- fp.yaw.push_back(atan2(dy,dx));
- fp.ds.push_back(sqrt(dx*dx + dy*dy));
- }
- fp.ds.push_back(fp.ds.back());
- fp.yaw.push_back(fp.yaw.back());
- for(int i = 0; i < (fp.yaw.size() - 1); ++i){
- fp.c.push_back((fp.yaw[i + 1] - fp.yaw[i]) / fp.ds[i]);
- }
- }
- /**
- * @brief iv::decition::FrenetPlanner::check_paths
- * 对多条frenet路径进行检验,排除不符合要求的路径。
- * @param fplist 多条frenet路径
- * @return 排除部分路径后的多条frenet路径
- */
- vector<iv::decition::Frenet_path> iv::decition::FrenetPlanner::check_paths(const vector<Frenet_path>& fplist){
- vector<Frenet_path> okind;
- int i=0;
- int j=0;
- for(i=0; i<fplist.size(); ++i){
- cout<<"&&&&&&&&&&fplist[i].roadflag: "<<fplist[i].roadflag<<endl;
- for(j=0; j<fplist[i].s_d.size(); ++j){
- if(fplist[i].s_d[j]>ServiceParameterStatus.MAX_SPEED) //最大速度检查
- goto ContinueFlag;
- }
- for(j=0; j<fplist[i].s_dd.size(); ++j){
- if(abs(fplist[i].s_dd[j])>ServiceParameterStatus.MAX_ACCEL) //最大加速度检查
- goto ContinueFlag;
- }
- for(j=30; j<fplist[i].c.size()-30; ++j){
- if(abs(fplist[i].c[j])>ServiceParameterStatus.MAX_CURVATURE)//最大曲率检查
- goto ContinueFlag;
- }
- if(!check_collision(fplist[i]))
- continue;
- okind.push_back(fplist[i]);
- ContinueFlag:continue;
- }
- return okind;
- }
- bool iv::decition::FrenetPlanner::check_single_path(const iv::decition::Frenet_path &fp){
- int j=0;
- cout<<"&&&&&&&&&&fp.roadflag: "<<fp.roadflag<<endl;
- for(j=0; j<fp.s_d.size(); ++j){
- if(fp.s_d[j]>ServiceParameterStatus.MAX_SPEED) //最大速度检查
- return false;
- }
- for(j=0; j<fp.s_dd.size(); ++j){
- if(abs(fp.s_dd[j])>ServiceParameterStatus.MAX_ACCEL) //最大加速度检查
- return false;
- }
- for(j=30; j<fp.c.size()-30; ++j){
- if(abs(fp.c[j])>ServiceParameterStatus.MAX_CURVATURE)//最大曲率检查
- return false;
- }
- if(!check_collision(fp))
- return false;
- return true;
- }
- /**
- * @brief iv::decition::FrenetPlanner::check_collision
- * 检验frenet路径上是否有障碍物,调用的是改进的函数computeObsOnRoadByFrenet。
- * @param frenet_path 一条frenet路径
- * @param car_now_frenet_point 车辆当前位置在frenet坐标系下的坐标
- * @return 在路径上有障碍物返回false,否则返回true。
- */
- bool iv::decition::FrenetPlanner::check_collision(const iv::decition::Frenet_path &frenet_path){
- std::vector<Point2D> gpsTrace = frenet_path_to_gpsTrace(frenet_path);
- double obs=-1;
- // iv::decition::DecideGps00().computeObsOnRoadByFrenet(this->lidarGridPtr,gpsTrace,obs,this->gpsMapLine,this->PathPoint,this->now_gps_ins);
- if(obs > 0 && obs < 30)
- return false;
- else
- return true;
- }
- /**
- * @brief iv::decition::FrenetPlanner::frenet_path_to_gpsTrace
- * 将frenet路径转换到车辆坐标系下。
- * @param frenet_path 一条frenet路径
- * @return 一条车辆坐标系下的路径
- */
- vector<iv::Point2D> iv::decition::FrenetPlanner::frenet_path_to_gpsTrace(const Frenet_path& frenet_path){
- vector<iv::Point2D> gpsTrace;
- for (int i=0; i<frenet_path.x.size(); ++i) {
- gpsTrace.push_back(Point2D(frenet_path.x[i],frenet_path.y[i]));
- gpsTrace[i].speed = sqrt(frenet_path.d_d[i]*frenet_path.d_d[i]+frenet_path.s_d[i]*frenet_path.s_d[i])*3.6;
- }
- return gpsTrace;
- }
- double iv::decition::FrenetPlanner::distance(double x1, double y1, double x2, double y2)
- {
- return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
- }
- //找出gpsTrace中距离(x,y)最近的一个点
- int iv::decition::FrenetPlanner::ClosestWaypoint(double x, double y, const std::vector<Point2D>& gpsTrace)
- {
- double closestLen = 100000; //large number
- int closestWaypoint = 0;
- for(int i = 1; i < gpsTrace.size(); i++)
- {
- double map_x = gpsTrace[i].x;
- double map_y = gpsTrace[i].y;
- double dist = distance(x,y,map_x,map_y);
- if(dist < closestLen)
- {
- closestLen = dist;
- closestWaypoint = i;
- }
- }
- return closestWaypoint;
- }
- /* |==========================================================|
- * | 车辆坐标系与 frenet 坐标系互转的第一种方法。 |
- * |==========================================================| */
- // 车体坐标转frenet坐标。frenet坐标原点是 gpsTrace 中序号为0的点。
- // Transform from Cartesian x,y coordinates to Frenet s,d coordinates
- iv::decition::FrenetPoint iv::decition::FrenetPlanner::XY2Frenet(double x, double y, const std::vector<iv::Point2D>& gpsTrace){
- int next_wp=ClosestWaypoint( x, y, gpsTrace);
- int prev_wp = next_wp-1; //prev_wp代表在next_wp的前一个点计算坐标,能够保证frenet_s都是依次相加的。避免在next_wp计算frenet_s的话,可能出现减的情况。
- // if(next_wp == 0){
- // prev_wp = gpsTrace.size()-1;
- // }
- double n_x = gpsTrace[next_wp].x-gpsTrace[prev_wp].x;
- double n_y = gpsTrace[next_wp].y-gpsTrace[prev_wp].y;
- double x_x = x - gpsTrace[prev_wp].x;
- double x_y = y - gpsTrace[prev_wp].y;
- // find the projection of x onto n
- double proj_norm = (x_x*n_x+x_y*n_y)/(n_x*n_x+n_y*n_y);
- double proj_x = proj_norm*n_x;
- double proj_y = proj_norm*n_y; //proj_x、proj_y应该为垂足的坐标
- double frenet_d = sqrt((x_x - proj_x) * (x_x - proj_x) + (x_y - proj_y) * (x_y - proj_y));
- //经手动推算frenet_d = abs(n_x * x_y - n_y * x_x) / sqrt(n_x * n_x + n_y * n_y)。
- //即frenet_d,等于点(x,y)到 过prev_wp、next_wp两点的直线 的垂直距离。
- //see if d value is positive or negative by comparing it to a center point
- double center_x = 1000-gpsTrace[prev_wp].x;
- double center_y = 2000-gpsTrace[prev_wp].y;
- double centerToPos = distance(center_x,center_y,x_x,x_y);
- double centerToRef = distance(center_x,center_y,proj_x,proj_y);
- if(centerToPos <= centerToRef){
- frenet_d *= -1;
- }
- // calculate s value
- double frenet_s = 0;
- for(int i = 0; i < prev_wp; i++){
- frenet_s += distance(gpsTrace[i].x,gpsTrace[i].y,gpsTrace[i+1].x,gpsTrace[i+1].y);
- }
- if(prev_wp<=0){
- frenet_s -= distance(0,0,proj_x,proj_y);
- }else{
- frenet_s += distance(0,0,proj_x,proj_y);
- }
- double tmp_Angle = atan2(n_y,n_x);
- return {x:x,y:y,s:frenet_s,d:frenet_d,tangent_Ang:tmp_Angle};
- }
- // frenet坐标转车体坐标。
- // Transform from Frenet s,d coordinates to Cartesian x,y
- void iv::decition::FrenetPlanner::Frenet2XY(double *res_x, double *res_y, double s, double d, const vector<iv::decition::FrenetPoint>& frenetTrace){
- int prev_wp = 0;
- //退出循环时,prev_wp 最大是等于 frenetTrace.size()-2。
- while(s > frenetTrace[prev_wp+1].s && (prev_wp < (int)(frenetTrace.size()-2) )){
- prev_wp++;
- }
- int wp2 = prev_wp+1;
- double heading = atan2((frenetTrace[wp2].y-frenetTrace[prev_wp].y),(frenetTrace[wp2].x-frenetTrace[prev_wp].x));
- double seg_s = (s-frenetTrace[prev_wp].s);
- double seg_x = frenetTrace[prev_wp].x+seg_s*cos(heading);
- double seg_y = frenetTrace[prev_wp].y+seg_s*sin(heading);
- double perp_heading = heading-M_PI*0.5;
- *res_x = seg_x + d*cos(perp_heading);
- *res_y = seg_y + d*sin(perp_heading);
- }
- /* |==========================================================|
- * | 车辆坐标系与 frenet 坐标系互转的第二种方法。 |
- * |==========================================================| */
- // 车体坐标转frenet坐标。frenet坐标原点是 gpsTrace 中序号为0的点。
- iv::decition::FrenetPoint iv::decition::FrenetPlanner::getFrenetfromXY(double x, double y, const std::vector<iv::Point2D>& gpsTrace,const std::vector<iv::GPSData>& gpsMap,int pathpoint,GPS_INS nowGps){
- int next_wp=ClosestWaypoint( x, y, gpsTrace);
- int prev_wp = next_wp-1; //prev_wp代表在next_wp的前一个点计算坐标,能够保证frenet_s都是依次相加的。避免在next_wp计算frenet_s的话,可能出现减的情况。
- // if(next_wp == 0){
- // prev_wp = gpsTrace.size()-1;
- // }
- GPS_INS gps = Coordinate_UnTransfer(x,y,nowGps);
- Point2D pt = Coordinate_Transfer(gps.gps_x,gps.gps_y, *gpsMap[(pathpoint+prev_wp)%gpsMap.size()]);
- // calculate s value
- double frenet_s = 0;
- for(int i = 0; i < prev_wp; i++){
- frenet_s += distance(gpsTrace[i].x,gpsTrace[i].y,gpsTrace[i+1].x,gpsTrace[i+1].y);
- }
- frenet_s += pt.y;
- //theta为prev_wp处车的航向角 与 nowGps处的车辆坐标系下x轴之间的夹角,逆时针为正。
- double theta = (nowGps.ins_heading_angle - gpsMap[(pathpoint+prev_wp)%gpsMap.size()]->ins_heading_angle+90);
- double tmp_Angle = theta * M_PI / 180;
- return {x:x,y:y,s:frenet_s,d:pt.x,tangent_Ang:tmp_Angle};
- }
- void iv::decition::FrenetPlanner::getXYfromFrenet(double *res_x, double *res_y, double s, double d, const vector<iv::decition::FrenetPoint>& frenetTrace,const std::vector<iv::GPSData>& gpsMap,int pathpoint,GPS_INS nowGps)
- {
- int prev_wp = -1;
- while((prev_wp < (int)(frenetTrace.size()-1) ) && s > frenetTrace[prev_wp+1].s)
- {
- prev_wp++;
- }
- if(prev_wp < 0){
- prev_wp = 0;
- }
- // int wp2 =prev_wp+1;
- GPS_INS gps= Coordinate_UnTransfer( d, s-frenetTrace[prev_wp].s , *gpsMap[(pathpoint+prev_wp)%gpsMap.size()]);
- Point2D pt = Coordinate_Transfer( gps.gps_x, gps.gps_y, nowGps);
- *res_x = pt.x;
- *res_y = pt.y;
- }
- iv::decition::Quintic_polynomial::Quintic_polynomial(double xs, double vxs, double axs, double xe, double vxe, double axe, double T){
- //计算五次多项式系数
- this->xs = xs;
- this->vxs = vxs;
- this->axs = axs;
- this->xe = xe;
- this->vxe = vxe;
- this->axe = axe;
- this->a0 = xs;
- this->a1 = vxs;
- this->a2 = axs/ 2.0;
- MatrixXd A(3, 3);
- MatrixXd b(3, 1);
- MatrixXd x(3, 1);
- A << pow(T, 3), pow(T, 4), pow(T, 5),
- 3*pow(T, 2), 4*pow(T, 3), 5*pow(T, 4),
- 6*T, 12*T*T, 20*pow(T, 3);
- b << xe - a0 - a1*T - a2*T*T,
- vxe - a1 - 2*a2*T,
- axe - 2*a2;
- x=A.colPivHouseholderQr().solve(b);
- this->a3 = x(0,0);
- this->a4 = x(1,0);
- this->a5 = x(2,0);
- }
- iv::decition::Quintic_polynomial::~Quintic_polynomial(){
- }
- double iv::decition::Quintic_polynomial::calc_point(double t){
- double xt = this->a0 + this->a1 * t + this->a2 * t*t + this->a3 * t*t*t + this->a4 * t*t*t*t + this->a5 * t*t*t*t*t;
- return xt;
- }
- double iv::decition::Quintic_polynomial::calc_first_derivative(double t){
- double xt = this->a1 + 2*this->a2 * t + 3*this->a3 * t*t + 4*this->a4 * t*t*t + 5*this->a5 * t*t*t*t;
- return xt;
- }
- double iv::decition::Quintic_polynomial::calc_second_derivative(double t){
- double xt = 2*this->a2 + 6*this->a3 * t + 12*this->a4 * t*t + 20*this->a5 * t*t*t;
- return xt;
- }
- double iv::decition::Quintic_polynomial::calc_third_derivative(double t){
- double xt = 6*this->a3 + 24*this->a4 * t + 60*this->a5 * t*t;
- return xt;
- }
- iv::decition::Quartic_polynomial::Quartic_polynomial(double xs, double vxs, double axs, double vxe, double axe, double T){
- //计算四次多项式系数
- this->xs = xs;
- this->vxs = vxs;
- this->axs = axs;
- this->vxe = vxe;
- this->axe = axe;
- this->a0 = xs;
- this->a1 = vxs;
- this->a2 = axs / 2.0;
- MatrixXd A(2, 2);
- MatrixXd b(2, 1);
- MatrixXd x(2, 1);
- A << 3*pow(T, 2), 4*pow(T, 3),
- 6*T, 12*T*T ;
- b << vxe - a1 - 2*a2*T,
- axe - 2*a2;
- x=A.colPivHouseholderQr().solve(b);
- this->a3 = x(0,0);
- this->a4 = x(1,0);
- }
- iv::decition::Quartic_polynomial::~Quartic_polynomial(){
- }
- double iv::decition::Quartic_polynomial::calc_point(double t){
- double xt = this->a0 + this->a1*t + this->a2*t*t + this->a3*t*t*t + this->a4*t*t*t*t;
- return xt;
- }
- double iv::decition::Quartic_polynomial::calc_first_derivative(double t){
- double xt = this->a1 + 2*this->a2*t + 3*this->a3*t*t + 4*this->a4*t*t*t;
- return xt;
- }
- double iv::decition::Quartic_polynomial::calc_second_derivative(double t){
- double xt = 2*this->a2 + 6*this->a3*t + 12*this->a4*t*t;
- return xt;
- }
- double iv::decition::Quartic_polynomial::calc_third_derivative(double t){
- double xt = 6*this->a3 + 24*this->a4*t;
- return xt;
- }
- bool iv::decition::FrenetPlanner::comp(const iv::decition::Frenet_path &a, const iv::decition::Frenet_path &b){
- return a.cf < b.cf;
- }
|