예제 #1
0
파일: prm.py 프로젝트: veds12/gennav
    def plan(self, start, goal, env):
        """Constructs a graph avoiding obstacles and then plans path from start to goal within the graph.
        Args:
            start (gennav.utils.RobotState): tuple with start point coordinates.
            goal (gennav.utils.RobotState): tuple with end point coordinates.
            env (gennav.envs.Environment): Base class for an envrionment.
        Returns:
            gennav.utils.Trajectory: The planned path as trajectory
            dict: Dictionary containing additional information
        """
        # Check if start and goal states are obstacle free
        if not env.get_status(start):
            raise InvalidStartState(start,
                                    message="Start state is in obstacle.")

        if not env.get_status(goal):
            raise InvalidGoalState(goal, message="Goal state is in obstacle.")
        # construct graph
        graph = self.construct(env)
        # find collision free point in graph closest to start_point
        min_dist = float("inf")
        for node in graph.nodes:
            dist = compute_distance(node.position, start.position)
            traj = Trajectory([node, start])
            if dist < min_dist and (env.get_traj_status(traj)):
                min_dist = dist
                s = node
        # find collision free point in graph closest to end_point
        min_dist = float("inf")
        for node in graph.nodes:
            dist = compute_distance(node.position, goal.position)
            traj = Trajectory([node, goal])
            if dist < min_dist and (env.get_traj_status(traj)):
                min_dist = dist
                e = node
        # add start_point to path
        path = [start]
        traj = Trajectory(path)
        # perform astar search
        p = astar(graph, s, e)
        if len(p.path) == 1:
            raise PathNotFound(p, message="Path contains only one state")
        else:
            traj.path.extend(p.path)
        # add end_point to path
        traj.path.append(goal)
        return traj, {}
예제 #2
0
    def plan(self, start, goal, env):
        """Plans the path to be taken by the robot to get from start to goal in the form of waypoints

        Args:
            start (gennav.utils.RobotState) : starting state of the robot (x, y and z coordinates)
            goal (gennav.utils.RobotState) : goal state of the robot (x, y and z coordinates)
            env (gennav.envs.Environment) : Type of environment the robot is operating in

        Returns:
            trajectory (gennav.utils.Trajectory) : A list of waypoints(in the form of robot states) that the robot will follow to go to the goal from the start
            dict: Dictionary containing additional information
        """
        # Check if start and goal states are obstacle free
        if not env.get_status(start):
            raise InvalidStartState(start,
                                    message="Start state is in obstacle.")

        if not env.get_status(goal):
            raise InvalidGoalState(goal, message="Goal state is in obstacle.")

        self.current = start
        self.goal = goal
        self.env = env
        waypoints = [self.current]
        while (math.sqrt((self.current.position.x - self.goal.position.x)**2 +
                         (self.current.position.y - self.goal.position.y)**2) >
               self.error):
            grad_attract = self.grad_attractive()
            grad_repel = self.grad_repulsive()
            grad = [0, 0]
            grad[0] = grad_attract[0] + grad_repel[0]
            grad[1] = grad_attract[1] + grad_repel[1]
            self.current.position.x = self.current.position.x - self.STEP_SIZE * grad[
                0]
            self.current.position.y = self.current.position.y - self.STEP_SIZE * grad[
                1]
            waypoints.append(self.current)
            trajectory = Trajectory(waypoints)
        if len(trajectory.path) == 1:
            raise PathNotFound(trajectory,
                               message="Path contains only one state")
        return trajectory, {}
