Esempio n. 1
0
File: rt.py Progetto: uncobruce/WPN
 def __init__(self,
              services: Services,
              testing: BasicTesting = None) -> None:
     super().__init__(services, testing)
     start_vertex = Vertex(self._get_grid().agent.position)
     goal_vertex = Vertex(self._get_grid().goal.position)
     self._graph = Forest(start_vertex, goal_vertex, [])
Esempio n. 2
0
File: rt.py Progetto: uncobruce/WPN
class RT(SampleBasedAlgorithm):
    _graph: Forest

    def __init__(self,
                 services: Services,
                 testing: BasicTesting = None) -> None:
        super().__init__(services, testing)
        start_vertex = Vertex(self._get_grid().agent.position)
        goal_vertex = Vertex(self._get_grid().goal.position)
        self._graph = Forest(start_vertex, goal_vertex, [])

    # Helper Functions #
    # -----------------#

    def _get_random_sample(self) -> Point:
        while True:
            sample: Point = Point(
                torch.randint(0,
                              self._get_grid().size.width, (1, )).item(),
                torch.randint(0,
                              self._get_grid().size.height, (1, )).item())
            if self._get_grid().is_agent_valid_pos(sample):
                return sample

    def _get_random_vertex(self) -> Vertex:
        return self._graph.get_random_vertex([self._graph.root_vertex_start])

    def _get_new_vertex(self, q_near: Vertex, q_sample: Point,
                        max_dist) -> Vertex:
        dir = q_sample.to_tensor() - q_near.position.to_tensor()
        if torch.norm(dir) <= max_dist:
            return Vertex(q_sample)

        dir_normalized = dir / torch.norm(dir)
        q_new = Point.from_tensor(q_near.position.to_tensor() +
                                  max_dist * dir_normalized)
        return Vertex(q_new)

    def _extract_path(self, q_new):
        goal_v: Vertex = Vertex(self._get_grid().goal.position)
        self._graph.add_edge(q_new, goal_v)
        # trace back
        path: List[Vertex] = [goal_v]

        while len(path[-1].parents) != 0:
            for parent in path[-1].parents:
                path.append(parent)
                break

        del path[-1]
        path.reverse()

        for p in path:
            self.move_agent(p.position)
            self.key_frame(ignore_key_frame_skip=True)

    # Overridden Implementation #
    # --------------------------#

    def _find_path_internal(self) -> None:

        max_dist: float = 10
        iterations: int = 10000

        for i in range(iterations):

            q_sample: Point = self._get_random_sample()
            q_near: Vertex = self._get_random_vertex()
            if q_near.position == q_sample:
                continue
            q_new: Vertex = self._get_new_vertex(q_near, q_sample, max_dist)

            if not self._get_grid().is_valid_line_sequence(
                    self._get_grid().get_line_sequence(q_near.position,
                                                       q_new.position)):
                continue

            self._graph.add_edge(q_near, q_new)

            if self._get_grid().is_agent_in_goal_radius(
                    agent_pos=q_new.position):
                self._extract_path(q_new)
                break

            self.key_frame()
