예제 #1
0
    def _try_plug_into_previous_block(self) -> bool:
        acc_lane_len = self.get_config()[Parameter.length]
        no_cross = True
        fork_lane_num = self.get_config()[Parameter.lane_num] + 1

        # extend road and acc raod part, part 0
        self.set_part_idx(0)
        sin_angle = np.sin(np.deg2rad(self.ANGLE))
        cos_angle = np.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.STRIPED, 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) 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.STRIPED, 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.STRIPED, LineType.STRIPED
        ]
        self.add_sockets(Block.create_socket_from_positive_road(acc_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)) and no_cross
        self.add_reborn_roads(straight_road)

        # p1 road 0, 1
        bend_1, connect_part = sharpbend(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 = 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 = sharpbend(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.STRIPED, 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)
        self.block_network.add_lane(acc_road.start_node, acc_road.end_node,
                                    acc_lane)
        no_cross = CreateRoadFrom(bend_2, fork_lane_num, bend_2_road,
                                  self.block_network, self._global_network,
                                  False) and no_cross
        no_cross = CreateRoadFrom(acc_lane, fork_lane_num, acc_road,
                                  self.block_network, self._global_network,
                                  False) and no_cross
        return no_cross
예제 #2
0
    def _try_plug_into_previous_block(self) -> bool:
        no_cross = True
        sin_angle = np.sin(np.deg2rad(self.ANGLE))
        cos_angle = np.cos(np.deg2rad(self.ANGLE))
        longitude_len = sin_angle * self.RADIUS * 2 + cos_angle * self.CONNECT_PART_LEN + self.RAMP_LEN

        self.set_part_idx(0)
        # part 0 road 0
        dec_lane_len = self.PARAMETER_SPACE.sample()[Parameter.length]
        dec_lane = ExtendStraightLane(self.positive_basic_lane,
                                      dec_lane_len + self.lane_width,
                                      [LineType.STRIPED, LineType.CONTINUOUS])
        dec_road = Road(self._pre_block_socket.positive_road.end_node,
                        self.add_road_node())
        no_cross = CreateRoadFrom(dec_lane, self.positive_lane_num, dec_road,
                                  self.block_network,
                                  self._global_network) and no_cross
        no_cross = CreateAdverseRoad(dec_road, self.block_network,
                                     self._global_network) and no_cross
        dec_right_lane = dec_road.get_lanes(self.block_network)[-1]
        dec_right_lane.line_types = [LineType.STRIPED, LineType.STRIPED]

        # part 0 road 1
        extend_lane = ExtendStraightLane(
            dec_right_lane, longitude_len,
            [LineType.STRIPED, LineType.CONTINUOUS])
        extend_road = Road(dec_road.end_node, self.add_road_node())
        no_cross = CreateRoadFrom(extend_lane, self.positive_lane_num,
                                  extend_road, self.block_network,
                                  self._global_network) and no_cross
        no_cross = CreateAdverseRoad(extend_road, self.block_network,
                                     self._global_network) and no_cross
        self.add_sockets(self.create_socket_from_positive_road(extend_road))

        # part 1 road 0
        self.set_part_idx(1)
        dec_side_right_lane = self._get_deacc_lane(dec_right_lane)
        self.block_network.add_lane(dec_road.start_node, self.add_road_node(),
                                    dec_side_right_lane)
        no_cross = (not check_lane_on_road(
            self._global_network, dec_side_right_lane, 0.95)) and no_cross

        bend_1, connect_part = sharpbend(dec_side_right_lane,
                                         self.CONNECT_PART_LEN,
                                         self.RADIUS,
                                         np.deg2rad(self.ANGLE),
                                         True,
                                         self.lane_width,
                                         self.LANE_TYPE,
                                         speed_limit=self.SPEED_LIMIT)
        bend_1_road = Road(self.road_node(1, 0), 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)) and no_cross
        no_cross = (not check_lane_on_road(self._global_network, connect_part,
                                           0.95)) and no_cross

        bend_2, straight_part = sharpbend(connect_part,
                                          self.RAMP_LEN,
                                          self.RADIUS,
                                          np.deg2rad(self.ANGLE),
                                          False,
                                          self.lane_width,
                                          self.LANE_TYPE,
                                          speed_limit=self.SPEED_LIMIT)
        bend_2_road = Road(
            connect_road.end_node,
            self.add_road_node())  # end at part1 road 0, extend road
        straight_road = Road(bend_2_road.end_node, self.add_road_node())
        self.block_network.add_lane(bend_2_road.start_node,
                                    bend_2_road.end_node, bend_2)
        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, bend_2,
                                           0.95)) and no_cross
        no_cross = (not check_lane_on_road(self._global_network, straight_part,
                                           0.95)) and no_cross

        decoration_part = self._get_merge_part(dec_side_right_lane)
        self.block_network.add_lane(Decoration.start, Decoration.end,
                                    decoration_part)
        return no_cross