예제 #3
0
    def plan(self, start, goal, env):
        """Path planning method

        Args:
            start (gennav.utils.common.RobotState): Starting state.
            goal (gennav.utils.common.RobotState): Destination state
            env (gennav.envs.Environment): Environment object

        Returns:
            gennav.utils.Trajectory: The path as a Trajectory
            dict: Dictionary containing additional information like the node_list
        """
        # Check if start and goal states are obstacle free
        if not env.get_status(start):
            raise InvalidStartState(start,
                                    message="Start state is in obstacle.")

        if not env.get_status(goal):
            raise InvalidGoalState(goal, message="Goal state is in obstacle.")
        # Initialize start and goal nodes.
        x_start = Node(state=start)
        x_goal = Node(state=goal)
        # Starting the tree:
        node_list = [x_start]

        # X_soln contains all the nodes near the goal
        X_soln = []

        for i in range(self.max_iter):
            # defining the best cost as cbest
            if len(X_soln) == 0:
                cbest = float("inf")
            else:
                cbest = X_soln[0].cost + compute_distance(
                    X_soln[0].state.position, x_goal.state.position)
                for node in X_soln:
                    if (node.cost + compute_distance(node.state.position,
                                                     x_goal.state.position) <
                            cbest):
                        cbest = node.cost + compute_distance(
                            node.state.position, x_goal.state.position)
            # sample the new random point using the sample function
            if cbest < float("inf"):
                # Converting x_start and x_goal into arrays so that matrix calculations can be handled
                x_start_array = np.array(
                    [x_start.state.position.x, x_start.state.position.y],
                    dtype=np.float32,
                ).reshape(2, 1)

                x_goal_array = np.array(
                    [x_goal.state.position.x, x_goal.state.position.y],
                    dtype=np.float32).reshape(2, 1)

                cmin = np.linalg.norm((x_goal_array - x_start_array))

                x_center = (x_start_array + x_goal_array) / 2

                a1 = (x_goal_array - x_start_array) / cmin
                I1 = np.eye(len(x_start_array))[0].reshape(
                    len(x_start_array), 1)

                M = np.dot(a1, I1.T)

                [u, s, v] = np.linalg.svd(M)

                # numpy returns the transposed value for v, so to convert it back
                v = v.T

                # Calculating the rotation to world frame matrix given by C = U*diag{1,....1.det(U)det(V)}*V.T where * denotes matrix multiplication
                diag = np.eye(2)
                diag[1, 1] = np.linalg.det(u) * np.linalg.det(v)
                C = np.dot(np.dot(u, diag), v.T)

                L = np.eye(2)
                L[0, 0] = cbest / 2
                L[1, 1] = np.sqrt(cbest**2 - cmin**2) / 2

                rand_state = self.circular_sampler()
                x_ball = np.array(
                    [rand_state.position.x, rand_state.position.y],
                    dtype=np.float32).reshape(2, 1)

                x_rand_array = np.dot(np.dot(C, L), x_ball) + x_center
                x_rand = RobotState()
                x_rand.position.x = x_rand_array[0, 0]
                x_rand.position.y = x_rand_array[1, 0]

                x_rand_node = Node(state=x_rand)

            else:
                x_rand = self.rectangular_sampler()
                x_rand_node = Node(state=x_rand)

            # Finding the nearest node to the random point
            distance_list = [
                compute_distance(node.state.position,
                                 x_rand_node.state.position)
                for node in node_list
            ]

            min_dist = distance_list[0]
            min_index = 0

            for index, distance in enumerate(distance_list):
                if distance < min_dist:
                    min_dist = distance
                    min_index = index

            x_nearest = node_list[min_index]

            # Steering at a distance of self.expand_dis

            theta = compute_angle(x_nearest.state.position,
                                  x_rand_node.state.position)

            x = x_nearest.state.position.x + self.expand_dis * math.cos(theta)
            y = x_nearest.state.position.y + self.expand_dis * math.sin(theta)
            t = RobotState(position=Point(x, y))

            x_new = Node(state=t)
            # Defining a temporary trajectory between the new node and its nearest node
            traj = Trajectory(path=[x_nearest.state, x_new.state])
            # Checking whether new node and the nearest node can be connected
            if env.get_traj_status(traj):
                # Adding new node to the node list
                node_list.append(x_new)

                # Defining the neighbours of x_new
                X_near = []
                for node in node_list:
                    if (compute_distance(
                            node.state.position, x_new.state.position)) < (
                                self.neighbourhood_radius
                            ) and (  # If it is inside the neighbourhood radius
                                compute_distance(node.state.position,
                                                 x_new.state.position) != 0):
                        X_near.append(node)

                x_min = x_nearest
                c_min = x_min.cost + self.expand_dis

                for x_near in X_near:
                    c_new = x_near.cost + compute_distance(
                        x_near.state.position, x_new.state.position)

                    if c_new < c_min:
                        traj = Trajectory(path=[x_near.state, x_new.state])

                        if env.get_traj_status(traj):
                            x_min = x_near
                            c_min = c_new

                # Defining the parent node and cost of x_new
                x_new.parent = x_min
                x_new.cost = c_min

                # Rewiring
                for x_near in X_near:
                    c_near = x_near.cost
                    c_new = x_new.cost + compute_distance(
                        x_near.state.position, x_new.state.position)

                    if c_new < c_near:
                        traj = Trajectory(path=[x_new.state, x_near.state])

                        if env.get_traj_status(traj):
                            x_near.parent = x_new
                            x_near.cost = c_new

                goal_traj = Trajectory(path=[x_new.state, x_goal.state])

                if (compute_distance(x_goal.state.position,
                                     x_new.state.position)
                    ) < self.goal_distance and env.get_traj_status(goal_traj):
                    X_soln.append(x_new)

        # X_soln contains all the solutions
        if len(X_soln) == 0:
            print("No solution found!")
            path = []
            path.append(x_start.state)
            traj = Trajectory(path=path)
            info_dict = {}
            info_dict["node_list"] = node_list
            if len(traj.path) == 1:
                raise PathNotFound(path,
                                   message="Path contains only one state")
            return (traj, info_dict)

        else:
            print("Goal reached!")
            Cbest = X_soln[0].cost
            Xbest = X_soln[0]
            node_list.append(x_goal)

            for node in X_soln:
                if node.cost < Cbest:
                    Cbest = node.cost
                    Xbest = node

            x_goal.parent = Xbest

            # Xbest is the optimum solution to the problem.

            # Back tracing the path:
            path = []
            path.append(x_goal.state)
            path.append(Xbest.state)
            p = Xbest.parent

            while p is not None:
                path.append(p.state)
                p = p.parent

            path.append(x_start.state)
            path.reverse()

            # print("No. of solutions " + str(len(X_soln)))

            trajectory = Trajectory(path=path)
            info_dict = {}
            info_dict["node_list"] = node_list

            return (trajectory, info_dict)
