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,
