Example #1
0
def observe(lidar: LidarSensor, scene: Frame, roadway: Roadway, vehicle_index: int):
    state_ego = scene[vehicle_index].state
    egoid = scene[vehicle_index].id
    ego_vel = VecE2.polar(state_ego.v, state_ego.posG.theta)

    in_range_ids = set()

    for i in range(scene.n):
        veh = scene[i]
        if veh.id != egoid:
            a = state_ego.posG - veh.state.posG
            distance = VecE2.norm(VecE2.VecE2(a.x, a.y))
            # account for the length and width of the vehicle by considering
            # the worst case where their maximum radius is aligned
            distance = distance - math.hypot(veh.definition.length_ / 2., veh.definition.width_ / 2.)
            if distance < lidar.max_range:
                in_range_ids.add(veh.id)

                # compute range and range_rate for each angle
    for (i, angle) in enumerate(lidar.angles):
        ray_angle = state_ego.posG.theta + angle
        ray_vec = VecE2.polar(1.0, ray_angle)
        ray = VecSE2.VecSE2(state_ego.posG.x, state_ego.posG.y, ray_angle)

        range_ = lidar.max_range
        range_rate = 0.0
        for j in range(scene.n):
            veh = scene[j]
            # only consider the set of potentially in range vehicles
            if veh.id in in_range_ids:
                lidar.poly.set(to_oriented_bounding_box_2(lidar.poly, veh))

                range2 = get_collision_time(ray, lidar.poly, 1.0)  # TODO: continue finish here
                if range2 and range2 < range_:
                    range_ = range2
                    relative_speed = VecE2.polar(veh.state.v, veh.state.posG.theta) - ego_vel
                    range_rate = VecE2.proj_(relative_speed, ray_vec)
        lidar.ranges[i] = range_
        lidar.range_rates[i] = range_rate

    return lidar
