diff --git a/include/opendrive_road.h b/include/opendrive_road.h
index 5896723aa29fe89c8aa23162b22c401e27a587c7..70736390774e5a71849852d64f09ea9740516606 100644
--- a/include/opendrive_road.h
+++ b/include/opendrive_road.h
@@ -66,7 +66,7 @@ class COpendriveRoad
     double get_closest_pose(TOpendriveWorldPose &pose,TOpendriveWorldPose &closest_pose,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,double angle_tol=0.1) const;
     std::vector<unsigned int> get_sub_road(std::vector<unsigned int> &path_nodes,TOpendriveWorldPose &start_pose,TOpendriveWorldPose &end_pose,COpendriveRoad &new_road);
-    void get_sub_road(TOpendriveWorldPose &start_pose,double &length,COpendriveRoad &new_road);
+    void get_sub_road(TOpendriveWorldPose &start_pose,double &length,double margin,COpendriveRoad &new_road);
     void operator=(const COpendriveRoad& object);
     friend std::ostream& operator<<(std::ostream& out, COpendriveRoad &road);
     ~COpendriveRoad();
diff --git a/src/opendrive_road.cpp b/src/opendrive_road.cpp
index 42a9a77a2e4fbac46f958e6c1eab6ea52759e1ad..486084a0a2bbe21e54cb2b2a717b0531abd5095e 100644
--- a/src/opendrive_road.cpp
+++ b/src/opendrive_road.cpp
@@ -907,66 +907,154 @@ std::vector<unsigned int> COpendriveRoad::get_sub_road(std::vector<unsigned int>
   return new_road.update_path(new_node_ref,path_nodes);
 }
 
