Example #1
0
def parse_lane_connection(line: str):
    cleanedline = re.sub(r"(\(|\))", "", line)
    print(cleanedline)
    tokens = cleanedline.split()
    assert tokens[0] == "D" or tokens[0] == "U"
    downstream = (tokens[0] == "D")
    mylane = CurvePt.CurveIndex(int(tokens[1]), float(tokens[2]))
    target = RoadIndex(CurvePt.CurveIndex(int(tokens[3]), float(tokens[4])),
                       LaneTag(int(tokens[5]), int(tokens[6])))
    return LaneConnection(downstream, mylane, target)
Example #2
0
def get_closest_perpendicular_point_between_points(
        A: VecSE2.VecSE2,
        B: VecSE2.VecSE2,
        Q: VecSE2.VecSE2,
        tolerance: float = 0.01,  # acceptable error in perpendicular component
        max_iter: int = 50,  # maximum number of iterations
):

    # CONDITIONS: a < b, either f(a) < 0 and f(b) > 0 or f(a) > 0 and f(b) < 0
    # OUTPUT: value which differs from a root of f(x)=0 by less than TOL

    a = 0.0
    b = 1.0

    f_a = geom.inertial2body(Q, A).x
    f_b = geom.inertial2body(Q, B).x

    if sign(f_a) == sign(f_b):  # both are wrong - use the old way
        t = CurvePt.get_lerp_time_unclamped_3(A, B, Q)
        t = CurvePt.clamp(t, 0.0, 1.0)
        return t, VecSE2.lerp(A, B, t)

    iter = 1
    while iter <= max_iter:
        c = (a + b) / 2  # new midpoint
        footpoint = VecSE2.lerp(A, B, c)
        f_c = geom.inertial2body(Q, footpoint).x
        if abs(f_c) < tolerance:  # solution found
            return c, footpoint
        if sign(f_c) == sign(f_a):
            a, f_a = c, f_c
        else:
            b = c
        iter += 1

    # Maximum number of iterations passed
    # This will occur when we project with a point that is not actually in the range,
    # and we converge towards one edge

    if a == 0.0:
        return 0.0, A
    elif b == 1.0:
        return 1.0, B
    else:
        warnings.warn(
            "get_closest_perpendicular_point_between_points - should not happen"
        )
        c = (a + b) / 2  # should not happen
        return c, VecSE2.lerp(A, B, c)
Example #3
0
 def get_by_ind_roadway(self, ind: CurvePt.CurveIndex, roadway):
     if ind.i == -1:
         pt_lo = prev_lane_point(self, roadway)
         pt_hi = self.curve[0]
         s_gap = VecE2.norm(VecE2.VecE2(pt_hi.pos - pt_lo.pos))
         pt_lo = CurvePt.CurvePt(pt_lo.pos, -s_gap, pt_lo.k, pt_lo.kd)
         return CurvePt.lerp(pt_lo, pt_hi, ind.t)
     elif ind.i < len(self.curve) - 1:
         return CurvePt.get_curve_list_by_index(self.curve, ind)
     else:
         pt_hi = next_lane_point(self, roadway)
         pt_lo = self.curve[-1]
         s_gap = VecE2.norm(VecE2.VecE2(pt_hi.pos - pt_lo.pos))
         pt_hi = CurvePt.CurvePt(pt_hi.pos, pt_lo.s + s_gap, pt_hi.k,
                                 pt_hi.kd)
         return CurvePt.lerp(pt_lo, pt_hi, ind.t)
Example #4
0
    def __init__(self,
                 tag: LaneTag,
                 curve: list,
                 width: float = DEFAULT_LANE_WIDTH,
                 speed_limit: SpeedLimit = DEFAULT_SPEED_LIMIT,
                 boundary_left: LaneBoundary = NULL_BOUNDARY,
                 boundary_right: LaneBoundary = NULL_BOUNDARY,
                 exits: list = [],
                 entrances: list = [],
                 next: RoadIndex = NULL_ROADINDEX,
                 prev: RoadIndex = NULL_ROADINDEX):
        self.tag = tag
        self.curve = curve  # Array of Curve
        self.width = width
        self.speed_limit = speed_limit
        self.boundary_left = boundary_left
        self.boundary_right = boundary_right
        self.exits = exits  # Array of LaneConnection
        self.entrances = entrances  # Array of LaneConnection

        if next != NULL_ROADINDEX:
            self.exits.insert(
                0,
                LaneConnection(True, CurvePt.curveindex_end(self.curve), next))

        if prev != NULL_ROADINDEX:
            self.entrances.insert(
                0, LaneConnection(False, CurvePt.CURVEINDEX_START, prev))
