def a_star(grid,heuristic,grid_start,grid_goal):
        path=[]
        queue=PriorityQueue()
        queue.put((0,grid_start))
        visited=set(grid_start)

        branch={}
        found=False


        while not queue.empty():
            item=queue.get()
            #print('item=',item[1])
            current_cost=item[0]
            current_node=item[1]
            #print('cu=',current_node,' goal=',grid_goal)
            if current_node==grid_goal:
                print('Found a path.')
                found=True
                break

            else:
                for action in valid_actions(grid,current_node):
                    #get the tuple representation
                    da = action.delta
                    cost=action.cost
                    next_node=(current_node[0]+da[0],current_node[1]+da[1])
                    new_cost=current_cost+cost+heuristic(next_node,grid_goal)
                
                    if next_node not in visited:
                        visited.add(next_node)
                        queue.put((new_cost,next_node))
                        branch[next_node]=(new_cost,current_node,action)
                        n=next_node
                        

            #path=[]
            #path_cost=0
        if found:
                #retrace steps
                #path=[]
                n=grid_goal
                path_cost=branch[n][0]
                path.append(grid_goal)
                while branch[n][1] != grid_start:
                    path.append(branch[n][1])
                    n=branch[n][1]
                    #print('cu=',branch[n][1])
                path.append(branch[n][1])
                print('path=',path)
                    
        return path[::-1],path_cost
Beispiel #2
0
def a_star(graph, start, goal):
    """Modified A* to work with NetworkX graphs."""

    path = []
    queue = PriorityQueue()
    queue.put((0, start))
    visited = set(start)

    branch = {}
    found = False

    while not queue.empty():
        item = queue.get()
        current_cost = item[0]
        current_node = item[1]

        if current_node == goal:
            print('Found a path.')
            found = True
            break
        else:
            for next_node in graph[current_node]:
                cost = graph.edges[current_node, next_node]['weight']
                new_cost = current_cost + cost + heuristic(next_node, goal)

                if next_node not in visited:
                    visited.add(next_node)
                    queue.put((new_cost, next_node))

                    branch[next_node] = (new_cost, current_node)

    path = []
    path_cost = 0
    if found:

        # retrace steps
        path = []
        n = goal
        path_cost = branch[n][0]
        path.append(goal)
        while branch[n][1] != start:
            path.append(branch[n][1])
            n = branch[n][1]
        path.append(branch[n][1])

    return path[::-1], path_cost
    def plan_path(self, id):
        self.flight_state = States.PLANNING
        print("Planning...")
        TARGET_ALTITUDE = 6
        SAFETY_DISTANCE = 7.0

        if id == 0:
            # Initial
            # Read lat0, lon0 from colliders into floating point values
            with open('colliders.csv', newline='') as file:
                line = csv.reader(file)
                (lat0, lon0) = next(line)
                lat0, lon0 = lat0[5:], lon0[5:]

            # Set home position to (lat0, lon0, 0)
            print("Setting home position:", lat0, lon0, 0.)
            self.set_home_position(float(lon0), float(lat0),
                                   0.)  # NOTE THE ORDER!!!

            # Retrieve current global position
            print("Current global position:", self.global_position)
            print("Verify:", self._longitude, self._latitude, self._altitude)

            print('global home:', self.global_home)
            print('global position:', self.global_position)
            print('local position:', self.local_position)

            if self.last_TARGET_ALTITUDE is None:
                if self.local_position[2] < 0.0:
                    self.last_TARGET_ALTITUDE = int(-self.local_position[2] +
                                                    SAFETY_DISTANCE + 1)
                else:
                    self.last_TARGET_ALTITUDE = TARGET_ALTITUDE

            # Read in obstacle map
            self.data = np.loadtxt('colliders.csv',
                                   delimiter=',',
                                   dtype='Float64',
                                   skiprows=2)

            # Create a 2D grid object
            self.grid = Grid(self.data)
            self.north_offset, self.east_offset = self.grid.get_offset()
            self.grid.update_obstacles(SAFETY_DISTANCE)
            print("Offset north: {0}, east: {1}".format(
                self.north_offset, self.east_offset))

            # Read in graph (map of city intersections)
            self.graph = np.loadtxt('graph.csv',
                                    delimiter=',',
                                    dtype='Float64',
                                    skiprows=0)

            # Read in itinerary (list of points to visit)
            self.itinerary = np.loadtxt('itinerary.csv',
                                        delimiter=',',
                                        dtype='Float64',
                                        skiprows=1)
            self.number_of_stops = len(self.itinerary)

            # Note: to set a specific goal, visit the top of this class
            if self.goal is not None:
                # Itinerary override: targeting specified goal instead
                # For safety, snap to closest itinerary item
                if self.snap:
                    self.itinerary = self.snap_to_closest(self.goal)
                else:
                    self.itinerary = np.array([[self.goal[0], self.goal[1]]])
                self.number_of_stops = 1
                self.visit_first = 0
            elif self.visit_first is None and not self.randomize_itin:
                # no priority on itin item
                self.last_id = -1

        # Set flight altitude to be current height + TARGET_ALTITUDE
        # in case drone is on top of a building
        self.target_position[2] = int(-self.local_position[2] +
                                      TARGET_ALTITUDE)

        print("Take off target altitude:", self.target_position[2])
        if id == 0 and self.visit_first is not None:
            next_id = self.visit_first
            self.last_id = next_id
        else:
            if self.randomize_itin:
                next_id = randint(0,
                                  len(self.itinerary) -
                                  1)  # get another itinerary destination
                while next_id == self.last_id:
                    next_id = randint(0,
                                      len(self.itinerary) -
                                      1)  # oops, same one, try again
                self.last_id = next_id
            else:
                next_id = self.last_id + 1
                if next_id > self.number_of_stops - 1:  # loop back to first item
                    next_id = 0
                self.last_id = next_id

        print(" ")
        print(
            "###############################################################################"
        )
        print("Time stamp:", strftime("%Y%m%d.%H%M%S", gmtime()))
        print("Stop number: {0} of {1}".format(id + 1, self.number_of_stops))
        print("Itinerary index number:", next_id)
        # set up the target
        local_target = global_to_local(
            np.array(
                [self.itinerary[next_id, 1], self.itinerary[next_id, 0], 0.0]),
            self.global_home)
        landing_altitude = self.grid.get_landing_altitude(
            int(local_target[0]) - self.north_offset,
            int(local_target[1]) - self.east_offset)
        target = [
            self.itinerary[next_id, 1], self.itinerary[next_id, 0],
            -landing_altitude
        ]
        print("Global target:", target)
        target_distance = heuristic(self.local_position, local_target)
        print("Distance to target:", target_distance)
        if self.graph_mode and target_distance > GRAPH_THRESHOLD:
            print("Attempting compound path...")
            waypoints = self.plan_compound_path(target, TARGET_ALTITUDE,
                                                SAFETY_DISTANCE)
            self.last_TARGET_ALTITUDE = TARGET_ALTITUDE
        else:
            print("Planning direct path...")
            waypoints = self.plan_simple_path(target, TARGET_ALTITUDE,
                                              SAFETY_DISTANCE)

        # Set self.waypoints for a queue of points to follow toward goal
        self.waypoints = waypoints
        # Send waypoints to sim for visualization
        self.send_waypoints()
