def _create_outer_lane_border(lane_borders, lane, coeff_factor) -> Border: """Create an outer lane border of a lane. InnerBorder is already saved in lane_borders, as it is the outer border of the inner neighbour of the lane. Args: lane_borders: Previous calculated lane borders of more inner lanes. lane: Lane for which outer border shall be created. This is specified in parameter ds of curve length. coeff_factor: factor of -1 or 1, dependent on which side of the reference path the lane is (right side is -1). Returns: The created outer lane border. """ # Create outer lane border # Offset from reference border is already included in first inner border # (lane_border[0]) # reference_border starts at beginning of road, prev: lane section border = Border() if len(lane_borders) == 1: border.ref_offset = lane.lane_section.sPos # last created border if lane.has_border_record: border.reference = lane_borders[0] else: border.reference = lane_borders[-1] for width in lane.widths: border.width_coefficient_offsets.append(width.start_offset) border.width_coefficients.append( [x * coeff_factor for x in width.polynomial_coefficients]) return border
def create_reference_border(plan_view, lane_offsets) -> Border: """Create the most inner border from a PlanView. This border is used as a reference for other borders which rely on the PlanView. Args: plan_view: PlanView object from OpenDrive which specifies the geometry of the reference path. lane_offsets: Object which contains information about width offset of reference path the plain_view path. Returns: The reference border on which all other borders in this lane section are based upon. """ reference_border = Border() # Set reference to plan view reference_border.reference = plan_view # Lane offsets will be coeffs # this has to be done if the reference path has the laneoffset attribute # and thus is different to the geometry described in the plan_view # openDRIVE lets multiple laneOffsets start at the same position # but only the last one counts -> delete all previous ones if any(lane_offsets): for lane_offset in lane_offsets: if lane_offset.start_pos in reference_border.width_coefficient_offsets: # offset is already there, delete previous entries idx = reference_border.width_coefficient_offsets.index( lane_offset.start_pos ) del reference_border.width_coefficient_offsets[idx] del reference_border.width_coefficients[idx] reference_border.width_coefficient_offsets.append(lane_offset.start_pos) reference_border.width_coefficients.append( lane_offset.polynomial_coefficients ) else: reference_border.width_coefficient_offsets.append(0.0) reference_border.width_coefficients.append([0.0]) return reference_border
def createReferenceBorder(planView, laneOffsets): """ Create the first (most inner) border line for a road, includes the lane Offsets """ firstLaneBorder = Border() # Set reference to plan view firstLaneBorder.reference = planView firstLaneBorder.refOffset = 0.0 # Lane offfsets will be coeffs if any(laneOffsets): for laneOffset in laneOffsets: firstLaneBorder.coeffsOffsets.append(laneOffset.sPos) firstLaneBorder.coeffs.append(laneOffset.coeffs) else: firstLaneBorder.coeffsOffsets.append(0.0) firstLaneBorder.coeffs.append([0.0]) return firstLaneBorder
def laneSectionToPLanes(laneSection, referenceBorder): """ Convert a whole lane section into a list of planes """ newPLanes = [] # Length of this lane section laneSectionStart = laneSection.sPos for side in ["right", "left"]: # lanes loaded by opendriveparser are aleady sorted by id # coeffsFactor decides if border is left or right of the reference line if side == "right": lanes = laneSection.rightLanes coeffsFactor = -1.0 else: lanes = laneSection.leftLanes coeffsFactor = 1.0 # Most inner border laneBorders = [referenceBorder] prevInnerNeighbours = [] for lane in lanes: if abs(lane.id) > 1: if lane.id > 0: innerLaneId = lane.id - 1 outerLaneId = lane.id + 1 else: innerLaneId = lane.id + 1 outerLaneId = lane.id - 1 innerNeighbourId = encode_road_section_lane_width_id(laneSection.parentRoad.id, laneSection.idx, innerLaneId, -1) innerNeighbourSameDirection = True outerNeighbourId = encode_road_section_lane_width_id(laneSection.parentRoad.id, laneSection.idx, outerLaneId, -1) else: # Skip lane id 0 if lane.id == 1: innerLaneId = -1 outerLaneId = 2 else: innerLaneId = 1 outerLaneId = -2 innerNeighbourId = encode_road_section_lane_width_id(laneSection.parentRoad.id, laneSection.idx, innerLaneId, -1) innerNeighbourSameDirection = False outerNeighbourId = encode_road_section_lane_width_id(laneSection.parentRoad.id, laneSection.idx, outerLaneId, -1) innerNeighbours = [] # Create outer lane border newPLaneBorder = Border() newPLaneBorder.reference = laneBorders[-1] if len(laneBorders) == 1: newPLaneBorder.refOffset = laneSectionStart else: # Offset from reference border is already included in first created outer lane border newPLaneBorder.refOffset = 0.0 for width in lane.widths: newPLaneBorder.coeffsOffsets.append(width.sOffset) newPLaneBorder.coeffs.append([x * coeffsFactor for x in width.coeffs]) laneBorders.append(newPLaneBorder) # Create new lane for each width segment newPLanesList = [] for width in lane.widths: newPLane = PLane( id=encode_road_section_lane_width_id(laneSection.parentRoad.id, laneSection.idx, lane.id, width.idx), type=lane.type ) if allCloseToZero(width.coeffs): newPLane.isNotExistent = True newPLane.innerNeighbours = prevInnerNeighbours newPLane.length = width.length newPLane.innerBorder = laneBorders[-2] newPLane.innerBorderOffset = width.sOffset + laneBorders[-1].refOffset newPLane.outerBorder = laneBorders[-1] newPLane.outerBorderOffset = width.sOffset newPLanesList.append(newPLane) innerNeighbours.append(newPLane) # Organize everything in a pLaneGroup if it is more than one element if len(newPLanesList) >= 1: newPLaneGroup = PLaneGroup( id=encode_road_section_lane_width_id(laneSection.parentRoad.id, laneSection.idx, lane.id, -1), innerNeighbour=innerNeighbourId, innerNeighbourSameDirection=innerNeighbourSameDirection, outerNeighbour=outerNeighbourId, reverse=True if lane.id > 0 else False ) for newPLane in newPLanesList: newPLaneGroup.append(newPLane) newPLanes.append(newPLaneGroup) else: newPLanes.append(newPLanesList[0]) prevInnerNeighbours = innerNeighbours return newPLanes