识别aruco码物块
一、机械臂摄像头装配
由于机械臂该案例是基于eye-in-hand模式下的,要求摄像头跟机械臂进行结合,所以需要用螺丝刀将机械臂的头部前端换成带摄像头的前端。为了确保程序正常运行,在更换机械臂的头部前端时,需要对机械臂六轴进行校准。对准六轴调零位置,如下图所示,根据如下讲解修改mycobot_ai包的tools.py并运行即可。请确保程序初始化机械臂后机械臂上的摄像头如上图所示。否则请终止程序,重新装配摄像头。
from pymycobot.mycobot import MyCobot
# 机械臂设备名称,需要跟实际机械臂设备名称保持一致。
port = "/dev/ttyUSB0"
mc = MyCobot(port)
# 放松机械臂
# mc.release_all_servos()
# 校准机械臂的六轴
mc.set_servo_calibration(6)
二、案例重现
如上视频操作即可实现颜色识别物块并抓取的demo。接下来我们将用文字描述视频中的操作流程:
M5版本:
- 通过文件管理器去到mycobot-ros的工作空间中的mycobot_ai包下。
- 鼠标右键,打开终端。
- 赋予操作机械臂权限,输入
sudo chmod 777 /dev/ttyU
并使用Tab键补出机械臂设备名称。 - 若设备名称不为
/dev/ttyUSB0
则需要更改vision.launch文件中的port值。 - 输入
roslaunch launch/vision.launch
开启vision.launch文件,该文件包含ros的一些核心库以及依赖等。 - 在rviz图形界面中创建一个marker,并为其命名为cube。
- 在命令终端中键入
ctrl+shift+t
开启同目录下的另一个命令窗口。 - 输入
python scripts/detect_encode.py
打开识别颜色程序,即可实现颜色识别并抓取了。
若不清楚如何修改port值以及创建marker可参考:ROS建立方块模型
树莓派版本:
一 在文件终端使用方法:
- 开机点击桌面Home文档,之后点击catkin_ws文档——src文档——mycobot_ros未定。
- 点击mycobot_ai,进入界面鼠标右键,打开终端。
- 输入roslaunch launch/vision.launch开启vision.launch文件,该文件包含ros的一些核心库以及依赖等。
- 在rviz图形界面中创建一个marker,并为其命名为cube。
- 在命令终端中键入ctrl+shift+t开启同目录下的另一个命令窗口。
- 输入python scripts/detect_encode.py打开识别颜色程序,即可实现颜色识别并抓取了。
二 桌面终端使用方法:
- 鼠标右键点击ai_windows,打开终端,输入python3 ai_windows.py,按回车开启gui。
- 打开gui界面,先点击“open ros按钮”打开ros
- 等待ros打开完毕,选择要运行的程序,点击运行即可。
注意事项
- 识别区域:请使用无二维码贴纸的另一面。
- 由于摄像头是需要自行装配的原因,会导致摄像头相对于吸泵的偏移量有所不同。若抓取效果不理想,可自行修改偏移量。
三、代码讲解
本案例是基于OpenCV以及ROS通信控制机械臂实现的。首先,对摄像头进行校准,确保摄像头的准确性。之后,调用OpenCV识别aruco的函数方法获得aruco码物块相对于摄像头的坐标,这样我们通过摄像头相对于吸泵的坐标以及吸泵相对于机械臂底部的坐标即可计算出aruco码物块相对于机械臂的坐标值。
aruco物块相对坐标计算
根据OpenCV识别aruco会获得aruco码相对于摄像头的一个平移坐标值tvec,以及相对于摄像头的一个旋转坐标值rvec。这里我们使用它的tvec值,这样就能获得aruco物块相对于摄像头的坐标值了。由于摄像头的装配会对识别抓取效果产生一些影响,为了更好的抓取效果可以修改全局变量pump_y,pump_x。
# 将图片转换成灰色度图
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# 检测aruco物块
corners, ids, rejectImaPoint = cv.aruco.detectMarkers(
gray, self.aruco_dict, parameters=self.aruco_params
)
if len(corners) > 0:
if ids is not None:
# 获取aruco的一系列信息
ret = cv.aruco.estimatePoseSingleMarkers(
corners, 0.03, self.camera_matrix, self.dist_coeffs
)
# 获取旋转坐标值和平移坐标值
(rvec, tvec) = (ret[0], ret[1])
(rvec - tvec).any()
xyz = tvec[0, 0, :]
"""
计算出aruco物块相对于吸泵的坐标值;
pump_y,pump_x表示摄像头相对于吸泵以及识别时发生的误差的总偏移量
可通过修改pump_y,pump_x偏移量纠正抓取效果;
"""
xyz = [round(xyz[0]*1000+pump_y, 2), round(xyz[1]*1000+pump_x, 2), round(xyz[2]*1000, 2)]
for i in range(rvec.shape[0]):
# 将aruco在图片中画出
cv.aruco.drawDetectedMarkers(img, corners)
cv.aruco.drawAxis(
img,
self.camera_matrix,
self.dist_coeffs,
rvec[i, :, :],
tvec[i, :, :],
0.03,
)
教程中仅给出了程序的重难点进行讲解,具体实现请查看源码。