使用 Python 和可视化编程控制树莓派机械臂myCobot

电子说

1.2w人已加入

描述

myCobot 280 Pi 是一款 6 自由度多功能桌面机械臂。它由大象机器人研发,使用 Raspberry Pi 作为主控制器。该机器人结构紧凑,运行稳定,非常适合新手入门。它还可以使用多种语言进行编程,简单易用,功能丰富。适合那些有兴趣学习如何对机械臂进行编程控制和项目开发的人。

myCobot 280 Pi开箱

机械臂

myCobot 280 Pi 机械臂工作半径为 280 毫米,本体重量为 850 克,可处理高达 250 克的有效载荷。它由 6 个伺服电机驱动,每个自由度一个,配备矩阵5×5 LED 显示屏,末端 Lego接口可接各种传感器。

机械臂

MyCobot 280 采用树莓派微处理器,可以搭配任意摄像头进行图像识别,具有4个 USB 端口,可以通过 Raspberry Pi 的微型 HDMI 端口连接到显示器. 最后,40 个GPIO 接头可以进行更多扩展应用,机械臂每个接口都有清晰的标记,面板上还有一个电源开关和一个直流电源插孔。

机械臂

MicroSD 卡插槽位于 MyCobot 280 Pi 机械臂下方。

机械臂

包装中还有一个100-240V~50/60Hz 1.2A 电源线,具有 8-12V输出高达 5A(42 瓦)。

机械臂

myCobot 套装中的其他配件包括:

myCobot-平面底座

4 个硅胶吸盘,确保底座牢固地固定在桌面上

myCobot 摄像头

myCobot 吸泵

各种连接线

乐高连接件

机械臂

如何将机械臂连接到平面底座上

机械臂

组装很简单。只需将吸盘插入四个角的安装孔中,然后用塑料螺丝头固定即可。

机械臂

这是完成后的样子。

机械臂

提供的乐高连接件,让您可以轻松地将底座连接到 myCobot 280 Pi 机械臂。

机械臂

根据需要在安装板插槽中插入一些乐高连接件。

机械臂

最后,将 myCobot 280 Pi 机械臂放在底座顶部,确保其与螺纹和乐高连接件对齐。您现在可以将机器人放在地板或桌子上,并用力拧紧吸盘,以确保机械臂的底座在操作过程中不会移动。最好将它放在光滑的表面上,例如玻璃或大理石。

机械臂

操作系统

myCobot 280 Pi 附带 Ubuntu Linux 操作系统,可以使用 myBlockly 可视化编程或者Python 进行编程。

机械臂

Python

myCobot 280 Pi 可使用 Python 编程,增加了使用摄像头检测物体的能力,并支持用于人工智能、图像处理和机器学习的 OpenCV 库。

机械臂

ROS

机器人操作系统(ROS)依靠Rviz 模拟机械臂的运动,通过ROS远程控制机械臂。

机械臂

使用 MyBlockly 对 MyCobot 280 Pi 机械臂进行编程

MyBlockly 是一个完全可视化的模块化编程软件,用户可以通过拖曳模块,来构建代码逻辑,过程很像搭积木,而不是手动编写基于文本的代码。如此一来,复杂又抽象的编程语言就变得容易理解。这些模块包括逻辑、循环、数学、文本、列表、颜色、变量、函数以及控制机械臂的函数等等,所以用户可以轻松入门编程,只需单击右上角的运行就可以启动程序,做一些有趣的应用。

机械臂

MyBlockly 中的时间

操作机械臂运动的程序是需要时间来完成的,所以在一个动作之后需要接上一个睡眠模块,给机械臂运动的时间再进行下一个运动。睡眠模块允许您以秒为单位添加延迟。

机械臂

树莓派-GPIO

这组模块控制 GPIO(通用输入/输出)。它用于在输出模式下将任何 Raspberry Pi GPIO 引脚设置为高电平或低电平或将它们配置为输入。

机械臂

ATOM IO

这模块控制着机械臂末端的 5×5 LED 矩阵。您可以更改每个 LED 的 RGB 数据(红色、蓝色、绿色)的值,也可以使用 PWM 控制。

机械臂

LED 的颜色将根据我们输入的数据而变化。

机械臂

状态

一组针对于 MyCobot 280 Pi机械臂的模块,主要用于打开或关闭机械臂电源、检查工作状态以及释放所有伺服系统。

机械臂

MDI运行和操作

