Last active
February 23, 2019 10:12
-
-
Save gonzaloruizdevilla/62d3f3504524660591d2a3910f0599e5 to your computer and use it in GitHub Desktop.
Hybrid A* Pseudocode
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def expand(state, goal): | |
next_states = [] | |
for delta in range(-35, 40, 5): | |
# Create a trajectory with delta as the steering angle using the bicycle model: | |
# ---Begin bicycle model--- | |
delta_rad = deg_to_rad(delta) | |
omega = SPEED/LENGTH * tan(delta_rad) | |
next_x = state.x + SPEED * cos(theta) | |
next_y = state.y + SPEED * sin(theta) | |
next_theta = normalize(state.theta + omega) | |
# ---End bicycle model----- | |
next_g = state.g + 1 | |
next_f = next_g + heuristic(next_x, next_y, goal) | |
# Create a new State object with all of the "next" values. | |
state = State(next_x, next_y, next_theta, next_g, next_f) | |
next_states.append(state) | |
return next_states | |
def search(grid, start, goal): | |
# The opened array keeps track of the stack of States objects we are | |
# searching through. | |
opened = [] | |
# 3D array of zeros with dimensions: | |
# (NUM_THETA_CELLS, grid x size, grid y size). | |
closed = [[[0 for x in range(grid[0])] for y in range(len(grid))] for cell in range(NUM_THETA_CELLS)] | |
# 3D array with same dimensions. Will be filled with State() objects to keep | |
# track of the path through the grid. | |
came_from = [[[0 for x in range(grid[0])] for y in range(len(grid))] for cell in range(NUM_THETA_CELLS)] | |
# Create new state object to start the search with. | |
x = start.x | |
y = start.y | |
theta = start.theta | |
g = 0 | |
f = heuristic(start.x, start.y, goal) | |
state = State(x, y, theta, 0, f) | |
opened.append(state) | |
# The range from 0 to 2pi has been discretized into NUM_THETA_CELLS cells. | |
# Here, theta_to_stack_number returns the cell that theta belongs to. | |
# Smaller thetas (close to 0 when normalized into the range from 0 to 2pi) | |
# have lower stack numbers, and larger thetas (close to 2pi whe normalized) | |
# have larger stack numbers. | |
stack_number = theta_to_stack_number(state.theta) | |
closed[stack_number][index(state.x)][index(state.y)] = 1 | |
# Store our starting state. For other states, we will store the previous state | |
# in the path, but the starting state has no previous. | |
came_from[stack_number][index(state.x)][index(state.y)] = state | |
# While there are still states to explore: | |
while opened: | |
# Sort the states by f-value and start search using the state with the | |
# lowest f-value. This is crucial to the A* algorithm; the f-value | |
# improves search efficiency by indicating where to look first. | |
opened.sort(key=lambda state:state.f) | |
current = opened.pop(0) | |
# Check if the x and y coordinates are in the same grid cell as the goal. | |
# (Note: The idx function returns the grid index for a given coordinate.) | |
if (idx(current.x) == goal[0]) and (idx(current.y) == goal.y): | |
# If so, the trajectory has reached the goal. | |
return path | |
# Otherwise, expand the current state to get a list of possible next states. | |
next_states = expand(current, goal) | |
for next_state in next_states: | |
# If we have expanded outside the grid, skip this next_state. | |
if next_states is not in the grid: | |
continue | |
# Otherwise, check that we haven't already visited this cell and | |
# that there is not an obstacle in the grid there. | |
stack_number = theta_to_stack_number(next_state.theta) | |
if closed_value[stack_number][idx(next_state.x)][idx(next_state.y)] == 0 and grid[idx(next_state.x)][idx(next_state.y)] == 0: | |
# The state can be added to the opened stack. | |
opened.append(next_state) | |
# The stack_number, idx(next_state.x), idx(next_state.y) tuple | |
# has now been visited, so it can be closed. | |
closed[stack_number][idx(next_state.x)][idx(next_state.y)] = 1 | |
# The next_state came from the current state, and that is recorded. | |
came_from[stack_number][idx(next_state.x)][idx(next_state.y)] = current |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment