141 lines
5.5 KiB
Python
141 lines
5.5 KiB
Python
import tkinter as tk
|
||
from PIL import Image, ImageTk
|
||
import torch
|
||
from ultralytics import YOLO
|
||
import cv2
|
||
from orbbec_camera.OrbbecCamera import OrbbecCamera
|
||
from robot_control.FRRobot import FRRobot
|
||
|
||
# 全局变量
|
||
model = YOLO('yolov8n.pt')
|
||
camera = OrbbecCamera('HW', True, image_width=640)
|
||
robot_controller = FRRobot()
|
||
correction_factor = 1
|
||
center_point = 320
|
||
|
||
|
||
class App:
|
||
def __init__(self, window, window_title):
|
||
self.window = window
|
||
self.window.title(window_title)
|
||
self.window.geometry("1280x720") # 设置窗口大小
|
||
|
||
# 设置图像帧,并固定大小
|
||
self.frame = tk.Label(self.window)
|
||
self.frame.grid(row=0, column=0, columnspan=3, padx=320, pady=20)
|
||
|
||
# 设置文本输出区域
|
||
self.text = tk.Text(self.window, height=10, width=50)
|
||
self.text.grid(row=3, column=0, columnspan=3, padx=320, pady=20)
|
||
|
||
# 控制按钮,居中对齐
|
||
self.btn_start = tk.Button(self.window, text="Start", command=self.start)
|
||
self.btn_start.grid(row=4, column=0, sticky="ew", padx=(106, 3))
|
||
|
||
self.btn_stop = tk.Button(self.window, text="Stop", command=self.stop)
|
||
self.btn_stop.grid(row=4, column=2, sticky="ew", padx=(3, 106))
|
||
|
||
self.btn_home = tk.Button(self.window, text="Home", command=self.to_home)
|
||
self.btn_home.grid(row=4, column=1, sticky="ew")
|
||
|
||
# 机械臂运动标志位
|
||
self.is_arm_moving_label = tk.Label(self.window, text="机械臂运动标志位: False", font=("Arial", 12))
|
||
self.is_arm_moving_label.grid(row=5, column=0, columnspan=1, sticky="ew", pady=10)
|
||
|
||
# 抓取动作标志位
|
||
self.is_catch_moving_label = tk.Label(self.window, text="抓取动作标志位: False", font=("Arial", 12))
|
||
self.is_catch_moving_label.grid(row=6, column=0, columnspan=1, sticky="ew", pady=10)
|
||
|
||
self.running = False
|
||
self.update_flag() # 初始化定时更新
|
||
|
||
self.window.mainloop()
|
||
|
||
def log(self, message):
|
||
self.text.insert(tk.END, message + '\n')
|
||
self.text.see(tk.END)
|
||
|
||
def start(self):
|
||
self.running = True
|
||
self.log("启动摄像头...")
|
||
camera.run()
|
||
self.to_home()
|
||
self.process_video_frame()
|
||
|
||
def stop(self):
|
||
self.running = False
|
||
self.log("停止中...")
|
||
camera.stop()
|
||
robot_controller.add_move_command("home")
|
||
robot_controller.add_move_command("stop")
|
||
|
||
def to_home(self):
|
||
self.log("回到原点...")
|
||
robot_controller.add_move_command("home")
|
||
|
||
def process_video_frame(self):
|
||
if self.running:
|
||
color_image = camera.get_color_image()
|
||
if color_image is not None:
|
||
self.display_image(color_image)
|
||
results = model.predict(source=color_image,
|
||
show=True,
|
||
conf=0.5,
|
||
half=True,
|
||
imgsz=640,
|
||
verbose=False)
|
||
self.handle_detection_results(results)
|
||
|
||
self.window.after(30, self.process_video_frame)
|
||
|
||
def display_image(self, img):
|
||
img_cv = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
|
||
img_pil = Image.fromarray(img_cv)
|
||
img_tk = ImageTk.PhotoImage(image=img_pil)
|
||
self.frame.imgtk = img_tk
|
||
self.frame.configure(image=img_tk)
|
||
|
||
def handle_detection_results(self, results):
|
||
for r in results:
|
||
if len(r.boxes.xywh) > 0 and not robot_controller.catch_moving and not robot_controller.is_arm_moving:
|
||
positions = r.boxes.xywh.tolist()
|
||
x_pos, y_pos, high, width = positions[0]
|
||
x_distance = (x_pos - center_point) * correction_factor
|
||
y_distance = (y_pos - center_point) * correction_factor
|
||
|
||
self.log(f"X距离: {x_distance}, Y距离: {y_distance}")
|
||
|
||
move_commands = []
|
||
if abs(x_distance) > 15:
|
||
move_commands.append(("x", x_distance))
|
||
if abs(y_distance) > 15:
|
||
move_commands.append(("y", y_distance))
|
||
|
||
if abs(x_distance) < 15 and abs(y_distance) < 15:
|
||
self.log("到达指定位置")
|
||
robot_controller.catch_moving = True
|
||
if camera.get_center_distance() <= 0:
|
||
self.log("抓取物体距离过近或相机参数错误,无法执行抓取")
|
||
robot_controller.catch_moving = False
|
||
continue
|
||
robot_controller.add_catch_commands(["catch", camera.get_center_distance()])
|
||
self.log(f"执行抓取命令,深度: {camera.get_center_distance()} mm")
|
||
|
||
if move_commands:
|
||
self.log(f"添加移动指令: {move_commands}")
|
||
if not robot_controller.is_arm_moving:
|
||
self.log(f"发送指令: {move_commands}")
|
||
robot_controller.add_move_command(move_commands)
|
||
|
||
def update_flag(self):
|
||
self.is_arm_moving_label.config(text='机械臂运动标志位: ' + str(robot_controller.is_arm_moving))
|
||
self.is_catch_moving_label.config(text='抓取动作标志位: ' + str(robot_controller.catch_moving))
|
||
# 每1000毫秒(1秒)调用一次自身,持续更新标志位
|
||
self.window.after(500, self.update_flag)
|
||
|
||
|
||
# 主运行环境
|
||
if __name__ == '__main__':
|
||
root = tk.Tk()
|
||
app = App(root, "Robot Camera Control")
|