Hướng phát triển của đề tài

Một phần của tài liệu Thiết kế hệ thống điều khiển robot thu hoạch dứa dựa trên công nghệ xử lý ảnh (Trang 74 - 108)

Về phần xử lý ảnh Góc của camera

+ Góc của camera cần phải cốđịnh để có thể tính toán chính xác được tọa độ vật thể. Tuy nhiên trong nhiều điều kiện thực tế rất khó để thực hiện được.

+ Đề xuất phương pháp sử dụng gimbal cho camera để đảm bảo góc của camera luôn được cốđịnh kể cảtrong trường hợp địa hình gồ ghề. Đồng thời hệ thống khung máy sẽ cần thêm hệ thống xy lanh, nhằm đảm bảo cho khung máy ổn định trong quá trình di chuyển trên thực địa.

Vấn đề chiều cao quả dứa.

+ Hiện tại tọa độ trục Z của quả dứa (chiều cao của quá dứa so với mặt đất) vẫn đang được tính phụ thuộc vào chiều cao của camera đến mặt đất. Tuy nhiên trong điều kiện thực tế, chiều cao của camera đến mặt đất là không cốđịnh do bề mặt địa hình không bằng phẳng.

+ Đề xuất phương án cải tiến: sử dụng thêm 1 camera đặt tại trục Y của khung xe để kết hợp với camera trục X dựng lại ảnh 3D của các quả dứa trong khung máy, qua đó sẽxác định được trục Z mà không phải dựa vào chiều cao của camera đến mặt đất.

64

TÀI LIỆU THAM KHẢO

[1] R. Girshick, “Fast R-CNN”, in Proc. IEEE Int. Conf. Comput. Vis., Dec. 2015, pp. 1440–1448. Stein, M., Bargoti, S., Underwood, J., “Image Based Mango Fruit Detection, Localisation and Yield Estimation Using Multiple View Geometry”, 2016.

[2] Halstead, M., McCool, C., Denman, S., Perez, T., Fookes, C., “Fruit Quantity and Quality Estimation using a Robotic Vision System”, 2018.

[3] Chen, S. W., Shivakumar, S. S., Dcunha, S., Das, J., Okon, E., Qu, C., Kumar, V., “Counting Apples and Oranges With Deep Learning: A Data-Driven Approach”, IEEE Robotics and Automation Letters, Vol. 2, Issue 2, 2017.

[4] Trần Trọng Minh, Giáo trình điện tử công suất, Nhà xuất bản Giáo Dục Việt Nam, 2015.

[5] R. Krishnan, Switched Reluctance Motor Drives, CRC Press LLC, 2001.

[6] Husain, I. and M. Ehsani, “Torque ripple Minimization in Switched Reluctance Motor Drives by PWM Control”, IEEE Trans. on Power Electronics, Vol. 11, No. 1, 1996, pp. 83-88.

[7] T.J.E. Miller, Switched Reluctance Motors and Their Control, Magna Physics, Oxford, 1992.

65

PHỤ LỤC

Đầu vào ra cho PLC điều khiển cánh tay 1

Phân bố đầu vào tín hiệu cho PLC FX3U-64M phụ trách điều khiển tay máy số 1

Tín hiệu

vào

Tên thiết bị kết nối với đầu

vào PLC Mô tả chức năng

X0 Cảm biến CB11 Tín hiệu truyền về của cảm biến tay máy 1 tại gốc tọa độ trục X X3 Cảm biến CB12 Tín hiệu truyền về của cảm biến tay máy 1 tại gốc tọa độ trục Y. X4 Nút ấn ST1 (Start 1) Tín hiệu truyền về của nút ấn khởi động tay máy 1. Sử dụng tiếp điểm thường mở (NO).

X5 Nút ấn SP1 (Stop 1)

Tín hiệu truyền về của nút ấn dừng tay máy 1. Sử dụng tiếp điểm thường đóng (NC).

X6 Nút ấn E1 (Emergency 1)

