예제 #1
0
def CreateAdverseRoad(
        positive_road: "Road",
        roadnet_to_get_road: "RoadNetwork",  # mostly, block network
        roadnet_to_check_cross: "RoadNetwork",  # mostly, previous global network
        ignore_start: str = None,
        ignore_end: str = None,
        center_line_type=LineType.
    CONTINUOUS,  # Identical to Block.CENTER_LINE_TYPE
        side_lane_line_type=LineType.SIDE,
        inner_lane_line_type=LineType.BROKEN,
        center_line_color=LineColor.YELLOW,
        ignore_intersection_checking=None) -> bool:
    adverse_road = -positive_road
    lanes = get_lanes_on_road(positive_road, roadnet_to_get_road)
    reference_lane = lanes[-1]
    num = len(lanes) * 2
    width = reference_lane.width_at(0)
    if isinstance(reference_lane, StraightLane):
        start_point = reference_lane.position(lanes[-1].length,
                                              -(num - 1) * width)
        end_point = reference_lane.position(0, -(num - 1) * width)
        symmetric_lane = StraightLane(start_point, end_point, width,
                                      lanes[-1].line_types,
                                      reference_lane.forbidden,
                                      reference_lane.speed_limit,
                                      reference_lane.priority)
    elif isinstance(reference_lane, CircularLane):
        start_phase = reference_lane.end_phase
        end_phase = reference_lane.start_phase
        clockwise = False if reference_lane.direction == 1 else True
        if not clockwise:
            radius = reference_lane.radius + (num - 1) * width
        else:
            radius = reference_lane.radius - (num - 1) * width
        symmetric_lane = CircularLane(reference_lane.center, radius,
                                      start_phase, end_phase, clockwise, width,
                                      reference_lane.line_types,
                                      reference_lane.forbidden,
                                      reference_lane.speed_limit,
                                      reference_lane.priority)
    else:
        raise ValueError("Creating other lanes is not supported")
    success = CreateRoadFrom(
        symmetric_lane,
        int(num / 2),
        adverse_road,
        roadnet_to_get_road,
        roadnet_to_check_cross,
        ignore_start=ignore_start,
        ignore_end=ignore_end,
        side_lane_line_type=side_lane_line_type,
        inner_lane_line_type=inner_lane_line_type,
        center_line_type=center_line_type,
        center_line_color=center_line_color,
        ignore_intersection_checking=ignore_intersection_checking)
    positive_road.get_lanes(roadnet_to_get_road)[0].line_color = [
        center_line_color, LineColor.GREY
    ]
    return success
예제 #2
0
 def _get_merge_part(self, side_lane: StraightLane):
     tool_lane = StraightLane(side_lane.end, side_lane.start, side_lane.width)
     merge_part, _ = create_bend_straight(
         tool_lane,
         10,
         self.lane_width / 2,
         np.pi / 2,
         True,
         width=self.lane_width,
         line_types=(LineType.CONTINUOUS, LineType.BROKEN)
     )
     return merge_part
예제 #3
0
def create_bend_straight(previous_lane: "StraightLane",
                         following_lane_length,
                         radius: float,
                         angle: float,
                         clockwise: bool = True,
                         width: float = AbstractLane.DEFAULT_WIDTH,
                         line_types: Tuple[LineType, LineType] = None,
                         forbidden: bool = False,
                         speed_limit: float = 20,
                         priority: int = 0):
    bend_direction = 1 if clockwise else -1
    center = previous_lane.position(previous_lane.length,
                                    bend_direction * radius)
    p_lateral = previous_lane.direction_lateral
    x, y = p_lateral
    start_phase = 0
    if y == 0:
        start_phase = 0 if x < 0 else -np.pi
    elif x == 0:
        start_phase = np.pi / 2 if y < 0 else -np.pi / 2
    else:
        base_angel = np.arctan(y / x)
        if x < 0:
            start_phase = base_angel
        elif y < 0:
            start_phase = np.pi + base_angel
        elif y > 0:
            start_phase = -np.pi + base_angel
    end_phase = start_phase + angle
    if not clockwise:
        start_phase = start_phase - np.pi
        end_phase = start_phase - angle
    bend = CircularLane(center, radius, start_phase, end_phase, clockwise,
                        width, line_types, forbidden, speed_limit, priority)
    length = 2 * radius * angle / 2
    bend_end = bend.position(length, 0)
    next_lane_heading = get_vertical_vector(bend_end - center)
    nxt_dir = next_lane_heading[0] if not clockwise else next_lane_heading[1]
    nxt_dir = np.asarray(nxt_dir)
    following_lane_end = nxt_dir * following_lane_length + bend_end
    following_lane = StraightLane(bend_end, following_lane_end, width,
                                  line_types, forbidden, speed_limit, priority)
    return bend, following_lane