-void COpendriveRoad::get_sub_road(TOpendriveWorldPose &start_pose,double &length,COpendriveRoad &new_road)
+void COpendriveRoad::get_sub_road(TOpendriveWorldPose &start_pose,double &length,double margin,COpendriveRoad &new_road)
 {
   segment_up_ref_t new_segment_ref;
   lane_up_ref_t new_lane_ref;
   node_up_ref_t new_node_ref;
   link_up_ref_t new_link_ref;
-  unsigned int segment_index,node_index;
-  TOpendriveWorldPose end_pose;
-  COpendriveRoadSegment *segment,*new_segment,*next_segment;
-  COpendriveRoadNode *node;
-  double rem_length=length,distance,start_length;
+  unsigned int segment_index;
+  TOpendriveWorldPose end_pose,int_pose;
+  const COpendriveRoadSegment *segment,*next_segment;
+  COpendriveRoadSegment *new_segment;
+  double rem_length=length+2.0*margin,distance,start_length;
   int node_side;
+  bool valid;
 
   new_road.free();
   new_road.set_resolution(this->resolution);
   new_road.set_scale_factor(this->scale_factor);
   new_road.set_min_road_length(this->min_road_length);
-  node_index=this->get_closest_node_index(start_pose,distance);
-  if(node_index==(unsigned int)-1)
-    throw CException(_HERE_,"Start position does not belang to the road");
-  node=this->nodes[node_index];
+  // get the first segment
   segment_index=this->get_closest_segment_index(start_pose,distance);
   if(segment_index==(unsigned int)-1)
-    throw CException(_HERE_,"Start position does not belang to the road");
+    throw CException(_HERE_,"Start position does not belong to the road");
   segment=this->segments[segment_index];
-  node_side=segment->get_node_side(node);
-  new_segment=segment->get_sub_segment(new_node_ref,new_lane_ref,new_link_ref,node_side,&start_pose,NULL);
-  start_length=new_segment->get_length()-distance;
-  if(rem_length<start_length)
+  node_side=segment->get_pose_side(start_pose);
+  if(margin>0.0)
   {
     if(node_side<0)
-      end_pose=new_segment->get_pose_at(rem_length);
+    {
+      rem_length=distance-margin;
+      if(rem_length<0.0)// get the previous segment
+      {
+        next_segment=&segment->get_prev_segment(node_side,valid);
+        if(valid)
+        {
+          segment=next_segment;
+          if(node_side<0)
+          {
+            int_pose=segment->get_pose_at(segment->get_length()+rem_length);
+            distance=segment->get_length()+rem_length;
+          }
+          else
+          {
+            int_pose=segment->get_pose_at(-rem_length);
+            distance=-rem_length;
+          }
+        }
+        else
+        {
+          int_pose=segment->get_pose_at(0.0);
+          distance=0.0;
+        }
+      }
+      else
+      {
+        int_pose=segment->get_pose_at(rem_length);
+        distance-=margin;
+      }
+    }
     else
-      end_pose=new_segment->get_pose_at(new_segment->get_length()-rem_length);
-    segment=new_segment;
-    new_segment=segment->get_sub_segment(new_node_ref,new_lane_ref,new_link_ref,node_side,NULL,&end_pose);
-    delete segment;
+    {
+      rem_length=distance+margin-segment->get_length();
+      if(rem_length>0.0)// get the prev segment
+      {
+        next_segment=&segment->get_prev_segment(node_side,valid);
+        if(valid)
+        {
+          segment=next_segment;
+          if(node_side<0)
+          {
+            int_pose=segment->get_pose_at(segment->get_length()-rem_length);
+            distance=segment->get_length()-rem_length;
+          }
+          else
+          {
+            int_pose=segment->get_pose_at(rem_length);
+            distance=rem_length;
+          }
+        }
+        else
+        {
+          int_pose=segment->get_pose_at(segment->get_length());
+          distance=0.0;
+        }
+      }
+      else
+      {
+        int_pose=segment->get_pose_at(distance+margin);
+        distance+=margin;
+      }
+    }
+  }
+  else
+    int_pose=start_pose;
+  rem_length=length+2.0*margin;
+  new_segment=segment->get_sub_segment(new_node_ref,new_lane_ref,new_link_ref,node_side,&int_pose,NULL);
+  valid=true;
+  if(new_segment->get_length()<this->min_road_length)
+  {
+    next_segment=&segment->get_next_segment(node_side,valid);
+    segment=next_segment;
+    delete new_segment;
+    if(valid)
+    {
+      new_segment=segment->clone(new_node_ref,new_lane_ref,new_link_ref);
+      distance=0.0;
+    }
   }
-  rem_length-=new_segment->get_length();
-  new_road.add_segment(new_segment);
-  new_segment_ref[segment]=new_segment;
-  while(rem_length>0)
+  if(valid)
   {
-    next_segment=segment->get_next_segment(node_side);
-    if(next_segment==NULL)
-      break;
-    if((rem_length-next_segment->get_length())<0.0)
+    start_length=new_segment->get_length()-distance;
+    if(rem_length<start_length)
     {
       if(node_side<0)
-        end_pose=next_segment->get_pose_at(rem_length);
+        end_pose=new_segment->get_pose_at(rem_length);
       else
-        end_pose=next_segment->get_pose_at(next_segment->get_length()-rem_length);
-      new_segment=next_segment->get_sub_segment(new_node_ref,new_lane_ref,new_link_ref,node_side,NULL,&end_pose);
+        end_pose=new_segment->get_pose_at(new_segment->get_length()-rem_length);
+      delete new_segment;
+      new_segment=segment->get_sub_segment(new_node_ref,new_lane_ref,new_link_ref,node_side,&start_pose,&end_pose);
     }
-    else
-      new_segment=next_segment->clone(new_node_ref,new_lane_ref,new_link_ref);
     rem_length-=new_segment->get_length();
     new_road.add_segment(new_segment);
-    new_segment_ref[next_segment]=new_segment;
+    new_segment_ref[(COpendriveRoadSegment *)segment]=new_segment;
+  }
+  while(rem_length>this->resolution && valid)
+  {
+    next_segment=&segment->get_next_segment(node_side,valid);
     segment=next_segment;
+    if(valid)
+    {
+      if((rem_length-segment->get_length())<0.0)
+      {
+        if(node_side<0)
+          end_pose=segment->get_pose_at(rem_length);
+        else
+          end_pose=segment->get_pose_at(segment->get_length()-rem_length);
+        new_segment=segment->get_sub_segment(new_node_ref,new_lane_ref,new_link_ref,node_side,NULL,&end_pose);
+      }
+      else
+        new_segment=segment->clone(new_node_ref,new_lane_ref,new_link_ref);
+      if(new_segment->get_length()>this->min_road_length)
+      {
+        rem_length-=new_segment->get_length();
+        new_road.add_segment(new_segment);
+        new_segment_ref[(COpendriveRoadSegment *)segment]=new_segment;
+      }
+      else
+        break;
+    }
   }
   length-=rem_length;
   new_road.update_references(new_segment_ref,new_lane_ref,new_node_ref);