Tín hiệu truyền về của nút ấn dừng khẩn cấp tay máy 1. Sử dụng tiếp điểm thường đóng có duy trì.

X7 Tín hiệu cảm biến báo vị trí xi lanh. Cảm biến XL11 Tín hiệu truyền về của cảm biến điện từbáo xi lanh đã thu về hết.

X10 Cảm biến

XL14

Tín hiệu truyền về của cảm biến điện từbáo xi lanh đã hạ xuống vịtrí dưới cùng. X12 Cảm biến XL13 Tín hiệu truyền về của cảm biến điện từ báo xi lanh đã hạ xuống vị trí giữa. X11 Cảm biến XL12 Tín hiệu truyền về của cảm biến điện từ báo xi lanh đã hạ xuống vị trí trên cùng. X13 Tín hiệu cần đặt vị trí xi lanh. Cần điều khiển J1L Tín hiệu truyền về từ cần đặt vị trí xi lanh xuống thấp nhất. X14 Cần điều khiển J1H Tín hiệu truyền về từ cần đặt vị trí xi lanh xuống tầm giữa. X15 Tín hiệu cần đặt. Cần điều khiển VANG Tín hiệu truyền về từ cần đặt điều khiển thu hoạch dứa chín.

66 X17 Cần điều khiển VANG_XANH Tín hiệu truyền về từ cần đặt điều khiển thu hoạch cả dứa chín và dứa xanh.

Phân bố đầu ra tín hiệu cho PLC FX3U-64M phụ trách điều khiển tay máy số 1

Đầu ra Y

Tên thiết bị kết nối với

đầu vào PLC Mô tả chức năng

Y0

Cấp tín hiệu cho cổng PUL- của Driver 1, 2 (Driver 1,2 điều khiển hai động cơ bước của trục X)

Tín hiệu đưa tới chân PUL- của Driver 1, 2. Có chức năng đặt tốc độ và vị trí cho động cơ.

Y1

Cấp tín hiệu cho cổng PUL- của Driver 3 (Driver 3 điều khiển động cơ bước của trục Y)

Tín hiệu đưa tới chân PUL- của Driver 3. Có chức năng đặt tốc độ và vị trí cho động cơ.

Y2 Cấp tín hiệu cho cổng ENA- của Driver 1, 2

Tín hiệu chạy cho động cơ 1, 2. Y2 = 0 động cơ 1, 2 dừng; Y2 = 1 động cơ 1, 2 chạy.

Y3 Cấp tín hiệu cho cổng ENA- của Driver 3

Tín hiệu chạy cho động cơ 3. Y3 = 0 động cơ 3 chạy; Y3 = 1 động cơ 3 dừng.

Y4 Cấp tín hiệu cho cổng DIR- của Driver 1, 2

Tín hiệu đảo chiều cho động cơ 1,2. Y4= 0 động cơ chạy thuận (cánh tay di chuyển theo trục X+); Y4=1 động cơ chạy ngược (cánh tay di chuyển theo trục X-).

Y5 Cấp tín hiệu cho cổng DIR- của Driver 3

Tín hiệu đảo chiều cho động cơ 3. Y5=0 động cơ 3 chạy ngược (cánh tay di chuyển theo trục Y-); Y5=1 động cơ 3 chạy thuận (cánh tay di chuyển theo trục Y+)

Y10

Cấp tín hiệu cho rơ le trung gian điều khiển van phân phối cho xi lanh khí nén 11

Xilanh khí nén 11 có chức năng dịch chuyển tay máy theo trục Z, hướng đi lên.

67 Y11

Cấp tín hiệu cho rơ le trung gian điều khiển van phân phối cho xi lanh khí nén 12

Xilanh khí nén 12 có chức năng dịch chuyển tay máy theo trục Z, hướng đi xuống.

Y12

Cấp tín hiệu cho rơ le trung gian điều khiển van phân phối cho xi lanh khí nén 21

Xilanh khí nén 21 có chức năng đóng mở bàn tay gắp dứa.

Y14