예제 #4
0
파일: rrg.py 프로젝트: veds12/gennav
    def plan(self, start, end, env):
        """Plans path from start to goal avoiding obstacles.
        Args:
            start (gennav.utils.RobotState): Starting state
            end (gennav.utils.RobotState): Goal state
            env: (gennav.envs.Environment) Base class for an envrionment.
        Returns:
            gennav.utils.Trajectory: The planned path as trajectory
            dict: Dictionary containing additional information
        """
        # Check if start and end states are obstacle free
        if not env.get_status(start):
            raise InvalidStartState(start,
                                    message="Start state is in obstacle.")

        if not env.get_status(end):
            raise InvalidGoalState(end, message="Goal state is in obstacle.")

        # Initialize graph
        graph = Graph()
        graph.add_node(start)

        # Initialize node list with Starting Position
        node_list = [start]

        # Loop for maximum iterations to get the best possible path
        for iter in range(self.max_iter):

            rnd_node = self.sampler()

            # Find nearest node to the sampled point

            distance_list = [
                compute_distance(node.position, rnd_node.position)
                for node in node_list
            ]

            try:
                # for python2
                nearest_node_index = min(xrange(len(distance_list)),
                                         key=distance_list.__getitem__)
            except NameError:
                # for python 3
                nearest_node_index = distance_list.index(min(distance_list))
            nearest_node = node_list[nearest_node_index]

            # Create new point in the direction of sampled point

            theta = math.atan2(
                rnd_node.position.y - nearest_node.position.y,
                rnd_node.position.x - nearest_node.position.x,
            )

            new_node = RobotState(position=Point(
                nearest_node.position.x + self.exp_dis * math.cos(theta),
                nearest_node.position.y + self.exp_dis * math.sin(theta),
            ))
            # Check whether new point is inside an obstacles
            trj = Trajectory([nearest_node, new_node])
            if not env.get_status(new_node) or not env.get_traj_status(trj):
                continue
            else:
                node_list.append(new_node)

            # FINDING NEAREST INDICES
            nnode = len(node_list) + 1
            # The circle in which to check parent node and rewiring
            r = self.circle * math.sqrt((math.log(nnode) / nnode))
            dist_list = [
                compute_distance(node.position, new_node.position)
                for node in node_list
            ]
            # Getting all the indexes within r units of new_node
            near_inds = [dist_list.index(i) for i in dist_list if i <= r**2]
            graph.add_node(new_node)
            graph.add_edge(nearest_node, new_node)
            # Add all the collision free edges to the graph.
            for ind in near_inds:
                node_check = node_list[ind]
                trj = Trajectory([new_node, node_check])
                # If the above condition is met append the edge.
                if env.get_traj_status(trj):
                    graph.add_edge(new_node, node_check)
        if end not in graph.nodes:
            min_cost = 2.0
            closest_node = RobotState()
            for node in graph.nodes:
                temp = compute_distance(node.position, end.position)
                if env.get_traj_status(Trajectory([node, end
                                                   ])) and temp < min_cost:
                    min_cost = temp
                    closest_node = node
            graph.add_edge(closest_node, end)
            graph.add_node(end)
        if start in graph.edges[end]:
            graph.del_edge(start, end)

        path = []
        p = astar(graph, start, end)
        path.extend(p.path)
        if len(path) != 1:
            print("Goal Reached!")
        path = Trajectory(path)

        if len(path.path) == 1:
            raise PathNotFound(path, message="Path contains only one state")

        return path, {}
