diff --git a/mycobot_ai/mechArm_270/CMakeLists.txt b/mycobot_ai/mechArm_270/CMakeLists.txt index a597ed9..cdbf847 100644 --- a/mycobot_ai/mechArm_270/CMakeLists.txt +++ b/mycobot_ai/mechArm_270/CMakeLists.txt @@ -9,6 +9,7 @@ project(mechArm_270) ## is used, also find other catkin packages find_package(catkin REQUIRED COMPONENTS mecharm_pi + mecharm ) ## System dependencies are found with CMake's conventions diff --git a/mycobot_ai/mechArm_270/launch/vision_m5.launch b/mycobot_ai/mechArm_270/launch/vision_m5.launch new file mode 100644 index 0000000..4805952 --- /dev/null +++ b/mycobot_ai/mechArm_270/launch/vision_m5.launch @@ -0,0 +1,27 @@ + + + + + + + + + + + + + ["joint_states"] + + + + + + + + + + + + + + diff --git a/mycobot_ai/mechArm_270/launch/vision.launch b/mycobot_ai/mechArm_270/launch/vision_pi.launch similarity index 66% rename from mycobot_ai/mechArm_270/launch/vision.launch rename to mycobot_ai/mechArm_270/launch/vision_pi.launch index a01ed45..df576e0 100644 --- a/mycobot_ai/mechArm_270/launch/vision.launch +++ b/mycobot_ai/mechArm_270/launch/vision_pi.launch @@ -2,8 +2,8 @@ - - + + @@ -13,14 +13,14 @@ ["joint_states"] - - + + - + diff --git a/mycobot_ai/mechArm_270/launch/vision_wio.launch b/mycobot_ai/mechArm_270/launch/vision_wio.launch index 654f540..51eb78b 100644 --- a/mycobot_ai/mechArm_270/launch/vision_wio.launch +++ b/mycobot_ai/mechArm_270/launch/vision_wio.launch @@ -3,7 +3,7 @@ - + @@ -20,7 +20,7 @@ - + diff --git a/mycobot_ai/mechArm_270/package.xml b/mycobot_ai/mechArm_270/package.xml index 31da1fc..fb15204 100644 --- a/mycobot_ai/mechArm_270/package.xml +++ b/mycobot_ai/mechArm_270/package.xml @@ -42,7 +42,8 @@ - + @@ -53,6 +54,9 @@ mecharm_pi mecharm_pi + mecharm + mecharm + mecharm diff --git a/mycobot_ai/mechArm_270/res/blue/goal3.jpeg b/mycobot_ai/mechArm_270/res/blue/goal3.jpeg new file mode 100644 index 0000000..7af2ae1 Binary files /dev/null and b/mycobot_ai/mechArm_270/res/blue/goal3.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/blue/goal4.jpeg b/mycobot_ai/mechArm_270/res/blue/goal4.jpeg new file mode 100644 index 0000000..e499bbb Binary files /dev/null and b/mycobot_ai/mechArm_270/res/blue/goal4.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/blue/goal5.jpeg b/mycobot_ai/mechArm_270/res/blue/goal5.jpeg new file mode 100644 index 0000000..c6061be Binary files /dev/null and b/mycobot_ai/mechArm_270/res/blue/goal5.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/blue/goal6.jpeg b/mycobot_ai/mechArm_270/res/blue/goal6.jpeg new file mode 100644 index 0000000..037a4a1 Binary files /dev/null and b/mycobot_ai/mechArm_270/res/blue/goal6.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/blue/goal7.jpeg b/mycobot_ai/mechArm_270/res/blue/goal7.jpeg new file mode 100644 index 0000000..d7e1970 Binary files /dev/null and b/mycobot_ai/mechArm_270/res/blue/goal7.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/blue/goal8.jpeg b/mycobot_ai/mechArm_270/res/blue/goal8.jpeg new file mode 100644 index 0000000..a49591f Binary files /dev/null and b/mycobot_ai/mechArm_270/res/blue/goal8.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/gray/goal3.jpeg b/mycobot_ai/mechArm_270/res/gray/goal3.jpeg new file mode 100644 index 0000000..1d3ddcb Binary files /dev/null and b/mycobot_ai/mechArm_270/res/gray/goal3.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/gray/goal4.jpeg b/mycobot_ai/mechArm_270/res/gray/goal4.jpeg new file mode 100644 index 0000000..e10f0f4 Binary files /dev/null and b/mycobot_ai/mechArm_270/res/gray/goal4.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/gray/goal5.jpeg b/mycobot_ai/mechArm_270/res/gray/goal5.jpeg new file mode 100644 index 0000000..5750a65 Binary files /dev/null and b/mycobot_ai/mechArm_270/res/gray/goal5.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/gray/goal6.jpeg b/mycobot_ai/mechArm_270/res/gray/goal6.jpeg new file mode 100644 index 0000000..32c5343 Binary files /dev/null and b/mycobot_ai/mechArm_270/res/gray/goal6.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/gray/goal7.jpeg b/mycobot_ai/mechArm_270/res/gray/goal7.jpeg new file mode 100644 index 0000000..519d153 Binary files /dev/null and b/mycobot_ai/mechArm_270/res/gray/goal7.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/gray/goal8.jpeg b/mycobot_ai/mechArm_270/res/gray/goal8.jpeg new file mode 100644 index 0000000..8ef7c4a Binary files /dev/null and b/mycobot_ai/mechArm_270/res/gray/goal8.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/green/goal10.jpeg b/mycobot_ai/mechArm_270/res/green/goal10.jpeg new file mode 100644 index 0000000..e63eb35 Binary files /dev/null and b/mycobot_ai/mechArm_270/res/green/goal10.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/green/goal11.jpeg b/mycobot_ai/mechArm_270/res/green/goal11.jpeg new file mode 100644 index 0000000..b1242b0 Binary files /dev/null and b/mycobot_ai/mechArm_270/res/green/goal11.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/green/goal5.jpeg b/mycobot_ai/mechArm_270/res/green/goal5.jpeg new file mode 100644 index 0000000..b4e7578 Binary files /dev/null and b/mycobot_ai/mechArm_270/res/green/goal5.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/green/goal6.jpeg b/mycobot_ai/mechArm_270/res/green/goal6.jpeg new file mode 100644 index 0000000..fe5bff1 Binary files /dev/null and b/mycobot_ai/mechArm_270/res/green/goal6.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/green/goal7.jpeg b/mycobot_ai/mechArm_270/res/green/goal7.jpeg new file mode 100644 index 0000000..0353ba3 Binary files /dev/null and b/mycobot_ai/mechArm_270/res/green/goal7.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/green/goal8.jpeg b/mycobot_ai/mechArm_270/res/green/goal8.jpeg new file mode 100644 index 0000000..241727e Binary files /dev/null and b/mycobot_ai/mechArm_270/res/green/goal8.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/green/goal9.jpeg b/mycobot_ai/mechArm_270/res/green/goal9.jpeg new file mode 100644 index 0000000..2946c5b Binary files /dev/null and b/mycobot_ai/mechArm_270/res/green/goal9.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/red/goal2.jpeg b/mycobot_ai/mechArm_270/res/red/goal2.jpeg new file mode 100644 index 0000000..10787b9 Binary files /dev/null and b/mycobot_ai/mechArm_270/res/red/goal2.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/red/goal3.jpeg b/mycobot_ai/mechArm_270/res/red/goal3.jpeg new file mode 100644 index 0000000..519460f Binary files /dev/null and b/mycobot_ai/mechArm_270/res/red/goal3.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/red/goal4.jpeg b/mycobot_ai/mechArm_270/res/red/goal4.jpeg new file mode 100644 index 0000000..11f77b3 Binary files /dev/null and b/mycobot_ai/mechArm_270/res/red/goal4.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/red/goal5.jpeg b/mycobot_ai/mechArm_270/res/red/goal5.jpeg new file mode 100644 index 0000000..1ffa851 Binary files /dev/null and b/mycobot_ai/mechArm_270/res/red/goal5.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/red/goal6.jpeg b/mycobot_ai/mechArm_270/res/red/goal6.jpeg new file mode 100644 index 0000000..4a4f9a5 Binary files /dev/null and b/mycobot_ai/mechArm_270/res/red/goal6.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/red/goal7.jpeg b/mycobot_ai/mechArm_270/res/red/goal7.jpeg new file mode 100644 index 0000000..ca20e77 Binary files /dev/null and b/mycobot_ai/mechArm_270/res/red/goal7.jpeg differ diff --git a/mycobot_ai/mechArm_270/res/takephoto.jpeg b/mycobot_ai/mechArm_270/res/takephoto.jpeg index 2a29a1e..1798785 100644 Binary files a/mycobot_ai/mechArm_270/res/takephoto.jpeg and b/mycobot_ai/mechArm_270/res/takephoto.jpeg differ diff --git a/mycobot_ai/mechArm_270/scripts/add_img.py b/mycobot_ai/mechArm_270/scripts/add_img.py index 4d38ec6..6ff25b9 100755 --- a/mycobot_ai/mechArm_270/scripts/add_img.py +++ b/mycobot_ai/mechArm_270/scripts/add_img.py @@ -49,19 +49,19 @@ def take_photo(): def cut_photo(): - path_red = '/home/ubuntu/catkin_ws/src/mycobot_ros/mycobot_ai/res/red' + path_red = '/home/ubuntu/catkin_ws/src/mycobot_ros/mycobot_ai/myPalletizer_260/res/red' for i, j, k in os.walk(path_red): file_len_red = len(k) - path_gray = '/home/ubuntu/catkin_ws/src/mycobot_ros/mycobot_ai/res/gray' + path_gray = '/home/ubuntu/catkin_ws/src/mycobot_ros/mycobot_ai/myPalletizer_260/res/gray' for i, j, k in os.walk(path_gray): file_len_gray = len(k) - path_green = '/home/ubuntu/catkin_ws/src/mycobot_ros/mycobot_ai/res/green' + path_green = '/home/ubuntu/catkin_ws/src/mycobot_ros/mycobot_ai/myPalletizer_260/res/green' for i, j, k in os.walk(path_green): file_len_green = len(k) - path_blue = '/home/ubuntu/catkin_ws/src/mycobot_ros/mycobot_ai/res/blue' + path_blue = '/home/ubuntu/catkin_ws/src/mycobot_ros/mycobot_ai/myPalletizer_260/res/blue' for i, j, k in os.walk(path_blue): file_len_blue = len(k) print("请截取要识别的部分") @@ -95,19 +95,19 @@ def cut_photo(): cv2.imshow('crop', crop) # 选择红桶文件夹 if kw == 'red': - cv2.imwrite('/home/ubuntu/catkin_ws/src/mycobot_ros/mycobot_ai/res/red/goal{}.jpeg'.format(str(file_len_red + 1)),crop) + cv2.imwrite('/home/ubuntu/catkin_ws/src/mycobot_ros/mycobot_ai/myPalletizer_260/res/red/goal{}.jpeg'.format(str(file_len_red + 1)),crop) print('Saved') # 选择灰桶文件夹 elif kw == 'gray': - cv2.imwrite('/home/ubuntu/catkin_ws/src/mycobot_ros/mycobot_ai/res/gray/goal{}.jpeg'.format(str(file_len_gray+1)),crop) + cv2.imwrite('/home/ubuntu/catkin_ws/src/mycobot_ros/mycobot_ai/myPalletizer_260/res/gray/goal{}.jpeg'.format(str(file_len_gray+1)),crop) print('Saved') # 选择绿桶文件夹 elif kw == 'green': - cv2.imwrite('/home/ubuntu/catkin_ws/src/mycobot_ros/mycobot_ai/res/green/goal{}.jpeg'.format(str(file_len_green+1)),crop) + cv2.imwrite('/home/ubuntu/catkin_ws/src/mycobot_ros/mycobot_ai/myPalletizer_260/res/green/goal{}.jpeg'.format(str(file_len_green+1)),crop) print('Saved') # 选择蓝桶文件夹 elif kw == 'blue': - cv2.imwrite('/home/ubuntu/catkin_ws/src/mycobot_ros/mycobot_ai/res/blue/goal{}.jpeg'.format(str(file_len_blue+1)),crop) + cv2.imwrite('/home/ubuntu/catkin_ws/src/mycobot_ros/mycobot_ai/myPalletizer_260/res/blue/goal{}.jpeg'.format(str(file_len_blue+1)),crop) print('Saved') # 退出 diff --git a/mycobot_ai/mechArm_270/scripts/detect_obj_img.py b/mycobot_ai/mechArm_270/scripts/combine_detect_obj_color.py old mode 100755 new mode 100644 similarity index 51% rename from mycobot_ai/mechArm_270/scripts/detect_obj_img.py rename to mycobot_ai/mechArm_270/scripts/combine_detect_obj_color.py index 47bc937..cf95c53 --- a/mycobot_ai/mechArm_270/scripts/detect_obj_img.py +++ b/mycobot_ai/mechArm_270/scripts/combine_detect_obj_color.py @@ -1,49 +1,50 @@ -# encoding:utf-8 +# -*- coding:utf-8 -*- #!/usr/bin/env python2 - +from operator import imod from tokenize import Pointfloat import cv2 import numpy as np import time import json -import os +import os,sys import rospy -from visualization_msgs.msg import Marker -from PIL import Image -from threading import Thread -import tkFileDialog as filedialog -import Tkinter as tk +from visualization_msgs.msg import Marker +from pymycobot.mypalletizer import MyPalletizer from moving_utils import Movement + IS_CV_4 = cv2.__version__[0] == '4' -__version__ = "1.0" # Adaptive seeed +__version__ = "1.0" +# Adaptive seeed class Object_detect(Movement): - def __init__(self, camera_x=150, camera_y=-10): + + def __init__(self, camera_x = 160, camera_y = 10): # inherit the parent class super(Object_detect, self).__init__() # get path of file dir_path = os.path.dirname(__file__) - - + + # declare mypal260 + self.mc = None + # 移动角度 self.move_angles = [ - [-7.11, -6.94, -55.01, -24.16, 0, 15], # init the point - [-1.14, -10.63, -87.8, 9.05, -3.07, 15], # point to grab + [0, 0, 0, 0], # init the point + [-29.0, 5.88, -4.92, -76.28], # point to grab [17.4, -10.1, -87.27, 5.8, -2.02, 15], # point to grab ] + # 移动坐标 self.move_coords = [ - [120.1, -141.6, 240.9, -173.34, -8.15, -110.11], # above the red bucket - # above the yello bucket - #[208.2, -127.8, 260.9, -157.51, -17.5, -71.18], - [205.6, -130.5, 263.0, -150.99, -0.07, -107.35], - [209.7, -18.6, 230.4, -168.48, -9.86, -39.38], - [196.9, -64.7, 232.6, -166.66, -9.44, -52.47], - [126.6, -118.1, 305.0, -157.57, -13.72, -75.3], + [141.2, -142.0, 210, -26.8], # above the red bucket + [234.3, -120, 210, -48.77], # above the green bucket + [100.9, 159.3, 248.6, -124.27], # above the blue bucket + [-17.6, 161.6, 238.4, -152.31], # above the gray bucket ] - # 判断连接设备:ttyUSB*为M5,ttyACM*为seeed + + # which robot: USB* is m5; ACM* is wio; AMA* is raspi self.robot_m5 = os.popen("ls /dev/ttyUSB*").readline()[:-1] self.robot_wio = os.popen("ls /dev/ttyACM*").readline()[:-1] self.robot_raspi = os.popen("ls /dev/ttyAMA*").readline()[:-1] @@ -57,37 +58,35 @@ class Object_detect(Movement): i[2] -= 20 elif "dev" in self.robot_raspi or "dev" in self.robot_jes: import RPi.GPIO as GPIO - self.GPIO = GPIO GPIO.setwarnings(False) + self.GPIO = GPIO GPIO.setmode(GPIO.BCM) GPIO.setup(20, GPIO.OUT) GPIO.setup(21, GPIO.OUT) - + GPIO.output(20, 1) + GPIO.output(21, 1) self.raspi = True if self.raspi: self.gpio_status(False) - self.Pin = [2, 5] # choose place to set cube self.color = 0 # parameters to calculate camera clipping parameters self.x1 = self.x2 = self.y1 = self.y2 = 0 # set cache of real coord self.cache_x = self.cache_y = 0 - # load model of img recognition - # self.model_path = os.path.join(dir_path, "frozen_inference_graph.pb") - # self.pbtxt_path = os.path.join(dir_path, "graph.pbtxt") - # self.label_path = os.path.join(dir_path, "labels.json") - # load class labels - # self.labels = json.load(open(self.label_path)) - - - - - # use to calculate coord between cube and mycobot + # set color HSV + self.HSV = { + "yellow": [np.array([11, 115, 70]), np.array([40, 255, 245])], + "red": [np.array([0, 43, 46]), np.array([8, 255, 255])], + "green": [np.array([35, 43, 46]), np.array([77, 255, 255])], + "blue": [np.array([100, 43, 46]), np.array([124, 255, 255])], + "cyan": [np.array([78, 43, 46]), np.array([99, 255, 255])], + } + # use to calculate coord between cube and mypal260 self.sum_x1 = self.sum_x2 = self.sum_y2 = self.sum_y1 = 0 - # The coordinates of the grab center point relative to the mycobot + # The coordinates of the grab center point relative to the mypal260 self.camera_x, self.camera_y = camera_x, camera_y - # The coordinates of the cube relative to the mycobot + # The coordinates of the cube relative to the mypal260 self.c_x, self.c_y = 0, 0 # The ratio of pixels to actual values self.ratio = 0 @@ -96,11 +95,6 @@ class Object_detect(Movement): # Get ArUco marker params. self.aruco_params = cv2.aruco.DetectorParameters_create() - # if IS_CV_4: - # self.net = cv2.dnn.readNetFromTensorflow(self.model_path, self.pbtxt_path) - # else: - # print('Load tensorflow model need the version of opencv is 4.') - # exit(0) # init a node and a publisher rospy.init_node("marker", anonymous=True) self.pub = rospy.Publisher('/cube', Marker, queue_size=1) @@ -126,11 +120,7 @@ class Object_detect(Movement): self.marker.pose.orientation.z = 0 self.marker.pose.orientation.w = 1.0 - self.cache_x = self.cache_y = 0 - - # publish marker - def pub_marker(self, x, y, z=0.03): self.marker.header.stamp = rospy.Time.now() self.marker.pose.position.x = x @@ -139,6 +129,7 @@ class Object_detect(Movement): self.marker.color.g = self.color self.pub.publish(self.marker) + # pump_control pi def gpio_status(self, flag): if flag: self.GPIO.output(20, 0) @@ -146,80 +137,69 @@ class Object_detect(Movement): else: self.GPIO.output(20, 1) self.GPIO.output(21, 1) + + # 开启吸泵 m5 + def pump_on(self): + # 让2号位工作 + self.mc.set_basic_output(2, 0) + # 让5号位工作 + self.mc.set_basic_output(5, 0) + + # 停止吸泵 m5 + def pump_off(self): + # 让2号位停止工作 + self.mc.set_basic_output(2, 1) + # 让5号位停止工作 + self.mc.set_basic_output(5, 1) # Grasping motion def move(self, x, y, color): - # send Angle to move mycobot - self.pub_angles(self.move_angles[0], 20) - time.sleep(1.5) - self.pub_angles(self.move_angles[1], 20) - time.sleep(1.5) - self.pub_angles(self.move_angles[2], 20) - time.sleep(1.5) - # send coordinates to move mycobot - self.pub_coords([x, y, 165, -178.9, -1.57, -66], 20, 1) - time.sleep(1.5) - # 根据不同底板机械臂,调整吸泵高度 - if "dev" in self.robot_m5: - # m5 and jetson nano - self.pub_coords([x, y, 90, -178.9, -1.57, -66], 25, 1) - elif "dev" in self.robot_wio: - h = 0 - if 165 < x < 180: - h = 10 - elif x > 180: - h = 20 - elif x < 135: - h = -20 - self.pub_coords([x, y, 31.9+h, -178.9, -1, -66], 20, 1) - elif "dev" in self.robot_jes: - h = 0 - if x<130: - h=15 - self.pub_coords([x, y, 90-h, -178.9, -1.57, -66], 25, 1) - time.sleep(1.5) - # open pump - if self.raspi: - self.gpio_status(True) - else: - self.pub_pump(True, self.Pin) - time.sleep(0.5) - self.pub_angles(self.move_angles[2], 20) + # send Angle to move mypal260 + print(color) + self.mc.send_angles(self.move_angles[0], 20) time.sleep(3) - self.pub_marker( - self.move_coords[2][0]/1000.0, self.move_coords[2][1]/1000.0, self.move_coords[2][2]/1000.0) - self.pub_angles(self.move_angles[1], 20) + # send coordinates to move mypal260 + self.mc.send_coords([x, y, 160, 0], 20, 0) + time.sleep(1.5) + self.mc.send_coords([x, y, 90, 0], 20, 0) time.sleep(1.5) - self.pub_marker( - self.move_coords[3][0]/1000.0, self.move_coords[3][1]/1000.0, self.move_coords[3][2]/1000.0) - self.pub_angles(self.move_angles[0], 20) + # open pump + if "dev" in self.robot_m5: + self.pump_on() + elif "dev" in self.robot_raspi or "dev" in self.robot_jes: + self.gpio_status(True) time.sleep(1.5) - self.pub_marker( - self.move_coords[4][0]/1000.0, self.move_coords[4][1]/1000.0, self.move_coords[4][2]/1000.0) - print self.move_coords[color] - self.pub_coords(self.move_coords[color], 20, 1) + + self.mc.send_angle(2, 0, 20) + time.sleep(0.3) + self.mc.send_angle(3, -15, 20) + time.sleep(2) + + self.mc.send_coords(self.move_coords[color], 20, 1) self.pub_marker(self.move_coords[color][0]/1000.0, self.move_coords[color] [1]/1000.0, self.move_coords[color][2]/1000.0) - time.sleep(2) + time.sleep(3) + # close pump - if self.raspi: + if "dev" in self.robot_m5: + self.pump_off() + elif "dev" in self.robot_raspi or "dev" in self.robot_jes: self.gpio_status(False) - else: - self.pub_pump(False, self.Pin) - time.sleep(1) + time.sleep(6) + if color == 1: self.pub_marker( self.move_coords[color][0]/1000.0+0.04, self.move_coords[color][1]/1000.0-0.02) elif color == 0: self.pub_marker( self.move_coords[color][0]/1000.0+0.03, self.move_coords[color][1]/1000.0) - self.pub_angles(self.move_angles[0], 20) - time.sleep(3) + + self.mc.send_angles(self.move_angles[1], 20) + time.sleep(1.5) # decide whether grab cube - def decide_move(self, x, y, color): print(x, y, self.cache_x, self.cache_y) # detect the cube status move or run @@ -229,43 +209,23 @@ class Object_detect(Movement): else: self.cache_x = self.cache_y = 0 # 调整吸泵吸取位置,y增大,向左移动;y减小,向右移动;x增大,前方移动;x减小,向后方移动 - if "dev" in self.robot_wio: - if (y < -30 and x > 140) or (x > 150 and y < -10): - x -= 10 - y += 10 - elif y > -10: - y += 10 - elif x > 170: - x -= 10 - y += 10 - elif "dev" in self.robot_m5: - y += 10 - x -= 15 - if y < -20: - y += 5 - # print x,y - elif "dev" in self.robot_jes: - if y<0: - x+=5 - y+=3 - y+=10 - print x,y self.move(x, y, color) - # init mycobot + # init mypal260 def run(self): + if "dev" in self.robot_m5: + self.mc = MyPalletizer(self.robot_m5, 115200) + elif "dev" in self.robot_raspi: + self.mc = MyPalletizer(self.robot_raspi, 1000000) if not self.raspi: self.pub_pump(False, self.Pin) - for _ in range(5): - self.pub_angles([-7.11, -6.94, -55.01, -24.16, 0, -15], 20) - print(_) - time.sleep(0.5) + self.mc.send_angles([-29.0, 5.88, -4.92, -76.28], 20) + time.sleep(3) # draw aruco - def draw_marker(self, img, x, y): # draw rectangle on img - cv2.rectangle( + cv2.rectangle( img, (x - 20, y - 20), (x + 20, y + 20), @@ -313,13 +273,13 @@ class Object_detect(Movement): self.y2 = int(y2) print(self.x1, self.y1, self.x2, self.y2) - # set parameters to calculate the coords between cube and mycobot + # set parameters to calculate the coords between cube and mypal260 def set_params(self, c_x, c_y, ratio): self.c_x = c_x self.c_y = c_y self.ratio = 220.0/ratio - # calculate the coords between cube and mycobot + # calculate the coords between cube and mypal260 def get_position(self, x, y): return ((y - self.c_y)*self.ratio + self.camera_x), ((x - self.c_x)*self.ratio + self.camera_y) @@ -328,7 +288,6 @@ class Object_detect(Movement): Enlarge the video pixel by 1.5 times, which means enlarge the video size by 1.5 times. If two ARuco values have been calculated, clip the video. """ - def transform_frame(self, frame): # enlarge the image by 1.5 times fx = 1.5 @@ -341,160 +300,88 @@ class Object_detect(Movement): int(self.x1*0.7):int(self.x2*1.15)] return frame - # according the class_id to get object name - def id_class_name(self, class_id): - for key, value in self.labels.items(): - if class_id == int(key): - return value - # detect object + # detect cube color + def color_detect(self, img): + # set the arrangement of color'HSV + x = y = 0 + for mycolor, item in self.HSV.items(): + # print("mycolor:",mycolor) + redLower = np.array(item[0]) + redUpper = np.array(item[1]) - def obj_detect(self, img, goal): - # rows, cols = frame.shape[:-1] - # Resize image and swap BGR to RGB. - # blob = cv2.dnn.blobFromImage( - # frame, - # size=(300, 300), - # mean=(0, 0, 0), - # swapRB=True, - # crop=False, - # ) + # transfrom the img to model of gray + hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) + # print("hsv",hsv) - # Detecting. - # self.net.setInput(blob) - # out = self.net.forward() - # x, y = 0, 0 + # wipe off all color expect color in range + mask = cv2.inRange(hsv, item[0], item[1]) - # Processing result. - # for detection in out[0, 0, :, :]: - # score = float(detection[2]) - # if score > 0.3: - # class_id = detection[1] - # left = detection[3] * cols - # top = detection[4] * rows - # right = detection[5] * cols - # bottom = detection[6] * rows - # if abs(right + bottom - left - top) > 380: - # continue - # x, y = (left + right) / 2.0, (top + bottom) / 2.0 - # cv2.rectangle( - # frame, - # (int(left), int(top)), - # (int(right), int(bottom)), - # (0, 230, 0), - # thickness=2, - # ) - # cv2.putText( - # frame, - # "{}: {}%".format(self.id_class_name(class_id),round(score * 100, 2)), - # (int(left), int(top) - 10), - # cv2.FONT_HERSHEY_COMPLEX_SMALL, - # 1, - # (243, 0, 0), - # 2, - # ) - i = 0 - MIN_MATCH_COUNT = 10 - sift = cv2.xfeatures2d.SIFT_create() + # a etching operation on a picture to remove edge roughness + erosion = cv2.erode(mask, np.ones((1, 1), np.uint8), iterations=2) - # find the keypoints and descriptors with SIFT - kp = [] - des = [] + # the image for expansion operation, its role is to deepen the color depth in the picture + dilation = cv2.dilate(erosion, np.ones( + (1, 1), np.uint8), iterations=2) - for i in goal: - kp0, des0 = sift.detectAndCompute(i, None) - kp.append(kp0) - des.append(des0) - # kp1, des1 = sift.detectAndCompute(goal, None) - kp2, des2 = sift.detectAndCompute(img, None) + # adds pixels to the image + target = cv2.bitwise_and(img, img, mask=dilation) - # FLANN parameters - FLANN_INDEX_KDTREE = 0 - index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5) - search_params = dict(checks=50) # or pass empty dictionary - flann = cv2.FlannBasedMatcher(index_params, search_params) + # the filtered image is transformed into a binary image and placed in binary + ret, binary = cv2.threshold(dilation, 127, 255, cv2.THRESH_BINARY) - x, y = 0, 0 - try: - for i in range(len(des)): - matches = flann.knnMatch(des[i], des2, k=2) - # store all the good matches as per Lowe's ratio test. 根据Lowe比率测试存储所有良好匹配项。 - good = [] - for m, n in matches: - if m.distance < 0.7*n.distance: - good.append(m) + # get the contour coordinates of the image, where contours is the coordinate value, here only the contour is detected + contours, hierarchy = cv2.findContours( + dilation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) - # When there are enough robust matching point pairs 当有足够的健壮匹配点对(至少个MIN_MATCH_COUNT)时 - if len(good) > MIN_MATCH_COUNT: + if len(contours) > 0: + # do something about misidentification + boxes = [ + box + for box in [cv2.boundingRect(c) for c in contours] + if min(img.shape[0], img.shape[1]) / 10 + < min(box[2], box[3]) + < min(img.shape[0], img.shape[1]) / 1 + ] + if boxes: + for box in boxes: + x, y, w, h = box + # find the largest object that fits the requirements + c = max(contours, key=cv2.contourArea) + # get the lower left and upper right points of the positioning object + x, y, w, h = cv2.boundingRect(c) + # locate the target by drawing rectangle + cv2.rectangle(img, (x, y), (x+w, y+h), (153, 153, 0), 2) + # calculate the rectangle center + x, y = (x*2+w)/2, (y*2+h)/2 + # calculate the real coordinates of mypal260 relative to the target + + if mycolor == "red": + self.color = 0 + elif mycolor == "green": + self.color = 1 + elif mycolor == "cyan": + self.color = 2 + else: + self.color = 3 - # extract corresponding point pairs from matching 从匹配中提取出对应点对 - # query index of small objects, training index of scenarios 小对象的查询索引,场景的训练索引 - src_pts = np.float32( - [kp[i][m.queryIdx].pt for m in good]).reshape(-1, 1, 2) - dst_pts = np.float32( - [kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2) - - # Using matching points to find homography matrix in cv2.ransac 利用匹配点找到CV2.RANSAC中的单应矩阵 - M, mask = cv2.findHomography( - src_pts, dst_pts, cv2.RANSAC, 5.0) - matchesMask = mask.ravel().tolist() - # Calculate the distortion of image, that is the corresponding position in frame 计算图1的畸变,也就是在图2中的对应的位置 - h, w, d = goal[i].shape - pts = np.float32( - [[0, 0], [0, h-1], [w-1, h-1], [w-1, 0]]).reshape(-1, 1, 2) - dst = cv2.perspectiveTransform(pts, M) - ccoord = (dst[0][0]+dst[1][0]+dst[2][0]+dst[3][0])/4.0 - cv2.putText(img, "{}".format(ccoord), (50, 60), fontFace=None, - fontScale=1, color=(0, 255, 0), lineType=1) - print(format(dst[0][0][0])) - x = (dst[0][0][0]+dst[1][0][0] + - dst[2][0][0]+dst[3][0][0])/4.0 - y = (dst[0][0][1]+dst[1][0][1] + - dst[2][0][1]+dst[3][0][1])/4.0 - - # bound box 绘制边框 - img = cv2.polylines( - img, [np.int32(dst)], True, 244, 3, cv2.LINE_AA) - # cv2.polylines(mixture, [np.int32(dst)], True, (0, 255, 0), 2, cv2.LINE_AA) - except Exception as e: - pass - - # else: - # if(len(good) < MIN_MATCH_COUNT): - - # i += 1 - # if(i % 10 == 0): - # print("Not enough matches are found - %d/%d" % - # (len(good), MIN_MATCH_COUNT)) - - # matchesMask = None - if x+y > 0: + if abs(x) + abs(y) > 0: return x, y else: return None +if __name__ == "__main__": -def run(): - - # Object_detect().take_photo() - # Object_detect().cut_photo() - # goal = Object_detect().distinguist() - goal = [] - path = os.getcwd()+'/local_photo/img' - - for i, j, k in os.walk(path): - for l in k: - goal.append(cv2.imread('local_photo/img/{}'.format(l))) - + # open the camera cap_num = 0 cap = cv2.VideoCapture(cap_num, cv2.CAP_V4L) if not cap.isOpened(): cap.open() # init a class of Object_detect detect = Object_detect() - # init mycobot + # init mypal260 detect.run() - _init_ = 20 # + _init_ = 20 init_num = 0 nparams = 0 num = 0 @@ -504,10 +391,10 @@ def run(): _, frame = cap.read() # deal img frame = detect.transform_frame(frame) - if _init_ > 0: _init_ -= 1 continue + # calculate the parameters of camera clipping if init_num < 20: if detect.get_calculate_params(frame) is None: @@ -534,7 +421,7 @@ def run(): init_num += 1 continue - # calculate params of the coords between cube and mycobot + # calculate params of the coords between cube and mypal260 if nparams < 10: if detect.get_calculate_params(frame) is None: cv2.imshow("figure", frame) @@ -551,27 +438,28 @@ def run(): continue elif nparams == 10: nparams += 1 - # calculate and set params of calculating real coord between cube and mycobot + # calculate and set params of calculating real coord between cube and mypal260 detect.set_params( (detect.sum_x1+detect.sum_x2)/20.0, (detect.sum_y1+detect.sum_y2)/20.0, abs(detect.sum_x1-detect.sum_x2)/10.0 + abs(detect.sum_y1-detect.sum_y2)/10.0 ) - print "ok" + print("ok") continue + # get detect result - detect_result = detect.obj_detect(frame, goal) + detect_result = detect.color_detect(frame) if detect_result is None: cv2.imshow("figure", frame) continue else: x, y = detect_result - # calculate real coord between cube and mycobot + # calculate real coord between cube and mypal260 real_x, real_y = detect.get_position(x, y) - if num == 5: - detect.pub_marker(real_sx/5.0/1000.0, real_sy/5.0/1000.0) - detect.decide_move(real_sx/5.0, real_sy/5.0, detect.color) + if num == 20: + detect.pub_marker(real_sx/20.0/1000.0, real_sy/20.0/1000.0) + detect.decide_move(real_sx/20.0, real_sy/20.0, detect.color) num = real_sx = real_sy = 0 else: @@ -581,8 +469,8 @@ def run(): cv2.imshow("figure", frame) - -if __name__ == "__main__": - run() - # Object_detect().take_photo() - # Object_detect().cut_photo() + # close the window + if cv2.waitKey(1) & 0xFF == ord('q'): + cap.release() + cv2.destroyAllWindows() + sys.exit() \ No newline at end of file diff --git a/mycobot_ai/mechArm_270/scripts/combine_detect_obj_img_folder_opt.py b/mycobot_ai/mechArm_270/scripts/combine_detect_obj_img_folder_opt.py new file mode 100755 index 0000000..c40ffbe --- /dev/null +++ b/mycobot_ai/mechArm_270/scripts/combine_detect_obj_img_folder_opt.py @@ -0,0 +1,667 @@ +#!/usr/bin/env python2 +# encoding:utf-8 +from multiprocessing import Process, Pipe +from cgi import parse +from difflib import restore +# import queue +from sys import path +from tokenize import Pointfloat +from turtle import color +# from typing_extensions import Self +import cv2 +import numpy as np +import time +import json +import os,sys +import rospy +from visualization_msgs.msg import Marker +from PIL import Image +from threading import Thread +import tkFileDialog as filedialog +import Tkinter as tk +from moving_utils import Movement +from pymycobot.mypalletizer import MyPalletizer + +IS_CV_4 = cv2.__version__[0] == '4' +__version__ = "1.0" # Adaptive seeed + + +class Object_detect(Movement): + + def __init__(self, camera_x = 160, camera_y = 10): + # inherit the parent class + super(Object_detect, self).__init__() + # get path of file + dir_path = os.path.dirname(__file__) + + # declare mypal260 + self.mc = None + # 移动角度 + self.move_angles = [ + [0, 0, 0, 0], # init the point + [-29.0, 5.88, -4.92, -76.28], # point to grab + [17.4, -10.1, -87.27, 5.8, -2.02, 15], # point to grab + ] + + # 移动坐标 + self.move_coords = [ + [141.2, -142.0, 210, -26.8], # above the red bucket + [234.3, -120, 210, -48.77], # above the green bucket + [100.9, 159.3, 248.6, -124.27], # above the blue bucket + [-17.6, 161.6, 238.4, -152.31], # above the gray bucket + ] + + # 判断连接设备:ttyUSB*为M5,ttyACM*为seeed + self.raspi = False + # import RPi.GPIO as GPIO + # self.GPIO = GPIO + # GPIO.setwarnings(False) + # GPIO.setmode(GPIO.BCM) + # GPIO.setup(20, GPIO.OUT) + # GPIO.setup(21, GPIO.OUT) + + # self.gpio_status(False) + # self.Pin = [2, 5] + self.robot_m5 = os.popen("ls /dev/ttyUSB*").readline()[:-1] + self.robot_wio = os.popen("ls /dev/ttyACM*").readline()[:-1] + self.robot_raspi = os.popen("ls /dev/ttyAMA*").readline()[:-1] + self.robot_jes = os.popen("ls /dev/ttyTHS1").readline()[:-1] + if "dev" in self.robot_m5: + self.Pin = [2, 5] + elif "dev" in self.robot_wio: + self.Pin = [20, 21] + for i in self.move_coords: + i[2] -= 20 + elif "dev" in self.robot_raspi or "dev" in self.robot_jes: + import RPi.GPIO as GPIO + GPIO.setwarnings(False) + self.GPIO = GPIO + GPIO.setmode(GPIO.BCM) + GPIO.setup(20, GPIO.OUT) + GPIO.setup(21, GPIO.OUT) + GPIO.output(20, 1) + GPIO.output(21, 1) + self.raspi = True + if self.raspi: + self.gpio_status(False) + # choose place to set cube + self.color = 0 + # parameters to calculate camera clipping parameters + self.x1 = self.x2 = self.y1 = self.y2 = 0 + # set cache of real coord + self.cache_x = self.cache_y = 0 + # load model of img recognition + # self.model_path = os.path.join(dir_path, "frozen_inference_graph.pb") + # self.pbtxt_path = os.path.join(dir_path, "graph.pbtxt") + # self.label_path = os.path.join(dir_path, "labels.json") + # # load class labels + # self.labels = json.load(open(self.label_path)) + + # use to calculate coord between cube and mycobot + self.sum_x1 = self.sum_x2 = self.sum_y2 = self.sum_y1 = 0 + # The coordinates of the grab center point relative to the mycobot + self.camera_x, self.camera_y = camera_x, camera_y + # The coordinates of the cube relative to the mycobot + self.c_x, self.c_y = 0, 0 + # The ratio of pixels to actual values + self.ratio = 0 + # Get ArUco marker dict that can be detected. + self.aruco_dict = cv2.aruco.Dictionary_get(cv2.aruco.DICT_6X6_250) + # Get ArUco marker params. + self.aruco_params = cv2.aruco.DetectorParameters_create() + + # if IS_CV_4: + # self.net = cv2.dnn.readNetFromTensorflow(self.model_path, self.pbtxt_path) + # else: + # print('Load tensorflow model need the version of opencv is 4.') + # exit(0) + + # init a node and a publisher + rospy.init_node("marker", anonymous=True) + self.pub = rospy.Publisher('/cube', Marker, queue_size=1) + # init a Marker + self.marker = Marker() + self.marker.header.frame_id = "/joint1" + self.marker.ns = "cube" + self.marker.type = self.marker.CUBE + self.marker.action = self.marker.ADD + self.marker.scale.x = 0.04 + self.marker.scale.y = 0.04 + self.marker.scale.z = 0.04 + self.marker.color.a = 1.0 + self.marker.color.g = 1.0 + self.marker.color.r = 1.0 + + # marker position initial + self.marker.pose.position.x = 0 + self.marker.pose.position.y = 0 + self.marker.pose.position.z = 0.03 + self.marker.pose.orientation.x = 0 + self.marker.pose.orientation.y = 0 + self.marker.pose.orientation.z = 0 + self.marker.pose.orientation.w = 1.0 + + self.cache_x = self.cache_y = 0 + + # publish marker + def pub_marker(self, x, y, z=0.03): + self.marker.header.stamp = rospy.Time.now() + self.marker.pose.position.x = x + self.marker.pose.position.y = y + self.marker.pose.position.z = z + self.marker.color.g = self.color + self.pub.publish(self.marker) + # pump_control pi + def gpio_status(self, flag): + if flag: + self.GPIO.output(20, 0) + self.GPIO.output(21, 0) + else: + self.GPIO.output(20, 1) + self.GPIO.output(21, 1) + + # 开启吸泵 m5 + def pump_on(self): + # 让2号位工作 + self.mc.set_basic_output(2, 0) + # 让5号位工作 + self.mc.set_basic_output(5, 0) + + # 停止吸泵 m5 + def pump_off(self): + # 让2号位停止工作 + self.mc.set_basic_output(2, 1) + # 让5号位停止工作 + self.mc.set_basic_output(5, 1) + + # Grasping motion + def move(self, x, y, color): + # send Angle to move mypal260 + self.mc.send_angles(self.move_angles[0], 20) + time.sleep(3) + + # send coordinates to move mypal260 根据不同底板机械臂,调整吸泵高度 + self.mc.send_coords([x, y, 160, 0], 20, 0) + time.sleep(1.5) + self.mc.send_coords([x, y, 90, 0], 20, 0) + time.sleep(1.5) + + # open pump + if "dev" in self.robot_m5: + self.pump_on() + elif "dev" in self.robot_raspi or "dev" in self.robot_jes: + self.gpio_status(True) + time.sleep(1.5) + + self.mc.send_angle(2, 0, 20) + time.sleep(0.3) + self.mc.send_angle(3, -15, 20) + time.sleep(2) + + self.mc.send_coords(self.move_coords[color], 20, 1) + self.pub_marker(self.move_coords[color][0] / 1000.0, + self.move_coords[color][1] / 1000.0, + self.move_coords[color][2] / 1000.0) + time.sleep(3) + + # close pump + if "dev" in self.robot_m5: + self.pump_off() + elif "dev" in self.robot_raspi or "dev" in self.robot_jes: + self.gpio_status(False) + time.sleep(6) + + self.mc.send_angles(self.move_angles[1], 20) + time.sleep(1.5) + + # decide whether grab cube + def decide_move(self, x, y, color): + print(x, y, self.cache_x, self.cache_y) + # detect the cube status move or run + if (abs(x - self.cache_x) + abs(y - self.cache_y)) / 2 > 5: # mm + self.cache_x, self.cache_y = x, y + return + else: + self.cache_x = self.cache_y = 0 + # 调整吸泵吸取位置,y增大,向左移动;y减小,向右移动;x增大,前方移动;x减小,向后方移动 + self.move(x, y, color) + + # init mypal260 + def run(self): + if "dev" in self.robot_m5: + self.mc = MyPalletizer(self.robot_m5, 115200) + elif "dev" in self.robot_raspi: + self.mc = MyPalletizer(self.robot_raspi, 1000000) + if not self.raspi: + self.pub_pump(False, self.Pin) + self.mc.send_angles([-29.0, 5.88, -4.92, -76.28], 20) + time.sleep(3) + + # draw aruco + def draw_marker(self, img, x, y): + # draw rectangle on img + cv2.rectangle( + img, + (x - 20, y - 20), + (x + 20, y + 20), + (0, 255, 0), + thickness=2, + lineType=cv2.FONT_HERSHEY_COMPLEX, + ) + # add text on rectangle + cv2.putText( + img, + "({},{})".format(x, y), + (x, y), + cv2.FONT_HERSHEY_COMPLEX_SMALL, + 1, + (243, 0, 0), + 2, + ) + + # get points of two aruco + def get_calculate_params(self, img): + # Convert the image to a gray image + gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) + # Detect ArUco marker. + corners, ids, rejectImaPoint = cv2.aruco.detectMarkers( + gray, self.aruco_dict, parameters=self.aruco_params) + + """ + Two Arucos must be present in the picture and in the same order. + There are two Arucos in the Corners, and each aruco contains the pixels of its four corners. + Determine the center of the aruco by the four corners of the aruco. + """ + if len(corners) > 0: + if ids is not None: + if len(corners) <= 1 or ids[0] == 1: + return None + x1 = x2 = y1 = y2 = 0 + point_11, point_21, point_31, point_41 = corners[0][0] + x1, y1 = int( + (point_11[0] + point_21[0] + point_31[0] + point_41[0]) / + 4.0), int( + (point_11[1] + point_21[1] + point_31[1] + point_41[1]) + / 4.0) + point_1, point_2, point_3, point_4 = corners[1][0] + x2, y2 = int( + (point_1[0] + point_2[0] + point_3[0] + point_4[0]) / + 4.0), int( + (point_1[1] + point_2[1] + point_3[1] + point_4[1]) / + 4.0) + return x1, x2, y1, y2 + return None + + # set camera clipping parameters + def set_cut_params(self, x1, y1, x2, y2): + self.x1 = int(x1) + self.y1 = int(y1) + self.x2 = int(x2) + self.y2 = int(y2) + print(self.x1, self.y1, self.x2, self.y2) + + # set parameters to calculate the coords between cube and mycobot + def set_params(self, c_x, c_y, ratio): + self.c_x = c_x + self.c_y = c_y + self.ratio = 220.0 / ratio + + # calculate the coords between cube and mycobot + def get_position(self, x, y): + return ((y - self.c_y) * self.ratio + + self.camera_x), ((x - self.c_x) * self.ratio + self.camera_y) + + """ + Calibrate the camera according to the calibration parameters. + Enlarge the video pixel by 1.5 times, which means enlarge the video size by 1.5 times. + If two ARuco values have been calculated, clip the video. + """ + + def transform_frame(self, frame): + # enlarge the image by 1.5 times + fx = 1.5 + fy = 1.5 + frame = cv2.resize(frame, (0, 0), + fx=fx, + fy=fy, + interpolation=cv2.INTER_CUBIC) + if self.x1 != self.x2: + # the cutting ratio here is adjusted according to the actual situation + frame = frame[int(self.y2 * 0.2):int(self.y1 * 1.15), + int(self.x1 * 0.7):int(self.x2 * 1.15)] + return frame + + # according the class_id to get object name + def id_class_name(self, class_id): + for key, value in self.labels.items(): + if class_id == int(key): + return value + + # detect object + def obj_detect(self, img, goal, kp_img, desc_img, kp_list, desc_list, connection): + i = 0 + MIN_MATCH_COUNT = 5 + # sift = cv2.xfeatures2d.SIFT_create() + + # find the keypoints and descriptors with SIFT + # kp = [] + # des = [] + kp = kp_list + des = desc_list + + # for i in goal: + # kp0, des0 = sift.detectAndCompute(i, None) + # kp.append(kp0) + # des.append(des0) + + # kp1, des1 = sift.detectAndCompute(goal, None) + # kp2, des2 = sift.detectAndCompute(img, None) + kp2, des2 = kp_img, desc_img + + # FLANN parameters + FLANN_INDEX_KDTREE = 0 + index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5) + search_params = dict(checks=50) # or pass empty dictionary + flann = cv2.FlannBasedMatcher(index_params, search_params) + + x, y = 0, 0 + try: + for i in range(len(des)): + matches = flann.knnMatch(des[i], des2, k=2) + # store all the good matches as per Lowe's ratio test. 根据Lowe比率测试存储所有良好匹配项。 + good = [] + for m, n in matches: + if m.distance < 0.7 * n.distance: + good.append(m) + + # When there are enough robust matching point pairs 当有足够的健壮匹配点对(至少个MIN_MATCH_COUNT)时 + if len(good) > MIN_MATCH_COUNT: + + # extract corresponding point pairs from matching 从匹配中提取出对应点对 + # query index of small objects, training index of scenarios 小对象的查询索引,场景的训练索引 + src_pts = np.float32([kp[i][m.queryIdx].pt + for m in good]).reshape(-1, 1, 2) + dst_pts = np.float32([kp2[m.trainIdx].pt + for m in good]).reshape(-1, 1, 2) + + # Using matching points to find homography matrix in cv2.ransac 利用匹配点找到CV2.RANSAC中的单应矩阵 + M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, + 5.0) + matchesMask = mask.ravel().tolist() + # Calculate the distortion of image, that is the corresponding position in frame 计算图1的畸变,也就是在图2中的对应的位置 + h, w, d = goal[i].shape + pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1], + [w - 1, 0]]).reshape(-1, 1, 2) + dst = cv2.perspectiveTransform(pts, M) + coord = (dst[0][0] + dst[1][0] + dst[2][0] + + dst[3][0]) / 4.0 + connection.send((DRAW_COORDS, coord)) + # cv2.putText(img, "{}".format(coord), (50, 60), + # fontFace=None, fontScale=1, + # color=(0, 255, 0), lineType=1) + print(format(dst[0][0][0])) + x = (dst[0][0][0] + dst[1][0][0] + dst[2][0][0] + + dst[3][0][0]) / 4.0 + y = (dst[0][0][1] + dst[1][0][1] + dst[2][0][1] + + dst[3][0][1]) / 4.0 + + # bound box 绘制边框 + # img = cv2.polylines(img, [np.int32(dst)], True, 244, 3, cv2.LINE_AA) + connection.send((DRAW_RECT, dst)) + # cv2.polylines(mixture, [np.int32(dst)], True, (0, 255, 0), 2, cv2.LINE_AA) + except Exception as e: + pass + + if x + y > 0: + return x, y + else: + return None + +# The path to save the image folder +def parse_folder(folder): + restore = [] + path1 = '/home/ubuntu/catkin_ws/src/mycobot_ros/mycobot_ai/myPalletizer_260/' + folder + path2 = '/home/h/catkin_ws/src/mycobot_ros/mycobot_ai/myPalletizer_260/' + folder + + if os.path.exists(path1): + path = path1 + elif os.path.exists(path2): + path = path2 + + for i, j, k in os.walk(path): + for l in k: + restore.append(cv2.imread(folder + '/{}'.format(l))) + return restore + +def compute_keypoints_and_descriptors(sift, images_lists): + kp_list = [] + desc_list = [] + for images in images_lists: + kp_tmp = [] + desc_tmp = [] + for img in images: + kp, desc = sift.detectAndCompute(img, None) + kp_tmp.append(kp) + desc_tmp.append(desc) + kp_list.append(kp_tmp) + desc_list.append(desc_tmp) + + return kp_list, desc_list + +GET_FRAME = 1 +STOP_PROCESSING = 2 +DRAW_COORDS = 3 +DRAW_RECT = 4 +CLEAR_DRAW = 5 +CROP_FRAME = 6 + +def get_frame(connection): + connection.send(GET_FRAME) + frame = connection.recv() + return frame + +def process_transform_frame(frame, x1, y1, x2, y2): + # enlarge the image by 1.5 times + fx = 1.5 + fy = 1.5 + frame = cv2.resize(frame, (0, 0), + fx=fx, + fy=fy, + interpolation=cv2.INTER_CUBIC) +# if x1 != x2: + # the cutting ratio here is adjusted according to the actual situation +# frame = frame[int(y2 * 0.2):int(y1 * 1.15), +# int(x1 * 0.7):int(x2 * 1.15)] + return frame + +def process_display_frame(connection): + cap_num = 0 + coord = None + dst = None + x1 = 0 + y1 = 0 + x2 = 0 + y2 = 0 + cap = cv2.VideoCapture(cap_num, cv2.CAP_V4L) + if not cap.isOpened(): + cap.open() + while cv2.waitKey(1) < 0: + _, frame = cap.read() + frame = process_transform_frame(frame, x1, y1, x2, y2) + if connection.poll(): + request = connection.recv() + if request == GET_FRAME: + connection.send(frame) + elif request == CLEAR_DRAW: + coord = None + dst = None + elif type(request) is tuple: + if request[0] == DRAW_COORDS: + coord = request[1] + elif request[0] == DRAW_RECT: + dst = request[1] + elif request[0] == CROP_FRAME: + x1 = request[1] + y1 = request[2] + x2 = request[3] + y2 = request[4] + + if not coord is None: + cv2.putText(frame, "{}".format(coord), (50, 60), fontFace=None, + fontScale=1, color=(0, 255, 0), lineType=1) + if not dst is None: + frame = cv2.polylines(frame, [np.int32(dst)], True, 244, 3, cv2.LINE_AA) + cv2.imshow("figure", frame) + time.sleep(0.04) + connection.send(STOP_PROCESSING) + +def run(): + parent_conn, child_conn = Pipe() + child = Process(target = process_display_frame, args=(child_conn,)) + child.start() + + # Object_detect().take_photo() + # Object_detect().cut_photo() + # goal = Object_detect().distinguist() + + res_queue = [[], [], [], []] + res_queue[0] = parse_folder('res/red') + res_queue[1] = parse_folder('res/green') + res_queue[2] = parse_folder('res/blue') + res_queue[3] = parse_folder('res/gray') + + # res_queue = [] + # res_queue.extend(parse_folder('res/red')) + # res_queue.extend(parse_folder('res/green')) + # res_queue.extend(parse_folder('res/gray')) + # res_queue.extend(parse_folder('res/blue')) + + sift = cv2.xfeatures2d.SIFT_create() + kp_list, desc_list = compute_keypoints_and_descriptors(sift, res_queue) + + # init a class of Object_detect + detect = Object_detect() + + # init mycobot + detect.run() + + # _init_ = 20 # + init_num = 0 + nparams = 0 + # num = 0 + # real_sx = real_sy = 0 + while True: + start_time = time.time() + if parent_conn.poll(): + data = parent_conn.recv() + if data == STOP_PROCESSING: + break + # read camera + frame = get_frame(parent_conn) + # deal img + #frame = detect.transform_frame(frame) + + # if _init_ > 0: + # _init_ -= 1 + # continue + # calculate the parameters of camera clipping + if init_num < 20: + if detect.get_calculate_params(frame) is None: + # cv2.imshow("figure", frame) + continue + else: + x1, x2, y1, y2 = detect.get_calculate_params(frame) + detect.draw_marker(frame, x1, y1) + detect.draw_marker(frame, x2, y2) + detect.sum_x1 += x1 + detect.sum_x2 += x2 + detect.sum_y1 += y1 + detect.sum_y2 += y2 + init_num += 1 + continue + elif init_num == 20: + detect.set_cut_params( + (detect.sum_x1) / 20.0, + (detect.sum_y1) / 20.0, + (detect.sum_x2) / 20.0, + (detect.sum_y2) / 20.0, + ) + parent_conn.send((CROP_FRAME, + (detect.sum_x1) / 20.0, + (detect.sum_y1) / 20.0, + (detect.sum_x2) / 20.0, + (detect.sum_y2) / 20.0)) + detect.sum_x1 = detect.sum_x2 = detect.sum_y1 = detect.sum_y2 = 0 + init_num += 1 + continue + + # calculate params of the coords between cube and mycobot + if nparams < 10: + if detect.get_calculate_params(frame) is None: + # cv2.imshow("figure", frame) + continue + else: + x1, x2, y1, y2 = detect.get_calculate_params(frame) + detect.draw_marker(frame, x1, y1) + detect.draw_marker(frame, x2, y2) + detect.sum_x1 += x1 + detect.sum_x2 += x2 + detect.sum_y1 += y1 + detect.sum_y2 += y2 + nparams += 1 + print ("ok") + continue + elif nparams == 10: + nparams += 1 + # calculate and set params of calculating real coord between cube and mycobot + detect.set_params((detect.sum_x1 + detect.sum_x2) / 20.0, + (detect.sum_y1 + detect.sum_y2) / 20.0, + abs(detect.sum_x1 - detect.sum_x2) / 10.0 + + abs(detect.sum_y1 - detect.sum_y2) / 10.0) + print("ok") + continue + + # get detect result + kp_img, desc_img = sift.detectAndCompute(frame, None) + frame = get_frame(parent_conn) + for i, v in enumerate(res_queue): + # HACK: to update frame every time + detect_result = detect.obj_detect(frame, v, kp_img, desc_img, kp_list[i], desc_list[i], parent_conn) + if detect_result: + x, y = detect_result + # calculate real coord between cube and mycobot + real_x, real_y = detect.get_position(x, y) + detect.color = i + detect.pub_marker(real_x / 1000.0, real_y / 1000.0) + detect.decide_move(real_x, real_y, detect.color) + # if num == 5: + # detect.color = i + # detect.pub_marker(real_sx / 5.0 / 1000.0, + # real_sy / 5.0 / 1000.0) + # detect.decide_move(real_sx / 5.0, real_sy / 5.0, + # detect.color) + # num = real_sx = real_sy = 0 + # else: + # num += 1 + # real_sy += real_y + # real_sx += real_x + parent_conn.send(CLEAR_DRAW) + + # cv2.imshow("figure", frame) + time.sleep(0.05) + end_time = time.time() + print("loop_time = ", end_time - start_time) + + # close the window + if cv2.waitKey(1) & 0xFF == ord('q'): + # cap.release() + cv2.destroyAllWindows() + sys.exit() + + child.join() + + +if __name__ == "__main__": + run() + # Object_detect().take_photo() + # Object_detect().cut_photo() diff --git a/mycobot_ai/mechArm_270/scripts/moving_utils.py b/mycobot_ai/mechArm_270/scripts/moving_utils.py index 1b6a651..d23ff8f 100755 --- a/mycobot_ai/mechArm_270/scripts/moving_utils.py +++ b/mycobot_ai/mechArm_270/scripts/moving_utils.py @@ -24,8 +24,8 @@ class Movement(object): self.coords.y = item[1] self.coords.z = item[2] self.coords.rx = item[3] - self.coords.ry = item[4] - self.coords.rz = item[5] + # self.coords.ry = item[4] + # self.coords.rz = item[5] self.coords.speed = sp self.coords.model = m self.coord_pub.publish(self.coords) @@ -36,8 +36,8 @@ class Movement(object): self.angles.joint_2 = item[1] self.angles.joint_3 = item[2] self.angles.joint_4 = item[3] - self.angles.joint_5 = item[4] - self.angles.joint_6 = item[5] + # self.angles.joint_5 = item[4] + # self.angles.joint_6 = item[5] self.angles.speed = sp self.angle_pub.publish(self.angles) diff --git a/mycobot_ai/mechArm_270/scripts/detect_obj_color.py b/mycobot_ai/mechArm_270/scripts/pi_detect_obj_color.py old mode 100755 new mode 100644 similarity index 84% rename from mycobot_ai/mechArm_270/scripts/detect_obj_color.py rename to mycobot_ai/mechArm_270/scripts/pi_detect_obj_color.py index 26032a4..cc9124e --- a/mycobot_ai/mechArm_270/scripts/detect_obj_color.py +++ b/mycobot_ai/mechArm_270/scripts/pi_detect_obj_color.py @@ -1,17 +1,18 @@ -# encoding:utf-8 +# -*- coding:utf-8 -*- #!/usr/bin/env python2 - +from operator import imod from tokenize import Pointfloat import cv2 import numpy as np import time import json -import os +import os,sys import rospy -from visualization_msgs.msg import Marker - +from visualization_msgs.msg import Marker +from pymycobot.mypalletizer import MyPalletizer from moving_utils import Movement + IS_CV_4 = cv2.__version__[0] == '4' __version__ = "1.0" # Adaptive seeed @@ -19,27 +20,30 @@ __version__ = "1.0" class Object_detect(Movement): - def __init__(self, camera_x=150, camera_y=-10): + def __init__(self, camera_x = 160, camera_y = 10): # inherit the parent class super(Object_detect, self).__init__() # get path of file dir_path = os.path.dirname(__file__) + + # declare mypal260 + self.mc = None + # 移动角度 self.move_angles = [ - [-7.11, -6.94, -55.01, -24.16, 0, 15], # init the point - [5, -10.63, -87.8, 9.05, -3.07, 15], # point to grab + [0, 0, 0, 0], # init the point + [-29.0, 5.88, -4.92, -76.28], # point to grab [17.4, -10.1, -87.27, 5.8, -2.02, 15], # point to grab ] + # 移动坐标 self.move_coords = [ - [120.1, -141.6, 240.9, -173.34, -8.15, -110.11], # above the red bucket - # above the yello bucket - #[215.2, -127.8, 260.9, -157.51, -17.5, -71.18], - [210.6, -130.5, 263.0, -150.99, -0.07, -107.35], - [209.7, -18.6, 230.4, -168.48, -9.86, -39.38], - [196.9, -64.7, 232.6, -166.66, -9.44, -52.47], - [126.6, -118.1, 305.0, -157.57, -13.72, -75.3], + [141.2, -142.0, 210, -26.8], # above the red bucket + [234.3, -120, 210, -48.77], # above the green bucket + [100.9, 159.3, 248.6, -124.27], # above the blue bucket + [-17.6, 161.6, 238.4, -152.31], # above the gray bucket ] + # which robot: USB* is m5; ACM* is wio; AMA* is raspi self.robot_m5 = os.popen("ls /dev/ttyUSB*").readline()[:-1] self.robot_wio = os.popen("ls /dev/ttyACM*").readline()[:-1] @@ -80,11 +84,11 @@ class Object_detect(Movement): "blue": [np.array([100, 43, 46]), np.array([124, 255, 255])], "cyan": [np.array([78, 43, 46]), np.array([99, 255, 255])], } - # use to calculate coord between cube and mycobot + # use to calculate coord between cube and mypal260 self.sum_x1 = self.sum_x2 = self.sum_y2 = self.sum_y1 = 0 - # The coordinates of the grab center point relative to the mycobot + # The coordinates of the grab center point relative to the mypal260 self.camera_x, self.camera_y = camera_x, camera_y - # The coordinates of the cube relative to the mycobot + # The coordinates of the cube relative to the mypal260 self.c_x, self.c_y = 0, 0 # The ratio of pixels to actual values self.ratio = 0 @@ -137,65 +141,54 @@ class Object_detect(Movement): # Grasping motion def move(self, x, y, color): - # send Angle to move mycobot - print color - self.pub_angles(self.move_angles[0], 20) + # send Angle to move mypal260 + print(color) + self.mc.send_angles(self.move_angles[0], 20) + time.sleep(3) + + # send coordinates to move mypal260 + self.mc.send_coords([x, y, 160, 0], 20, 0) time.sleep(1.5) - self.pub_angles(self.move_angles[1], 20) + self.mc.send_coords([x, y, 90, 0], 20, 0) time.sleep(1.5) - self.pub_angles(self.move_angles[2], 20) - time.sleep(1.5) - # send coordinates to move mycobot - self.pub_coords([x, y, 165, -178.9, -1.57, -25.95], 20, 1) - time.sleep(1.5) - - self.pub_coords([x, y, 80, -178.9, -1.57, -25.95], 20, 1) - - time.sleep(1) + # open pump if self.raspi: self.gpio_status(True) else: self.pub_pump(True, self.Pin) - time.sleep(0.5) - self.pub_angles(self.move_angles[2], 20) - time.sleep(3) - self.pub_marker( - self.move_coords[2][0]/1000.0, self.move_coords[2][1]/1000.0, self.move_coords[2][2]/1000.0) - - self.pub_angles(self.move_angles[1], 20) time.sleep(1.5) - self.pub_marker( - self.move_coords[3][0]/1000.0, self.move_coords[3][1]/1000.0, self.move_coords[3][2]/1000.0) - self.pub_angles(self.move_angles[0], 20) + self.mc.send_angle(2, 0, 20) + time.sleep(0.3) + self.mc.send_angle(3, -15, 20) time.sleep(2) - self.pub_marker( - self.move_coords[4][0]/1000.0, self.move_coords[4][1]/1000.0, self.move_coords[4][2]/1000.0) - self.pub_coords(self.move_coords[color], 20, 1) + self.mc.send_coords(self.move_coords[color], 20, 1) self.pub_marker(self.move_coords[color][0]/1000.0, self.move_coords[color] [1]/1000.0, self.move_coords[color][2]/1000.0) - time.sleep(2) + time.sleep(3) + # close pump if self.raspi: self.gpio_status(False) else: self.pub_pump(False, self.Pin) - time.sleep(1) + time.sleep(6) + if color == 1: self.pub_marker( self.move_coords[color][0]/1000.0+0.04, self.move_coords[color][1]/1000.0-0.02) elif color == 0: self.pub_marker( self.move_coords[color][0]/1000.0+0.03, self.move_coords[color][1]/1000.0) - self.pub_angles(self.move_angles[0], 20) - time.sleep(3) + + # self.pub_angles(self.move_angles[0], 20) + self.mc.send_angles(self.move_angles[1], 20) + time.sleep(1.5) # decide whether grab cube - def decide_move(self, x, y, color): - print(x, y, self.cache_x, self.cache_y) # detect the cube status move or run if (abs(x - self.cache_x) + abs(y - self.cache_y)) / 2 > 5: # mm @@ -204,24 +197,20 @@ class Object_detect(Movement): else: self.cache_x = self.cache_y = 0 # 调整吸泵吸取位置,y增大,向左移动;y减小,向右移动;x增大,前方移动;x减小,向后方移动 - - self.move(x,y, color) - # init mycobot + # init mypal260 def run(self): + self.mc = MyPalletizer("/dev/ttyAMA0",1000000) # ok if not self.raspi: self.pub_pump(False, self.Pin) - for _ in range(5): - self.pub_angles([-7.11, -6.94, -55.01, -24.16, 0, -15], 20) - print(_) - time.sleep(0.5) + self.mc.send_angles([-29.0, 5.88, -4.92, -76.28], 20) # ok + time.sleep(3) # draw aruco - def draw_marker(self, img, x, y): # draw rectangle on img - cv2.rectangle( + cv2.rectangle( img, (x - 20, y - 20), (x + 20, y + 20), @@ -269,13 +258,13 @@ class Object_detect(Movement): self.y2 = int(y2) print(self.x1, self.y1, self.x2, self.y2) - # set parameters to calculate the coords between cube and mycobot + # set parameters to calculate the coords between cube and mypal260 def set_params(self, c_x, c_y, ratio): self.c_x = c_x self.c_y = c_y self.ratio = 220.0/ratio - # calculate the coords between cube and mycobot + # calculate the coords between cube and mypal260 def get_position(self, x, y): return ((y - self.c_y)*self.ratio + self.camera_x), ((x - self.c_x)*self.ratio + self.camera_y) @@ -284,7 +273,6 @@ class Object_detect(Movement): Enlarge the video pixel by 1.5 times, which means enlarge the video size by 1.5 times. If two ARuco values have been calculated, clip the video. """ - def transform_frame(self, frame): # enlarge the image by 1.5 times fx = 1.5 @@ -302,21 +290,30 @@ class Object_detect(Movement): # set the arrangement of color'HSV x = y = 0 for mycolor, item in self.HSV.items(): + # print("mycolor:",mycolor) redLower = np.array(item[0]) redUpper = np.array(item[1]) + # transfrom the img to model of gray hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) + # print("hsv",hsv) + # wipe off all color expect color in range mask = cv2.inRange(hsv, item[0], item[1]) + # a etching operation on a picture to remove edge roughness erosion = cv2.erode(mask, np.ones((1, 1), np.uint8), iterations=2) + # the image for expansion operation, its role is to deepen the color depth in the picture dilation = cv2.dilate(erosion, np.ones( (1, 1), np.uint8), iterations=2) + # adds pixels to the image target = cv2.bitwise_and(img, img, mask=dilation) + # the filtered image is transformed into a binary image and placed in binary ret, binary = cv2.threshold(dilation, 127, 255, cv2.THRESH_BINARY) + # get the contour coordinates of the image, where contours is the coordinate value, here only the contour is detected contours, hierarchy = cv2.findContours( dilation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) @@ -341,33 +338,35 @@ class Object_detect(Movement): cv2.rectangle(img, (x, y), (x+w, y+h), (153, 153, 0), 2) # calculate the rectangle center x, y = (x*2+w)/2, (y*2+h)/2 - # calculate the real coordinates of mycobot relative to the target - if mycolor == "yellow": - self.color = 1 - elif mycolor == "red": + # calculate the real coordinates of mypal260 relative to the target + + if mycolor == "red": self.color = 0 - else: + elif mycolor == "green": self.color = 1 + elif mycolor == "cyan": + self.color = 2 + else: + self.color = 3 if abs(x) + abs(y) > 0: return x, y else: return None - if __name__ == "__main__": + # open the camera cap_num = 0 cap = cv2.VideoCapture(cap_num, cv2.CAP_V4L) - if not cap.isOpened(): cap.open() # init a class of Object_detect detect = Object_detect() - # init mycobot + # init mypal260 detect.run() - _init_ = 20 # + _init_ = 20 init_num = 0 nparams = 0 num = 0 @@ -377,10 +376,10 @@ if __name__ == "__main__": _, frame = cap.read() # deal img frame = detect.transform_frame(frame) - if _init_ > 0: _init_ -= 1 continue + # calculate the parameters of camera clipping if init_num < 20: if detect.get_calculate_params(frame) is None: @@ -407,7 +406,7 @@ if __name__ == "__main__": init_num += 1 continue - # calculate params of the coords between cube and mycobot + # calculate params of the coords between cube and mypal260 if nparams < 10: if detect.get_calculate_params(frame) is None: cv2.imshow("figure", frame) @@ -424,14 +423,14 @@ if __name__ == "__main__": continue elif nparams == 10: nparams += 1 - # calculate and set params of calculating real coord between cube and mycobot + # calculate and set params of calculating real coord between cube and mypal260 detect.set_params( (detect.sum_x1+detect.sum_x2)/20.0, (detect.sum_y1+detect.sum_y2)/20.0, abs(detect.sum_x1-detect.sum_x2)/10.0 + abs(detect.sum_y1-detect.sum_y2)/10.0 ) - print "ok" + print("ok") continue # get detect result @@ -441,7 +440,7 @@ if __name__ == "__main__": continue else: x, y = detect_result - # calculate real coord between cube and mycobot + # calculate real coord between cube and mypal260 real_x, real_y = detect.get_position(x, y) if num == 20: detect.pub_marker(real_sx/20.0/1000.0, real_sy/20.0/1000.0) @@ -454,3 +453,9 @@ if __name__ == "__main__": real_sx += real_x cv2.imshow("figure", frame) + + # close the window + if cv2.waitKey(1) & 0xFF == ord('q'): + cap.release() + cv2.destroyAllWindows() + sys.exit() \ No newline at end of file diff --git a/mycobot_ai/mechArm_270/scripts/detect_obj_img_folder_opt.py b/mycobot_ai/mechArm_270/scripts/pi_detect_obj_img_folder_opt.py similarity index 87% rename from mycobot_ai/mechArm_270/scripts/detect_obj_img_folder_opt.py rename to mycobot_ai/mechArm_270/scripts/pi_detect_obj_img_folder_opt.py index 1ed9909..971082f 100644 --- a/mycobot_ai/mechArm_270/scripts/detect_obj_img_folder_opt.py +++ b/mycobot_ai/mechArm_270/scripts/pi_detect_obj_img_folder_opt.py @@ -22,6 +22,7 @@ from threading import Thread import tkFileDialog as filedialog import Tkinter as tk from moving_utils import Movement +from pymycobot.mypalletizer import MyPalletizer IS_CV_4 = cv2.__version__[0] == '4' __version__ = "1.0" # Adaptive seeed @@ -29,28 +30,27 @@ __version__ = "1.0" # Adaptive seeed class Object_detect(Movement): - def __init__(self, camera_x=150, camera_y=-10): + def __init__(self, camera_x = 160, camera_y = 10): # inherit the parent class super(Object_detect, self).__init__() # get path of file dir_path = os.path.dirname(__file__) + # declare mypal260 + self.mc = None # 移动角度 self.move_angles = [ - [-26.11, -6.94, -55.01, -24.16, 0, 15], # init the point - [-1.14, 0.63, -87.8, 9.05, -3.07, 15], # point to grab + [0, 0, 0, 0], # init the point + [-29.0, 5.88, -4.92, -76.28], # point to grab [17.4, -10.1, -87.27, 5.8, -2.02, 15], # point to grab ] # 移动坐标 self.move_coords = [ - [120.1, -141.6, 240.9, -173.34, -8.15, -110.11], # above the red bucket - # above the yello bucket - #[208.2, -127.8, 260.9, -157.51, -17.5, -71.18], - [205.6, -130.5, 263.0, -150.99, -0.07, -107.35], # above the green bucket - [-20.0, 176.7, 242.6, -166.66, -9.44, -52.47], # above the gray bucket - [104.9, 176.7, 242.6, -166.66, -9.44, -52.47], # above the blue bucket - [126.6, -118.1, 305.0, -157.57, -13.72, -75.3], + [141.2, -142.0, 210, -26.8], # above the red bucket + [234.3, -120, 210, -48.77], # above the green bucket + [100.9, 159.3, 248.6, -124.27], # above the blue bucket + [-17.6, 161.6, 238.4, -152.31], # above the gray bucket ] # 判断连接设备:ttyUSB*为M5,ttyACM*为seeed @@ -97,6 +97,7 @@ class Object_detect(Movement): # else: # print('Load tensorflow model need the version of opencv is 4.') # exit(0) + # init a node and a publisher rospy.init_node("marker", anonymous=True) self.pub = rospy.Publisher('/cube', Marker, queue_size=1) @@ -125,7 +126,6 @@ class Object_detect(Movement): self.cache_x = self.cache_y = 0 # publish marker - def pub_marker(self, x, y, z=0.03): self.marker.header.stamp = rospy.Time.now() self.marker.pose.position.x = x @@ -144,56 +144,40 @@ class Object_detect(Movement): # Grasping motion def move(self, x, y, color): - # send Angle to move mycobot - self.pub_angles(self.move_angles[0], 20) + # send Angle to move mypal260 + self.mc.send_angles(self.move_angles[0], 20) + time.sleep(3) + + # send coordinates to move mypal260 根据不同底板机械臂,调整吸泵高度 + self.mc.send_coords([x, y, 160, 0], 20, 0) time.sleep(1.5) - self.pub_angles(self.move_angles[1], 20) - time.sleep(1.5) - self.pub_angles(self.move_angles[2], 20) - time.sleep(1.5) - # send coordinates to move mycobot - self.pub_coords([x, y, 165, -178.9, -1.57, -66], 20, 1) - time.sleep(1.5) - # 根据不同底板机械臂,调整吸泵高度 - self.pub_coords([x, y, 90, -178.9, -1.57, -66], 25, 1) + self.mc.send_coords([x, y, 90, 0], 20, 0) time.sleep(1.5) + # open pump self.gpio_status(True) - - time.sleep(0.5) - self.pub_angles(self.move_angles[2], 20) - time.sleep(3) - self.pub_marker(self.move_coords[2][0] / 1000.0, - self.move_coords[2][1] / 1000.0, - self.move_coords[2][2] / 1000.0) - - self.pub_angles(self.move_angles[1], 20) time.sleep(1.5) - self.pub_marker(self.move_coords[3][0] / 1000.0, - self.move_coords[3][1] / 1000.0, - self.move_coords[3][2] / 1000.0) - self.pub_angles(self.move_angles[0], 20) - time.sleep(1.5) - self.pub_marker(self.move_coords[4][0] / 1000.0, - self.move_coords[4][1] / 1000.0, - self.move_coords[4][2] / 1000.0) + self.mc.send_angle(2, 0, 20) + time.sleep(0.3) + self.mc.send_angle(3, -15, 20) + time.sleep(2) print(self.move_coords[color]) - self.pub_coords(self.move_coords[color], 20, 1) + + self.mc.send_coords(self.move_coords[color], 20, 1) self.pub_marker(self.move_coords[color][0] / 1000.0, self.move_coords[color][1] / 1000.0, self.move_coords[color][2] / 1000.0) - time.sleep(4) + time.sleep(3) + # close pump self.gpio_status(False) - - time.sleep(1) - self.pub_marker(self.move_coords[color][0] / 1000.0 + 0.04, - self.move_coords[color][1] / 1000.0 - 0.02) - self.pub_angles(self.move_angles[0], 20) time.sleep(3) + self.mc.send_angles(self.move_angles[1], 20) + time.sleep(1.5) + # decide whether grab cube def decide_move(self, x, y, color): print(x, y, self.cache_x, self.cache_y) @@ -209,13 +193,14 @@ class Object_detect(Movement): # init mycobot def run(self): - for _ in range(5): - self.pub_angles([-26.11, -6.94, -55.01, -24.16, 0, -15], 20) - print(_) - time.sleep(0.5) + self.mc = MyPalletizer("/dev/ttyAMA0",1000000) # ok + if not self.raspi: + self.pub_pump(False, self.Pin) + + self.mc.send_angles([-29.0, 5.88, -4.92, -76.28], 20) # ok + time.sleep(3) # draw aruco - def draw_marker(self, img, x, y): # draw rectangle on img cv2.rectangle( @@ -244,6 +229,7 @@ class Object_detect(Movement): # Detect ArUco marker. corners, ids, rejectImaPoint = cv2.aruco.detectMarkers( gray, self.aruco_dict, parameters=self.aruco_params) + """ Two Arucos must be present in the picture and in the same order. There are two Arucos in the Corners, and each aruco contains the pixels of its four corners. @@ -389,15 +375,6 @@ class Object_detect(Movement): except Exception as e: pass - # else: - # if(len(good) < MIN_MATCH_COUNT): - - # i += 1 - # if(i % 10 == 0): - # print("Not enough matches are found - %d/%d" % - # (len(good), MIN_MATCH_COUNT)) - - # matchesMask = None if x + y > 0: return x, y else: @@ -406,13 +383,12 @@ class Object_detect(Movement): # The path to save the image folder def parse_folder(folder): restore = [] - path = '/home/ubuntu/catkin_ws/src/mycobot_ros/mycobot_ai/' + folder + path = '/home/ubuntu/catkin_ws/src/mycobot_ros/mycobot_ai/myPalletizer_260/' + folder for i, j, k in os.walk(path): for l in k: restore.append(cv2.imread(folder + '/{}'.format(l))) return restore - def compute_keypoints_and_descriptors(sift, images_lists): kp_list = [] desc_list = [] @@ -428,7 +404,6 @@ def compute_keypoints_and_descriptors(sift, images_lists): return kp_list, desc_list - GET_FRAME = 1 STOP_PROCESSING = 2 DRAW_COORDS = 3 @@ -436,13 +411,11 @@ DRAW_RECT = 4 CLEAR_DRAW = 5 CROP_FRAME = 6 - def get_frame(connection): connection.send(GET_FRAME) frame = connection.recv() return frame - def process_transform_frame(frame, x1, y1, x2, y2): # enlarge the image by 1.5 times fx = 1.5 @@ -457,7 +430,6 @@ def process_transform_frame(frame, x1, y1, x2, y2): # int(x1 * 0.7):int(x2 * 1.15)] return frame - def process_display_frame(connection): cap_num = 0 coord = None @@ -502,8 +474,7 @@ def process_display_frame(connection): def run(): parent_conn, child_conn = Pipe() - - child = Process(target=process_display_frame, args=(child_conn,)) + child = Process(target = process_display_frame, args=(child_conn,)) child.start() # Object_detect().take_photo() @@ -513,8 +484,8 @@ def run(): res_queue = [[], [], [], []] res_queue[0] = parse_folder('res/red') res_queue[1] = parse_folder('res/green') - res_queue[2] = parse_folder('res/gray') - res_queue[3] = parse_folder('res/blue') + res_queue[2] = parse_folder('res/blue') + res_queue[3] = parse_folder('res/gray') # res_queue = [] # res_queue.extend(parse_folder('res/red')) @@ -527,6 +498,7 @@ def run(): # init a class of Object_detect detect = Object_detect() + # init mycobot detect.run() @@ -607,9 +579,7 @@ def run(): continue # get detect result - kp_img, desc_img = sift.detectAndCompute(frame, None) - frame = get_frame(parent_conn) for i, v in enumerate(res_queue): # HACK: to update frame every time @@ -639,8 +609,14 @@ def run(): end_time = time.time() print("loop_time = ", end_time - start_time) - child.join() + # close the window + if cv2.waitKey(1) & 0xFF == ord('q'): + cap.release() + cv2.destroyAllWindows() + sys.exit() + child.join() + if __name__ == "__main__": run() diff --git a/mycobot_ai/mechArm_270/scripts/test.py b/mycobot_ai/mechArm_270/scripts/test.py index 8f974fb..d73de19 100755 --- a/mycobot_ai/mechArm_270/scripts/test.py +++ b/mycobot_ai/mechArm_270/scripts/test.py @@ -1,104 +1,41 @@ # -*- coding: utf-8 -*- - -# from fileinput import filename -# from genericpath import isfile -# import os -# from sys import path -# import cv2 -# from PIL import Image - - -# # #count=0 -# for file in dirs: -# pic_dir=os.path.join(path,file) # res中子文件夹的路径 -# print(pic_dir) -# for i in os.listdir(pic_dir): -# imgdir=os.path.join(pic_dir,i) -# print(imgdir) -# for i in os.listdir(pic_dir): -# image_dir=os.path.join(pic_dir,i) #res中每个子文件夹中图片的路径 -# img1 = cv2.imread(image_dir) # 读取res中每个子文件夹中的图片 -# #count+=1 -# print(image_dir)#输出图片的路径 -#print(img1)#输出图片 -#print(count)#图片个数 -# dir_path = os.path.dirname(__file__) -# print(dir_path) -# # path1 = os.path.split(os.path.realpath(__file__))[0] -# # print(path1) -# path3=os.path.join(os.path.split(dir_path)[0]+'/res/') - -# print(path3) -# #for file in os.listdir(path3): -# pic_dir=os.path.join(path3+'red') -# # print(pic_dir) -# for i in os.listdir(pic_dir): -# img=os.path.join(pic_dir,i) -# print(img) -# print(os.getcwd()+'/mycobot_ai/res/red') - -# list1 = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]] -# print(list1[0][0]) -# for i, v in enumerate(list1): -# print(i) - -# res = [] -# for i in list1: -# res.append(i) -# print(res) - -# # for i in list1: -# # print(i) - -# color=i -# print(color) -# for color in range(0,4): -# print(color) - -from pymycobot.mycobot import MyCobot +from pymycobot.mypalletizer import MyPalletizer from pymycobot.genre import Angle from pymycobot import PI_PORT, PI_BAUD # 当使用树莓派版本的mycobot时,可以引用这两个变量进行MyCobot初始化 -import time +import time,os -# mc = MyCobot("/dev/ttyACM0", 115200) +mc = MyPalletizer(os.popen("ls /dev/ttyUSB*").readline()[:-1], 115200) -mc = MyCobot("/dev/ttyAMA0", 1000000) -# mc.send_angles([0,0,0,0,0,0], 20) +# mc = MyPalletizer("/dev/ttyAMA0", 1000000) +# mc.send_angles([-29.0, 5.88, -4.92, -76.28],25) # init the point coords:[155.3, -86.1, 218.4, -47.28] +# time.sleep(1.5) +# mc.send_angles([-47.1, 10.19, -10.1, -76.37],25) # above the red bucket; coords:[127.3, -137.1, 219.2, -29.26] +# time.sleep(1.5) + +mc.send_angles([0,0,-15,0],25) time.sleep(2) -# move_coords = [ -# [120.1, -141.6, 240.9, -173.34, -8.15, -110.11], # above the red bucket -# # above the green bucket -# #[208.2, -127.8, 260.9, -157.51, -17.5, -71.18], -# [205.6, -130.5, 263.0, -150.99, -0.07, -107.35], -# [209.7, -18.6, 230.4, -168.48, -9.86, -39.38], -# [196.9, -64.7, 232.6, -166.66, -9.44, -52.47], -# [126.6, -118.1, 305.0, -157.57, -13.72, -75.3], -# ] -# mc.send_coords([126.6, -118.1, 305.0, -157.57, -13.72, -75.3],20,1) +# mc.send_coords([141.2, -142.0, 206.2, -26.8],25,1) # above the red bucket # time.sleep(2) -# mc.send_coords([104.9, 176.7, 242.6, -166.66, -9.44, -52.47],20,1) # above the blue bucket +# mc.send_coords([234.3, -120, 210, -48.77],25,1) # above the green bucket # time.sleep(2) -# mc.send_coords([-20.0, 176.7, 242.6, -166.66, -9.44, -52.47],20,1) # abobe the gray bucket -# time.sleep(2) -# mc.send_coords([120.1,151.6,250.0,-173.34,-8.15,-110.11],20,1) -# time.sleep(2) -# mc.send_coords([104.9, 176.7, 242.6, -166.66, -9.44, -52.47],20,1) +# mc.send_coords([100.9, 159.3, 248.6, -124.27],20,1) # above the blue bucket +# time.sleep(3) +# mc.send_coords([-17.6, 161.6, 238.4, -152.31],20,1) # above the gray bucket +# time.sleep(3) + +# mc.send_angle(3,0,25) +# print(mc.get_angles()) +# print(mc.get_coords()) + +# while True: +# print("angles:%s"%mc.get_angles()) +# print("coords:%s"%mc.get_coords()) +# print("\n") -mc.send_angles([-26.11, -6.94, -55.01, -24.16, 0, 15],20) # mc.release_all_servos() -time.sleep(3) -print(mc.get_angles()) -# mc.send_angles([-1.14, 3.63, -87.8, 9.05, -3.07, 15],20) -time.sleep(2) -# print(mc.get_angles()) -# mc.send_angles([17.4, -10.1, -87.27, 5.8, -2.02, 15],20) -# time.sleep(2) -# print(mc.get_angles()) - -# mc.release_servo(6) -mc.release_all_servos() -# mc.set_servo_calibration(6) -# if os.listdir(path,filename='blue'): -# pass \ No newline at end of file +# mc.set_servo_calibration(1) +# mc.set_servo_calibration(2) +# mc.set_servo_calibration(3) +# mc.set_servo_calibration(4) \ No newline at end of file