Cấp tín hiệu cho rơ le trung gian điều khiển van phân phối cho động cơ khí nén 31

Xilanh khí nén 31 có chức năng bật tắt cưa khí nén.

Y15 Cấp tín hiệu cho đèn xanh Đèn xanh báo hiệu chế độ hoạt động của tay máy (chếđộ RUN)

Y16 Cấp tín hiệu cho đèn đỏ Đèn đỏ báo hiệu chếđộ hoạt động của tay máy (chếđộ STOP).

Đầu vào ra cho PLC điều khiển cánh tay 2

Phân bố đầu vào tín hiệu cho PLC FX3U-64M phụ trách điều khiển tay máy số 2

Tín hiệu

vào

Tên thiết bị kết nối với

đầu vào PLC Mô tả chức năng

X0 Cảm biến CB21 Tín hiệu truyền về của cảm biến tay máy 2 tại gốc tọa độ trục X. X3 Cảm biến CB22 Tín hiệu truyền về của cảm biến tay máy 2 tại gốc tọa độ trục Y. X4 Nút ấn ST2 (Start 2) Tín hiệu truyền về của nút ấn khởi động tay máy 2. Sử dụng tiếp điểm thường mở (NO).

X5 Nút ấn SP2 (Stop 2)

Tín hiệu truyền về của nút ấn dừng tay máy 2. Sử dụng tiếp điểm thường đóng (NC).

X6 Nút ấn E2 (Emergency 2)

Tín hiệu truyền về của nút ấn dừng khẩn cấp tay máy 2. Sử dụng tiếp điểm thường đóng có duy trì. X7 Tín hiệu cảm biến Cảm biến XL21 Tín hiệu truyền về của cảm biến điện từbáo xi lanh đã thu về hết.

68 X10 báo vị trí xi lanh. Cảm biến XL24 Tín hiệu truyền về của cảm biến điện từ báo xi lanh đã hạ xuống vị trí dưới cùng. X12 Cảm biến XL23 Tín hiệu truyền về của cảm biến điện từbáo xi lanh đã hạ xuống vị trí giữa. X11 Cảm biến XL22 Tín hiệu truyền về của cảm biến điện từ báo xi lanh đã hạ xuống vị trí trên cùng. X13 Tín hiệu cần đặt vị trí xi lanh. Cần điều khiển J2L Tín hiệu truyền về từ cần đặt vị trí xi lanh xuống thấp nhất. X14 Cần điều khiển J2H Tín hiệu truyền về từ cần đặt vị trí xi lanh xuống tầm giữa. X15 Tín hiệu cần đặt. Cần điều khiển VANG Tín hiệu truyền về từ cần đặt điều khiển thu hoạch dứa chín. X17 Cần điều khiển VANG_XANH Tín hiệu truyền về từ cần đặt điều khiển thu hoạch cả dứa chín và dứa xanh.

Phân bố đầu ra tín hiệu cho PLC FX3U-64M phụ trách điều khiển tay máy số 2

Đầu ra

Y

Tên thiết bị kết nối với

đầu vào PLC Mô tả chức năng

Y0

Cấp tín hiệu cho cổng PUL- của Driver 1, 2 (Driver 1,2 điều khiển hai động cơ bước của trục X)

Tín hiệu đưa tới chân PUL- của Driver 1, 2. Có chức năng đặt tốc độ và vịtrí cho động cơ.

Y1

Cấp tín hiệu cho cổng PUL- của Driver 3 (Driver 3 điều khiển động cơ bước của trục Y)

Tín hiệu đưa tới chân PUL- của Driver 3. Có chức năng đặt tốc độ và vị trí cho động cơ.

Y2 Cấp tín hiệu cho cổng ENA- của Driver 1, 2

Tín hiệu chạy cho động cơ 1, 2. Y2 = 0 động cơ 1, 2 dừng; Y2 = 1 động cơ 1, 2 chạy.

Y3 Cấp tín hiệu cho cổng ENA- của Driver 3

