Search code examples
pythonpath-findinga-star

How to calculate the height of an obstacle in every node and take its effect on the path finding of the A star algorithm Formula?


I'm working on A star algorithm to generate an optimal trajectory. For my problem, I'm trying to find an optimal path to drone between two points, but I need to take into consideration the height of obstacles. As you know, through searching the algorithm will calculate the g (cost) and h(heuristic) in every node and choose the best one through this formula F=G+H. I need also to calculate the height of obstacles and add it to my formula to become F=G+H+E. E will represent the height of obstacles.

If the drone is flying with a specific height and faces a very high obstacle will turn around, if the high of the obstacle is close to the drone height, it means the risk will be very high and will consider the short obstacle to fly over it.

I have generated a map with the same size as my grid and I gave random numbers (random heights) to the obstacles, then I applied it to my formula. Throughout my expansion stage, I have made a condition if the height of obstacles less the height of drone height then the drone will be able to fly over it, but I see there is no effect. Could I get any assistance?.

This is below my code:

#grid format
# 0 = navigable space
# 1 = occupied space

import random

grid = [[0, 1, 0, 0, 0, 0],
        [0, 1, 0, 0, 0, 0],
        [0, 1, 0, 0, 0, 0],
        [0, 1, 0, 0, 0, 0],
        [0, 0, 0, 0, 1, 0]]

heuristic = [[9, 8, 7, 6, 5, 4],
             [8, 7, 6, 5, 4, 3],
             [7, 6, 5, 4, 3, 2],
             [6, 5, 4, 3, 2, 1],
             [5, 4, 3, 2, 1, 0]]

init = [0,0]                            #Start location is (0,0) which we put it in open list.
goal = [len(grid)-1,len(grid[0])-1]     #Our goal in (4,5) and here are the coordinates of the cell.

#Below the four potential actions to the single field

delta = [[-1 , 0],   #up 
         [ 0 ,-1],   #left
         [ 1 , 0],   #down
         [ 0 , 1]]   #right

delta_name = ['^','<','V','>']  #The name of above actions

cost = 1   #Each step costs you one


drone_h = 60  #The altitude of drone

def search():
    #open list elements are of the type [g,x,y] 

    closed = [[0 for row in range(len(grid[0]))] for col in range(len(grid))]

    action = [[-1 for row in range(len(grid[0]))] for col in range(len(grid))]
    #We initialize the starting location as checked
    closed[init[0]][init[1]] = 1

    expand=[[-1 for row in range(len(grid[0]))] for col in range(len(grid))]

    elevation = [[0 for row in range(len(grid[0]))] for col in range(len(grid))]
    for i in range(len(grid)):    
        for j in range(len(grid[0])): 
            if grid[i][j] == 1:
                elevation[i][j] = random.randint(1,100)
                print(elevation[i][j])
            else:
                elevation[i][j] = 0


    # we assigned the cordinates and g value
    x = init[0]
    y = init[1]
    g = 0
    h = heuristic[x][y]
    e = elevation[x][y]

    f = g + h + e

    #our open list will contain our initial value
    open = [[f, g, h, x, y]]

    found  = False   #flag that is set when search complete
    resign = False   #Flag set if we can't find expand
    count = 0

    #print('initial open list:')
    #for i in range(len(open)):
            #print('  ', open[i])
    #print('----')


    while found is False and resign is False:

        #Check if we still have elements in the open list
        if len(open) == 0:    
            resign = True
            print('Fail')
            print('############# Search terminated without success')
            print()
        else: 

            open.sort()            
            open.reverse()          
            next = open.pop()       
            #print('list item')
            #print('next')


            x = next[3]
            y = next[4]
            g = next[1]

            expand[x][y] = count
            count+=1

            #Check if we are done
            if x == goal[0] and y == goal[1]:
                found = True
                print(next) 
                print('############## Search is success')
                print()

            else:
                #expand winning element and add to new open list
                for i in range(len(delta)):       
                    x2 = x + delta[i][0]
                    y2 = y + delta[i][1]

                    #if x2 and y2 falls into the grid
                    if x2 >= 0 and x2 < len(grid) and y2 >=0 and y2 <= len(grid[0])-1:
                        #if x2 and y2 not checked yet and there is not obstacles
                        if closed[x2][y2] == 0 and grid[x2][y2] == 0 and elevation[x2][y2]< drone_h:
                            g2 = g + cost            
                            h2 = heuristic[x2][y2]
                            e = elevation[x2][y2]
                            f2 = g2 + h2 + e

                            open.append([f2,g2,h2,x2,y2])   
                            #print('append list item')
                            #print([g2,x2,y2])
                            #Then we check them to never expand again
                            closed[x2][y2] = 1
                            action[x2][y2] = i
    for i in range(len(expand)):
        print(expand[i])
    print()
    policy=[[' ' for row in range(len(grid[0]))] for col in range(len(grid))]
    x=goal[0]
    y=goal[1]
    policy[x][y]='*'
    while x !=init[0] or y !=init[1]:
        x2=x-delta[action[x][y]][0]
        y2=y-delta[action[x][y]][1]
        policy[x2][y2]= delta_name[action[x][y]]
        x=x2
        y=y2
    for i in range(len(policy)):
        print(policy[i])


search()

The results that I got:

[11, 11, 0, 4, 5]
############## Search is success

[0, -1, -1, -1, -1, -1]
[1, -1, -1, -1, -1, -1]
[2, -1, -1, -1, -1, -1]
[3, -1, 8, 9, 10, 11]
[4, 5, 6, 7, -1, 12]

['V', ' ', ' ', ' ', ' ', ' ']
['V', ' ', ' ', ' ', ' ', ' ']
['V', ' ', ' ', ' ', ' ', ' ']
['V', ' ', ' ', '>', '>', 'V']
['>', '>', '>', '^', ' ', '*']

Solution

  • You need to associate a cost with the height of obstacles. So, you need to figure out how costly, in terms of distance, the risk a high obstacle represents, is.

    So, basically your heuristic stays your actual distance is G(up to now)+E(up to now), and your heuristic stays G(up to now)+E(up to now)+H

    Since you haven't stated how bad taking the risk is and how much you want to avoid it, let's say, as an example, you never want to take the risk unless there is no other way.

    Then you could associate a cost for the elevation as follows:

    E(x) = 0 if obstacle is low
    E(x) = maximal_possible_distance + (elevation - drone height)
    

    That way, it is always better to take a detour, and it favors smaller elevations (add a factor or exponent if you want to favor smaller elevations even more)