예제 #5
0
파일: rrtstar.py 프로젝트: veds12/gennav
    def plan(self, start, goal, env):
        """Path planning method

        Args:
            start (gennav.utils.common.RobotState): Starting state.
            goal (gennav.utils.common.RobotState): Destination state
            env (gennav.envs.Environment): Environment object

        Returns:
            gennav.utils.Trajectory: The path as a Trajectory
            dict: Dictionary containing additional information like the node_list
        """
        # Check if start and goal states are obstacle free
        if not env.get_status(start):
            raise InvalidStartState(start, message="Start state is in obstacle.")

        if not env.get_status(goal):
            raise InvalidGoalState(goal, message="Goal state is in obstacle.")
        # Initialize start and goal nodes.
        x_start = Node(state=start)
        x_goal = Node(state=goal)
        # Starting the tree:
        node_list = [x_start]

        # X_soln contains all the nodes near the goal
        X_soln = []

        for i in range(self.max_iter):
            # defining the best cost as cbest
            if len(X_soln) == 0:
                cbest = float("inf")
            else:
                cbest = X_soln[0].cost + compute_distance(
                    X_soln[0].state.position, x_goal.state.position
                )
                for node in X_soln:
                    if (
                        node.cost
                        + compute_distance(node.state.position, x_goal.state.position)
                        < cbest
                    ):
                        cbest = node.cost + compute_distance(
                            node.state.position, x_goal.state.position
                        )
            # sample the new random point using the sample function
            x_rand = self.rectangular_sampler()
            x_rand_node = Node(state=x_rand)

            # Finding the nearest node to the random point
            distance_list = [
                compute_distance(node.state.position, x_rand_node.state.position)
                for node in node_list
            ]

            min_dist = distance_list[0]
            min_index = 0

            for index, distance in enumerate(distance_list):
                if distance < min_dist:
                    min_dist = distance
                    min_index = index

            x_nearest = node_list[min_index]

            # Steering at a distance of self.expand_dis

            theta = compute_angle(x_nearest.state.position, x_rand_node.state.position)

            x = x_nearest.state.position.x + self.expand_dis * math.cos(theta)
            y = x_nearest.state.position.y + self.expand_dis * math.sin(theta)
            t = RobotState(position=Point(x, y))

            x_new = Node(state=t)
            # Defining a temporary trajectory between the new node and its nearest node
            traj = Trajectory(path=[x_nearest.state, x_new.state])
            # Checking whether new node and the nearest node can be connected
            if env.get_traj_status(traj):
                # Adding new node to the node list
                node_list.append(x_new)

                # Defining the neighbours of x_new
                X_near = []
                for node in node_list:
                    if (compute_distance(node.state.position, x_new.state.position)) < (
                        self.neighbourhood_radius
                    ) and (  # If it is inside the neighbourhood radius
                        compute_distance(node.state.position, x_new.state.position) != 0
                    ):
                        X_near.append(node)

                x_min = x_nearest
                c_min = x_min.cost + self.expand_dis

                for x_near in X_near:
                    c_new = x_near.cost + compute_distance(
                        x_near.state.position, x_new.state.position
                    )

                    if c_new < c_min:
                        traj = Trajectory(path=[x_near.state, x_new.state])

                        if env.get_traj_status(traj):
                            x_min = x_near
                            c_min = c_new

                # Defining the parent node and cost of x_new
                x_new.parent = x_min
                x_new.cost = c_min

                # Rewiring
                for x_near in X_near:
                    c_near = x_near.cost
                    c_new = x_new.cost + compute_distance(
                        x_near.state.position, x_new.state.position
                    )

                    if c_new < c_near:
                        traj = Trajectory(path=[x_new.state, x_near.state])

                        if env.get_traj_status(traj):
                            x_near.parent = x_new
                            x_near.cost = c_new

                goal_traj = Trajectory(path=[x_new.state, x_goal.state])

                if (
                    compute_distance(x_goal.state.position, x_new.state.position)
                ) < self.goal_distance and env.get_traj_status(goal_traj):
                    X_soln.append(x_new)

        # X_soln contains all the solutions
        if len(X_soln) == 0:
            print("No solution found!")
            path = []
            path.append(x_start.state)
            traj = Trajectory(path=path)
            info_dict = {}
            info_dict["node_list"] = node_list
            if len(traj.path) == 1:
                raise PathNotFound(path, message="Path contains only one state")
            return (traj, info_dict)

        else:
            print("Goal reached!")
            Cbest = X_soln[0].cost
            Xbest = X_soln[0]
            node_list.append(x_goal)

            for node in X_soln:
                if node.cost < Cbest:
                    Cbest = node.cost
                    Xbest = node

            x_goal.parent = Xbest

            # Xbest is the optimum solution to the problem.

            # Back tracing the path:
            path = []
            path.append(x_goal.state)
            path.append(Xbest.state)
            p = Xbest.parent

            while p is not None:
                path.append(p.state)
                p = p.parent

            path.append(x_start.state)
            path.reverse()

            # print("No. of solutions " + str(len(X_soln)))

            trajectory = Trajectory(path=path)
            info_dict = {}
            info_dict["node_list"] = node_list

            return (trajectory, info_dict)