Tín hiệu chạy cho động cơ 3. Y3 = 0 động cơ 3 chạy; Y3 = 1 động cơ 3 dừng.

Y4 Cấp tín hiệu cho cổng DIR- của Driver 1, 2

Tín hiệu đảo chiều cho động cơ 1,2. Y4= 1 động cơ chạy thuận (cánh tay di chuyển theo trục X+); Y4=0 động cơ chạy ngược (cánh tay di chuyển

69 theotrục X-).

Y5 Cấp tín hiệu cho cổng DIR- của Driver 3

Tín hiệu đảo chiều cho động cơ 3. Y5=0 động cơ 3 chạy ngược (cánh tay di chuyển theo trục Y-); Y5=1 động cơ 3 chạy thuận (cánh tay di chuyển theo trục Y+)

Y10

Cấp tín hiệu cho rơ le trung gian điều khiển van phân phối cho xi lanh khí nén 21

Xilanh khí nén 21 có chức năng dịch chuyển tay máy theo trục Z, hướng đi lên.

Y11

Cấp tín hiệu cho rơ le trung gian điều khiển van phân phối cho xi lanh khí nén 22

Xilanh khí nén 22 có chức năng dịch chuyển tay máy theo trục Z, hướng đi xuống.

Y12

Cấp tín hiệu cho rơ le trung gian điều khiển van phân phối cho xi lanh khí nén 22

Xilanh khí nén 22 có chức năng đóng mở bàn tay gắp dứa.

Y14

Cấp tín hiệu cho rơ le trung gian điều khiển van phân phối cho động cơ khí nén 32

Xilanh khí nén 32 có chức năng bật tắt cưa khí nén.

70

Thiết kế mạch nguyên lí cho cấp điều khiển

Đầu vào của PLC Mitsubishi FX3U-64M (1)

71 Hệ thống xilanh và động cơ khí nén của robot (1)

72 Hệthống Driver điều khiển và động cơ Stepper (1)

73

74 Đầuvào của PLC Mitsubishi FX3U-64M (2)

75 Hệ thống xi lanh và động cơ khí nén của robot (2)

76 Hệ thống Driver điều khiển và động cơ Stepper (2)

77

79

Chương trình điều khiển viết bằng SFC cho tay máy 1

80

81

82

// Chương trình trong khối chức năng S12

// Chương trình trong khối chức năng S13

83

//Chương trình trong khối chức năng S15

84

//Chương trình trong khối chức năng S18

85

86

Chương trình điều khiển viết bằng SFC cho tay máy 2

87

//Chương trình trong khối chức năng S10

88

89

90

Chương trình điều khiển giám sát trên ngôn ngữ Python

import tkinter import cv2

import pyrealsense2 as rs import operator

import time

from threading import Thread from yolo import YOLO

from utils.PLC_IO import PLC_IO

from utils.realSenseDepth import realSenseStream from utils.DepthTool import DepthTool

import utils.image2coordc as i2c from time import sleep

from PIL import Image, ImageDraw, ImageFont, ImageTK from PLC.PLCASync import PLCASync

import queue

import numpy as np

from tkinter import messengebox import tensorflow as tf

from keras.backend.tensorflow_backend import set_session threads = []

teststr = '1'

class App: #Giao dien hien thi

def__init__(self, window, window_title): self.window = window

self.window.title(window_title) self.window.geometry("1920x1080") self.testThread = None

self.realSenseStream = realSenseStream()

self.background_label = tkinter.Label(window, bg='grey') self.background_label.place(relx=0, rely=0, relheight=1, relwidth=1)

self.recipe = 0 self.input_str = "

# open video souce (by default this will try to open the computer webcam) # Creat a canvas that can fit the above video source size

91 self.canvas.place(relx=0.003, rely=0.1, relheight=0.7,

relwidth=0.498)

self.canvas1 = tkinter.Canvas(self.background_label) self.canvas1.place(relx=0.052, rely=0.1, relheight=0.7, relwidth=0.497)

