Skip to content

Commit 66e9c69

Browse files
Fix centerline creation from OpenDRIVE maps with very short lane segments (#12)
* handle invalid centerlines in odr maps * add warning when fixing centerline in map_odr
1 parent 0b69a90 commit 66e9c69

File tree

2 files changed

+20
-15
lines changed

2 files changed

+20
-15
lines changed

omega_prime/locator.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ def extend_linestring(cls, l: shapely.LineString, simplify: bool = True, l_appen
3838
if isinstance(l, shapely.Point):
3939
cl = np.asarray(l.coords)[0]
4040
return shapely.LineString(np.stack([cl - np.array([0, 1]), cl, cl + np.array([0, 1])]))
41-
41+
if l.is_empty:
42+
cl = np.array([0, 0])
43+
return shapely.LineString(np.stack([cl - np.array([0, 1]), cl, cl + np.array([0, 1])]))
4244
startvec = np.asarray(l.interpolate(0, normalized=True).coords) - np.asarray(
4345
l.interpolate(0 + cls.epsi, normalized=True).coords
4446
)

omega_prime/map_odr.py

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import logging
22
from dataclasses import dataclass
33
from omega_prime.map import Map, Lane, LaneBoundary
4-
from shapely import LineString, Polygon, simplify
4+
from shapely import LineString, Polygon, simplify, make_valid
55
import numpy as np
66
from betterosi import LaneClassificationType, LaneClassificationSubtype, LaneBoundaryClassificationType
77
from pyxodr_omega_prime.road_objects.network import RoadNetwork as PyxodrRoadNetwork
@@ -17,7 +17,6 @@
1717
from collections import namedtuple
1818
import warnings
1919

20-
2120
logger = logging.getLogger(__name__)
2221

2322

@@ -352,19 +351,17 @@ def create(
352351
lane_idx: int = None,
353352
):
354353
if side == "left":
355-
if len(boundary.boundary_line) == 1:
356-
polyline = LineString([boundary.boundary_line[0]] * 2)
357-
else:
358-
polyline = LineString(boundary.boundary_line)
354+
bl = boundary.boundary_line
359355
elif side == "right":
360-
if len(boundary.lane_reference_line) == 1:
361-
polyline = LineString([boundary.lane_reference_line[0]] * 2)
362-
else:
363-
polyline = LineString(boundary.lane_reference_line)
364-
356+
bl = boundary.lane_reference_line
365357
else:
366358
raise ValueError(f"Invalid side '{side}'. Expected 'left' or 'right'.")
367359

360+
if len(bl) == 1:
361+
polyline = LineString([bl[0]] * 2)
362+
else:
363+
polyline = LineString(bl)
364+
368365
if type is None and hasattr(boundary, "lane_xml"):
369366
type = cls._extract_lane_boundary_type_from_xml(boundary, side)
370367

@@ -402,17 +399,23 @@ class LaneXodr(Lane):
402399

403400
@classmethod
404401
def create(cls, lane: PyxodrLane, road: PyxodrRoad, lane_section_id: int, lane_idx: int = None):
402+
idx = XodrLaneId(road.id, lane.id, lane_section_id)
405403
centre_line = getattr(lane, "centre_line", None)
406404
if centre_line is None or not len(centre_line):
407405
raise ValueError(f"Lane {lane.id} has no centre_line")
408406

409-
centerline_2d = lane.centre_line[:, :2]
407+
centerline = LineString(centre_line[:, :2])
408+
if not centerline.is_valid:
409+
centerline = make_valid(centerline)
410+
warnings.warn(
411+
f"Needed to make centerline of lane {idx} valid. Most likely, because the OpenDRIVE geometry is translated to a zero length polyline. Try to decrease `step_size`."
412+
)
413+
410414
lane_type, lane_subtype = cls._determine_lane_type_and_subtype(lane, road)
411-
idx = XodrLaneId(road.id, lane.id, lane_section_id)
412415
return cls(
413416
_xodr=lane,
414417
idx=idx,
415-
centerline=LineString(centerline_2d),
418+
centerline=centerline,
416419
type=lane_type,
417420
subtype=lane_subtype,
418421
successor_ids=[

0 commit comments

Comments
 (0)