diff --git a/include/opendrive_road_segment.h b/include/opendrive_road_segment.h
index fb263febcec659ee1675d451d9b074e7f6ff9a09..7a635d70b2e91bd11c9b80809a0c30df1ee18efb 100644
--- a/include/opendrive_road_segment.h
+++ b/include/opendrive_road_segment.h
@@ -63,17 +63,15 @@ class COpendriveRoadSegment
     void add_node(TOpendriveRoadSegmentGeometry &geometry,COpendriveLane *lane);
     void add_empty_node(TOpendriveWorldPose &pose,COpendriveLane *lane);
     void remove_node(COpendriveRoadNode *node);
-    bool has_node(COpendriveRoadNode *node);
-    int get_node_side(COpendriveRoadNode *node);
+    bool has_node(COpendriveRoadNode *node) const;
     void link_neightbour_lanes(lanes::laneSection_type &lane_section);
     void link_neightbour_lanes(void);
     void link_segment(COpendriveRoadSegment *segment);
     void link_segment(COpendriveRoadSegment *segment,int from,bool from_start, int to,bool to_start);
     bool connects_to(COpendriveRoadSegment *segment);
     bool connects_segments(COpendriveRoadSegment *segment1,COpendriveRoadSegment *segment2);
-    COpendriveRoadSegment *get_sub_segment(node_up_ref_t &new_node_ref,lane_up_ref_t &new_lane_ref,link_up_ref_t &new_link_ref,int node_side,TOpendriveWorldPose *start=NULL,TOpendriveWorldPose *end=NULL);
-    COpendriveRoadSegment *clone(node_up_ref_t &new_node_ref,lane_up_ref_t &new_lane_ref,link_up_ref_t &new_link_ref);
-    COpendriveRoadSegment *get_next_segment(int &side);
+    COpendriveRoadSegment *get_sub_segment(node_up_ref_t &new_node_ref,lane_up_ref_t &new_lane_ref,link_up_ref_t &new_link_ref,int node_side,TOpendriveWorldPose *start=NULL,TOpendriveWorldPose *end=NULL) const;
+    COpendriveRoadSegment *clone(node_up_ref_t &new_node_ref,lane_up_ref_t &new_lane_ref,link_up_ref_t &new_link_ref) const;
   public:
     std::string get_name(void) const;
     unsigned int get_id(void) const;
@@ -89,16 +87,19 @@ class COpendriveRoadSegment
     const COpendriveObject &get_object(unsigned int index) const;
     unsigned int get_num_connecting(void) const;
     const COpendriveRoadSegment &get_connecting(unsigned int index) const;
-    double get_length(void);
-    TOpendriveWorldPose get_pose_at(double length);
-    double get_curvature_at(double length);
+    double get_length(void) const;
+    TOpendriveWorldPose get_pose_at(double length) const;
+    double get_curvature_at(double length) const;
     TOpendriveLocalPose transform_to_local_pose(const TOpendriveTrackPose &track);
     TOpendriveWorldPose transform_to_world_pose(const TOpendriveTrackPose &track);
     const COpendriveRoadNode &get_closest_node(TOpendriveWorldPose &pose,double &distance,double angle_tol=0.1) const;
     unsigned int get_closest_node_index(TOpendriveWorldPose &pose,double &distance,double angle_tol=0.1) const;
-    const COpendriveLane &get_closest_lane(TOpendriveWorldPose &pose,double &distance,double angle_tol=0.1);
+    const COpendriveLane &get_closest_lane(TOpendriveWorldPose &pose,double &distance,double angle_tol=0.1) const;
     int get_closest_lane_id(TOpendriveWorldPose &pose,double &distance,double angle_tol=0.1) const;
     double get_closest_pose(TOpendriveWorldPose &pose,TOpendriveWorldPose &closest_pose,double angle_tol=0.1) const;
+    const COpendriveRoadSegment &get_next_segment(int &side,bool &valid) const;
+    const COpendriveRoadSegment &get_prev_segment(int &side,bool &valid) const;
+    int get_pose_side(TOpendriveWorldPose &pose) const;
     friend std::ostream& operator<<(std::ostream& out, COpendriveRoadSegment &segment);
     ~COpendriveRoadSegment();
 };
diff --git a/src/opendrive_road_segment.cpp b/src/opendrive_road_segment.cpp
index c48d4765bccadfad4a915da4f8b0d61d767a144b..41e6f6b312e67834399f50da5efe05827ea754f4 100644
--- a/src/opendrive_road_segment.cpp
+++ b/src/opendrive_road_segment.cpp
@@ -521,7 +521,7 @@ void COpendriveRoadSegment::remove_node(COpendriveRoadNode *node)
   }
 }
 
-bool COpendriveRoadSegment::has_node(COpendriveRoadNode *node)
+bool COpendriveRoadSegment::has_node(COpendriveRoadNode *node) const
 {
   for(unsigned int i=0;i<this->nodes.size();i++)
     if(this->nodes[i]==node)
@@ -530,25 +530,20 @@ bool COpendriveRoadSegment::has_node(COpendriveRoadNode *node)
   return false;
 }
 