# Button that lets the user take a snapshot self.btn_snapshot =

tkinter.Button(self.background_label,bg='salmon3',text="Start",fg='black',font=(" helvetica",25),command=self.snapshot)

self.btn_snapshot.place(relx=0.77, rely=0.85, relheight=0.09, relwidth=0.2)

self.btn_update =

tkinter.Button(self.background_label,bg='salmon3',text="Update",fg='black',font =("helvetica",25),command=self.btn_update)

self.btn_update.place(relx=0.53, rely=0.85, relheight=0.09, relwidth=0.2)

# After it is called once, the update method will be automatically called every delay milliseconds

self.label1 =

tkinter.Label(self.background_label,bg='salmon3',text="Camera Angle",font=("helvetica",25))

self.label1.place(relx=0.05, rely=0.85, relheight=0.09, relwidth=0.25)

self.label2 =

tkinter.Label(self.background_label,bg='salmon3',text="Pineapples Harverting Machine",fg='white',font=("helvetica",60))

self.label2.place(relx=0.003, rely=0.001, relheight=0.09, relwidth=0.996) self.entry1 = tkinter.Entry(self.background_label,bg='white') self.entry1.place(relx=0.35, rely=0.87) self.delay = 15 self.update() def_delete_window(self) print("delete_window") self.testThread.isstop = True self.testThread.join() try # self.testThread.join() self.window.destroy() except Exception as e:

92 print(e) pass def btn_update(self) teststr = self.entry1.get() if teststr == ":

messengebox.showerror("Error","Hay nhap thong so")

self.recipe = int(teststr)

self.testThread.recipe = self.recipe def snapshot(self)

# Get a frame from the video source teststr = self.entry1.get()

if teststr == ":

messengebox.showerror("Error","Hay nhap thong so") print(teststr) elif teststr!= ": flame1 = self.realSenseStream.get_flame() self.photo1 = ImageTK.PhotoImage(image=Image.fromarray(flame1)) self.canvas1.creat_image(0, 0, image=self.photo1, anchor=tkinter.NW) self.testThread = PLCASync1(self.realSenseStream) self.testThread.start() self.testThread.recipe = self.recipe print(self.testThread.recipe) threads.append(self.testThread) print(len(threads)) self.btn_snapshot.config(state = 'disable') def update(self)

# Get a frame from the realsense

frame = self.realSenseStream.get_flame() self.photo = ImageTK.PhotoImage(image=Image.fromarray(frame)) self.canvas.creat_image(0, 0, image=self.photo, anchor=tkinter.NW) self.testThread.image = self.testThread.image.resize((956, 756), Image.ANTIALIAS)

93 self.photo1 = ImageTK.PhotoImage(image=self.testThread.image) self.canvas1.creat_image(0, 0, image=self.photo1, anchor=tkinter.NW) super().__init__()

self.ready = False # flag tay cat dua self.take = False # flag chup anh

self.realSenseStream = realSenseStream self.isstop = False self.image = None self.imageUpdate = False self.systemready = False self.recipe = 1 self.parameter = 0 def run(self): gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.5)

config = tf.ConfigProto(gpu_options = gpu_options) sess = tf.Session(config = config)

detect = YOLO().raw_detect_image take_image = self.realSenseStream.take_image font = ImageFont.truetype('Pillow/Tests/fonts/FreeMono.ttf',size=32) hand_queue = queue.Queue(0) boxList1 = [] boxList2 = [] # PLC 1 plc1 = PLC_IO("PLC1",'/dev/ttyUSB0') plcThread1 = PLCASync(plc1) plcThread1.start() # PLC 2 plc2 = PLC_IO("PLC2",'/dev/ttyUSB1') plcThread2 = PLCASync(plc2)

# B2: Camera chup anh va detect

# B3: Chuyen sang toa do Cam va gui len PLC # B4: Quay lai vong lap

while True:

