Mobile Robot Control 2024 Ultron:Solution 3: Difference between revisions
| Line 24: | Line 24: | ||
#* If the goal is reached, reconstruct the path using the parent references. | #* If the goal is reached, reconstruct the path using the parent references. | ||
#* If the open list is empty and the goal has not been reached, return failure indicating no path exists. | #* If the open list is empty and the goal has not been reached, return failure indicating no path exists. | ||
A* implementation assignment | A* implementation assignment | ||
# ''' | # '''Find the index of the node with minimum f and store it in the variable nodeID_minimum_f:''' | ||
#* | #* First, the code initializes the variable <code>min_f</code> to infinity to ensure that any node's <code>f</code> value will be smaller than this initial value. Then, it iterates through each node index <code>nodeID</code> in the open list <code>open_nodes</code>. For each node, it accesses its <code>f</code> value via <code>_nodelist[nodeID].f</code>. This <code>f</code> value is the sum of the actual cost <code>g</code> from the start node to the current node and the estimated cost <code>h</code> from the current node to the goal node. If the current node's <code>f</code> value is smaller than the current minimum <code>f</code> value, the code updates <code>min_f</code> to the current node's <code>f</code> value and stores the index of the node with the smallest <code>f</code> value in <code>nodeID_minimum_f</code>. By comparing the <code>f</code> values of all nodes in the open list, the code ultimately determines the node with the smallest <code>f</code> value, and its index is stored in <code>nodeID_minimum_f</code> for use in the next step of the A* algorithm. | ||
# '''Explore the nodes connected to the current node''': | |||
# ''' | #* For each neighbor of the current node, the code checks if the neighbor is not in the closed list by searching through the <code>closed_nodes</code> list. If the neighbor is not in the closed list, the code calculates the tentative cost-to-come <code>tentative_g</code>, which is the cost from the start node to the current node plus the distance from the current node to the neighbor. If this tentative cost-to-come is lower than the neighbor's current <code>g</code> value, the code updates the neighbor's <code>g</code> value to the tentative <code>g</code>, recalculates the neighbor's <code>f</code> value (which is the sum of the updated <code>g</code> value and the heuristic estimate <code>h</code> value), and sets the neighbor's parent node to the current node. | ||
#* | # '''Put the node IDs of nodes in the optimal path''': | ||
#* It initializes the current node ID to the goal node's ID <code>_goal_nodeID</code> and then iterates in a loop, tracing back through the parent nodes until reaching the start node. In each iteration, the current node ID is added to the front of the path list <code>path_node_IDs</code>, and the current node ID is updated to its parent node's ID. This process continues step by step along the parent node chain, ultimately building the optimal path from the start node to the goal node. The path node IDs are stored in <code>path_node_IDs</code> in sequence, representing the optimal path from start to goal. | |||
# ''' | |||
#* | |||
=== Probabilistic Road Map === | === Probabilistic Road Map === | ||
=== Answers of the questions === | === Answers of the questions === | ||
Revision as of 22:59, 28 May 2024
A* Algorithm
The A* algorithm is a widely used heuristic search algorithm for finding the shortest path from a start node to a goal node in a graph. It combines the strengths of Dijkstra's algorithm and Greedy Best-First-Search. The core idea of A* is to use a heuristic function to prioritize paths that seem more promising to reach the goal.
The steps for running the algorithm for A* are as follows.
- Initialization:
- Create the open list (priority queue) and closed list (empty).
- Initialize the start node with
g(start) = 0andf(start) = h(start), then add it to the open list.
- Main Loop:
- While the open list is not empty:
- Select the node
currentfrom the open list with the lowestfvalue.
- Select the node
- While the open list is not empty:
- Goal Check:
- If
currentis the goal node, reconstruct and return the path from start to goal.
- If
- Process Neighbors:
- For each neighbor of
current:- Ignore the neighbor if it's in the closed list.
- Calculate the tentative
gvalue (tentative_g = g(current) + cost(current, neighbor)). - If the neighbor is not in the open list or the tentative
gis lower thang(neighbor):- Update
g(neighbor),f(neighbor), and set the parent of the neighbor tocurrent. - Add the neighbor to the open list if it's not already there.
- Update
- For each neighbor of
- Path Reconstruction or Failure:
- If the goal is reached, reconstruct the path using the parent references.
- If the open list is empty and the goal has not been reached, return failure indicating no path exists.
A* implementation assignment
- Find the index of the node with minimum f and store it in the variable nodeID_minimum_f:
- First, the code initializes the variable
min_fto infinity to ensure that any node'sfvalue will be smaller than this initial value. Then, it iterates through each node indexnodeIDin the open listopen_nodes. For each node, it accesses itsfvalue via_nodelist[nodeID].f. Thisfvalue is the sum of the actual costgfrom the start node to the current node and the estimated costhfrom the current node to the goal node. If the current node'sfvalue is smaller than the current minimumfvalue, the code updatesmin_fto the current node'sfvalue and stores the index of the node with the smallestfvalue innodeID_minimum_f. By comparing thefvalues of all nodes in the open list, the code ultimately determines the node with the smallestfvalue, and its index is stored innodeID_minimum_ffor use in the next step of the A* algorithm.
- First, the code initializes the variable
- Explore the nodes connected to the current node:
- For each neighbor of the current node, the code checks if the neighbor is not in the closed list by searching through the
closed_nodeslist. If the neighbor is not in the closed list, the code calculates the tentative cost-to-cometentative_g, which is the cost from the start node to the current node plus the distance from the current node to the neighbor. If this tentative cost-to-come is lower than the neighbor's currentgvalue, the code updates the neighbor'sgvalue to the tentativeg, recalculates the neighbor'sfvalue (which is the sum of the updatedgvalue and the heuristic estimatehvalue), and sets the neighbor's parent node to the current node.
- For each neighbor of the current node, the code checks if the neighbor is not in the closed list by searching through the
- Put the node IDs of nodes in the optimal path:
- It initializes the current node ID to the goal node's ID
_goal_nodeIDand then iterates in a loop, tracing back through the parent nodes until reaching the start node. In each iteration, the current node ID is added to the front of the path listpath_node_IDs, and the current node ID is updated to its parent node's ID. This process continues step by step along the parent node chain, ultimately building the optimal path from the start node to the goal node. The path node IDs are stored inpath_node_IDsin sequence, representing the optimal path from start to goal.
- It initializes the current node ID to the goal node's ID
Probabilistic Road Map
Answers of the questions
1. How could finding the shortest path through the maze using the A* algorithm be made more efficient by placing the nodes differently? Sketch the small maze with the proposed nodes and the connections between them. Why would this be more efficient?
2. Would implementing PRM in a map like the maze be efficient?
3. What would change if the map suddenly changes (e.g. the map gets updated)?
4. How did you connect the local and global planner?
5. Test the combination of your local and global planner for a longer period of time on the real robot. What do you see that happens in terms of the calculated position of the robot? What is a way to solve this?
6. Run the A* algorithm using the gridmap (with the provided nodelist) and using the PRM. What do you observe? Comment on the advantage of using PRM in an open space.