예제 #4
0
    def _try_plug_into_previous_block(self) -> bool:
        acc_lane_len = self.get_config()[Parameter.length]
        no_cross = True

        # extend road and acc raod part, part 0
        self.set_part_idx(0)
        sin_angle = math.sin(np.deg2rad(self.ANGLE))
        cos_angle = math.cos(np.deg2rad(self.ANGLE))
        longitude_len = sin_angle * self.RADIUS * 2 + cos_angle * self.CONNECT_PART_LEN + self.RAMP_LEN

        extend_lane = ExtendStraightLane(
            self.positive_basic_lane, longitude_len + self.EXTRA_PART, [LineType.BROKEN, LineType.CONTINUOUS]
        )
        extend_road = Road(self.pre_block_socket.positive_road.end_node, self.add_road_node())
        no_cross = CreateRoadFrom(
            extend_lane,
            self.positive_lane_num,
            extend_road,
            self.block_network,
            self._global_network,
            side_lane_line_type=LineType.CONTINUOUS,
            ignore_intersection_checking=self.ignore_intersection_checking
        ) and no_cross
        extend_road.get_lanes(self.block_network)[-1].line_types = [
            LineType.BROKEN if self.positive_lane_num != 1 else LineType.CONTINUOUS, LineType.CONTINUOUS
        ]
        no_cross = CreateAdverseRoad(
            extend_road,
            self.block_network,
            self._global_network,
            ignore_intersection_checking=self.ignore_intersection_checking
        ) and no_cross
        _extend_road = -extend_road
        left_lane_line = LineType.NONE if self.positive_lane_num == 1 else LineType.BROKEN
        _extend_road.get_lanes(self.block_network)[-1].line_types = [left_lane_line, LineType.SIDE]

        # main acc part
        acc_side_lane = ExtendStraightLane(
            extend_lane, acc_lane_len + self.lane_width, [extend_lane.line_types[0], LineType.SIDE]
        )
        acc_road = Road(extend_road.end_node, self.add_road_node())
        no_cross = CreateRoadFrom(
            acc_side_lane,
            self.positive_lane_num,
            acc_road,
            self.block_network,
            self._global_network,
            side_lane_line_type=LineType.CONTINUOUS,
            ignore_intersection_checking=self.ignore_intersection_checking
        ) and no_cross
        no_cross = CreateAdverseRoad(
            acc_road,
            self.block_network,
            self._global_network,
            ignore_intersection_checking=self.ignore_intersection_checking
        ) and no_cross
        left_line_type = LineType.CONTINUOUS if self.positive_lane_num == 1 else LineType.BROKEN
        acc_road.get_lanes(self.block_network)[-1].line_types = [left_line_type, LineType.BROKEN]

        # socket part
        socket_side_lane = ExtendStraightLane(acc_side_lane, self.SOCKET_LEN, acc_side_lane.line_types)
        socket_road = Road(acc_road.end_node, self.add_road_node())
        no_cross = CreateRoadFrom(
            socket_side_lane,
            self.positive_lane_num,
            socket_road,
            self.block_network,
            self._global_network,
            side_lane_line_type=LineType.CONTINUOUS,
            ignore_intersection_checking=self.ignore_intersection_checking
        ) and no_cross
        no_cross = CreateAdverseRoad(
            socket_road,
            self.block_network,
            self._global_network,
            ignore_intersection_checking=self.ignore_intersection_checking
        ) and no_cross
        self.add_sockets(PGBlock.create_socket_from_positive_road(socket_road))

        # ramp part, part 1
        self.set_part_idx(1)
        lateral_dist = (1 - cos_angle) * self.RADIUS * 2 + sin_angle * self.CONNECT_PART_LEN
        end_point = extend_lane.position(self.EXTRA_PART + self.RAMP_LEN, lateral_dist + self.lane_width)
        start_point = extend_lane.position(self.EXTRA_PART, lateral_dist + self.lane_width)
        straight_part = StraightLane(
            start_point, end_point, self.lane_width, self.LANE_TYPE, speed_limit=self.SPEED_LIMIT
        )
        straight_road = Road(self.add_road_node(), self.add_road_node())
        self.block_network.add_lane(straight_road.start_node, straight_road.end_node, straight_part)
        no_cross = (
            not check_lane_on_road(
                self._global_network,
                straight_part,
                0.95,
                ignore_intersection_checking=self.ignore_intersection_checking
            )
        ) and no_cross
        self.add_respawn_roads(straight_road)

        # p1 road 0, 1
        bend_1, connect_part = create_bend_straight(
            straight_part,
            self.CONNECT_PART_LEN,
            self.RADIUS,
            np.deg2rad(self.ANGLE),
            False,
            self.lane_width,
            self.LANE_TYPE,
            speed_limit=self.SPEED_LIMIT
        )
        bend_1_road = Road(straight_road.end_node, self.add_road_node())
        connect_road = Road(bend_1_road.end_node, self.add_road_node())
        self.block_network.add_lane(bend_1_road.start_node, bend_1_road.end_node, bend_1)
        self.block_network.add_lane(connect_road.start_node, connect_road.end_node, connect_part)
        no_cross = (
            not check_lane_on_road(
                self._global_network, bend_1, 0.95, ignore_intersection_checking=self.ignore_intersection_checking
            )
        ) and no_cross
        no_cross = (
            not check_lane_on_road(
                self._global_network,
                connect_part,
                0.95,
                ignore_intersection_checking=self.ignore_intersection_checking
            )
        ) and no_cross

        # p1, road 2, 3
        bend_2, acc_lane = create_bend_straight(
            connect_part,
            acc_lane_len,
            self.RADIUS,
            np.deg2rad(self.ANGLE),
            True,
            self.lane_width,
            self.LANE_TYPE,
            speed_limit=self.SPEED_LIMIT
        )
        acc_lane.line_types = [LineType.BROKEN, LineType.CONTINUOUS]
        bend_2_road = Road(connect_road.end_node, self.road_node(0, 0))  # end at part1 road 0, extend road
        self.block_network.add_lane(bend_2_road.start_node, bend_2_road.end_node, bend_2)
        self.block_network.add_lane(acc_road.start_node, acc_road.end_node, acc_lane)
        no_cross = (
            not check_lane_on_road(
                self._global_network, bend_2, 0.95, ignore_intersection_checking=self.ignore_intersection_checking
            )
        ) and no_cross
        no_cross = (
            not check_lane_on_road(
                self._global_network, acc_lane, 0.95, ignore_intersection_checking=self.ignore_intersection_checking
            )
        ) and no_cross

        # p1, road 4, small circular to decorate
        merge_lane, _ = create_bend_straight(
            acc_lane, 10, self.lane_width / 2, np.pi / 2, False, self.lane_width,
            (LineType.BROKEN, LineType.CONTINUOUS)
        )
        self.block_network.add_lane(Decoration.start, Decoration.end, merge_lane)

        return no_cross