94 plcThread1.isstop = True plcThread2.isstop = True return plcThread1.ready = False plcThread1.take = False plcThread2.ready = False plcThread2.take = False plcThread1.mode1 = False plcThread2.mode2 = False plcThread1.RESET = False plcThread1.finish = False plcThread2.finish = False print("Wait") plc1.ser.flushOutput() plc1.serialOutready(1,1) plc1.ser.flushInput() self.systemready = True

while plcThread1.take == False: if self.isstop: plcThread1.isstop = True plcThread2.isstop = True print("Stop PLC Test") return continue plcThread1.RESET = False

# wait for pulse for i in range(2)

if plcThread1.RESET == True: break

if i == 1:

while plcThread1.ready == False or plcThread2.ready == False: if plcThread1.RESET == True: break continue if plcThread1.RESET == True: break

95 boxList1.clear()

boxList2.clear()

print("Taking image...")

path, dataPath, _ = take_image() #chup anh image = Image.open(path)

draw = ImageDraw.Draw(image) #khoi tao anh de luu

print("Tsh! Detecting...")

data = detect(image) #nhan dien qua dua print("Detected.") count_dua = 0 depthTool = DepthTool() depthTool.readCord(dataPath) bias = 0.1 gridSize = 10

for box in data['objects']:

if plcThread1.mode2 == True: if box['class'] == 2 count_dua += 1 depth =

depthTool.getDepthBoundingBox([box['box']['left'], box['box']['top'], box['box']['right'], box['box']['buttom']], gridSize, bias) * 100

x = (box['box']['left'] + box['box']['right'])/2 y = box['box']['buttom'] rx, ry = i2x.to_coord_from_depth(x,y,depth) draw.rectangle([box['box']['left'], box['box']['top'], box['box']['right'], box['box']['buttom']], outline=(255,0,0), width=10)

campov = str(rx)+''+str(ry) draw.text((box['box']['left'], box['box']['top'] -35 ), campov, fill = (255,0,0), font = font)

print(box['score'], box['box']['left'], box['box']['top']-35)

# xep toa do cho 2 tay cat if rx>0: #PLC1

boxList1.append({'x':rx, 'y':ry, 'box':box}) #them vao danh sach cat PLC 1

96 else

boxList2.append({'x':rx, 'y':ry, 'box':box}) #them vao danh sach cat PLC 1

pass if plcThread1.mode1 == True: if box['class'] == 3 or box['class'] == 2 count_dua += 1 depth = depthTool.getDepthBoundingBox([box['box']['left'], box['box']['top'], box['box']['right'], box['box']['buttom']], gridSize, bias) * 100

x = (box['box']['left'] + box['box']['right'])/2 y = box['box']['buttom'] rx, ry = i2x.to_coord_from_depth(x,y,depth) draw.rectangle([box['box']['left'], box['box']['top'], box['box']['right'], box['box']['buttom']], outline=(255,0,0), width=10)

campov = str(rx)+''+str(ry) draw.text((box['box']['left'], box['box']['top'] -35 ), campov, fill = (255,0,0), font = font)

print(box['score'], box['box']['left'], box['box']['top']-35)

# xep toa do cho 2 tay cat if rx>0: #PLC1

boxList1.append({'x':rx, 'y':ry, 'box':box}) #them vao danh sach cat PLC 1

else

boxList2.append({'x':rx, 'y':ry, 'box':box}) #them vao danh sach cat PLC 2

pass

if plc2.serialOut(obj['x'],obj['y']) == True #xuat toa do

plcThread2.ready = False

plcThread2.finish = False #reset tay

97 if i==1:

while plcThread2.finish == False or plcThread1.finish == False: if plcThread1.RESET == True: break if self.isstop: plcThread1.isstop = True plcThread2.isstop = True return continue # Create a window and pass it to the Application object App(tkinter.Tk(),"PINEAPPLE")

Một phần của tài liệu Thiết kế hệ thống điều khiển robot thu hoạch dứa dựa trên công nghệ xử lý ảnh (Trang 74 - 108)

Tải bản đầy đủ (PDF)

(108 trang)