예제 #6
0
파일: rrt.py 프로젝트: archit2604/gennav
    def plan(self, start, goal, env):
        """Plans path from start to goal avoiding obstacles.

        Args:
            start_point(gennav.utils.RobotState): with start point coordinates.
            end_point (gennav.utils.RobotState): with end point coordinates.
            env: (gennav.envs.Environment) Base class for an envrionment.

        Returns:
            gennav.utils.Trajectory: The planned path as trajectory
            dict: Dictionary containing additional information like the node_list
        """
        # Check if start and goal states are obstacle free
        if not env.get_status(start):
            raise InvalidStartState(start,
                                    message="Start state is in obstacle.")

        if not env.get_status(goal):
            raise InvalidGoalState(goal, message="Goal state is in obstacle.")

        # Initialize start and goal nodes
        start_node = Node(state=start)
        goal_node = Node(state=goal)

        # Initialize node_list with start
        node_list = [start_node]

        # Loop to keep expanding the tree towards goal if there is no direct connection
        traj = Trajectory(path=[start, goal])
        if not env.get_traj_status(traj):
            while True:
                # Sample random state in specified area
                rnd_state = self.sampler()

                # Find nearest node to the sampled point
                distance_list = [
                    compute_distance(node.state.position, rnd_state.position)
                    for node in node_list
                ]
                try:
                    # for python2
                    nearest_node_index = min(xrange(len(distance_list)),
                                             key=distance_list.__getitem__)
                except NameError:
                    # for python 3
                    nearest_node_index = distance_list.index(
                        min(distance_list))

                nearest_node = node_list[nearest_node_index]

                # Create new point in the direction of sampled point
                theta = math.atan2(
                    rnd_state.position.y - nearest_node.state.position.y,
                    rnd_state.position.x - nearest_node.state.position.x,
                )
                new_point = Point()
                new_point.x = (nearest_node.state.position.x +
                               self.expand_dis * math.cos(theta))
                new_point.y = (nearest_node.state.position.y +
                               self.expand_dis * math.sin(theta))

                # Check whether new point is inside an obstacles
                if not env.get_status(RobotState(position=new_point)):
                    continue
                else:
                    new_node = Node.from_coordinates(new_point)
                    new_node.parent = nearest_node
                    node_list.append(new_node)

                # Check if goal has been reached or if there is direct connection to goal
                distance_to_goal = compute_distance(goal_node.state.position,
                                                    new_node.state.position)

                traj = Trajectory(path=[RobotState(position=new_point), goal])
                if distance_to_goal < self.expand_dis or env.get_traj_status(
                        traj):
                    goal_node.parent = node_list[-1]
                    node_list.append(goal_node)
                    print("Goal reached!")
                    break

        else:
            goal_node.parent = start_node
            node_list = [start_node, goal_node]

        # Construct path by traversing backwards through the tree
        path = []
        last_node = node_list[-1]
        while last_node.parent is not None:
            path.append(last_node.state)
            last_node = last_node.parent
        path.append(start)
        info_dict = {}
        info_dict["node_list"] = node_list
        path = Trajectory(path[::-1])

        if len(path.path) == 1:
            raise PathNotFound(path, message="Path contains only one state")

        return (path, info_dict)