这些模块控制机械臂在每个轴上的运动程度。可以同时输入数据,包括速度控制,或者如果您愿意,可以使用协调模式。这使得对机械臂进行编程非常容易。

机械臂

点动控制

控制机械臂在每个轴上的移动程度。

机械臂

运行状态和设置

机械臂

可以设置机械臂的速度,查询当前速度,以及特定关节的最小和最大角度。

找到机械臂在每个轴上的角度

我们可以通过从程序中读取值来找到每个轴的角度。这个功能有助于减少通过单击右上角来查找角度的时间。

机械臂

将弹出一个窗口。我们可以手动调整机械臂的角度,点击Read Angles读取角度按钮。这些值将自动输入到“设置角度”模块中。

机械臂

MyCobot 280 Pi 精度测试

我们测试了 myCobot 280 Pi 机械臂的运动精度,测量精度为 +/– 0.5。在测试中,将画出5种不同颜色的圆圈,同时更改机械臂末端 LED 矩阵显示屏以匹配该颜色圆圈,如下面的视频所示。

https://www.bilibili.com/video/BV1JP4y197ZY/?spm_id_from=333.999.0.0&vd_source=bb3d7739950ffca01b2e2089b2a5c22a

myCobot 吸泵

吸附物体使用,可以通过吸力提升和移动物体,从而增强 myCobot 280 Pi 机械臂的拓展能力。使用 吸泵举起的物体的最大重量为 250 克。

吸泵亮点

功能——吸住物体以提起和移动它们

被提升物体的最大重量 – 250 克

材料 – 光聚合物/尼龙

颜色-白色

尺寸 – 94 x 74 x 51 毫米

重量 – 220 克

机械臂

将吸泵安装到 myCobot 280 Pi

吸泵,通过吸泵控制套件作为机械臂的末端执行器,执行吸附物体的功能,吸泵提供乐高连接件插入的孔位,接上末端ATOM

机械臂

机械臂

将吸泵盒连接到机械臂底座IO接口

我们仍然需要将吸泵盒连接到机械臂底部接口。可以通过将四根杜邦线连接到 Raspberry Pi的 GPIO 接头连接器来完成:5V、GND、G2 (GPIO21)、G5 和 (GPIO22)。

机械臂

我们将使用插入 GPIO 接头的公杜邦电缆,即 5V、GND、G2 连接到 GPIO21,G5 连接到 GPIO22。

机械臂

将 myCobot 吸泵与 myBlockly 结合使用

让我们进入 Raspi-GPIO 菜单,并选择“Set Mode BCM”模块以使用 Set pin 命令模块将引脚 20 和 21 作为输出 (OUT)。

两组模块用于控制 myCobot吸泵

为了使吸泵工作,我们将引脚 20 和 21 设置为高电平

为了阻止它,我们将引脚 20 和 21设置为低电平。

这就是启用和禁用 myCobot吸泵 所需的全部内容。

机械臂

吸泵升降复位测试

我们通过将特定颜色的积木块移动到相同颜色的填充圆来测试机械臂与吸泵同时工作的状态。我们已经注意到,如果物体很重,则需要一段时间才能吸住物体,如果物体很轻,则需要一些时间才能将其释放。但是从下面的测试视频中可以看出,机械臂和吸泵可以非常准确地工作。

https://www.bilibili.com/video/BV1g8411j7k9/?spm_id_from=333.999.0.0

MyCobot 280 摄像头

该摄像头重量轻,可以在几分钟内轻松安装到机械臂上。它基本上是即插即用的,紧凑的设计意味着您不必担心它会占用太多空间。USB 2.0彩色摄像头最高支持720p高清分辨率,色彩广角,适用于人脸识别、智慧屏、智能快递、自动售货机、条码/二维码扫描、门禁、医疗设备等。

机械臂

机械臂

将 myCobot 吸泵和 摄像头安装到 myCobot 280 Pi

我们现在将 MyCobot 280摄像头连接到 myCobot 吸泵,方法是首先将乐高连接器插入吸泵……

机械臂

在将其插入相机之前,我们将向其添加更多 LEGO 连接器

机械臂

以便将其安装在 MyCobot 280 Pi 机械臂上。

机械臂

完美安装!非常简单。

机械臂

使用 pip 安装 OpenCV 和 Numpy

我们需要安装库,即 OpenCV 和 Numpy,以便在机器人上运行图像处理工作负载。我们可以通过机器人操作系统中的终端安装它们。