Example #5
0
def proj_2(posG: VecSE2.VecSE2, roadway: Roadway):

    best_dist2 = math.inf
    best_proj = RoadProjection(
        CurvePt.CurveProjection(CurvePt.CurveIndex(-1, -1), None, None),
        NULL_LANETAG)

    for seg in roadway.segments:
        for lane in seg.lanes:
            roadproj = proj_1(posG, lane, roadway,
                              move_along_curves=False)  # return RoadProjection
            targetlane = roadway.get_by_tag(roadproj.tag)  # return Lane
            footpoint = targetlane.get_by_ind_roadway(roadproj.curveproj.ind,
                                                      roadway)
            vec = posG - footpoint.pos
            dist2 = VecE2.normsquared(VecE2.VecE2(vec.x, vec.y))
            if dist2 < best_dist2:
                best_dist2 = dist2
                best_proj = roadproj

    return best_proj
Example #6
0
def proj_1(posG: VecSE2.VecSE2,
           lane: Lane,
           roadway: Roadway,
           move_along_curves: bool = True):
    curveproj = CurvePt.proj(posG, lane.curve)
    rettag = lane.tag
    if curveproj.ind == CurvePt.CurveIndex(0, 0.0) and has_prev(lane):
        pt_lo = prev_lane_point(lane, roadway)
        pt_hi = lane.curve[0]
        t = CurvePt.get_lerp_time_unclamped_2(pt_lo, pt_hi, posG)
        if t <= 0.0 and move_along_curves:
            return proj_1(posG, prev_lane(lane, roadway), roadway)
        elif t < 1.0:
            assert ((not move_along_curves) or 0.0 <= t < 1.0)
            # t was computed assuming a constant angle
            # this is not valid for the large distances and angle disparities between lanes
            # thus we now use a bisection search to find the appropriate location

            t, footpoint = get_closest_perpendicular_point_between_points(
                pt_lo.pos, pt_hi.pos, posG)

            ind = CurvePt.CurveIndex(-1, t)
            curveproj = CurvePt.get_curve_projection(posG, footpoint, ind)
    elif curveproj.ind == CurvePt.curveindex_end(
            lane.curve) and has_next(lane):
        pt_lo = lane.curve[-1]
        pt_hi = next_lane_point(lane, roadway)
        t = CurvePt.get_lerp_time_unclamped_2(pt_lo, pt_hi, posG)
        if t >= 1.0 and move_along_curves:
            return proj_1(posG, next_lane(lane, roadway), roadway)
        elif t >= 0.0:
            assert ((not move_along_curves) or 0.0 <= t < 1.0)
            # t was computed assuming a constant angle
            # this is not valid for the large distances and angle disparities between lanes
            # thus we now use a bisection search to find the appropriate location

            t, footpoint = get_closest_perpendicular_point_between_points(
                pt_lo.pos, pt_hi.pos, posG)

            ind = CurvePt.CurveIndex(len(lane.curve) - 1, t)
            curveproj = CurvePt.get_curve_projection(posG, footpoint, ind)
    #print(rettag.segment, rettag.lane)
    return RoadProjection(curveproj, rettag)