Esempio n. 3
0
class RRT_Connect(SampleBasedAlgorithm):
    _graph: Forest
    _max_dist: float
    _iterations: int

    def __init__(self, services: Services, testing: BasicTesting = None) -> None:
        super().__init__(services, testing)
        self._graph = Forest(Vertex(self._get_grid().agent.position), Vertex(self._get_grid().goal.position), [])
        self._max_dist = 10
        self._iterations = 10000

    # Helper Functions #
    # -----------------#

    def _extend(self, root_vertex: Vertex, q: Point) -> str:
        self._q_near: Vertex = self._get_nearest_vertex(root_vertex, q)
        self._q_new: Vertex = self._get_new_vertex(self._q_near, q, self._max_dist)
        if self._get_grid().is_valid_line_sequence(self._get_grid().get_line_sequence(self._q_near.position, self._q_new.position)):
            self._graph.add_edge(self._q_near, self._q_new)
            if self._q_new.position == q:
                return 'reached'
            else:
                return 'advanced'
        return 'trapped'

    def _connect(self, root_vertex: Vertex, q: Vertex) -> str:
        S = 'advanced'
        while S == 'advanced':
            S = self._extend(root_vertex, q.position)
        self._mid_vertex = q
        return S

    def _extract_path(self):

        # trace back
        path_mid_to_b: List[Vertex] = [self._q_new]

        while len(path_mid_to_b[-1].parents) != 0:
            for parent in path_mid_to_b[-1].parents:
                path_mid_to_b.append(parent)
                break

        path_a_to_mid: List[Vertex] = [self._extension_target]

        while len(path_a_to_mid[-1].parents) != 0:
            for parent in path_a_to_mid[-1].parents:
                path_a_to_mid.append(parent)
                break

        path_a_to_mid.reverse()
        path = path_a_to_mid + path_mid_to_b

        if self._graph.root_vertices[0] is self._graph.root_vertex_goal:
            path.reverse()

        for p in path:
            self.move_agent(p.position)
            self.key_frame(ignore_key_frame_skip=True)

    def _get_random_sample(self) -> Point:
        while True:
            sample: Point = Point(torch.randint(0, self._get_grid().size.width, (1,)).item(),
                                  torch.randint(0, self._get_grid().size.height, (1,)).item())
            if self._get_grid().is_agent_valid_pos(sample):
                return sample

    def _get_nearest_vertex(self, graph_root_vertex: Vertex, q_sample: Point) -> Vertex:
        return self._graph.get_nearest_vertex([graph_root_vertex], q_sample)

    def _get_new_vertex(self, q_near: Vertex, q_sample: Point, max_dist) -> Vertex:
        dir = q_sample.to_tensor() - q_near.position.to_tensor()
        if torch.norm(dir) <= max_dist:
            return Vertex(q_sample)

        dir_normalized = dir / torch.norm(dir)
        q_new = Point.from_tensor(q_near.position.to_tensor() + max_dist * dir_normalized)
        return Vertex(q_new)

    # Overridden Implementation #
    # --------------------------#

    def _find_path_internal(self) -> None:

        for i in range(self._iterations):

            q_rand: Point = self._get_random_sample()

            if not self._extend(self._graph.root_vertices[0], q_rand) == 'trapped':
                self._extension_target = self._q_new
                if self._connect(self._graph.root_vertices[-1], self._q_new) == 'reached':
                    self._extract_path()
                    break
            self._graph.reverse_root_vertices()

            # visualization code
            self.key_frame()
Esempio n. 4
0
 def __init__(self, services: Services, testing: BasicTesting = None) -> None:
     super().__init__(services, testing)
     self._graph = Forest(Vertex(self._get_grid().agent.position), Vertex(self._get_grid().goal.position), [])
     self._max_dist = 10
     self._iterations = 10000