예제 #5
0
 def _get_deacc_lane(self, att_lane: StraightLane):
     start = att_lane.position(self.lane_width, self.lane_width)
     end = att_lane.position(att_lane.length, self.lane_width)
     return StraightLane(start, end, self.lane_width, (LineType.BROKEN, LineType.CONTINUOUS))
예제 #6
0
    def __init__(self,
                 global_network: RoadNetwork,
                 lane_width: float,
                 lane_num: int,
                 render_root_np: NodePath,
                 physics_world: PhysicsWorld,
                 length: float = 50,
                 ignore_intersection_checking=False):
        place_holder = PGBlockSocket(Road(Decoration.start, Decoration.end),
                                     Road(Decoration.start, Decoration.end))
        super(FirstPGBlock, self).__init__(
            0,
            place_holder,
            global_network,
            random_seed=0,
            ignore_intersection_checking=ignore_intersection_checking)
        assert length > self.ENTRANCE_LENGTH, (length, self.ENTRANCE_LENGTH)
        self._block_objects = []
        basic_lane = StraightLane(
            [0, lane_width * (lane_num - 1)],
            [self.ENTRANCE_LENGTH, lane_width * (lane_num - 1)],
            line_types=(LineType.BROKEN, LineType.SIDE),
            width=lane_width)
        ego_v_spawn_road = Road(self.NODE_1, self.NODE_2)
        CreateRoadFrom(
            basic_lane,
            lane_num,
            ego_v_spawn_road,
            self.block_network,
            self._global_network,
            ignore_intersection_checking=self.ignore_intersection_checking)
        CreateAdverseRoad(
            ego_v_spawn_road,
            self.block_network,
            self._global_network,
            ignore_intersection_checking=self.ignore_intersection_checking)

        next_lane = ExtendStraightLane(basic_lane,
                                       length - self.ENTRANCE_LENGTH,
                                       [LineType.BROKEN, LineType.SIDE])
        other_v_spawn_road = Road(self.NODE_2, self.NODE_3)
        CreateRoadFrom(
            next_lane,
            lane_num,
            other_v_spawn_road,
            self.block_network,
            self._global_network,
            ignore_intersection_checking=self.ignore_intersection_checking)
        CreateAdverseRoad(
            other_v_spawn_road,
            self.block_network,
            self._global_network,
            ignore_intersection_checking=self.ignore_intersection_checking)

        self._create_in_world()

        # global_network += self.block_network
        global_network.add(self.block_network)

        socket = self.create_socket_from_positive_road(other_v_spawn_road)
        socket.set_index(self.name, 0)

        self.add_sockets(socket)
        self.attach_to_world(render_root_np, physics_world)
        self._respawn_roads = [other_v_spawn_road]