Example #7
0
def read_roadway(fp):
    lines = fp.readlines()
    fp.close()
    line_index = 0
    if "ROADWAY" in lines[line_index]:  #文件第一行 ROADWAY title
        line_index += 1  #继续读下一行

    nsegs = int(lines[line_index].strip())  # 读Roadway.segments的长度
    line_index += 1  #继续读下一行

    roadway = Roadway([])
    for i_seg in range(nsegs):  # 循环读每个segments的内容
        segid = int(lines[line_index].strip())  # parse segments.id
        line_index += 1  #继续读下一行
        nlanes = int(lines[line_index].strip())  # 读出Roadway.segments.lanes的长度
        line_index += 1  #继续读下一行
        seg = RoadSegment(segid, [])  #
        for i_lane in range(nlanes):  # 循环读每个lane的内容
            assert i_lane + 1 == int(
                lines[line_index].strip())  # 这里是用来确认lane符合顺序且读的方式正确
            line_index += 1  #继续读下一行
            tag = LaneTag(segid, i_lane)  # make Roadway.segments.lanes.tag
            #print(segid, nlanes, i_lane)
            width = float(lines[line_index].strip())  # parse width
            line_index += 1  #继续读下一行
            tokens = (lines[line_index].strip()).split()
            line_index += 1  #继续读下一行
            speed_limit = SpeedLimit(float(tokens[0]),
                                     float(tokens[1]))  # parse speed limit
            tokens = (lines[line_index].strip()).split()
            line_index += 1  #继续读下一行
            boundary_left = LaneBoundary(tokens[0],
                                         tokens[1])  # parse boundary_left
            tokens = (lines[line_index].strip()).split()
            line_index += 1  #继续读下一行
            boundary_right = LaneBoundary(tokens[0],
                                          tokens[1])  # parse boundary_right
            exits = []
            entrances = []
            n_conns = int(lines[line_index].strip()
                          )  # 这里应该是Roadway.segments.lanes.exits以及entrances的长度
            line_index += 1  #继续读下一行
            for i_conn in range(n_conns):  # 循环parse每个exit以及entrance
                conn = parse_lane_connection(
                    lines[line_index].strip())  # parse LaneConnection
                line_index += 1  #继续读下一行
                if conn.downstream:
                    exits.append(conn)  # if downstream 就是exit的数据
                else:
                    entrances.append(conn)  # else entrance的数据
            npts = int(lines[line_index].strip()
                       )  # 有多少个curve点————Roadway.segments.lanes.curve的长度
            line_index += 1  #继续读下一行
            curve = []
            for i_pt in range(npts):  # 循环parse CurvePt
                line = lines[line_index].strip()
                line_index += 1  #继续读下一行
                cleanedline = re.sub(r"(\(|\))", "", line)
                tokens = cleanedline.split()
                x = float(tokens[0])
                y = float(tokens[1])
                theta = float(tokens[2])
                s = float(tokens[3])
                k = float(tokens[4])
                kd = float(tokens[5])
                curve.append(
                    CurvePt.CurvePt(
                        VecSE2.VecSE2(x, y, theta), s, k,
                        kd))  # append CurvePt in Roadway.segments.lanes.curve
            seg.lanes.append(
                Lane(tag,
                     curve,
                     width=width,
                     speed_limit=speed_limit,
                     boundary_left=boundary_left,
                     boundary_right=boundary_right,
                     entrances=entrances,
                     exits=exits))  # append lane in Roadway.segments.lanes
        roadway.segments.append(seg)  # append segs in Roadway.segments
        #print(len(roadway.segments))
    return roadway
Example #8
0
def has_next(lane: Lane):
    return (not len(lane.exits) == 0
            ) and lane.exits[0].mylane == CurvePt.curveindex_end(lane.curve)
Example #9
0
class LaneTag:
    def __init__(self, segment: int, lane: int):
        self.segment = segment
        self.lane = lane


NULL_LANETAG = LaneTag(0, 0)


class RoadIndex:
    def __init__(self, ind: CurvePt.CurveIndex, tag: LaneTag):
        self.ind = ind
        self.tag = tag


NULL_ROADINDEX = RoadIndex(CurvePt.CurveIndex(-1, None), LaneTag(-1, -1))


class LaneConnection:
    def __init__(self, downstream: bool, mylane: CurvePt.CurveIndex,
                 target: RoadIndex):
        self.downstream = downstream
        self.mylane = mylane
        self.target = target


def parse_lane_connection(line: str):
    cleanedline = re.sub(r"(\(|\))", "", line)
    print(cleanedline)
    tokens = cleanedline.split()
    assert tokens[0] == "D" or tokens[0] == "U"