Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Fastest way tkinter
#1
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:

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,
Reply
#2
When you compute the path, make the obstacles wider/longer by half the width of the robot.
Reply
#3
Your code appears to be a basic implementation of the A* algorithm for finding the shortest path between two points while avoiding obstacles in a Tkinter window.

The heuristic function (heuristic) you're using calculates the Euclidean distance between two points. While this is a common choice, it might not always be appropriate for your specific scenario.

The get_neighbors function generates neighboring nodes for the A* algorithm. It currently only checks adjacent cells, which might lead to paths being too close to obstacles. Consider expanding the search space or refining the neighbor generation logic to produce better paths..

The draw_path function is responsible for drawing the calculated path on the canvas. Ensure that the path is being drawn correctly and that the drawn path does not intersect with obstacles.

By addressing these potential issues and experimenting with different parameters, you may be able to generate paths that avoid obstacles more effectively.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  What is the fastest way to get all the frames from a video file? glorsh66 3 1,088 May-26-2023, 04:41 AM
Last Post: Gribouillis
  Fastest Way of Writing/Reading Data JamesA 1 2,206 Jul-27-2021, 03:52 PM
Last Post: Larz60+
  Fastest Method for Querying SQL Server with Python Pandas BuJayBelvin 7 6,934 Aug-02-2020, 06:21 PM
Last Post: jefsummers
  Fastest dict/map method when 'key' is already a hash? tasket 6 4,009 Apr-20-2019, 06:40 PM
Last Post: tasket
  fastest way to record values between quotes paul18fr 5 3,308 Apr-15-2019, 01:51 PM
Last Post: snippsat
  Fastest Way to declare this list. Kowalski 2 2,832 Feb-21-2018, 06:26 PM
Last Post: DeaD_EyE

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020