OpenCV是一个流行的基本图像处理库,例如模糊、混合、增强图像质量、提高视频质量、图像识别、图像和视频中的人脸检测,以及我们将在本项目/评论中使用的颜色识别.

 

 

1 pip install opencv-python

 

 

Numpy是一个 Python 扩展模块,具有通常用于数据集(数组)和矩阵操作的数学函数。

 

 

1 pip install numpy

 

 

图像阈值

阈值处理是将对象与背景图像分离的技术之一。这是通过获取灰度图像并将其转换为像素值为 0(黑色)或 255(同时)的二值图像来工作的,并使用用于将图像的每个像素分类为黑色或白色的恒定阈值。我在 VSCode 中编写了一个 Python 程序,可以检测具有 3 种不同颜色的对象。程序的下一步将首先尝试使用相机输入找到红色物体。为红色定义了以下下限和上限范围:lowerR = np.array([142, 114, 181]) 和 upperR = np.array([194, 255, 255])

机械臂

对于蓝色对象,我们将使用以下值:lowerB = np.array([83, 228, 206]) 和 upperB = np.array([106, 255, 255])

机械臂

最后,这里是绿色对象的值: lowerG = np.array([54, 82, 228]) upperG = np.array([81, 255, 255])

机械臂

Python 中的阈值示例代码

导入了两个模块:cv2 用于处理图像,numpy 用于处理数组和矩阵。

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import cv2
import numpy as np
def nothing(x):
pass
cv2.namedWindow("Tracking")
cv2.createTrackbar("LH", "Tracking", 0, 255, nothing)
cv2.createTrackbar("LS", "Tracking", 0, 255, nothing)
cv2.createTrackbar("LV", "Tracking", 0, 255, nothing)
cv2.createTrackbar("UH", "Tracking", 255, 255, nothing)
cv2.createTrackbar("US", "Tracking", 255, 255, nothing)
cv2.createTrackbar("UV", "Tracking", 255, 255, nothing)
vs = cv2.VideoCapture(0)
while True:
_, frame = vs.read()
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
l_h = cv2.getTrackbarPos("LH", "Tracking")
l_s = cv2.getTrackbarPos("LS", "Tracking")
l_v = cv2.getTrackbarPos("LV", "Tracking")
u_h = cv2.getTrackbarPos("UH", "Tracking")
u_s = cv2.getTrackbarPos("US", "Tracking")
u_v = cv2.getTrackbarPos("UV", "Tracking")
l_b = np.array([l_h, l_s, l_v])
u_b = np.array([u_h, u_s, u_v])
mask = cv2.inRange(hsv, l_b, u_b)
res = cv2.bitwise_and(frame, frame, mask=mask)
cv2.imshow("frame", frame)
cv2.imshow("mask", mask)
cv2.imshow("res", res)
key = cv2.waitKey(1)
if key == 27:
break
cv2.destroyAllWindows()

 

 

使用带有传送带的 myCobot 280 Pi 对物体进行分类(颜色分类)

我们将使 myCobot 280 Pi 机械臂与传送带一起工作,以对不同颜色的物体进行分类。该项目由两部分组成:

传送带依靠 Arduino 板来控制其电机,程序/草图检查传感器的状况以根据传送带位置测量物体的停止距离。

myCobot 280 Pi 使用图像阈值检测颜色,并使用吸泵选择红色、蓝色或绿色对象并将其移动到相同颜色的桶中。设置了四个位置:

1、红框位置

2、蓝框位置

3、绿框位置

4、在方便 myCobot 280 Pi 的位置检测彩色物体的初始位置。我们可以将机械臂移动到那个位置,从Serial Monitor中读取数值,并将得到的数值放入程序中,这是一个很好的寻找不同位置的点

机械臂

myCobot 280 Pi 颜色识别示例代码