Beispiel #4
0
    def plan_path(self):
        print("Searching for a path ...")
        TARGET_ALTITUDE = 5.0

        # read lat0, lon0 from colliders into floating point values
        with open('colliders.csv') as f:
            first_line = f.readline().split(',')
            lat0, lon0 = float(first_line[0].split(' ')[-1]), float(
                first_line[1].split(' ')[-1])

            # set home position to (lon0, lat0, 0)
            self.set_home_position(
                lon0, lat0,
                0)  # set the current location to be the home position

        # Convert drone global position to local position (relative to global home) using global_to_local()
        local_position = global_to_local(self.global_position,
                                         self.global_home)

        print('global home {0}, position {1}, local position {2}'.format(
            self.global_home, self.global_position, self.local_position))

        # Load precomputed graph
        print('Loading graph {0}'.format(len(self.graph.nodes)))

        # Set grid start position at our current drone global position
        drone_location = (self.local_position[0] - self.north_offset,
                          self.local_position[1] - self.east_offset,
                          self.local_position[2])
        print('Drone location local: {0}, Drone location map: {1}'.format(
            self.local_position, drone_location))

        # Select the nearest node closest to the drone location
        nearest_start = None
        closest_distance = sys.float_info.max
        for n in self.graph.nodes:
            # heuristic is the Euclidean distance:
            distance = heuristic(drone_location, n)
            if distance < closest_distance:
                closest_distance = distance
                nearest_start = n

        if nearest_start == None:
            print('Error while getting closest starting node')
            return
        print('Found starting node = {0}'.format(nearest_start))

        # Select a random goal node
        rnd_goal = np.random.randint(len(self.graph.nodes))
        goal = list(self.graph.nodes)[rnd_goal]
        print('Selecting random goal[{0}]: {1}'.format(rnd_goal, goal))

        print('****')
        path, cost = a_star_graph(self.graph, heuristic, nearest_start, goal)
        print('A* from {0} to {1} with a length of: {2}'.format(
            nearest_start, goal, len(path)))
        print('A* path: ', path)

        # First waypoint of path
        curr = path[0]

        # Save height for Takeoff
        self.target_position[2] = curr[2]

        # Add first waypoint
        waypoints = [[curr[0], curr[1], curr[2], 0]]

        idx = 1
        while idx < len(path):
            prev_wp = waypoints[len(waypoints) - 1]
            # idx indicate a good waypoint candidate to be inserted
            # path[idx] is supposed to be a good candidate already for the A* construction
            # Check following waypoints
            while idx + 1 < len(path):
                candidate_wp = path[idx + 1]
                hit = False
                cells = list(
                    bresenham(int(prev_wp[0]), int(prev_wp[1]),
                              int(candidate_wp[0]), int(candidate_wp[1])))
                for c in cells:
                    # Check if we're in collision
                    if self.collision_grid[
                            c[0], c[1]] >= FLYING_ALTITUDE + SAFETY_DISTANCE:
                        hit = True
                        break
                # If the path does not hit on obstacle, add it to the list
                if not hit:
                    # It's a good candidate. Update idx
                    idx = idx + 1
                else:
                    break

            # Add the candidate using idx
            good_candidate = path[idx]
            curr_wp = [
                good_candidate[0], good_candidate[1], good_candidate[2], 0
            ]

            # Set heading of curr_wp based on relative position to prev_wp
            heading = np.arctan2((curr_wp[1] - prev_wp[1]),
                                 (curr_wp[0] - prev_wp[0]))
            curr_wp[3] = heading

            # Append it to waypoints
            waypoints.append(curr_wp)
            idx = idx + 1

        # Set self.waypoints
        self.waypoints = waypoints
        #self.send_waypoints()

        self.flight_state = States.PLANNING