-int COpendriveRoadSegment::get_node_side(COpendriveRoadNode *node)
+int COpendriveRoadSegment::get_pose_side(TOpendriveWorldPose &pose) const
 {
-  std::map<int,COpendriveLane *>::iterator it;
+  const COpendriveRoadNode *node;
+  std::map<int,COpendriveLane *>::const_iterator it;
   std::stringstream error;
+  double distance;
 
-  if(this->has_node(node))
-  {
-    for(it=this->lanes.begin();it!=this->lanes.end();it++)
-      if(it->second->has_node(node))
-        return it->first;
+  node=&this->get_closest_node(pose,distance,3.14159);
+  for(it=this->lanes.begin();it!=this->lanes.end();it++)
+    if(it->second->has_node((COpendriveRoadNode *)node))
+      return it->first;
 
-    error << "Segment " << this->name << " does not include node " << node->get_index();
-    throw CException(_HERE_,error.str());
-  }
-  else
-  {
-    error << "Segment " << this->name << " does not include node " << node->get_index();
-    throw CException(_HERE_,error.str());
-  }
+  error << "Segment " << this->name << " does not include node " << node->get_index();
+  throw CException(_HERE_,error.str());
 }
 
 void COpendriveRoadSegment::link_neightbour_lanes(lanes::laneSection_type &lane_section)
@@ -690,7 +685,7 @@ bool COpendriveRoadSegment::connects_segments(COpendriveRoadSegment *segment1,CO
     return false;
 }
 