예제 #7
0
    def _create_circular_part(self, road: Road, part_idx: int,
                              radius_exit: float, radius_inner: float,
                              angle: float) -> (str, str, StraightLane, bool):
        """
        Create a part of roundabout according to a straight road
        """
        none_cross = True
        self.set_part_idx(part_idx)
        radius_big = (self.positive_lane_num * 2 -
                      1) * self.lane_width + radius_inner

        # circular part 0
        segment_start_node = road.end_node
        segment_end_node = self.add_road_node()
        segment_road = Road(segment_start_node, segment_end_node)
        lanes = road.get_lanes(
            self._global_network) if part_idx == 0 else road.get_lanes(
                self.block_network)
        right_lane = lanes[-1]
        bend, straight = create_bend_straight(right_lane, 10, radius_exit,
                                              np.deg2rad(angle), True,
                                              self.lane_width,
                                              (LineType.BROKEN, LineType.SIDE))
        ignore_last_2_part_start = self.road_node((part_idx + 3) % 4, 0)
        ignore_last_2_part_end = self.road_node((part_idx + 3) % 4, 0)
        none_cross = CreateRoadFrom(
            bend,
            self.positive_lane_num,
            segment_road,
            self.block_network,
            self._global_network,
            ignore_start=ignore_last_2_part_start,
            ignore_end=ignore_last_2_part_end,
            ignore_intersection_checking=self.ignore_intersection_checking
        ) and none_cross

        # set circular part 0 visualization
        for k, lane in enumerate(segment_road.get_lanes(self.block_network)):
            if k == self.positive_lane_num - 1:
                lane.line_types = [LineType.NONE, LineType.SIDE]
            else:
                lane.line_types = [LineType.NONE, LineType.NONE]

        # circular part 1
        tool_lane_start = straight.position(-5, 0)
        tool_lane_end = straight.position(0, 0)
        tool_lane = StraightLane(tool_lane_start, tool_lane_end)

        bend, straight_to_next_iter_part = create_bend_straight(
            tool_lane, 10, radius_big, np.deg2rad(2 * angle - 90), False,
            self.lane_width, (LineType.BROKEN, LineType.SIDE))

        segment_start_node = segment_end_node
        segment_end_node = self.add_road_node()
        segment_road = Road(segment_start_node, segment_end_node)

        none_cross = CreateRoadFrom(
            bend,
            self.positive_lane_num,
            segment_road,
            self.block_network,
            self._global_network,
            ignore_intersection_checking=self.ignore_intersection_checking
        ) and none_cross

        self.intermediate_spawn_places.append(
            segment_road.get_lanes(self.block_network))

        # circular part 2 and exit straight part
        length = self.EXIT_PART_LENGTH
        tool_lane_start = straight_to_next_iter_part.position(-5, 0)
        tool_lane_end = straight_to_next_iter_part.position(0, 0)
        tool_lane = StraightLane(tool_lane_start, tool_lane_end)

        bend, straight = create_bend_straight(tool_lane, length, radius_exit,
                                              np.deg2rad(angle), True,
                                              self.lane_width,
                                              (LineType.BROKEN, LineType.SIDE))

        segment_start_node = segment_end_node
        segment_end_node = self.add_road_node(
        ) if part_idx < 3 else self.pre_block_socket.negative_road.start_node
        segment_road = Road(segment_start_node, segment_end_node)

        none_cross = CreateRoadFrom(
            bend,
            self.positive_lane_num,
            segment_road,
            self.block_network,
            self._global_network,
            ignore_intersection_checking=self.ignore_intersection_checking
        ) and none_cross

        # set circular part 2 (curve) visualization
        for k, lane in enumerate(segment_road.get_lanes(self.block_network)):
            if k == self.positive_lane_num - 1:
                lane.line_types = [LineType.NONE, LineType.SIDE]
            else:
                lane.line_types = [LineType.NONE, LineType.NONE]

        exit_start = segment_end_node
        exit_end = self.add_road_node()
        segment_road = Road(exit_start, exit_end)
        if part_idx < 3:
            none_cross = CreateRoadFrom(
                straight,
                self.positive_lane_num,
                segment_road,
                self.block_network,
                self._global_network,
                ignore_intersection_checking=self.ignore_intersection_checking
            ) and none_cross
            self.add_sockets(
                self.create_socket_from_positive_road(segment_road))

        #  add circular part 3 at last
        segment_start = self.road_node(part_idx, 1)
        segment_end = self.road_node((part_idx + 1) % 4, 0)
        segment_road = Road(segment_start, segment_end)
        tool_lane_start = straight_to_next_iter_part.position(-6, 0)
        tool_lane_end = straight_to_next_iter_part.position(0, 0)
        tool_lane = StraightLane(tool_lane_start, tool_lane_end)

        beneath = (self.positive_lane_num * 2 -
                   1) * self.lane_width / 2 + radius_exit
        cos = math.cos(np.deg2rad(angle))
        radius_this_seg = beneath / cos - radius_exit

        bend, _ = create_bend_straight(tool_lane, 5, radius_this_seg,
                                       np.deg2rad(180 - 2 * angle), False,
                                       self.lane_width,
                                       (LineType.BROKEN, LineType.SIDE))
        CreateRoadFrom(
            bend,
            self.positive_lane_num,
            segment_road,
            self.block_network,
            self._global_network,
            ignore_intersection_checking=self.ignore_intersection_checking)

        # set circular part 2 visualization
        for k, lane in enumerate(segment_road.get_lanes(self.block_network)):
            if k == 0:
                if self.positive_lane_num > 1:
                    lane.line_types = [LineType.CONTINUOUS, LineType.BROKEN]
                else:
                    lane.line_types = [LineType.CONTINUOUS, LineType.NONE]
            else:
                lane.line_types = [LineType.BROKEN, LineType.BROKEN]

        return Road(exit_start, exit_end), none_cross
