Example #1
0
 def __init__(self,
              space,
              agent_pos,
              assisting_metric=None,
              t_exp=0.15,
              t_root=0.003,
              t_steer=0.002):
     """
     :param space: State space planner operates in
     :param agent_pos: Initial position of agent
     :param assisting_metric: Assisting metric for the planner, default None for Euclidean
     :param t_exp: Time spent expanding and rewiring
     :param t_root: Time spent rewiring at the root
     :param t_steer: Time spent steering
     """
     self.space = space
     self.euclidean_metric = EuclideanMetric()
     self.assisting_metric = assisting_metric if assisting_metric is not None else self.euclidean_metric
     self.euclidean_distance = lambda a, b: self.euclidean_metric.distance(
         a, b)
     self.assisting_distance = lambda a, b: self.assisting_metric.distance(
         a, b)
     self.tree = Tree(self.space.create_state(agent_pos),
                      self.space,
                      assisting_dist_fn=self.assisting_distance)
     self.goal = None
     self.root_queue = []
     self.rewired_root = set()
     self.t_exp, self.t_root, self.t_steer = t_exp, t_root, t_steer
Example #2
0
def test_add(empty_environment_info):
    space = empty_environment_info["space"]
    root = space.create_state(np.array([10, 10]))
    new = space.create_state(np.array([5, 5]))
    tree = Tree(root, space)
    tree.add_node(new, root)
    assert tree.parent(new) == root
Example #3
0
def test_nearest(empty_environment_info):
    space = empty_environment_info["space"]
    root = space.create_state(np.array([10, 10]))
    seeds = [np.random.rand() for _ in range(50)]
    nodes = [
        space.create_state(space.bounds[:, 0] * seed + space.bounds[:, 1] *
                           (1 - seed)) for seed in seeds
    ]
    tree = Tree(root, space)
    for node in nodes:
        tree.add_node(node)
    search = space.create_state(np.array([15, 15]))
    assert np.linalg.norm(search.pos - tree.nearest(search).pos) == min(
        [np.linalg.norm(search.pos - node.pos) for node in nodes])
Example #4
0
def test_set_root(empty_environment_info):
    space = empty_environment_info["space"]
    old = space.create_state(np.array([10, 10]))
    new = space.create_state(np.array([11, 10]))
    tree = Tree(old, space)
    tree.add_node(new, old)
    tree.set_root(new)
    assert tree.path(old) == [new, old]
Example #5
0
def test_root_path(empty_environment_info):
    space = empty_environment_info["space"]
    root = space.create_state(np.array([10, 10]))
    a = space.create_state(np.array([11, 10]))
    b = space.create_state(np.array([12, 10]))
    tree = Tree(root, space)
    tree.add_node(a, root)
    tree.add_node(b, a)
    assert tree.path(root) == [root]
Example #6
0
def test_update(empty_environment_info):
    space = empty_environment_info["space"]
    root = space.create_state(np.array([10, 10]))
    a = space.create_state(np.array([11, 10]))
    b = space.create_state(np.array([12, 10]))
    tree = Tree(root, space)
    tree.add_node(a, root)
    tree.add_node(b, root)
    tree.update_edge(b, a)
    assert tree.parent(a) == b
Example #7
0
class RTSamplingPlanner:
    """
    Real time sampling planner, parent class for RTRRT and AMRRT
    """
    def __init__(self,
                 space,
                 agent_pos,
                 assisting_metric=None,
                 t_exp=0.15,
                 t_root=0.003,
                 t_steer=0.002):
        """
        :param space: State space planner operates in
        :param agent_pos: Initial position of agent
        :param assisting_metric: Assisting metric for the planner, default None for Euclidean
        :param t_exp: Time spent expanding and rewiring
        :param t_root: Time spent rewiring at the root
        :param t_steer: Time spent steering
        """
        self.space = space
        self.euclidean_metric = EuclideanMetric()
        self.assisting_metric = assisting_metric if assisting_metric is not None else self.euclidean_metric
        self.euclidean_distance = lambda a, b: self.euclidean_metric.distance(
            a, b)
        self.assisting_distance = lambda a, b: self.assisting_metric.distance(
            a, b)
        self.tree = Tree(self.space.create_state(agent_pos),
                         self.space,
                         assisting_dist_fn=self.assisting_distance)
        self.goal = None
        self.root_queue = []
        self.rewired_root = set()
        self.t_exp, self.t_root, self.t_steer = t_exp, t_root, t_steer

    def _nearest_node(self, node):
        """
        Find nearest node, first by Euclidean metric if the path is free or fallback on the assisting metric
        """
        euclidean = self.tree.euclidean_nearest(node)
        if self.space.free_path(
                node,
                euclidean) or self.euclidean_metric == self.assisting_metric:
            return euclidean
        return self.tree.nearest(node)

    def set_root(self, root):
        """
        Set the root node for the planner tree, and reset rewiring queue
        """
        self.tree.set_root(root)
        self.root_queue = [self.tree.root]
        self.rewired_root = {self.tree.root}

    def set_goal(self, pos):
        """
        Set new goal from position, try to add goal to tree if within range & path free
        """
        self.goal = self.space.create_state(pos)
        xnearest = self._nearest_node(self.goal)
        if self.euclidean_distance(
                xnearest, self.goal) < self.max_step and self.space.free_path(
                    xnearest, self.goal):
            self.tree.add_node(self.goal, xnearest)

    def _add_node(self, xnew, xnearest, nearby):
        """
        Add new node to the tree, connecting it to the node in nearby that minimises cost
        Also attempt to add the goal to the tree via xnew if within range & free path

        :param xnew: New state to be added
        :param xnearest: Nearest node to xnew
        :param nearby: Set of nodes in the neighbourhood of xnew
        """
        xmin = xnearest
        cmin = self.cost(xnearest) + self.euclidean_distance(xnearest, xnew)
        for xnear in nearby:
            cnew = self.cost(xnear) + self.euclidean_distance(xnear, xnew)
            if cnew < cmin and self.space.free_path(xnear, xnew):
                xmin = xnear
                cmin = cnew
        self.tree.add_node(xnew, xmin)
        if self.goal is not None and self.euclidean_distance(
                xnew, self.goal) < self.max_step and self.space.free_path(
                    xnew, self.goal):
            self.tree.add_node(self.goal, xnew)

    def goal_path(self):
        """
        Return path to the goal if one exists, if not a path to the nearest node
        """
        if self.goal is None:
            return []
        if self.goal in self.tree.nodes:
            return self.tree.path(self.goal)
        return self.tree.path(self._nearest_node(self.goal))

    def cost(self, node):
        """
        Returns path cost to given node (as Cost object)
        """
        if node == self.tree.root:
            return Cost(0, False)
        path = self.tree.path(node)
        running_cost = 0
        blocked = False
        for i in range(1, len(path)):
            if not self.space.dynamically_free_path(path[i - 1], path[i]):
                blocked = True
            running_cost += self.euclidean_distance(path[i - 1], path[i])
        return Cost(running_cost, blocked)

    def add_dynamic_obstacle(self, pos, radius):
        """
        Add circular dynamic obstacle, and reset goal queues

        :param pos: Position of dynamic obstacle
        :param radius: Radius of dynamic obstacle
        """
        self.space.add_dynamic_obstacle(pos, radius)
        if self.goal is not None: self.set_goal(self.goal.pos)
Example #8
0
def test_add_duplicate(empty_environment_info):
    space = empty_environment_info["space"]
    root = space.create_state(np.array([10, 10]))
    tree = Tree(root, space)
    tree.add_node(root, root)
    assert tree.parent(root) == None