Feb-17-2024, 10:59 PM
Hello sorry for my bad english, it's not my mother tongue, I'm trying to make a python code that allows to make the fastest path between two points while avoiding obstacles.
For the moment, this is to be done in a tkinter window but later, using sonar, I'll create a zone that recognizes obstacles.
However, I've got a problem with the program that lets me make the robot move. I was thinking of tracing the shortest path between the two points, passing it as a vector and then making the robot move.
However, the paths chosen are too close to the objects and I can't modify them. Here's the code I'm currently using and what it comes out with:
https://ibb.co/h7n5XvP
and sometimes I get the impression that what I'm adding isn't taken into account. I must be doing it wrong, given that I've never used search algorithms :
https://ibb.co/n8WTxY2
If you see any major errors in my code or in the way it works, please let me know,
For the moment, this is to be done in a tkinter window but later, using sonar, I'll create a zone that recognizes obstacles.
However, I've got a problem with the program that lets me make the robot move. I was thinking of tracing the shortest path between the two points, passing it as a vector and then making the robot move.
However, the paths chosen are too close to the objects and I can't modify them. Here's the code I'm currently using and what it comes out with:
import tkinter as tk import heapq import math class ObstacleGrid(tk.Tk): def __init__(self): super().__init__() self.title("Placement des objets") self.canvas = tk.Canvas(self, width=800, height=800, bg="white") self.canvas.pack() self.obstacles = [] # Liste pour stocker les segments des obstacles self.green_node = None # Stocker le nœud correspondant au point vert self.orange_node = None # Stocker le nœud correspondant au point orange self.place_obstacle_button = tk.Button(self, text="Placer Obstacle", command=self.place_obstacle) self.place_obstacle_button.pack(side=tk.LEFT) self.place_green_button = tk.Button(self, text="Placer Point Vert", command=self.place_green) self.place_green_button.pack(side=tk.LEFT) self.place_orange_button = tk.Button(self, text="Placer Point Orange", command=self.place_orange) self.place_orange_button.pack(side=tk.LEFT) self.find_path_button = tk.Button(self, text="Trouver Chemin", command=self.find_path) self.find_path_button.pack(side=tk.LEFT) self.canvas.bind("<Button-1>", self.on_mouse_press) self.canvas.bind("<ButtonRelease-1>", self.on_mouse_release) def place_obstacle(self): self.current_object = "obstacle" self.obstacle_start = None def place_green(self): self.current_object = "green" def place_orange(self): self.current_object = "orange" def on_mouse_press(self, event): self.start_x = event.x self.start_y = event.y def on_mouse_release(self, event): end_x = event.x end_y = event.y if self.current_object == "obstacle": self.canvas.create_rectangle(self.start_x, self.start_y, end_x, end_y, fill="red") self.obstacles.append((self.start_x, self.start_y, end_x, end_y)) elif self.current_object == "green": oval_id = self.canvas.create_oval(self.start_x - 10, self.start_y - 10, self.start_x + 10, self.start_y + 10, fill="green") # Enregistrer les coordonnées du point vert self.green_node = (self.start_x, self.start_y) elif self.current_object == "orange": oval_id = self.canvas.create_oval(self.start_x - 10, self.start_y - 10, self.start_x + 10, self.start_y + 10, fill="orange") # Enregistrer les coordonnées du point orange self.orange_node = (self.start_x, self.start_y) def find_path(self): print("Points de départ et d'arrivée :", self.green_node, self.orange_node) if self.green_node and self.orange_node: path = self.astar(self.green_node, self.orange_node) self.draw_path(path) else: print("Placez d'abord le point vert et le point orange.") def astar(self, start, goal): open_set = [] heapq.heappush(open_set, (0, start)) came_from = {} cost_so_far = {} came_from[start] = None cost_so_far[start] = 0 while open_set: current_cost, current_node = heapq.heappop(open_set) if current_node == goal: break for next_node in self.get_neighbors(current_node): new_cost = cost_so_far[current_node] + self.distance(current_node, next_node) if next_node not in cost_so_far or new_cost < cost_so_far[next_node]: cost_so_far[next_node] = new_cost priority = new_cost + self.heuristic(next_node, goal) heapq.heappush(open_set, (priority, next_node)) came_from[next_node] = current_node path = [] current_node = goal while current_node != start: path.append(current_node) current_node = came_from[current_node] path.append(start) path.reverse() return path def heuristic(self, a, b): return math.sqrt((a[0] - b[0])**2 + (a[1] - b[1])**2) def get_neighbors(self, node): neighbors = [] x, y = node for i in range(x - 1, x + 2): for j in range(y - 1, y + 2): if (i, j) != node and not self.is_obstacle((i, j)) and 0 <= i < 800 and 0 <= j < 800: # Vérifier si le voisin potentiel est à l'intérieur d'un obstacle inside_obstacle = False for obstacle in self.obstacles: x1, y1, x2, y2 = obstacle if x1 < i < x2 and y1 < j < y2: inside_obstacle = True break if not inside_obstacle: # Ne pas permettre les déplacements diagonaux si les deux cellules adjacentes sont des obstacles if not (self.is_obstacle((i, y)) and self.is_obstacle((x, j))): neighbors.append((i, j)) return neighbors def is_obstacle(self, node): x, y = node for obstacle in self.obstacles: x1, y1, x2, y2 = obstacle if x1 <= x <= x2 and y1 <= y <= y2: return True return False def distance(self, node1, node2): x1, y1 = node1 x2, y2 = node2 return abs(x1 - x2) + abs(y1 - y2) def draw_path(self, path): if path: for i in range(len(path) - 1): start_x, start_y = path[i] end_x, end_y = path[i+1] self.canvas.create_line(start_x, start_y, end_x, end_y, fill="blue", width=2) if __name__ == "__main__": app = ObstacleGrid() app.mainloop()and what I get :
https://ibb.co/h7n5XvP
and sometimes I get the impression that what I'm adding isn't taken into account. I must be doing it wrong, given that I've never used search algorithms :
https://ibb.co/n8WTxY2
If you see any major errors in my code or in the way it works, please let me know,