예제 #8
0
def CreateTwoWayRoad(
        road_to_change: "Road",
        roadnet_to_get_road: "RoadNetwork",  # mostly, block network
        roadnet_to_check_cross: "RoadNetwork",  # mostly, previous global network
        new_road_name: Road = None,
        ignore_start: str = None,
        ignore_end: str = None,
        center_line_type=LineType.
    CONTINUOUS,  # Identical to Block.CENTER_LINE_TYPE
        side_lane_line_type=LineType.SIDE,
        inner_lane_line_type=LineType.BROKEN,
        ignore_intersection_checking=None) -> bool:
    """
    This function will add a new road in reverse direction to the road network
    Then the road will change from:
    ---------->
    ---------->
    to:
    <--------->
    <--------->
    As a result, vehicles can drive in both direction
    :return: cross or not
    """
    adverse_road = Road(
        road_to_change.end_node,
        road_to_change.start_node) if new_road_name is None else new_road_name
    lanes = get_lanes_on_road(road_to_change, roadnet_to_get_road)
    reference_lane = lanes[-1]
    num = len(lanes)
    width = reference_lane.width_at(0)
    if isinstance(reference_lane, StraightLane):
        start_point = reference_lane.position(lanes[-1].length,
                                              -(num - 1) * width)
        end_point = reference_lane.position(0, -(num - 1) * width)
        symmetric_lane = StraightLane(start_point, end_point, width,
                                      lanes[-1].line_types,
                                      reference_lane.forbidden,
                                      reference_lane.speed_limit,
                                      reference_lane.priority)
    elif isinstance(reference_lane, CircularLane):
        start_phase = reference_lane.end_phase
        end_phase = reference_lane.start_phase
        clockwise = False if reference_lane.direction == 1 else True
        if not clockwise:
            radius = reference_lane.radius + (num - 1) * width
        else:
            radius = reference_lane.radius - (num - 1) * width
        symmetric_lane = CircularLane(reference_lane.center, radius,
                                      start_phase, end_phase, clockwise, width,
                                      reference_lane.line_types,
                                      reference_lane.forbidden,
                                      reference_lane.speed_limit,
                                      reference_lane.priority)
    else:
        raise ValueError("Creating other lanes is not supported")
    success = CreateRoadFrom(
        symmetric_lane,
        num,
        adverse_road,
        roadnet_to_get_road,
        roadnet_to_check_cross,
        ignore_start=ignore_start,
        ignore_end=ignore_end,
        side_lane_line_type=side_lane_line_type,
        inner_lane_line_type=inner_lane_line_type,
        center_line_type=center_line_type,
        ignore_intersection_checking=ignore_intersection_checking)
    return success