Example #2
0
def integrate(centerline_fn: str,
              boundary_fn: str,
              dist_threshold_lane_connect: float = 2.0,
              desired_distance_between_curve_samples: float = 1.0):
    '''
    :param centerline_path: center line file path
    :param boundary_path: boundary file path
    :param dist_threshold_lane_connect: [m]
    :param desired_distance_between_curve_samples: [m]
    :return:
    '''
    centerline_path = os.path.join(DIR, "../data/", centerline_fn)
    boundary_path = os.path.join(DIR, "../data/", boundary_fn)
    input_params = RoadwayInputParams(filepath_boundaries=boundary_path,
                                      filepath_centerlines=centerline_path)
    roadway_data = read_roadway(input_params)
    print("Finish loading centerlines and boundaries.")
    lane_pts_dict = dict()
    for (handle_int, lane) in enumerate(roadway_data.centerlines):
        segid = get_segid(lane)
        N = len(lane)
        pts = [None for _ in range(N)]  # VecE2 list
        for i in range(N):
            x = lane[i].pos.x
            y = lane[i].pos.y
            pts[i] = VecE2.VecE2(x, y)
        laneid = 1
        for tag in lane_pts_dict.keys():
            if tag.segment == segid:
                laneid += 1
        lane_pts_dict[roadway.LaneTag(segid, laneid)] = pts

    ###################################################
    # Shift pts to connect to previous / next pts

    lane_next_dict = dict()
    lane_prev_dict = dict()

    for (tag, pts) in lane_pts_dict.items():
        # see if can connect to next
        best_tag = roadway.NULL_LANETAG
        best_ind = -1
        best_sq_dist = dist_threshold_lane_connect
        for (tag2, pts2) in lane_pts_dict.items():
            if tag2.segment != tag.segment:
                for (ind, pt) in enumerate(pts2):
                    sq_dist = VecE2.normsquared(VecE2.VecE2(pt - pts[-1]))
                    if sq_dist < best_sq_dist:
                        best_sq_dist = sq_dist
                        best_ind = ind
                        best_tag = tag2
        if best_tag != roadway.NULL_LANETAG:
            # remove our last pt and set next to pt to their pt
            pts.pop()
            lane_next_dict[tag] = (lane_pts_dict[best_tag][best_ind], best_tag)
            if best_ind == 0:  # set connect prev as well
                lane_prev_dict[best_tag] = (pts[-1], tag)

    for (tag, pts) in lane_pts_dict.items():
        # see if can connect to prev
        if tag not in lane_prev_dict.keys():
            best_tag = roadway.NULL_LANETAG
            best_ind = -1
            best_sq_dist = dist_threshold_lane_connect
            for (tag2, pts2) in lane_pts_dict.items():
                if tag2.segment != tag.segment:
                    for (ind, pt) in enumerate(pts2):
                        sq_dist = VecE2.normsquared(VecE2.VecE2(pt - pts[0]))
                        if sq_dist < best_sq_dist:
                            best_sq_dist = sq_dist
                            best_ind = ind
                            best_tag = tag2
            if best_tag != roadway.NULL_LANETAG:
                lane_prev_dict[tag] = (lane_pts_dict[best_tag][best_ind],
                                       best_tag)

    ###################################################
    # Build the roadway
    retval = roadway.Roadway()
    for (tag, pts) in lane_pts_dict.items():
        if not retval.has_segment(tag.segment):
            retval.segments.append(roadway.RoadSegment(tag.segment))
    lane_new_dict = dict()  # old -> new tag
    for seg in retval.segments:

        # pull lanetags for this seg
        lanetags = []  # LaneTag
        for tag in lane_pts_dict.keys():
            if tag.segment == seg.id:
                lanetags.append(tag)

        # sort the lanes such that the rightmost lane is lane 1
        # do this by taking the first lane,
        # then project each lane's midpoint to the perpendicular at the midpoint

        assert len(lanetags) != 0
        proj_positions = [None for _ in range(len(lanetags))]  # list of float
        first_lane_pts = lane_pts_dict[lanetags[0]]
        n = len(first_lane_pts)
        lo = first_lane_pts[n // 2 - 1]
        hi = first_lane_pts[n // 2]
        midpt_orig = (lo + hi) / 2
        dir = VecE2.polar(
            1.0, (hi - lo).atan() +
            math.pi / 2)  # direction perpendicular (left) of lane

        for (i, tag) in enumerate(lanetags):
            pts = lane_pts_dict[tag]
            n = len(pts)
            midpt = (pts[n // 2 - 1] + pts[n // 2]) / 2
            proj_positions[i] = VecE2.proj_(midpt - midpt_orig, dir)

        for (i, j) in enumerate(
                sorted(range(len(proj_positions)),
                       key=proj_positions.__getitem__)):
            tag = lanetags[j]

            boundary_left = roadway.LaneBoundary("solid", "white") if i == len(proj_positions) - 1 \
                else roadway.LaneBoundary("broken", "white")

            boundary_right = roadway.LaneBoundary("solid", "white") if i == 0 \
                else roadway.LaneBoundary("broken", "white")

            pts = lane_pts_dict[tag]
            pt_matrix = np.zeros((2, len(pts)))
            for (k, P) in enumerate(pts):
                pt_matrix[0, k] = P.x
                pt_matrix[1, k] = P.y
            print("fitting curve ", len(pts), "  ")
            curve = _fit_curve(pt_matrix,
                               desired_distance_between_curve_samples)

            tag_new = roadway.LaneTag(seg.id, len(seg.lanes) + 1)
            lane = roadway.Lane(tag_new,
                                curve,
                                boundary_left=boundary_left,
                                boundary_right=boundary_right)
            seg.lanes.append(lane)
            lane_new_dict[tag] = tag_new

    ###################################################
    # Connect the lanes
    for (tag_old, tup) in lane_next_dict.items():
        next_pt, next_tag_old = tup
        lane = retval.get_by_tag(lane_new_dict[tag_old])
        next_tag_new = lane_new_dict[next_tag_old]
        dest = retval.get_by_tag(next_tag_new)
        roadproj = roadway.proj_1(VecSE2.VecSE2(next_pt, 0.0), dest, retval)
        print("connecting {} to {}".format(lane.tag, dest.tag))
        cindS = CurvePt.curveindex_end(lane.curve)
        cindD = roadproj.curveproj.ind

        if cindD == CurvePt.CURVEINDEX_START:  # a standard connection
            lane, dest = roadway.connect(lane, dest)
            # remove any similar connection from lane_prev_dict
            if next_tag_old in lane_prev_dict.keys(
            ) and lane_prev_dict[next_tag_old][1] == tag_old:
                lane_prev_dict.pop(next_tag_old)
        else:
            lane.exits.insert(
                0,
                roadway.LaneConnection(True, cindS,
                                       roadway.RoadIndex(cindD, dest.tag)))
            dest.entrances.append(
                roadway.LaneConnection(False, cindD,
                                       roadway.RoadIndex(cindS, lane.tag)))

    for (tag_old, tup) in lane_prev_dict.items():
        prev_pt, prev_tag_old = tup
        lane = retval.get_by_tag(lane_new_dict[tag_old])
        prev_tag_new = lane_new_dict[prev_tag_old]
        prev = retval.get_by_tag(prev_tag_new)
        roadproj = roadway.proj_1(VecSE2.VecSE2(prev_pt, 0.0), prev, retval)
        print("connecting {} from {}".format(lane.tag, prev.tag))
        cindS = roadproj.curveproj.ind
        cindD = CurvePt.CURVEINDEX_START
        if cindS == CurvePt.curveindex_end(
                prev.curve):  # a standard connection
            assert roadway.has_prev(prev)
            prev, lane = roadway.connect(prev, lane)
        else:
            # a standard connection
            prev.exits.append(
                roadway.LaneConnection(True, cindS,
                                       roadway.RoadIndex(cindD, lane.tag)))
            lane.entrances.insert(
                0,
                roadway.LaneConnection(False, cindD,
                                       roadway.RoadIndex(cindS, prev.tag)))

    retval = convert_curves_feet_to_meters(retval)