diff --git a/include/opendrive_link.h b/include/opendrive_link.h index fe015f02b3e7f79dd58d26620b0951b577a5ec4d..0ea31cc51ddeab6aa6ec858c09297a8376ff9430 100644 --- a/include/opendrive_link.h +++ b/include/opendrive_link.h @@ -1,20 +1,24 @@ #ifndef _OPENDRIVE_LINK_H #define _OPENDRIVE_LINK_H +#include "opendrive_common.h" #include "g2_spline.h" #include "opendrive_line.h" #include "opendrive_spiral.h" #include "opendrive_arc.h" #include "opendrive_param_poly3.h" - -class COpendriveRoadNode; +#include "opendrive_road_node.h" class COpendriveLink { + friend class COpendriveRoadSegment; friend class COpendriveRoadNode; + friend class COpendriveRoad; private: COpendriveRoadNode *prev; COpendriveRoadNode *next; + COpendriveRoadSegment *segment; + COpendriveLane *lane; CG2Spline *spline; opendrive_mark_t mark; double resolution; @@ -25,14 +29,21 @@ class COpendriveLink void set_prev(COpendriveRoadNode *node); void set_next(COpendriveRoadNode *node); void set_road_mark(opendrive_mark_t mark); + void set_parent_segment(COpendriveRoadSegment *segment); + void set_parent_lane(COpendriveLane *lane); void set_resolution(double res); void set_scale_factor(double scale); void generate(double start_curvature,double end_curvature,double length,bool lane); - void update_references(std::map<COpendriveRoadNode *,COpendriveRoadNode *> refs); + void update_references(segment_up_ref_t &segment_refs,lane_up_ref_t &lanei_refs,node_up_ref_t &node_refs); + bool clean_references(node_up_ref_t &refs); + void update_start_pose(TOpendriveWorldPoint *start=NULL); + void update_end_pose(TOpendriveWorldPoint *end=NULL); public: const COpendriveRoadNode &get_prev(void) const; const COpendriveRoadNode &get_next(void) const; opendrive_mark_t get_road_mark(void) const; + const COpendriveRoadSegment &get_parent_segment(void) const; + const COpendriveLane &get_parent_lane(void) const; double get_resolution(void) const; double get_scale_factor(void) const; double find_closest_world_point(TOpendriveWorldPoint &world,TPoint &point); diff --git a/src/opendrive_link.cpp b/src/opendrive_link.cpp index 6ded7614b285b23a92ed38ca47bb0b210d6940f5..14dbf64737142e18ac6a93eda6df8917e40c791c 100644 --- a/src/opendrive_link.cpp +++ b/src/opendrive_link.cpp @@ -5,6 +5,8 @@ COpendriveLink::COpendriveLink() { this->prev=NULL; this->next=NULL; + this->segment=NULL; + this->lane=NULL; this->spline=NULL; this->mark=OD_MARK_NONE; this->resolution=DEFAULT_RESOLUTION; @@ -15,6 +17,8 @@ COpendriveLink::COpendriveLink(const COpendriveLink &object) { this->prev=object.prev; this->next=object.next; + this->segment=object.segment; + this->lane=object.lane; this->spline=new CG2Spline(*object.spline); this->mark=object.mark; this->resolution=object.resolution; @@ -36,6 +40,16 @@ void COpendriveLink::set_road_mark(opendrive_mark_t mark) this->mark=mark; } +void COpendriveLink::set_parent_segment(COpendriveRoadSegment *segment) +{ + this->segment=segment; +} + +void COpendriveLink::set_parent_lane(COpendriveLane *lane) +{ + this->lane=lane; +} + void COpendriveLink::set_resolution(double res) { this->resolution=res; @@ -65,10 +79,55 @@ void COpendriveLink::generate(double start_curvature,double end_curvature,double this->spline->generate(this->resolution,length); } -void COpendriveLink::update_references(std::map<COpendriveRoadNode *,COpendriveRoadNode *> refs) +void COpendriveLink::update_references(segment_up_ref_t &segment_refs,lane_up_ref_t &lane_refs,node_up_ref_t &node_refs) +{ + if(node_refs.find(this->prev)!=node_refs.end()) + this->prev=node_refs[this->prev]; + if(node_refs.find(this->next)!=node_refs.end()) + this->next=node_refs[this->next]; + if(segment_refs.find(this->segment)!=segment_refs.end()) + this->segment=segment_refs[this->segment]; + if(lane_refs.find(this->lane)!=lane_refs.end()) + this->lane=lane_refs[this->lane]; +} + +bool COpendriveLink::clean_references(node_up_ref_t &refs) +{ + if(refs.find(this->prev)!=refs.end()) + this->prev=refs[this->prev]; + else if(!this->prev->updated(refs)) + return true; + if(refs.find(this->next)!=refs.end()) + this->next=refs[this->next]; + else if(!this->next->updated(refs)) + return true; + + return false; +} + +void COpendriveLink::update_start_pose(TOpendriveWorldPoint *start) +{ + TPoint spline_start; + double length; + + if(start==NULL) + return; + length=this->find_closest_world_point(*start,spline_start); + length=this->spline->get_length()-length; + this->spline->set_start_point(spline_start); + this->spline->generate(this->resolution,length); +} + +void COpendriveLink::update_end_pose(TOpendriveWorldPoint *end) { - this->prev=refs[this->prev]; - this->next=refs[this->next]; + TPoint spline_end; + double length; + + if(end==NULL) + return; + length=this->find_closest_world_point(*end,spline_end); + this->spline->set_end_point(spline_end); + this->spline->generate(this->resolution,length); } const COpendriveRoadNode &COpendriveLink::get_prev(void) const @@ -86,6 +145,16 @@ opendrive_mark_t COpendriveLink::get_road_mark(void) const return this->mark; } +const COpendriveRoadSegment &COpendriveLink::get_parent_segment(void) const +{ + return *this->segment; +} + +const COpendriveLane &COpendriveLink::get_parent_lane(void) const +{ + return *this->lane; +} + double COpendriveLink::get_resolution(void) const { return this->resolution; @@ -101,7 +170,10 @@ double COpendriveLink::find_closest_world_point(TOpendriveWorldPoint &world,TPoi double length; if(this->spline!=NULL) + { length=this->spline->find_closest_point(world.x,world.y,point); + point.heading=normalize_angle(point.heading); + } else length=std::numeric_limits<double>::max(); @@ -160,8 +232,8 @@ double COpendriveLink::get_length(void) const std::ostream& operator<<(std::ostream& out, COpendriveLink &link) { - out << " Previous node: " << link.get_prev().get_index() << " of road " << link.get_prev().get_parent_segment().get_name() << std::endl; - out << " Next node: " << link.get_next().get_index() << " of road " << link.get_next().get_parent_segment().get_name() << std::endl; + out << " Previous node: " << link.get_prev().get_index() << std::endl; + out << " Next node: " << link.get_next().get_index() << std::endl; out << " Road mark: "; switch(link.get_road_mark()) { @@ -195,6 +267,8 @@ COpendriveLink::~COpendriveLink() { this->prev=NULL; this->next=NULL; + this->segment=NULL; + this->lane=NULL; if(this->spline!=NULL) { delete this->spline;