From b44f59c738424648b52c22a663e2f3a36797fbe8 Mon Sep 17 00:00:00 2001 From: Sergi Hernandez Juan <shernand@iri.upc.edu> Date: Wed, 30 Dec 2020 15:56:24 +0100 Subject: [PATCH] Added functions to get the pose of signals and objects in local and world coordinates. --- include/opendrive_lane.h | 2 + include/opendrive_road_segment.h | 6 ++- src/opendrive_lane.cpp | 54 +++++++++++++++++++ src/opendrive_road_segment.cpp | 89 +++++++++++++++++++++++--------- 4 files changed, 127 insertions(+), 24 deletions(-) diff --git a/include/opendrive_lane.h b/include/opendrive_lane.h index 8e461aa..7873c75 100644 --- a/include/opendrive_lane.h +++ b/include/opendrive_lane.h @@ -48,6 +48,8 @@ class COpendriveLane TOpendriveWorldPoint get_start_point(void); TOpendriveWorldPoint get_end_point(void); double get_length(void); + TOpendriveLocalPoint transform_to_local_point(TOpendriveTrackPoint &track); + TOpendriveWorldPoint transform_to_world_point(TOpendriveTrackPoint &track); friend std::ostream& operator<<(std::ostream& out, COpendriveLane &lane); ~COpendriveLane(); }; diff --git a/include/opendrive_road_segment.h b/include/opendrive_road_segment.h index 51f15de..5834478 100644 --- a/include/opendrive_road_segment.h +++ b/include/opendrive_road_segment.h @@ -12,6 +12,8 @@ class COpendriveLane; class COpendriveRoad; +class COpendriveSignal; +class COpendriveObject; class COpendriveRoadSegment { @@ -53,10 +55,12 @@ class COpendriveRoadSegment const COpendriveRoad &get_parent_road(void) const; unsigned int get_num_signals(void) const; const COpendriveSignal &get_signal(unsigned int index) const; - unsigned int get_num_obstacles(void) const; + unsigned int get_num_objects(void) const; const COpendriveObject &get_object(unsigned int index) const; unsigned int get_num_connecting(void) const; const COpendriveRoadSegment &get_connecting(unsigned int index) const; + TOpendriveLocalPoint transform_to_local_point(const TOpendriveTrackPoint &track); + TOpendriveWorldPoint transform_to_world_point(const TOpendriveTrackPoint &track); friend std::ostream& operator<<(std::ostream& out, COpendriveRoadSegment &segment); ~COpendriveRoadSegment(); }; diff --git a/src/opendrive_lane.cpp b/src/opendrive_lane.cpp index 491758f..afa462d 100644 --- a/src/opendrive_lane.cpp +++ b/src/opendrive_lane.cpp @@ -309,6 +309,60 @@ double COpendriveLane::get_length(void) return length; } +TOpendriveLocalPoint COpendriveLane::transform_to_local_point(TOpendriveTrackPoint &track) +{ + TOpendriveLocalPoint local; + + if(track.s<0.0) + throw CException(_HERE_,"Invalid track point"); + for(unsigned int i=0;i<this->nodes.size();i++) + { + for(unsigned int j=0;j<this->nodes[i]->get_num_lanes();j++) + { + if(this->nodes[i]->get_lane(j).get_id()==this->id) + { + if(track.s<=this->nodes[i]->get_geometry(j).get_length()) + { + if(!this->nodes[i]->get_geometry(j).get_local_pose(track,local)) + throw CException(_HERE_,"Impossible to transform to local coordinates"); + return local; + } + else + track.s-=this->nodes[i]->get_geometry(j).get_length(); + } + } + } + + throw CException(_HERE_,"Track point does not belong to lane"); +} + +TOpendriveWorldPoint COpendriveLane::transform_to_world_point(TOpendriveTrackPoint &track) +{ + TOpendriveWorldPoint world; + + if(track.s<0.0) + throw CException(_HERE_,"Invalid track point"); + for(unsigned int i=0;i<this->nodes.size();i++) + { + for(unsigned int j=0;j<this->nodes[i]->get_num_lanes();j++) + { + if(this->nodes[i]->get_lane(j).get_id()==this->id) + { + if(track.s<=this->nodes[i]->get_geometry(j).get_length()) + { + if(!this->nodes[i]->get_geometry(j).get_world_pose(track,world)) + throw CException(_HERE_,"Impossible to transform to world coordinates"); + return world; + } + else + track.s-=this->nodes[i]->get_geometry(j).get_length(); + } + } + } + + throw CException(_HERE_,"Track point does not belong to lane"); +} + std::ostream& operator<<(std::ostream& out, COpendriveLane &lane) { out << " Lane: " << lane.id << " (offset: " << lane.offset << ")" << std::endl; diff --git a/src/opendrive_road_segment.cpp b/src/opendrive_road_segment.cpp index 737342d..a1370fe 100644 --- a/src/opendrive_road_segment.cpp +++ b/src/opendrive_road_segment.cpp @@ -100,6 +100,10 @@ void COpendriveRoadSegment::set_scale_factor(double scale) for(lane_it=this->lanes.begin();lane_it!=this->lanes.end();++lane_it) lane_it->second->set_scale_factor(scale); + for(unsigned int i=0;i<this->signals.size();i++) + this->signals[i]->set_scale_factor(scale); + for(unsigned int i=0;i<this->objects.size();i++) + this->objects[i]->set_scale_factor(scale); } void COpendriveRoadSegment::set_min_road_length(double length) @@ -116,6 +120,10 @@ void COpendriveRoadSegment::update_references(std::map<COpendriveRoadSegment *,C { for(unsigned int i=0;i<this->connecting.size();i++) this->connecting[i]=segment_refs[this->connecting[i]]; + for(unsigned int i=0;i<this->signals.size();i++) + this->signals[i]->update_references(segment_refs); + for(unsigned int i=0;i<this->objects.size();i++) + this->objects[i]->update_references(segment_refs); } void COpendriveRoadSegment::add_lanes(lanes::laneSection_type &lane_section) @@ -123,6 +131,7 @@ void COpendriveRoadSegment::add_lanes(lanes::laneSection_type &lane_section) right::lane_iterator r_lane_it; left::lane_iterator l_lane_it; COpendriveLane *new_lane; + std::stringstream text; // right lanes if(lane_section.right().present()) @@ -137,7 +146,8 @@ void COpendriveRoadSegment::add_lanes(lanes::laneSection_type &lane_section) this->lanes[new_lane->get_id()]=new_lane; this->num_right_lanes++; }catch(CException &e){ - std::cout << e.what() << std::endl; + text << e.what() << " in road " << this->name; + throw CException(_HERE_,text.str()); } } } @@ -154,7 +164,8 @@ void COpendriveRoadSegment::add_lanes(lanes::laneSection_type &lane_section) this->lanes[new_lane->get_id()]=new_lane; this->num_left_lanes++; }catch(CException &e){ - std::cout << e.what() << std::endl; + text << e.what() << " in road " << this->name; + throw CException(_HERE_,text.str()); } } } @@ -397,30 +408,37 @@ void COpendriveRoadSegment::load(OpenDRIVE::road_type &road_info) lane_section=road_info.lanes().laneSection().begin(); // add lanes - this->add_lanes(*lane_section); - // add road nodes - this->add_nodes(road_info); - // link lanes - this->link_neightbour_lanes(*lane_section); - // add road signals - if(road_info.signals().present()) - { - for(signal_it=road_info.signals().get().signal().begin();signal_it!=road_info.signals().get().signal().end();++signal_it) + try{ + this->add_lanes(*lane_section); + // add road nodes + this->add_nodes(road_info); + // link lanes + this->link_neightbour_lanes(*lane_section); + // add road signals + if(road_info.signals().present()) { - new_signal=new COpendriveSignal(); - new_signal->load(*signal_it); - this->signals.push_back(new_signal); + for(signal_it=road_info.signals().get().signal().begin();signal_it!=road_info.signals().get().signal().end();++signal_it) + { + new_signal=new COpendriveSignal(); + new_signal->load(*signal_it,this); + new_signal->set_scale_factor(this->scale_factor); + this->signals.push_back(new_signal); + } } - } - // add road objects - if(road_info.objects().present()) - { - for(object_it=road_info.objects().get().object().begin();object_it!=road_info.objects().get().object().end();++object_it) + // add road objects + if(road_info.objects().present()) { - new_object=new COpendriveObject(); - new_object->load(*object_it); - this->objects.push_back(new_object); + for(object_it=road_info.objects().get().object().begin();object_it!=road_info.objects().get().object().end();++object_it) + { + new_object=new COpendriveObject(); + new_object->load(*object_it,this); + new_object->set_scale_factor(this->scale_factor); + this->objects.push_back(new_object); + } } + }catch(CException &e){ + this->free(); + throw e; } } @@ -474,7 +492,7 @@ const COpendriveSignal &COpendriveRoadSegment::get_signal(unsigned int index) co throw CException(_HERE_,"Invalid signal index"); } -unsigned int COpendriveRoadSegment::get_num_obstacles(void) const +unsigned int COpendriveRoadSegment::get_num_objects(void) const { return this->objects.size(); } @@ -500,6 +518,31 @@ const COpendriveRoadSegment &COpendriveRoadSegment::get_connecting(unsigned int throw CException(_HERE_,"Invalid connecting segment index"); } +TOpendriveLocalPoint COpendriveRoadSegment::transform_to_local_point(const TOpendriveTrackPoint &track) +{ + +} + +TOpendriveWorldPoint COpendriveRoadSegment::transform_to_world_point(const TOpendriveTrackPoint &track) +{ + TOpendriveTrackPoint point; + TOpendriveWorldPoint world; + + if(track.s<0.0) + throw CException(_HERE_,"Invalid track point"); + point=track; + if(this->num_right_lanes>0) + world=this->lanes[-1]->transform_to_world_point(point); + else + { + point.s=this->lanes[1]->get_length()-track.s; + point.heading=normalize_angle(track.heading+3.14159); + world=this->lanes[1]->transform_to_world_point(point); + } + + return world; +} + std::ostream& operator<<(std::ostream& out, COpendriveRoadSegment &segment) { out << "Road " << segment.get_name() << " (" << segment.get_id() << ")" << std::endl; -- GitLab