-COpendriveRoadSegment *COpendriveRoadSegment::get_sub_segment(node_up_ref_t &new_node_ref,lane_up_ref_t &new_lane_ref,link_up_ref_t &new_link_ref,int node_side,TOpendriveWorldPose *start,TOpendriveWorldPose *end)
+COpendriveRoadSegment *COpendriveRoadSegment::get_sub_segment(node_up_ref_t &new_node_ref,lane_up_ref_t &new_lane_ref,link_up_ref_t &new_link_ref,int node_side,TOpendriveWorldPose *start,TOpendriveWorldPose *end) const
 {
   TOpendriveWorldPose *start_pose,*end_pose;
   std::map<int,COpendriveLane *>::iterator lane_it;
@@ -708,7 +703,7 @@ COpendriveRoadSegment *COpendriveRoadSegment::get_sub_segment(node_up_ref_t &new
   if(start==NULL && end==NULL)
     return this->clone(new_node_ref,new_lane_ref,new_link_ref);
   new_segment=new COpendriveRoadSegment(*this);
-  new_segment_ref[this]=new_segment;
+  new_segment_ref[(COpendriveRoadSegment *)this]=new_segment;
   if(node_side<0)
   {
     start_pose=start;
@@ -770,7 +765,7 @@ COpendriveRoadSegment *COpendriveRoadSegment::get_sub_segment(node_up_ref_t &new
   return new_segment; 
 }
 
-COpendriveRoadSegment *COpendriveRoadSegment::clone(node_up_ref_t &new_node_ref,lane_up_ref_t &new_lane_ref,link_up_ref_t &new_link_ref)
+COpendriveRoadSegment *COpendriveRoadSegment::clone(node_up_ref_t &new_node_ref,lane_up_ref_t &new_lane_ref,link_up_ref_t &new_link_ref) const
 {
   std::map<int,COpendriveLane *>::iterator lane_it;
   lane_up_ref_t::iterator lane_ref_it;
@@ -781,7 +776,7 @@ COpendriveRoadSegment *COpendriveRoadSegment::clone(node_up_ref_t &new_node_ref,
   node_up_ref_t::iterator node_ref_it;
 
   new_segment=new COpendriveRoadSegment(*this);
-  new_segment_ref[this]=new_segment;
+  new_segment_ref[(COpendriveRoadSegment *)this]=new_segment;
   /* get the sublanes */
   for(lane_it=new_segment->lanes.begin();lane_it!=new_segment->lanes.end();lane_it++)
   {
@@ -793,7 +788,7 @@ COpendriveRoadSegment *COpendriveRoadSegment::clone(node_up_ref_t &new_node_ref,
   return new_segment;
 }
 
-COpendriveRoadSegment *COpendriveRoadSegment::get_next_segment(int &side)
+const COpendriveRoadSegment &COpendriveRoadSegment::get_next_segment(int &side,bool &valid) const
 {
   std::vector<COpendriveRoadSegment *> segment_candidates;
   std::vector<int> side_candidates;
@@ -848,16 +843,90 @@ COpendriveRoadSegment *COpendriveRoadSegment::get_next_segment(int &side)
     }
   }
   if(segment_candidates.size()==0)
-    return NULL;
+  {
+    valid=false;
+    return *this;
+  }
+  else if(segment_candidates.size()>1)
+    throw CException(_HERE_,"Road has multiple paths and no unique subroad exists");
+  else
+  {
+    valid=true;
+    side=side_candidates[0];
+    return *segment_candidates[0];
+  }
+}
+
+const COpendriveRoadSegment &COpendriveRoadSegment::get_prev_segment(int &side,bool &valid) const
+{
+  std::vector<COpendriveRoadSegment *> segment_candidates;
+  std::vector<int> side_candidates;
+  bool already_present;
+
+  if(side<0)
+  {
+    for(unsigned int i=1;i<=this->get_num_right_lanes();i++)
+    {
+      const COpendriveLane &lane=this->get_lane(-i);
+      if(lane.get_num_prev_lanes()>1)
+        throw CException(_HERE_,"Road has multiple paths and no unique subroad exists");
+      if(lane.get_num_prev_lanes()==1)
+      {
+        already_present=false;
+        for(unsigned int k=0;k<segment_candidates.size();k++)
+          if(segment_candidates[k]==lane.get_prev_lane(0).segment)
+          {
+            already_present=true;
+            break;
+          }
+        if(!already_present)
+        {
+          segment_candidates.push_back(lane.get_prev_lane(0).segment);
+          side_candidates.push_back(lane.get_prev_lane(0).get_id());
+        }
+      }
+    }
+  }
+  else
+  {
+    for(unsigned int i=1;i<=this->get_num_left_lanes();i++)
+    {
+      const COpendriveLane &lane=this->get_lane(i);
+      if(lane.get_num_prev_lanes()>1)
+        throw CException(_HERE_,"Road has multiple paths and no unique subroad exists");
+      if(lane.get_num_prev_lanes()==1)
+      {
+        already_present=false;
+        for(unsigned int k=0;k<segment_candidates.size();k++)
+          if(segment_candidates[k]==lane.get_prev_lane(0).segment)
+          {
+            already_present=true;
+            break;
+          }
+        if(!already_present)
+        {
+          segment_candidates.push_back(lane.get_prev_lane(0).segment);
+          side_candidates.push_back(lane.get_prev_lane(0).get_id());
+        }
+      }
+    }
+  }
+  if(segment_candidates.size()==0)
+  {
+    valid=false;
+    return *this;
+  }
   else if(segment_candidates.size()>1)
     throw CException(_HERE_,"Road has multiple paths and no unique subroad exists");
   else
   {
+    valid=true;
     side=side_candidates[0];
-    return segment_candidates[0];
+    return *segment_candidates[0];
   }
 }
 
+
 void COpendriveRoadSegment::load(OpenDRIVE::road_type &road_info)
 {
   std::map<int,COpendriveLane *>::const_iterator lane_it;
@@ -1034,17 +1103,17 @@ const COpendriveRoadSegment &COpendriveRoadSegment::get_connecting(unsigned int
   }
 }
 
-double COpendriveRoadSegment::get_length(void)
+double COpendriveRoadSegment::get_length(void) const
 {
   double length=0.0;
 
   for(unsigned int i=0;i<this->geometries.size();i++)
-    length+=this->geometries[i].opendrive->get_length();
+    length+=this->geometries[i].spline->get_length();
 
   return length;
 }
 
-TOpendriveWorldPose COpendriveRoadSegment::get_pose_at(double length)
+TOpendriveWorldPose COpendriveRoadSegment::get_pose_at(double length) const
 {
   TOpendriveWorldPose world_pose{0};
   TPoint spline_pose;
@@ -1066,7 +1135,7 @@ TOpendriveWorldPose COpendriveRoadSegment::get_pose_at(double length)
   return world_pose;
 }
 
-double COpendriveRoadSegment::get_curvature_at(double length)
+double COpendriveRoadSegment::get_curvature_at(double length) const
 {
   double curvature;
   TPoint spline_pose;
@@ -1207,12 +1276,18 @@ int COpendriveRoadSegment::get_closest_lane_id(TOpendriveWorldPose &pose,double
   return closest_id;
 }
 
-const COpendriveLane &COpendriveRoadSegment::get_closest_lane(TOpendriveWorldPose &pose,double &distance,double angle_tol) 
+const COpendriveLane &COpendriveRoadSegment::get_closest_lane(TOpendriveWorldPose &pose,double &distance,double angle_tol) const
 {
+  std::map<int,COpendriveLane *>::const_iterator lane_it;
+
   int closest_id=this->get_closest_lane_id(pose,distance,angle_tol);
   if(closest_id==0)
     throw CException(_HERE_,"Impossible to find the closest lane");
-  return *this->lanes[closest_id];
+  for(lane_it=this->lanes.begin();lane_it!=this->lanes.end();lane_it++)
+    if(lane_it->first==closest_id)
+      return *lane_it->second;
+
+  throw CException(_HERE_,"Impossible to find the closest lane");
 }
 
 double COpendriveRoadSegment::get_closest_pose(TOpendriveWorldPose &pose,TOpendriveWorldPose &closest_pose,double angle_tol) const
@@ -1246,7 +1321,6 @@ double COpendriveRoadSegment::get_closest_pose(TOpendriveWorldPose &pose,TOpendr
   {
     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();