Beispiel #5
0
def perform_astar(Gr, Cg, nmin=0, emin=0):

	#drone_location = (-emin, -nmin, 5.0) # map coordinates
	drone_location = (445.04762260615826, 315.94609723985195, 5.0)
	print('Find Start node from {0}'.format(drone_location))
	nearest_start = None
	closest_distance = sys.float_info.max
	for n in Gr.nodes:
		# heuristic is the Euclidean distance:
		distance = heuristic(drone_location, n)
		if distance < closest_distance:
			closest_distance = distance
			nearest_start = n

	if nearest_start == None:
		print('Error while getting closest starting node')
		return
	print('Found starting node = {0}'.format(nearest_start))

	##########
	
	goal_location = (240.7685, 360.76114, 5.0) # map coordinates
	print('Find Goal node from {0}'.format(goal_location))
	nearest_goal = None
	closest_distance = sys.float_info.max
	for n in Gr.nodes:
		# heuristic is the Euclidean distance:
		distance = heuristic(goal_location, n)
		if distance < closest_distance:
			closest_distance = distance
			nearest_goal = n

	################
	start = nearest_start
	print('Start: ', start)
	goal = nearest_goal
	print('Goal: ', goal)

	path, cost = a_star_graph(Gr, heuristic, start, goal)
	print(len(path), path)
	if len(path) == 0:
		return

	waypoints = [[p[0], p[1], p[2], 0] for p in path]

	print("start")

	fig = plt.figure(figsize=(10,10))
	plt.imshow(Cg, cmap='Greys', origin='lower')

	path_pairs = zip(waypoints[:-1], waypoints[1:])
	for (n1, n2) in path_pairs:
		plt.plot([n1[1], n2[1]], [n1[0], n2[0]], 'green')

	plt.scatter(drone_location[0], drone_location[1], c='blue') # (0,0)
	plt.scatter(emin - emin, nmin - nmin , c='green') # Lowest point
	plt.scatter(100, 0, c='purple') # (0,0)

	plt.xlabel('EAST')
	plt.ylabel('NORTH')
	plt.show()