Esempio n. 5
0
class RRT_Star(SampleBasedAlgorithm):
    _graph: Forest

    def __init__(self,
                 services: Services,
                 testing: BasicTesting = None) -> None:
        super().__init__(services, testing)
        start_vertex = Vertex(self._get_grid().agent.position)
        start_vertex.cost = 0
        goal_vertex = Vertex(self._get_grid().goal.position)
        self._graph = Forest(start_vertex, goal_vertex, [])

    # Helper Functions #
    # -----------------#

    def _get_random_sample(self) -> Point:
        while True:
            sample: Point = Point(
                torch.randint(0,
                              self._get_grid().size.width, (1, )).item(),
                torch.randint(0,
                              self._get_grid().size.height, (1, )).item())
            if self._get_grid().is_agent_valid_pos(sample):
                return sample

    def _get_nearest_vertex(self, q_sample: Point) -> Vertex:
        return self._graph.get_nearest_vertex([self._graph.root_vertex_start],
                                              q_sample)

    def _get_vertices_within_radius(self, vertex: Vertex,
                                    radius: float) -> List[Vertex]:
        return self._graph.get_vertices_within_radius(
            [self._graph.root_vertex_start], vertex.position, radius)

    def _get_new_vertex(self, q_near: Vertex, q_sample: Point,
                        max_dist) -> Vertex:
        dir = q_sample.to_tensor() - q_near.position.to_tensor()
        dir_norm = torch.norm(dir)
        if dir_norm <= max_dist:
            return Vertex(q_sample)

        dir_normalized = dir / torch.norm(dir)
        q_new = Point.from_tensor(q_near.position.to_tensor() +
                                  max_dist * dir_normalized)
        return Vertex(q_new)

    def _extract_path(self, q_new):

        goal_v: Vertex = Vertex(self._get_grid().goal.position)
        child_parent_dist = torch.norm(q_new.position.to_tensor() -
                                       goal_v.position.to_tensor())
        goal_v.cost = q_new.cost + child_parent_dist
        self._graph.add_edge(q_new, goal_v)
        path: List[Vertex] = [goal_v]

        while len(path[-1].parents) != 0:
            for parent in path[-1].parents:
                path.append(parent)
                break

        del path[-1]
        path.reverse()

        for p in path:
            self.move_agent(p.position)
            self.key_frame(ignore_key_frame_skip=True)

    # Overridden Implementation #
    # --------------------------#

    def _find_path_internal(self) -> None:

        max_dist: float = 10
        iterations: int = 10000
        max_radius: float = 50
        lambda_rrt_star: float = 50
        dimension = 2

        for i in range(iterations):

            q_sample: Point = self._get_random_sample()
            q_nearest: Vertex = self._get_nearest_vertex(q_sample)
            if q_nearest.position == q_sample:
                continue
            q_new: Vertex = self._get_new_vertex(q_nearest, q_sample, max_dist)

            if not self._get_grid().is_valid_line_sequence(
                    self._get_grid().get_line_sequence(q_nearest.position,
                                                       q_new.position)):
                continue

            card_v = torch.tensor(float(self._graph.size))
            log_card_v = torch.log(card_v)
            radius = min(
                lambda_rrt_star * ((log_card_v / card_v)**(1 / dimension)),
                max_radius)
            Q_near: List[Vertex] = self._get_vertices_within_radius(
                q_new, radius)
            q_min = q_nearest
            c_min = q_nearest.cost + torch.norm(
                q_nearest.position.to_tensor() - q_new.position.to_tensor())

            for q_near in Q_near:
                near_new_collision_free = self._get_grid(
                ).is_valid_line_sequence(self._get_grid().get_line_sequence(
                    q_near.position, q_new.position))
                cost_near_to_new = q_near.cost + torch.norm(
                    q_near.position.to_tensor() - q_new.position.to_tensor())
                if near_new_collision_free and cost_near_to_new < c_min:
                    q_min = q_near
                    c_min = cost_near_to_new

            child_parent_dist = torch.norm(q_min.position.to_tensor() -
                                           q_new.position.to_tensor())
            q_new.cost = q_min.cost + child_parent_dist
            self._graph.add_edge(q_min, q_new)

            for q_near in Q_near:
                near_new_collision_free = self._get_grid(
                ).is_valid_line_sequence(self._get_grid().get_line_sequence(
                    q_near.position, q_new.position))
                cost_new_to_near = q_new.cost + torch.norm(
                    q_new.position.to_tensor() - q_near.position.to_tensor())
                if near_new_collision_free and cost_new_to_near < q_near.cost:
                    q_parent = None
                    for parent in q_near.parents:
                        q_parent = parent
                        break
                    q_near.cost = None
                    self._graph.remove_edge(q_parent, q_near)
                    child_parent_dist = torch.norm(q_new.position.to_tensor() -
                                                   q_near.position.to_tensor())
                    q_near.cost = q_new.cost + child_parent_dist
                    self._graph.add_edge(q_new, q_near)

            if self._get_grid().is_agent_in_goal_radius(
                    agent_pos=q_new.position):
                self._extract_path(q_new)
                break

            self.key_frame()