From d2f67dbeadb21b7bc102ffde9edce331f14fcbab Mon Sep 17 00:00:00 2001 From: Sergi Hernandez Juan <shernand@iri.upc.edu> Date: Tue, 19 Jan 2021 16:31:30 +0100 Subject: [PATCH] Modified the gradient class to return false when the gradient goes outside the limits. The spline class returns maximum length when the is no closest point belonging to the spline. All other classes check the returned length to check for the existance of the closest point. --- include/opendrive_road_node.h | 4 +- src/g2_spline.cpp | 8 +-- src/gradient.cpp | 5 +- src/opendrive_lane.cpp | 37 ++++++++------ src/opendrive_road.cpp | 83 ++++++++++++++++++++----------- src/opendrive_road_node.cpp | 90 +++++++++++++++++++++------------- src/opendrive_road_segment.cpp | 74 +++++++++++++++++----------- 7 files changed, 186 insertions(+), 115 deletions(-) diff --git a/include/opendrive_road_node.h b/include/opendrive_road_node.h index c5625b0..1436a11 100644 --- a/include/opendrive_road_node.h +++ b/include/opendrive_road_node.h @@ -36,7 +36,6 @@ class COpendriveRoadNode void add_link(COpendriveLink *link); void remove_link(COpendriveLink *link); bool has_link(COpendriveLink *link); - bool has_link_with(COpendriveRoadNode *node); COpendriveLink *get_link_with(COpendriveRoadNode *node); void set_resolution(double res); void set_scale_factor(double scale); @@ -62,10 +61,11 @@ class COpendriveRoadNode unsigned int get_num_links(void) const; const COpendriveLink &get_link(unsigned int index) const; const COpendriveLink &get_link_ending_at(unsigned int node_index) const; + bool has_link_with(const COpendriveRoadNode &node) const; unsigned int get_closest_link(TOpendriveWorldPose &pose,double angle_tol=0.1) const; double get_closest_distance(TOpendriveWorldPose &pose,bool only_lanes=false,double angle_tol=0.1) const; double get_closest_pose(TOpendriveWorldPose &pose,TOpendriveWorldPose &closest_pose,bool only_lanes=false,double angle_tol=0.1) const; - void get_closest_poses(TOpendriveWorldPose &pose,std::vector<TOpendriveWorldPose> &closest_poses,std::vector<double> &closest_lengths,double dist_tol,bool only_lanes,double angle_tol=0.1) const; + void get_closest_poses(TOpendriveWorldPose &pose,std::vector<TOpendriveWorldPose> &closest_poses,std::vector<double> &closest_lengths,double dist_tol,bool only_lanes=false,double angle_tol=0.1) const; friend std::ostream& operator<<(std::ostream& out, COpendriveRoadNode &node); ~COpendriveRoadNode(); }; diff --git a/src/g2_spline.cpp b/src/g2_spline.cpp index acb107c..5709b60 100644 --- a/src/g2_spline.cpp +++ b/src/g2_spline.cpp @@ -801,7 +801,7 @@ double CG2Spline::get_max_curvature(double max_error,unsigned int max_iter) { start_point=this->get_max_sample_point(boost::bind(&CG2Spline::curvature_pow2,this,_1)); if(!this->curvature_grad.compute(max_error,max_iter,start_point,true)) - return std::numeric_limits<double>::infinity(); + return std::numeric_limits<double>::max(); else { this->curvature_computed=true; @@ -821,7 +821,7 @@ double CG2Spline::get_max_curvature_der(double max_error,unsigned int max_iter) { start_point=this->get_max_sample_point(boost::bind(&CG2Spline::curvature_der_pow2,this,_1)); if(!this->curvature_der_grad.compute(max_error,max_iter,start_point,true)) - return std::numeric_limits<double>::infinity(); + return std::numeric_limits<double>::max(); else { this->curvature_der_computed=true; @@ -839,7 +839,7 @@ double CG2Spline::find_closest_point(double x, double y, TPoint &point,double ma this->dist_y=y; start_point=this->get_min_sample_point(boost::bind(&CG2Spline::distance_pow2,this,_1)); if(!this->distance_grad.compute(max_error,max_iter,start_point,false)) - return std::numeric_limits<double>::infinity(); + return std::numeric_limits<double>::max(); else { point=this->evaluate_parameter(this->distance_grad.get_coordinate()); @@ -858,7 +858,7 @@ double CG2Spline::find_closest_point(double x, double y,double max_error,unsigne this->dist_y=y; start_point=this->get_min_sample_point(boost::bind(&CG2Spline::distance_pow2,this,_1)); if(!this->distance_grad.compute(max_error,max_iter,start_point,false)) - return std::numeric_limits<double>::infinity(); + return std::numeric_limits<double>::max(); else { if(this->num_points) diff --git a/src/gradient.cpp b/src/gradient.cpp index 92c876f..3301bb4 100644 --- a/src/gradient.cpp +++ b/src/gradient.cpp @@ -52,6 +52,7 @@ bool CGradient::compute(double max_func_error,unsigned int max_iter,double start unsigned int iteration=0; double gamma=1.0,func_value,func_der_value,prev_func_value,prev_func_der_value; double coord,prev_coord,coord_inc; + bool beyond_limits=false; coord=start_point; func_value=this->p_function(coord); @@ -72,6 +73,7 @@ bool CGradient::compute(double max_func_error,unsigned int max_iter,double start coord=this->max_coord; this->coordinate=coord; this->value=this->p_function(coord); + beyond_limits=true; break; } else if(coord<this->min_coord) @@ -79,6 +81,7 @@ bool CGradient::compute(double max_func_error,unsigned int max_iter,double start coord=this->min_coord; this->coordinate=coord; this->value=this->p_function(coord); + beyond_limits=true; break; } prev_func_value=func_value; @@ -90,7 +93,7 @@ bool CGradient::compute(double max_func_error,unsigned int max_iter,double start }while((fabs(func_value-prev_func_value)>max_func_error || fabs(coord-prev_coord)>0.001) && iteration<max_iter); this->coordinate=coord; this->value=func_value; - if(iteration==max_iter) + if(iteration==max_iter || beyond_limits) return false; else return true; diff --git a/src/opendrive_lane.cpp b/src/opendrive_lane.cpp index 8e2f245..035100b 100644 --- a/src/opendrive_lane.cpp +++ b/src/opendrive_lane.cpp @@ -779,22 +779,25 @@ TOpendriveWorldPose COpendriveLane::transform_to_world_pose(TOpendriveTrackPose unsigned int COpendriveLane::get_closest_node_index(TOpendriveWorldPose &pose,double &distance,double angle_tol) const { - double dist,min_dist=std::numeric_limits<double>::max(); + double dist,min_dist=std::numeric_limits<double>::max(),length; TOpendriveWorldPose found_pose; unsigned int closest_index=-1; for(unsigned int i=0;i<this->nodes.size();i++) { - this->nodes[i]->get_closest_pose(pose,found_pose,true,angle_tol); - dist=sqrt(pow(found_pose.x-pose.x,2.0)+pow(found_pose.y-pose.y,2.0)); - if(dist<min_dist) + length=this->nodes[i]->get_closest_pose(pose,found_pose,true,angle_tol); + if(length<std::numeric_limits<double>::max()) { - min_dist=dist; - closest_index=i; + dist=sqrt(pow(found_pose.x-pose.x,2.0)+pow(found_pose.y-pose.y,2.0)); + if(dist<min_dist) + { + min_dist=dist; + closest_index=i; + distance=length; + } } } - distance=min_dist; return closest_index; } @@ -810,7 +813,7 @@ const COpendriveRoadNode &COpendriveLane::get_closest_node(TOpendriveWorldPose & double COpendriveLane::get_closest_pose(TOpendriveWorldPose &pose,TOpendriveWorldPose &closest_pose,double angle_tol) const { - double dist,min_dist=std::numeric_limits<double>::max(),distance; + double dist,min_dist=std::numeric_limits<double>::max(),distance,length; TOpendriveWorldPose found_pose; unsigned int closest_index=-1; COpendriveLink *link; @@ -820,17 +823,20 @@ double COpendriveLane::get_closest_pose(TOpendriveWorldPose &pose,TOpendriveWorl closest_pose.heading=std::numeric_limits<double>::max(); for(unsigned int i=0;i<this->nodes.size();i++) { - this->nodes[i]->get_closest_pose(pose,found_pose,true,angle_tol); - dist=sqrt(pow(found_pose.x-pose.x,2.0)+pow(found_pose.y-pose.y,2.0)); - if(dist<min_dist) + length=this->nodes[i]->get_closest_pose(pose,found_pose,true,angle_tol); + if(length<std::numeric_limits<double>::max()) { - min_dist=dist; - closest_index=i; - closest_pose=found_pose; + dist=sqrt(pow(found_pose.x-pose.x,2.0)+pow(found_pose.y-pose.y,2.0)); + if(dist<min_dist) + { + min_dist=dist; + closest_index=i; + closest_pose=found_pose; + distance=length; + } } } - distance=0.0; for(unsigned int i=0;i<this->nodes.size();i++) { if(i<closest_index) @@ -842,7 +848,6 @@ double COpendriveLane::get_closest_pose(TOpendriveWorldPose &pose,TOpendriveWorl else break; } - distance+=min_dist; return distance; } diff --git a/src/opendrive_road.cpp b/src/opendrive_road.cpp index f26267a..42a9a77 100644 --- a/src/opendrive_road.cpp +++ b/src/opendrive_road.cpp @@ -671,18 +671,22 @@ const COpendriveRoadSegment& COpendriveRoad::operator[](std::size_t index) unsigned int COpendriveRoad::get_closest_node_index(TOpendriveWorldPose &pose,double &distance,double angle_tol) const { - double dist,min_dist=std::numeric_limits<double>::max(); + double dist,min_dist=std::numeric_limits<double>::max(),length; TOpendriveWorldPose closest_pose; unsigned int closest_index=-1; for(unsigned int i=0;i<this->nodes.size();i++) { - this->nodes[i]->get_closest_pose(pose,closest_pose,false,angle_tol); - dist=sqrt(pow(closest_pose.x-pose.x,2.0)+pow(closest_pose.y-pose.y,2.0)); - if(dist<min_dist) + length=this->nodes[i]->get_closest_pose(pose,closest_pose,false,angle_tol); + if(length<std::numeric_limits<double>::max()) { - min_dist=dist; - closest_index=i; + dist=sqrt(pow(closest_pose.x-pose.x,2.0)+pow(closest_pose.y-pose.y,2.0)); + if(dist<min_dist) + { + min_dist=dist; + closest_index=i; + distance=length; + } } } @@ -701,18 +705,22 @@ const COpendriveRoadNode &COpendriveRoad::get_closest_node(TOpendriveWorldPose & unsigned int COpendriveRoad::get_closest_lane_index(TOpendriveWorldPose &pose,double &distance,double angle_tol) const { - double dist,min_dist=std::numeric_limits<double>::max(); + double dist,min_dist=std::numeric_limits<double>::max(),length; TOpendriveWorldPose closest_pose; unsigned int closest_index=-1; for(unsigned int i=0;i<this->lanes.size();i++) { - this->lanes[i]->get_closest_pose(pose,closest_pose,angle_tol); - dist=sqrt(pow(closest_pose.x-pose.x,2.0)+pow(closest_pose.y-pose.y,2.0)); - if(dist<min_dist) - { - min_dist=dist; - closest_index=i; + length=this->lanes[i]->get_closest_pose(pose,closest_pose,angle_tol); + if(length<std::numeric_limits<double>::max()) + { + dist=sqrt(pow(closest_pose.x-pose.x,2.0)+pow(closest_pose.y-pose.y,2.0)); + if(dist<min_dist) + { + min_dist=dist; + closest_index=i; + distance=length; + } } } @@ -731,18 +739,22 @@ const COpendriveLane &COpendriveRoad::get_closest_lane(TOpendriveWorldPose &pose unsigned int COpendriveRoad::get_closest_segment_index(TOpendriveWorldPose &pose,double &distance,double angle_tol) const { - double dist,min_dist=std::numeric_limits<double>::max(); + double dist,min_dist=std::numeric_limits<double>::max(),length; TOpendriveWorldPose closest_pose; unsigned int closest_index=-1; for(unsigned int i=0;i<this->segments.size();i++) { - this->segments[i]->get_closest_pose(pose,closest_pose,angle_tol); - dist=sqrt(pow(closest_pose.x-pose.x,2.0)+pow(closest_pose.y-pose.y,2.0)); - if(dist<min_dist) - { - min_dist=dist; - closest_index=i; + length=this->segments[i]->get_closest_pose(pose,closest_pose,angle_tol); + if(length<std::numeric_limits<double>::max()) + { + dist=sqrt(pow(closest_pose.x-pose.x,2.0)+pow(closest_pose.y-pose.y,2.0)); + if(dist<min_dist) + { + min_dist=dist; + closest_index=i; + distance=length; + } } } @@ -768,12 +780,15 @@ double COpendriveRoad::get_closest_pose(TOpendriveWorldPose &pose,TOpendriveWorl for(unsigned int i=0;i<this->nodes.size();i++) { length=this->nodes[i]->get_closest_pose(pose,pose_found,false,angle_tol); - dist=sqrt(pow(pose_found.x-pose.x,2.0)+pow(pose_found.y-pose.y,2.0)); - if(dist<min_dist) + if(length<std::numeric_limits<double>::max()) { - min_dist=dist; - closest_pose=pose_found; - closest_length=length; + dist=sqrt(pow(pose_found.x-pose.x,2.0)+pow(pose_found.y-pose.y,2.0)); + if(dist<min_dist) + { + min_dist=dist; + closest_pose=pose_found; + closest_length=length; + } } } @@ -784,16 +799,28 @@ void COpendriveRoad::get_closest_poses(TOpendriveWorldPose &pose,std::vector<TOp { std::vector<TOpendriveWorldPose> poses; std::vector<double> lengths; + bool already_added; closest_poses.clear(); closest_lengths.clear(); for(unsigned int i=0;i<this->nodes.size();i++) { this->nodes[i]->get_closest_poses(pose,poses,lengths,dist_tol,false,angle_tol); - for(unsigned int j=0;j<poses.size();i++) + for(unsigned int j=0;j<poses.size();j++) { - closest_poses.push_back(poses[i]); - closest_lengths.push_back(lengths[i]); + already_added=false; + for(unsigned int k=0;k<closest_poses.size();k++) + if(fabs(closest_poses[k].x-poses[j].x)<this->resolution && + fabs(closest_poses[k].y-poses[j].y)<this->resolution) + { + already_added=true; + break; + } + if(!already_added) + { + closest_poses.push_back(poses[j]); + closest_lengths.push_back(lengths[j]); + } } } } diff --git a/src/opendrive_road_node.cpp b/src/opendrive_road_node.cpp index ee7d6df..bff1134 100644 --- a/src/opendrive_road_node.cpp +++ b/src/opendrive_road_node.cpp @@ -47,7 +47,7 @@ bool COpendriveRoadNode::add_link(COpendriveRoadNode *node,opendrive_mark_t mark double start_curvature,end_curvature; COpendriveLink *new_link; - if(this->has_link_with(node) || node->has_link_with(this)) + if(this->has_link_with(*node) || node->has_link_with(*this)) return false; new_link=new COpendriveLink(); new_link->set_prev(this); @@ -118,10 +118,10 @@ bool COpendriveRoadNode::has_link(COpendriveLink *link) return false; } -bool COpendriveRoadNode::has_link_with(COpendriveRoadNode *node) +bool COpendriveRoadNode::has_link_with(const COpendriveRoadNode &node) const { for(unsigned int i=0;i<this->links.size();i++) - if(this->links[i]->prev==this && this->links[i]->next==node) + if(this->links[i]->prev==this && this->links[i]->next==&node) return true; return false; @@ -325,7 +325,6 @@ void COpendriveRoadNode::update_end_pose(COpendriveLane *lane,TOpendriveWorldPos { std::vector<TOpendriveRoadNodeParent>::iterator parent_it; std::vector<COpendriveLink *>::iterator link_it; - TOpendriveRoadNodeParent *parent; // remove the references to all lanes and segments except for lane for(parent_it=this->parents.begin();parent_it!=this->parents.end();) @@ -333,10 +332,7 @@ void COpendriveRoadNode::update_end_pose(COpendriveLane *lane,TOpendriveWorldPos if(parent_it->lane!=lane) parent_it=this->parents.erase(parent_it); else - { - parent=&(*parent_it); parent_it++; - } } // update the links for(link_it=this->links.begin();link_it!=this->links.end();) @@ -438,22 +434,25 @@ unsigned int COpendriveRoadNode::get_closest_link(TOpendriveWorldPose &pose,doub { double dist,min_dist=std::numeric_limits<double>::max(); unsigned int closest_index=-1; - double angle; + double angle,length; TOpendriveWorldPose closest_pose; for(unsigned int i=0;i<this->links.size();i++) { if(&this->links[i]->get_prev()==this)// links starting at this node { - this->links[i]->find_closest_world_pose(pose,closest_pose); - angle=diff_angle(normalize_angle(pose.heading),closest_pose.heading); - if(fabs(angle)<angle_tol) + length=this->links[i]->find_closest_world_pose(pose,closest_pose); + if(length<std::numeric_limits<double>::max()) { - dist=sqrt(pow(closest_pose.x-pose.x,2.0)+pow(closest_pose.y-pose.y,2.0)); - if(dist<min_dist) + angle=diff_angle(normalize_angle(pose.heading),closest_pose.heading); + if(fabs(angle)<angle_tol) { - min_dist=dist; - closest_index=i; + dist=sqrt(pow(closest_pose.x-pose.x,2.0)+pow(closest_pose.y-pose.y,2.0)); + if(dist<min_dist) + { + min_dist=dist; + closest_index=i; + } } } } @@ -465,7 +464,7 @@ unsigned int COpendriveRoadNode::get_closest_link(TOpendriveWorldPose &pose,doub double COpendriveRoadNode::get_closest_distance(TOpendriveWorldPose &pose,bool only_lanes,double angle_tol)const { double dist,min_dist=std::numeric_limits<double>::max(); - double angle; + double angle,length; TOpendriveWorldPose closest_pose; for(unsigned int i=0;i<this->links.size();i++) @@ -474,13 +473,16 @@ double COpendriveRoadNode::get_closest_distance(TOpendriveWorldPose &pose,bool o { if(!only_lanes || (only_lanes && this->links[i]->lane!=NULL)) { - this->links[i]->find_closest_world_pose(pose,closest_pose); - angle=diff_angle(normalize_angle(pose.heading),closest_pose.heading); - if(fabs(angle)<angle_tol) + length=this->links[i]->find_closest_world_pose(pose,closest_pose); + if(length<std::numeric_limits<double>::max()) { - dist=sqrt(pow(closest_pose.x-pose.x,2.0)+pow(closest_pose.y-pose.y,2.0)); - if(dist<min_dist) - min_dist=dist; + angle=diff_angle(normalize_angle(pose.heading),closest_pose.heading); + if(fabs(angle)<angle_tol) + { + dist=sqrt(pow(closest_pose.x-pose.x,2.0)+pow(closest_pose.y-pose.y,2.0)); + if(dist<min_dist) + min_dist=dist; + } } } } @@ -506,15 +508,18 @@ double COpendriveRoadNode::get_closest_pose(TOpendriveWorldPose &pose,TOpendrive if(!only_lanes || (only_lanes && this->links[i]->lane!=NULL)) { length=this->links[i]->find_closest_world_pose(pose,tmp_pose); - angle=diff_angle(normalize_angle(pose.heading),tmp_pose.heading); - if(fabs(angle)<angle_tol) + if(length<std::numeric_limits<double>::max()) { - dist=sqrt(pow(tmp_pose.x-pose.x,2.0)+pow(tmp_pose.y-pose.y,2.0)); - if(dist<min_dist) + angle=diff_angle(normalize_angle(pose.heading),tmp_pose.heading); + if(fabs(angle)<angle_tol) { - min_dist=dist; - closest_length=length; - closest_pose=tmp_pose; + dist=sqrt(pow(tmp_pose.x-pose.x,2.0)+pow(tmp_pose.y-pose.y,2.0)); + if(dist<min_dist) + { + min_dist=dist; + closest_length=length; + closest_pose=tmp_pose; + } } } } @@ -530,6 +535,7 @@ void COpendriveRoadNode::get_closest_poses(TOpendriveWorldPose &pose,std::vector double angle; double length; TOpendriveWorldPose closest_pose; + bool already_added; closest_poses.clear(); closest_lengths.clear(); @@ -540,14 +546,28 @@ void COpendriveRoadNode::get_closest_poses(TOpendriveWorldPose &pose,std::vector if(!only_lanes || (only_lanes && this->links[i]->lane!=NULL)) { length=this->links[i]->find_closest_world_pose(pose,closest_pose); - angle=diff_angle(normalize_angle(pose.heading),closest_pose.heading); - if(fabs(angle)<angle_tol) + if(length<std::numeric_limits<double>::max()) { - dist=sqrt(pow(closest_pose.x-pose.x,2.0)+pow(closest_pose.y-pose.y,2.0)); - if(dist<=dist_tol) + angle=diff_angle(normalize_angle(pose.heading),closest_pose.heading); + if(fabs(angle)<angle_tol) { - closest_poses.push_back(closest_pose); - closest_lengths.push_back(length); + dist=sqrt(pow(closest_pose.x-pose.x,2.0)+pow(closest_pose.y-pose.y,2.0)); + if(dist<=dist_tol) + { + already_added=false; + for(unsigned int j=0;j<closest_poses.size();j++) + if(fabs(closest_poses[j].x-closest_pose.x)<this->resolution && + fabs(closest_poses[j].y-closest_pose.y)<this->resolution) + { + already_added=true; + break; + } + if(!already_added) + { + closest_poses.push_back(closest_pose); + closest_lengths.push_back(length); + } + } } } } diff --git a/src/opendrive_road_segment.cpp b/src/opendrive_road_segment.cpp index 6018639..c48d476 100644 --- a/src/opendrive_road_segment.cpp +++ b/src/opendrive_road_segment.cpp @@ -732,9 +732,7 @@ COpendriveRoadSegment *COpendriveRoadSegment::get_sub_segment(node_up_ref_t &new for(geom_it=new_segment->geometries.begin();geom_it!=new_segment->geometries.end();) { length=geom_it->spline->find_closest_point(start_pose->x,start_pose->y,new_point); - if(fabs(length-geom_it->spline->get_length())<this->resolution) - geom_it=new_segment->geometries.erase(geom_it); - else + if(length<std::numeric_limits<double>::max()) { geom_it->spline->set_start_point(new_point); geom_it->spline->generate(this->resolution); @@ -742,6 +740,8 @@ COpendriveRoadSegment *COpendriveRoadSegment::get_sub_segment(node_up_ref_t &new geom_it->opendrive->set_max_s(geom_it->opendrive->get_max_s()-length); break; } + else + geom_it=new_segment->geometries.erase(geom_it); } for(unsigned int i=1;i<new_segment->geometries.size();i++) { @@ -754,7 +754,7 @@ COpendriveRoadSegment *COpendriveRoadSegment::get_sub_segment(node_up_ref_t &new for(geom_it=new_segment->geometries.begin();geom_it!=new_segment->geometries.end();) { length=geom_it->spline->find_closest_point(end_pose->x,end_pose->y,new_point); - if(length<geom_it->spline->get_length()) + if(length<std::numeric_limits<double>::max()) { geom_it->spline->set_end_point(new_point); geom_it->spline->generate(this->resolution); @@ -1150,18 +1150,22 @@ TOpendriveWorldPose COpendriveRoadSegment::transform_to_world_pose(const TOpendr unsigned int COpendriveRoadSegment::get_closest_node_index(TOpendriveWorldPose &pose,double &distance,double angle_tol) const { - double dist,min_dist=std::numeric_limits<double>::max(); + double dist,min_dist=std::numeric_limits<double>::max(),length; TOpendriveWorldPose closest_pose; unsigned int closest_index=-1; for(unsigned int i=0;i<this->nodes.size();i++) { - this->nodes[i]->get_closest_pose(pose,closest_pose,false,angle_tol); - dist=sqrt(pow(closest_pose.x-pose.x,2.0)+pow(closest_pose.y-pose.y,2.0)); - if(dist<min_dist) + length=this->nodes[i]->get_closest_pose(pose,closest_pose,false,angle_tol); + if(length<std::numeric_limits<double>::max()) { - min_dist=dist; - closest_index=i; + dist=sqrt(pow(closest_pose.x-pose.x,2.0)+pow(closest_pose.y-pose.y,2.0)); + if(dist<min_dist) + { + min_dist=dist; + closest_index=i; + distance=length; + } } } @@ -1180,19 +1184,23 @@ const COpendriveRoadNode &COpendriveRoadSegment::get_closest_node(TOpendriveWorl int COpendriveRoadSegment::get_closest_lane_id(TOpendriveWorldPose &pose,double &distance,double angle_tol) const { - double dist,min_dist=std::numeric_limits<double>::max(); + double dist,min_dist=std::numeric_limits<double>::max(),length; TOpendriveWorldPose closest_pose; int closest_id=0; std::map<int,COpendriveLane *>::const_iterator lane_it; for(lane_it=this->lanes.begin();lane_it!=this->lanes.end();lane_it++) { - lane_it->second->get_closest_pose(pose,closest_pose,angle_tol); - dist=sqrt(pow(closest_pose.x-pose.x,2.0)+pow(closest_pose.y-pose.y,2.0)); - if(dist<min_dist) + length=lane_it->second->get_closest_pose(pose,closest_pose,angle_tol); + if(length<std::numeric_limits<double>::max()) { - min_dist=dist; - closest_id=lane_it->first; + dist=sqrt(pow(closest_pose.x-pose.x,2.0)+pow(closest_pose.y-pose.y,2.0)); + if(dist<min_dist) + { + min_dist=dist; + closest_id=lane_it->first; + distance=length; + } } } @@ -1209,7 +1217,7 @@ const COpendriveLane &COpendriveRoadSegment::get_closest_lane(TOpendriveWorldPos double COpendriveRoadSegment::get_closest_pose(TOpendriveWorldPose &pose,TOpendriveWorldPose &closest_pose,double angle_tol) const { - double dist,min_dist=std::numeric_limits<double>::max(),distance; + double dist,min_dist=std::numeric_limits<double>::max(),distance,length; unsigned int closest_index=-1; TPoint closest_spline_point; @@ -1218,22 +1226,30 @@ double COpendriveRoadSegment::get_closest_pose(TOpendriveWorldPose &pose,TOpendr closest_pose.heading=std::numeric_limits<double>::max(); for(unsigned int i=0;i<this->geometries.size();i++) { - this->geometries[i].spline->find_closest_point(pose.x,pose.y,closest_spline_point); - dist=sqrt(pow(closest_spline_point.x-pose.x,2.0)+pow(closest_spline_point.y-pose.y,2.0)); - if(dist<min_dist) + length=this->geometries[i].spline->find_closest_point(pose.x,pose.y,closest_spline_point); + if(length<std::numeric_limits<double>::max()) { - min_dist=dist; - closest_index=i; - closest_pose.x=closest_spline_point.x; - closest_pose.y=closest_spline_point.y; - closest_pose.heading=normalize_angle(closest_spline_point.heading); + dist=sqrt(pow(closest_spline_point.x-pose.x,2.0)+pow(closest_spline_point.y-pose.y,2.0)); + if(dist<min_dist) + { + min_dist=dist; + closest_index=i; + closest_pose.x=closest_spline_point.x; + closest_pose.y=closest_spline_point.y; + closest_pose.heading=normalize_angle(closest_spline_point.heading); + distance=length; + } } } - distance=0.0; - for(unsigned int i=0;i<closest_index;i++) - distance+=this->geometries[i].spline->get_length(); - distance+=min_dist; + if(closest_index!=(unsigned int)-1) + { + for(unsigned int i=0;i<closest_index;i++) + distance+=this->geometries[i].spline->get_length(); + distance+=min_dist; + } + else + distance=std::numeric_limits<double>::max(); return distance; } -- GitLab