Elephant RoboticsMavis
Published © GPL3+

Automated Desktop Trash Removal Robot Based on YOLOv10

The article features the 6 DOF robot arm myCobot 320 to create an automated desktop trash-removal assistant.

BeginnerFull instructions provided2 hours252
Automated Desktop Trash Removal Robot Based on YOLOv10

Things used in this project

Hand tools and fabrication machines

myCobot 320 m5
Elephant Robotics myCobot 320 m5

Story

Read more

Schematics

YOLOv10_model

best.pt

Code

test.py

Python
import time
from time import sleep
import math
import cv2
import torch
import matplotlib.pyplot as plt
from ultralytics import YOLOv10
import numpy as np

from pymycobot import MyCobot320,utils

# define robot
mc = MyCobot320(utils.get_port_list()[0])
mc.set_pro_gripper_torque(gripper_id=14, torque_value=10)
# define model
model = YOLOv10('best.pt')
# define camera
cap = cv2.VideoCapture(0)
# define robot init status
robot_status = 0

# check camera status
if not cap.isOpened():
    print("could not open the camera")
    exit()


def get_yolov10_result(_model,_input_image):
    boxes = []
    confidences = []

    if _input_image is None:
        print("Error: Image is not loaded.")
        return boxes,confidences

    results = _model(_input_image)


    for result in results:
        for detection in result:
            box = detection.boxes.xyxy
            confidence = detection.boxes.conf
            #print(detection)

            # set freshould
            if confidence[0]< 0.5:
                continue

            boxes.append(box.numpy())
            confidences.append(confidence.numpy())

    for box in boxes:
        x_min, y_min, x_max, y_max = box[0]

        # draw detect rectangle
        x_min, y_min, x_max, y_max = int(x_min), int(y_min), int(x_max), int(y_max)
        color = (0, 255, 0)
        thickness = 2
        _input_image = cv2.rectangle(_input_image, (x_min, y_min), (x_max, y_max), color, thickness)


        # draw the center point
        x_center = (x_min + x_max) // 2
        y_center = (y_min + y_max) // 2

        center_color = (0, 0, 255)  # red
        radius = 5  # raduis of point
        _input_image = cv2.circle(_input_image, (x_center, y_center), radius, center_color, -1)
        #print(f"x_center: {x_center},\n y_center: {y_center}")

        # show
        image_show = cv2.resize(_input_image, (640, 640))
        cv2.imshow("Displayed Image", image_show)
        cv2.waitKey(1)

    return boxes,confidences

def get_best_object(_boxes,_confidences):

    best_index = _confidences.index(max(_confidences))
    best_box = _boxes[best_index]

    x_min, y_min, x_max, y_max = best_box[0]
    x_min, y_min, x_max, y_max = int(x_min), int(y_min), int(x_max), int(y_max)

    x_center = round((x_min + x_max) // 2 / 640 * 1920)
    y_center = round((y_min + y_max) // 2 / 640 * 1080)
    #print(f"x_center: {x_center},\n y_center: {y_center}")

    return x_center,y_center


def get_camera_coordinate(_x,_y):
    # camera intrisic matrix
    f_x = 933.33  #
    f_y = 933.33  #
    c_x = 960
    c_y = 540
    K = np.array([
        [f_x, 0, c_x],
        [0, f_y, c_y],
        [0, 0, 1]
    ])


    # depth Z (已知, 36 cm)
    Z = 0.36  #m


    X= (_x-c_x)*Z/f_x
    Y= (_y-c_y)*Z/f_y
    camera_coordinates = [X*1000,Y*1000,Z*1000]  # mm
    print(f"camera_coords:{camera_coordinates}")
    return camera_coordinates


def get_robot_coordinate(_cam_point_xyz):
    R_y_180 = np.array([
        [-1, 0, 0],
        [0, 1, 0],
        [0, 0, -1]
    ])

    T = np.array([0, 450, 400])

    T_cam_to_arm = np.eye(4)
    T_cam_to_arm[:3, :3] = R_y_180
    T_cam_to_arm[:3, 3] = T


    camera_coordinates = np.array(
        [[_cam_point_xyz[0]], [_cam_point_xyz[1]], [_cam_point_xyz[2]]])


    arm_coordinates = np.dot(R_y_180,camera_coordinates)
    arm_coordinates[1,0] += 450
    arm_coordinates[2,0] += 360

    print(arm_coordinates)
    return arm_coordinates

def check_move(_myCobot,_goal):
    m = _myCobot
    recent_coords=m.get_coords()
    dist = math.sqrt(pow(_goal[0]-recent_coords[0],2)+pow(_goal[1]-recent_coords[1],2)+pow(_goal[2]-recent_coords[2],2))
    print(f"dist={dist}")
    if dist < 12:
        return True
    else:
        return False


def move_one_object(_myCobot,_Coords_X,_Coords_Y,_Coords_Z):
    m = _myCobot
    coords_object = [float(_Coords_X),float(_Coords_Y),float(_Coords_Z),-175,0,130]

    print(f" now move to {coords_object}")
    m.send_coords(coords_object,40,1)
    while check_move(m,coords_object) != True:
        time.sleep(0.5)
        print("----- waiting -----")

    m.set_pro_gripper_close(14)
    sleep(3)
    return coords_object

def move_trash(_myCobot):
    m = _myCobot
    coords_trash=[250,150,280,160,0,70]
    m.send_coords(coords_trash,50,1)
    time.sleep(1)
    return coords_trash


def move_base(_myCobot):
    m = _myCobot

    base_coords = [250,150,280,160,0,70]
    m.send_coords(base_coords,50,1)
    time.sleep(2)
    m.set_pro_gripper_open(14)
    sleep(2)
    return base_coords


if __name__ == "__main__":

    gripper_height =185
    init_status = check_move(mc,move_base(mc))
    while init_status != True:
        time.sleep(1)

    print("robot init")
    robot_status = 0
    while True:
        # 读取每一帧图像
        ret, frame = cap.read()
        if not ret:
            print("No Image")
            break

        # crop to 640x640
        image_resized = cv2.resize(frame, (640, 640))
        image_rgb = image_resized.copy()
        cv2.imshow("1",image_rgb)
        cv2.waitKey(1)

        detect_boxes,detect_confidences = get_yolov10_result(model, image_rgb)

        print(f"len boxes:{len(detect_boxes)}")

        if len(detect_boxes) != 0 and robot_status==0:

            robot_status = 1
            x_image, y_image = get_best_object(detect_boxes, detect_confidences)
            xyz_camera = get_camera_coordinate(x_image, y_image)
            xyz_robot = get_robot_coordinate(xyz_camera)

            #limit the robot arm
            if xyz_robot[1] > 350.0:
                xyz_robot[1] = 340.5

            move_object = move_one_object(mc,xyz_robot[0],xyz_robot[1],xyz_robot[2]+gripper_height)

            current_status = check_move(mc, move_base(mc))
            while current_status != True:
                print("wait for mobing to base")
                time.sleep(0.5)
            robot_status = 0

Credits

Elephant Robotics
101 projects • 216 followers
An Innovative Robotics Company.
Contact
Mavis
1 project • 0 followers
Contact

Comments

Please log in or sign up to comment.