예제 #3
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 = sharpbend(right_lane, 10, radius_exit,
                                   np.deg2rad(angle), True, self.lane_width,
                                   (LineType.STRIPED, 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) 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 = sharpbend(
            tool_lane, 10, radius_big, np.deg2rad(2 * angle - 90), False,
            self.lane_width, (LineType.STRIPED, 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) and none_cross

        # 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 = sharpbend(tool_lane, length, radius_exit,
                                   np.deg2rad(angle), True, self.lane_width,
                                   (LineType.STRIPED, 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) 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) 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 = np.cos(np.deg2rad(angle))
        radius_this_seg = beneath / cos - radius_exit

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

        # 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.STRIPED]
                else:
                    lane.line_types = [LineType.CONTINUOUS, LineType.NONE]
            else:
                lane.line_types = [LineType.STRIPED, LineType.STRIPED]

        return Road(exit_start, exit_end), none_cross
예제 #4
0
class RoutingLocalizationModule:
    navigation_info_dim = 10
    NAVI_POINT_DIST = 50
    PRE_NOTIFY_DIST = 40
    MARK_COLOR = COLLISION_INFO_COLOR["green"][1]
    MIN_ALPHA = 0.15
    CKPT_UPDATE_RANGE = 5
    FORCE_CALCULATE = False
    LINE_TO_DEST_HEIGHT = 0.6

    def __init__(self,
                 pg_world,
                 show_navi_mark: bool = False,
                 random_navi_mark_color=False,
                 show_dest_mark=False,
                 show_line_to_dest=False):
        """
        This class define a helper for localizing vehicles and retrieving navigation information.
        It now only support from first block start to the end node, but can be extended easily.
        """
        self.map = None
        self.final_road = None
        self.checkpoints = None
        self.final_lane = None
        self.current_ref_lanes = None
        self.current_road = None
        self._target_checkpoints_index = None
        self._navi_info = np.zeros(
            (self.navigation_info_dim, ))  # navi information res
        self.navi_mark_color = (
            0.6, 0.8,
            0.5) if not random_navi_mark_color else get_np_random().rand(3)

        # Vis
        self._is_showing = True  # store the state of navigation mark
        self._show_navi_info = (
            pg_world.mode == RENDER_MODE_ONSCREEN
            and not pg_world.world_config["debug_physics_world"])
        self._dest_node_path = None
        self._goal_node_path = None
        self._arrow_node_path = None
        self._line_to_dest = None
        self._show_line_to_dest = show_line_to_dest
        if self._show_navi_info:
            # nodepath
            self._line_to_dest = pg_world.render.attachNewNode("line")
            self._goal_node_path = pg_world.render.attachNewNode("target")
            self._dest_node_path = pg_world.render.attachNewNode("dest")
            self._arrow_node_path = pg_world.aspect2d.attachNewNode("arrow")

            navi_arrow_model = AssetLoader.loader.loadModel(
                AssetLoader.file_path("models", "navi_arrow.gltf"))
            navi_arrow_model.setScale(0.1, 0.12, 0.2)
            navi_arrow_model.setPos(2, 1.15, -0.221)
            self._left_arrow = self._arrow_node_path.attachNewNode(
                "left arrow")
            self._left_arrow.setP(180)
            self._right_arrow = self._arrow_node_path.attachNewNode(
                "right arrow")
            self._left_arrow.setColor(self.MARK_COLOR)
            self._right_arrow.setColor(self.MARK_COLOR)
            navi_arrow_model.instanceTo(self._left_arrow)
            navi_arrow_model.instanceTo(self._right_arrow)
            self._arrow_node_path.setPos(0, 0, 0.08)
            self._arrow_node_path.hide(BitMask32.allOn())
            self._arrow_node_path.show(CamMask.MainCam)
            self._arrow_node_path.setQuat(
                LQuaternionf(np.cos(-np.pi / 4), 0, 0, np.sin(-np.pi / 4)))

            # the transparency attribute of gltf model is invalid on windows
            # self._arrow_node_path.setTransparency(TransparencyAttrib.M_alpha)
            if show_navi_mark:
                navi_point_model = AssetLoader.loader.loadModel(
                    AssetLoader.file_path("models", "box.bam"))
                navi_point_model.reparentTo(self._goal_node_path)
            if show_dest_mark:
                dest_point_model = AssetLoader.loader.loadModel(
                    AssetLoader.file_path("models", "box.bam"))
                dest_point_model.reparentTo(self._dest_node_path)
            if show_line_to_dest:
                line_seg = LineSegs("line_to_dest")
                line_seg.setColor(self.navi_mark_color[0],
                                  self.navi_mark_color[1],
                                  self.navi_mark_color[2], 0.7)
                line_seg.setThickness(2)
                self._dynamic_line_np = NodePath(line_seg.create(True))
                self._dynamic_line_np.reparentTo(pg_world.render)
                self._line_to_dest = line_seg

            self._goal_node_path.setTransparency(TransparencyAttrib.M_alpha)
            self._dest_node_path.setTransparency(TransparencyAttrib.M_alpha)

            self._goal_node_path.setColor(self.navi_mark_color[0],
                                          self.navi_mark_color[1],
                                          self.navi_mark_color[2], 0.7)
            self._dest_node_path.setColor(self.navi_mark_color[0],
                                          self.navi_mark_color[1],
                                          self.navi_mark_color[2], 0.7)
            self._goal_node_path.hide(BitMask32.allOn())
            self._dest_node_path.hide(BitMask32.allOn())
            self._goal_node_path.show(CamMask.MainCam)
            self._dest_node_path.show(CamMask.MainCam)
        logging.debug("Load Vehicle Module: {}".format(
            self.__class__.__name__))

    def update(self,
               map: Map,
               current_lane_index,
               final_road_node=None,
               random_seed=False):
        start_road_node = current_lane_index[0]
        self.map = map
        if start_road_node is None:
            start_road_node = FirstBlock.NODE_1
        if final_road_node is None:
            current_road_negative = Road(
                *current_lane_index[:-1]).is_negative_road()
            random_seed = random_seed if random_seed is not False else map.random_seed
            # choose first block when born on negative road
            block = map.blocks[0] if current_road_negative else map.blocks[-1]
            sockets = block.get_socket_list()
            while True:
                socket = get_np_random(random_seed).choice(sockets)
                if not socket.is_socket_node(start_road_node):
                    break
                else:
                    sockets.remove(socket)
                    if len(sockets) == 0:
                        raise ValueError("Can not set a destination!")
            # choose negative road end node when current road is negative road
            final_road_node = socket.negative_road.end_node if current_road_negative else socket.positive_road.end_node
        self.set_route(start_road_node, final_road_node)

    def set_route(self, start_road_node: str, end_road_node: str):
        """
        Find a shorest path from start road to end road
        :param start_road_node: start road node
        :param end_road_node: end road node
        :return: None
        """
        self.checkpoints = self.map.road_network.shortest_path(
            start_road_node, end_road_node)
        assert len(
            self.checkpoints) > 2, "Can not find a route from {} to {}".format(
                start_road_node, end_road_node)
        # update routing info
        self.final_road = Road(self.checkpoints[-2], end_road_node)
        final_lanes = self.final_road.get_lanes(self.map.road_network)
        self.final_lane = final_lanes[-1]
        self._target_checkpoints_index = [0, 1]
        self._navi_info.fill(0.0)
        target_road_1_start = self.checkpoints[0]
        target_road_1_end = self.checkpoints[1]
        self.current_ref_lanes = self.map.road_network.graph[
            target_road_1_start][target_road_1_end]
        self.current_road = Road(target_road_1_start, target_road_1_end)
        if self._dest_node_path is not None:
            ref_lane = final_lanes[0]
            later_middle = (float(self.get_current_lane_num()) / 2 -
                            0.5) * self.get_current_lane_width()
            check_point = ref_lane.position(ref_lane.length, later_middle)
            self._dest_node_path.setPos(check_point[0], -check_point[1], 1.8)

    def update_navigation_localization(self, ego_vehicle):
        position = ego_vehicle.position
        lane, lane_index = self.get_current_lane(ego_vehicle)
        if lane is None:
            lane, lane_index = ego_vehicle.lane, ego_vehicle.lane_index
            ego_vehicle.on_lane = False
            if self.FORCE_CALCULATE:
                lane_index, _ = self.map.road_network.get_closest_lane_index(
                    position)
                lane = self.map.road_network.get_lane(lane_index)
        long, _ = lane.local_coordinates(position)
        self._update_target_checkpoints(lane_index, long)

        assert len(self.checkpoints) > 2

        target_road_1_start = self.checkpoints[
            self._target_checkpoints_index[0]]
        target_road_1_end = self.checkpoints[self._target_checkpoints_index[0]
                                             + 1]
        target_road_2_start = self.checkpoints[
            self._target_checkpoints_index[1]]
        target_road_2_end = self.checkpoints[self._target_checkpoints_index[1]
                                             + 1]
        target_lanes_1 = self.map.road_network.graph[target_road_1_start][
            target_road_1_end]
        target_lanes_2 = self.map.road_network.graph[target_road_2_start][
            target_road_2_end]
        self.current_ref_lanes = target_lanes_1
        self.current_road = Road(target_road_1_start, target_road_1_end)

        self._navi_info.fill(0.0)
        half = self.navigation_info_dim // 2
        self._navi_info[:
                        half], lanes_heading1, checkpoint = self._get_info_for_checkpoint(
                            lanes_id=0,
                            lanes=target_lanes_1,
                            ego_vehicle=ego_vehicle)

        self._navi_info[
            half:], lanes_heading2, _ = self._get_info_for_checkpoint(
                lanes_id=1, lanes=target_lanes_2, ego_vehicle=ego_vehicle)

        if self._show_navi_info:
            pos_of_goal = checkpoint
            self._goal_node_path.setPos(pos_of_goal[0], -pos_of_goal[1], 1.8)
            self._goal_node_path.setH(self._goal_node_path.getH() + 3)
            self._update_navi_arrow([lanes_heading1, lanes_heading2])
            dest_pos = self._dest_node_path.getPos()
            self._draw_line_to_dest(pg_world=ego_vehicle.pg_world,
                                    start_position=ego_vehicle.position,
                                    end_position=(dest_pos[0], -dest_pos[1]))

        return lane, lane_index

    def _get_info_for_checkpoint(self, lanes_id, lanes, ego_vehicle):
        ref_lane = lanes[0]
        later_middle = (float(self.get_current_lane_num()) / 2 -
                        0.5) * self.get_current_lane_width()
        check_point = ref_lane.position(ref_lane.length, later_middle)
        if lanes_id == 0:
            # calculate ego v lane heading
            lanes_heading = ref_lane.heading_at(
                ref_lane.local_coordinates(ego_vehicle.position)[0])
        else:
            lanes_heading = ref_lane.heading_at(
                min(self.PRE_NOTIFY_DIST, ref_lane.length))
        dir_vec = check_point - ego_vehicle.position
        dir_norm = norm(dir_vec[0], dir_vec[1])
        if dir_norm > self.NAVI_POINT_DIST:
            dir_vec = dir_vec / dir_norm * self.NAVI_POINT_DIST
        proj_heading, proj_side = ego_vehicle.projection(dir_vec)
        bendradius = 0.0
        dir = 0.0
        angle = 0.0
        if isinstance(ref_lane, CircularLane):
            bendradius = ref_lane.radius / (
                BlockParameterSpace.CURVE[Parameter.radius].max +
                self.get_current_lane_num() * self.get_current_lane_width())
            dir = ref_lane.direction
            if dir == 1:
                angle = ref_lane.end_phase - ref_lane.start_phase
            elif dir == -1:
                angle = ref_lane.start_phase - ref_lane.end_phase
        return (clip((proj_heading / self.NAVI_POINT_DIST + 1) / 2, 0.0, 1.0),
                clip((proj_side / self.NAVI_POINT_DIST + 1) / 2, 0.0,
                     1.0), clip(bendradius, 0.0,
                                1.0), clip((dir + 1) / 2, 0.0, 1.0),
                clip((np.rad2deg(angle) /
                      BlockParameterSpace.CURVE[Parameter.angle].max + 1) / 2,
                     0.0, 1.0)), lanes_heading, check_point

    def _update_navi_arrow(self, lanes_heading):
        lane_0_heading = lanes_heading[0]
        lane_1_heading = lanes_heading[1]
        if abs(lane_0_heading - lane_1_heading) < 0.01:
            if self._is_showing:
                self._left_arrow.detachNode()
                self._right_arrow.detachNode()
                self._is_showing = False
        else:
            dir_0 = np.array(
                [math.cos(lane_0_heading),
                 math.sin(lane_0_heading), 0])
            dir_1 = np.array(
                [math.cos(lane_1_heading),
                 math.sin(lane_1_heading), 0])
            cross_product = np.cross(dir_1, dir_0)
            left = False if cross_product[-1] < 0 else True
            if not self._is_showing:
                self._is_showing = True
            if left:
                if not self._left_arrow.hasParent():
                    self._left_arrow.reparentTo(self._arrow_node_path)
                if self._right_arrow.hasParent():
                    self._right_arrow.detachNode()
            else:
                if not self._right_arrow.hasParent():
                    self._right_arrow.reparentTo(self._arrow_node_path)
                if self._left_arrow.hasParent():
                    self._left_arrow.detachNode()

    def _update_target_checkpoints(self, ego_lane_index, ego_lane_longitude):
        """
        Return should_update: True or False
        """
        if self._target_checkpoints_index[0] == self._target_checkpoints_index[
                1]:  # on last road
            return False

        # arrive to second checkpoint
        current_road_start_point = ego_lane_index[0]
        if current_road_start_point in self.checkpoints[self._target_checkpoints_index[1]:] \
                and ego_lane_longitude < self.CKPT_UPDATE_RANGE:
            if current_road_start_point not in self.checkpoints[
                    self._target_checkpoints_index[1]:-1]:
                return False
            idx = self.checkpoints.index(current_road_start_point,
                                         self._target_checkpoints_index[1], -1)
            self._target_checkpoints_index = [idx]
            if idx + 1 == len(self.checkpoints) - 1:
                self._target_checkpoints_index.append(idx)
            else:
                self._target_checkpoints_index.append(idx + 1)
            return True
        return False

    def get_navi_info(self):
        return self._navi_info

    def destroy(self):
        if self._show_navi_info:
            self._arrow_node_path.removeNode()
            self._line_to_dest.removeNode()
            self._dest_node_path.removeNode()
            self._goal_node_path.removeNode()

    def set_force_calculate_lane_index(self, force: bool):
        self.FORCE_CALCULATE = force

    def __del__(self):
        logging.debug("{} is destroyed".format(self.__class__.__name__))

    def get_current_lateral_range(self, current_position, pg_world) -> float:
        """Return the maximum lateral distance from left to right."""
        # special process for special block
        current_block_id = self.current_road.block_ID()
        if current_block_id == Split.ID or current_block_id == Merge.ID:
            left_lane = self.current_ref_lanes[0]
            assert isinstance(
                left_lane,
                StraightLane), "Reference lane should be straight lane here"
            long, lat = left_lane.local_coordinates(current_position)
            current_position = left_lane.position(long, -left_lane.width / 2)
            return self._ray_lateral_range(
                pg_world, current_position,
                self.current_ref_lanes[0].direction_lateral)
        else:
            return self.get_current_lane_width() * self.get_current_lane_num()

    def get_current_lane_width(self) -> float:
        return self.map.config[self.map.LANE_WIDTH]

    def get_current_lane_num(self) -> float:
        return len(self.current_ref_lanes)

    def get_current_lane(self, ego_vehicle):
        possible_lanes = ray_localization(np.array(
            ego_vehicle.heading.tolist()),
                                          ego_vehicle.position,
                                          ego_vehicle.pg_world,
                                          return_all_result=True)
        for lane, index, l_1_dist in possible_lanes:
            if lane in self.current_ref_lanes:
                return lane, index
        return possible_lanes[0][:-1] if len(possible_lanes) > 0 else (None,
                                                                       None)

    def _ray_lateral_range(self, pg_world, start_position, dir, length=50):
        """
        It is used to measure the lateral range of special blocks
        :param start_position: start_point
        :param dir: ray direction
        :param length: length of ray
        :return: lateral range [m]
        """
        end_position = start_position[0] + dir[0] * length, start_position[
            1] + dir[1] * length
        start_position = panda_position(start_position, z=0.15)
        end_position = panda_position(end_position, z=0.15)
        mask = BitMask32.bit(FirstBlock.CONTINUOUS_COLLISION_MASK)
        res = pg_world.physics_world.static_world.rayTestClosest(
            start_position, end_position, mask=mask)
        if not res.hasHit():
            return length
        else:
            return res.getHitFraction() * length

    def _draw_line_to_dest(self, pg_world, start_position, end_position):
        if not self._show_line_to_dest:
            return
        line_seg = self._line_to_dest
        line_seg.moveTo(
            panda_position(start_position, self.LINE_TO_DEST_HEIGHT))
        line_seg.drawTo(panda_position(end_position, self.LINE_TO_DEST_HEIGHT))
        self._dynamic_line_np.removeNode()
        self._dynamic_line_np = NodePath(line_seg.create(False))
        self._dynamic_line_np.hide(CamMask.Shadow | CamMask.RgbCam)
        self._dynamic_line_np.reparentTo(pg_world.render)
예제 #5
0
    def _add_one_parking_space(
        self, in_socket: BlockSocket, out_socket: BlockSocket, part_idx: int, radius, dist_to_in, dist_to_out
    ) -> bool:
        no_cross = True

        # lane into parking space and parking space, 1
        if in_socket.is_same_socket(self.pre_block_socket) or in_socket.is_same_socket(
                self.pre_block_socket.get_socket_in_reverse()):
            net = self._global_network
        else:
            net = self.block_network
        in_lane = in_socket.positive_road.get_lanes(net)[0]
        start_node = in_socket.positive_road.end_node
        if dist_to_in > 1e-3:
            # a straight part will be added
            in_lane = ExtendStraightLane(in_lane, dist_to_in, [LineType.NONE, LineType.NONE])
            in_road = Road(in_socket.positive_road.end_node, self.road_node(part_idx, 0))
            CreateRoadFrom(
                in_lane,
                self.positive_lane_num,
                in_road,
                self.block_network,
                self._global_network,
                center_line_type=LineType.NONE,
                inner_lane_line_type=LineType.NONE,
                side_lane_line_type=LineType.NONE
            )
            start_node = self.road_node(part_idx, 0)

        bend, straight = create_bend_straight(
            in_lane, self.parking_space_length, radius, self.ANGLE, True, self.parking_space_width
        )
        bend_road = Road(start_node, self.road_node(part_idx, 1))
        bend_no_cross = CreateRoadFrom(
            bend,
            self.positive_lane_num,
            bend_road,
            self.block_network,
            self._global_network,
            center_line_type=LineType.NONE,
            inner_lane_line_type=LineType.NONE,
            side_lane_line_type=LineType.SIDE if dist_to_in < 1e-3 else LineType.NONE
        )
        if dist_to_in < 1e-3:
            no_cross = no_cross and bend_no_cross

        straight_road = Road(self.road_node(part_idx, 1), self.road_node(part_idx, 2))
        self.dest_roads.append(straight_road)
        no_cross = no_cross and CreateRoadFrom(
            straight,
            self.positive_lane_num,
            straight_road,
            self.block_network,
            self._global_network,
            center_line_type=LineType.CONTINUOUS,
            inner_lane_line_type=LineType.NONE,
            side_lane_line_type=LineType.SIDE if dist_to_in < 1e-3 else LineType.NONE,
            center_line_color=LineColor.GREY
        )

        # lane into parking space and parking space, 2
        neg_road: Road = out_socket.negative_road
        if out_socket.is_same_socket(self.pre_block_socket) or out_socket.is_same_socket(
                self.pre_block_socket.get_socket_in_reverse()):
            net = self._global_network
        else:
            net = self.block_network
        neg_lane = \
            neg_road.get_lanes(net)[0]
        start_node = neg_road.end_node
        if dist_to_out > 1e-3:
            # a straight part will be added
            neg_lane = ExtendStraightLane(neg_lane, dist_to_out, [LineType.NONE, LineType.NONE])
            neg_road = Road(neg_road.end_node, self.road_node(part_idx, 3))
            CreateRoadFrom(
                neg_lane,
                self.positive_lane_num,
                neg_road,
                self.block_network,
                self._global_network,
                center_line_type=LineType.NONE,
                inner_lane_line_type=LineType.NONE,
                side_lane_line_type=LineType.NONE
            )
            start_node = self.road_node(part_idx, 3)

        bend, straight = create_bend_straight(
            neg_lane, self.lane_width, radius, self.ANGLE, False, self.parking_space_width
        )
        bend_road = Road(start_node, self.road_node(part_idx, 4))
        CreateRoadFrom(
            bend,
            self.positive_lane_num,
            bend_road,
            self.block_network,
            self._global_network,
            center_line_type=LineType.NONE,
            inner_lane_line_type=LineType.NONE,
            side_lane_line_type=LineType.NONE
        )

        straight_road = Road(self.road_node(part_idx, 4), self.road_node(part_idx, 1))
        CreateRoadFrom(
            straight,
            self.positive_lane_num,
            straight_road,
            self.block_network,
            self._global_network,
            center_line_type=LineType.NONE,
            inner_lane_line_type=LineType.NONE,
            side_lane_line_type=LineType.NONE
        )

        # give it a new road name to make it be a two way road (1,2) = (5,6) = parking space !
        parking_road = Road(self.road_node(part_idx, 5), self.road_node(part_idx, 6))
        self.spawn_roads.append(parking_road)
        CreateTwoWayRoad(
            Road(self.road_node(part_idx, 1), self.road_node(part_idx, 2)),
            self.block_network,
            self._global_network,
            parking_road,
            center_line_type=LineType.NONE,
            inner_lane_line_type=LineType.NONE,
            side_lane_line_type=LineType.SIDE if dist_to_out < 1e-3 else LineType.NONE
        )

        # out part
        parking_lane = parking_road.get_lanes(self.block_network)[0]

        # out part 1
        bend, straight = create_bend_straight(
            parking_lane, 0.1 if dist_to_out < 1e-3 else dist_to_out, radius, self.ANGLE, True, parking_lane.width
        )
        out_bend_road = Road(
            self.road_node(part_idx, 6),
            self.road_node(part_idx, 7) if dist_to_out > 1e-3 else out_socket.positive_road.start_node
        )
        bend_success = CreateRoadFrom(
            bend,
            self.positive_lane_num,
            out_bend_road,
            self.block_network,
            self._global_network,
            center_line_type=LineType.NONE,
            inner_lane_line_type=LineType.NONE,
            side_lane_line_type=LineType.SIDE if dist_to_out < 1e-3 else LineType.NONE
        )
        if dist_to_out < 1e-3:
            no_cross = no_cross and bend_success

        if dist_to_out > 1e-3:
            out_straight_road = Road(self.road_node(part_idx, 7), out_socket.positive_road.start_node)
            no_cross = no_cross and CreateRoadFrom(
                straight,
                self.positive_lane_num,
                out_straight_road,
                self.block_network,
                self._global_network,
                center_line_type=LineType.NONE,
                inner_lane_line_type=LineType.NONE,
                side_lane_line_type=LineType.NONE
            )
        # out part 2
        extend_lane = ExtendStraightLane(parking_lane, self.lane_width, [LineType.NONE, LineType.NONE])
        CreateRoadFrom(
            extend_lane,
            self.positive_lane_num,
            Road(self.road_node(part_idx, 6), self.road_node(part_idx, 8)),
            self.block_network,
            self._global_network,
            center_line_type=LineType.NONE,
            inner_lane_line_type=LineType.NONE,
            side_lane_line_type=LineType.NONE
        )

        bend, straight = create_bend_straight(
            extend_lane, 0.1 if dist_to_in < 1e-3 else dist_to_in, radius, self.ANGLE, False, parking_lane.width
        )
        out_bend_road = Road(
            self.road_node(part_idx, 8),
            self.road_node(part_idx, 9) if dist_to_in > 1e-3 else in_socket.negative_road.start_node
        )
        CreateRoadFrom(
            bend,
            self.positive_lane_num,
            out_bend_road,
            self.block_network,
            self._global_network,
            center_line_type=LineType.NONE,
            inner_lane_line_type=LineType.NONE,
            side_lane_line_type=LineType.NONE
        )
        if dist_to_in > 1e-3:
            out_straight_road = Road(self.road_node(part_idx, 9), in_socket.negative_road.start_node)
            CreateRoadFrom(
                straight,
                self.positive_lane_num,
                out_straight_road,
                self.block_network,
                self._global_network,
                center_line_type=LineType.NONE,
                inner_lane_line_type=LineType.NONE,
                side_lane_line_type=LineType.NONE
            )

        return no_cross