예제 #9
0
    def _try_plug_into_previous_block(self) -> bool:
        acc_lane_len = self.get_config()[Parameter.length]
        no_cross = True
        fork_lane_num = 2

        # extend road and acc raod part, part 0
        self.set_part_idx(0)
        sin_angle = math.sinsin(np.deg2rad(self.ANGLE))
        cos_angle = math.cos(np.deg2rad(self.ANGLE))
        longitude_len = sin_angle * self.RADIUS * 2 + cos_angle * self.CONNECT_PART_LEN + self.RAMP_LEN

        extend_lane = ExtendStraightLane(
            self.positive_basic_lane, longitude_len + self.EXTRA_PART,
            [LineType.BROKEN, LineType.CONTINUOUS])
        extend_road = Road(self.pre_block_socket.positive_road.end_node,
                           self.add_road_node())
        no_cross = CreateRoadFrom(
            extend_lane,
            self.positive_lane_num,
            extend_road,
            self.block_network,
            self._global_network,
            side_lane_line_type=LineType.CONTINUOUS) and no_cross
        no_cross = CreateAdverseRoad(extend_road, self.block_network,
                                     self._global_network) and no_cross

        acc_side_lane = ExtendStraightLane(
            extend_lane, acc_lane_len + self.lane_width,
            [LineType.BROKEN, LineType.CONTINUOUS])
        acc_road = Road(extend_road.end_node, self.add_road_node())
        no_cross = CreateRoadFrom(acc_side_lane, self.positive_lane_num,
                                  acc_road, self.block_network,
                                  self._global_network) and no_cross
        no_cross = CreateAdverseRoad(acc_road, self.block_network,
                                     self._global_network) and no_cross
        acc_road.get_lanes(self.block_network)[-1].line_types = [
            LineType.BROKEN, LineType.BROKEN
        ]

        # ramp part, part 1
        self.set_part_idx(1)
        lateral_dist = (1 - cos_angle
                        ) * self.RADIUS * 2 + sin_angle * self.CONNECT_PART_LEN
        end_point = extend_lane.position(self.EXTRA_PART + self.RAMP_LEN,
                                         lateral_dist + self.lane_width)
        start_point = extend_lane.position(self.EXTRA_PART,
                                           lateral_dist + self.lane_width)
        straight_part = StraightLane(start_point,
                                     end_point,
                                     self.lane_width,
                                     self.LANE_TYPE,
                                     speed_limit=self.SPEED_LIMIT)

        # p1 road 0, 1
        bend_1, connect_part = create_bend_straight(
            straight_part,
            self.CONNECT_PART_LEN,
            self.RADIUS,
            np.deg2rad(self.ANGLE),
            False,
            self.lane_width,
            self.LANE_TYPE,
            speed_limit=self.SPEED_LIMIT)
        bend_1_road = Road(self.add_road_node(), self.add_road_node())
        self.add_respawn_roads(bend_1_road)
        connect_road = Road(bend_1_road.end_node, self.add_road_node())
        self.block_network.add_lane(bend_1_road.start_node,
                                    bend_1_road.end_node, bend_1)
        self.block_network.add_lane(connect_road.start_node,
                                    connect_road.end_node, connect_part)
        no_cross = CreateRoadFrom(bend_1, fork_lane_num, bend_1_road,
                                  self.block_network, self._global_network,
                                  False) and no_cross
        no_cross = CreateRoadFrom(connect_part, fork_lane_num, connect_road,
                                  self.block_network, self._global_network,
                                  False) and no_cross

        # p1, road 2, 3
        bend_2, acc_lane = create_bend_straight(connect_part,
                                                acc_lane_len + self.lane_width,
                                                self.RADIUS,
                                                np.deg2rad(self.ANGLE),
                                                True,
                                                self.lane_width,
                                                self.LANE_TYPE,
                                                speed_limit=self.SPEED_LIMIT)
        acc_lane.line_types = [LineType.BROKEN, LineType.CONTINUOUS]
        bend_2_road = Road(connect_road.end_node, self.road_node(
            0, 0))  # end at part1 road 0, extend road
        acc_road = Road(self.road_node(0, 0), self.road_node(0, 1))
        self.block_network.add_lane(bend_2_road.start_node,
                                    bend_2_road.end_node, bend_2)
        no_cross = CreateRoadFrom(
            bend_2,
            fork_lane_num,
            bend_2_road,
            self.block_network,
            self._global_network,
            False,
            inner_lane_line_type=LineType.BROKEN) and no_cross
        no_cross = CreateRoadFrom(
            acc_lane,
            fork_lane_num,
            acc_road,
            self.block_network,
            self._global_network,
            False,
            inner_lane_line_type=LineType.BROKEN,
        ) and no_cross
        self.add_sockets(PGBlock.create_socket_from_positive_road(acc_road))
        return no_cross