调用库MyCobot来控制机械臂,库RPi.GPIO用于启用/禁用吸泵,cv2库用于操作图像,numpy用于操作数组和矩阵。

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
from pymycobot.mycobot import MyCobot
from pymycobot import PI_BAUD, PI_PORT
import RPi.GPIO as GPIO
import numpy as np
import time
import cv2
GPIO.setmode(GPIO.BCM)
GPIO.setup(20, GPIO.OUT)
GPIO.setup(21, GPIO.OUT)
vs = cv2.VideoCapture(0)
print("Camera On: {}".format(vs.isOpened()))
lR = np.array([142, 114, 181])
uR = np.array([194, 255, 255])
lG = np.array([54, 82, 228])
uG = np.array([81, 255, 255])
lB = np.array([83, 228, 206])
uB = np.array([106, 255, 255])
def pump(state):
if state == 1: #On
print('Pump on')
GPIO.output(20, 0)
GPIO.output(21, 0)
elif state == 0: #Off
print('Pump off')
GPIO.output(20, 1)
GPIO.output(21, 1)
def findContour(mask):
minArea = 10000
found = False
x, y, w, h = 0, 0, 0, 0
contours, hierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for pic, contour in enumerate(contours):
area = cv2.contourArea(contour)
if area >= minArea:
x, y, w, h = cv2.boundingRect(contour)
found = True
break
return x, y, w, h, found
camera = [7.82, -15.82, -110.12, 37.7, -19.59, -123.04]
preTrash = [29.0, -4.21, -78.75, -1.75, -23.2, -150.46]
trashAngle, comebackAngle = [], []
pickup = [
[33.92, -5.53, -117.94, 39.63, -21.79, -133.5],
[32.69, -17.57, -121.46, 52.73, -20.83, -123.31]
]
trashR = [-79.27, -16.25, -85.95, 16.78, -15.11, -139.83]
trashG = [-37.0, -35.41, -55.01, 13.44, -15.73, -136.66]
trashB = [-55.72, -17.4, -78.83, 15.55, -12.04, -134.56]
comebackR = [-75.93, -17.49, -57.04, -9.58, -21.0, -136.93]
comebackB = [-51.85, -17.22, -60.29, -0.26, -20.3, -136.93]
comebackG = [-35.77, -31.02, -41.3, -3.69, -19.95, -164.44]
mc = MyCobot("/dev/ttyAMA0", 1000000)
pump(0)
time.sleep(1)
while True:
try:
mc.set_color(255, 255, 255)
mc.send_angles(camera, 40)
time.sleep(2)
dR, dG, dB = False, False, False
while True:
# Clearing buffer
for i in range(30):
_, frame = vs.read()
_, frame = vs.read()
#cv2.imwrite("a.jpg", frame)
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
maskR = cv2.inRange(hsv, lR, uR)
maskG = cv2.inRange(hsv, lG, uG)
maskB = cv2.inRange(hsv, lB, uB)
xr, yr, wr, hr, dR = findContour(maskR)
xg, yg, wg, hg, dG = findContour(maskG)
xb, yb, wb, hb, dB = findContour(maskB)
if dR:
trashAngle = trashR
comebackAngle = comebackR
mc.set_color(255, 0, 0)
print("Detected Red Block")
cv2.rectangle(frame, (xr, yr), (xr+wr, yr+hr), (0, 0, 0), 2)
elif dG:
trashAngle = trashG
comebackAngle = comebackG
mc.set_color(0, 255, 0)
print("Detected Green Block")
cv2.rectangle(frame, (xg, yg), (xg+wg, yg+hg), (0, 0, 0), 2)
elif dB:
trashAngle = trashB
comebackAngle = comebackB
mc.set_color(0, 0, 255)
print("Detected Blue Block")
cv2.rectangle(frame, (xb, yb), (xb+wb, yb+hb), (0, 0, 0), 2)
cv2.imshow("frame", frame)
cv2.waitKey(1)
if dR or dG or dB:
break
for angle in pickup:
mc.send_angles(angle, 40)
time.sleep(1.5)
pump(1)
time.sleep(1)
mc.send_angles(preTrash, 40)
time.sleep(1)
mc.send_angles(trashAngle, 40)
time.sleep(3)
pump(0)
time.sleep(3.5)
mc.send_angles(comebackAngle, 40)
time.sleep(1.5)
except KeyboardInterrupt:
break
pump(0)
time.sleep(1)
mc.send_angles(pickup[1], 40)
time.sleep(3)
mc.release_all_servos()
GPIO.cleanup()
vs.release()
cv2.destroyAllWindows()
time.sleep(1)

 

 

myCobot 280 Pi 具有很多功能。它适合机器人教育的初学者,起价为5999元,可用于从高中到大学的教学。myCobot 280 Pi 机械臂也是学习工业机器人入门首选。正如您将从我们上面的示例中看到的那样,编写程序来读取手臂的角度非常容易,它还可以用于研究正向和逆向运动学来控制机器人。

审核编辑 黄昊宇

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分