最近开始学习视觉识别这一块的知识,刚好在之前学习ROS机器人开发的时候有一台大象机器人的Mycobot机械臂,所以潜心研究数周后用机械臂联合RGB摄像头开发了一个物体识别并抓取的一个小项目。将理论知识转化为实际项目的过程虽然曲折艰辛,但是看到成品成功运行起来并获取到想要的效果时还是无比激动和欣慰的。所以在这里记录并分享一下我得开发思路和过程,希望和有同样爱好的大家多多交流。

一、ROS简介

ROS 是机器人操作系统(Robot Operating System)的英文缩写,ROS 是用于编写机器人软件程序的一种具有高度灵活性的软件架构。

ROS 是开源的,是用于机器人控制的一种后操作系统,或者说次级操作系统。它提供类似操作系统所提供的功能,包含硬件抽象描述、底层驱动程序管理、共用功能的执行、程序间的消息传递、程序发行包管理,它也提供一些工具程序和库用于获取、建 立、编写和运行多机整合的程序。

ROS 的首要设计目标是在机器人研发领域提高代码复用率。ROS 是一个分布式的进程(也就是“节点”)框架,这些进程被封装在易于被分享和发布的程序包和功能包中。ROS 也支持一种类似于代码储存库的联合系统,这个系统也可以实现工程的协作及发布。这个设计可以使一个工程的开发实现从文件系统到用户接口完全独立决策(不受 ROS 限制)。同时,所有的工程都可以被 ROS 的基础工具整合在一起。

二、Aruco标记

一个ArUco marker是一个二进制平方标记,它由一个宽的黑边和一个内部的二进制矩阵组成,内部的矩阵决定了它们的id。黑色的边界有利于快速检测到图像,二进制编码可以验证id,并且允许错误检测和矫正技术的应用。marker的大小决定了内部矩阵的大小。例如,一个4x4的marker由16bits组成。

一些ArUco markers的例子:

Example of markers images

应当注意到,我们需要检测到一个Marker在空间中发生了旋转,但是,检测的过程需要确定它的初始角度,所以每个角落需要是明确的,不能有歧义,保证上述这点也是靠二进制编码完成的。当Marker在空间中旋转,对应的二进制信息也会发生变化,根据变化量就可以得出Marker在空间中相对摄像头的位置及姿态,如下图所示,还可以在摄像头画面中显示Marker的坐标系和边界:

三、摄像头识别抓取实战

Mycobot在GitHub上有一个开源的代码库:https://github.com/elephantrobotics/mycobot_ros

里面有mycobot各种使用功能的代码文件,让功能跑起来挺简单的,只需要在命令行终端launch一个文件run一个文件就能实现。这次来详细看看各个代码文件,来扒一扒识别抓取到底是如何实现的。

四、主要代码及功能

首先看一下launch文件,有了解过ROS的肯定都知道一个launch文件会打开多个节点,开启各个节点之间的通信。

在这个launch中主要有三个节点文件:

opencv_camera.cpp   /   detect_marker.py   /   following_marker.py

  1. /mycobot_ros/src/opencv_camera.cpp

想要识别物体,当然首先要打开摄像头,在这里将摄像头拍摄到的录像图片利用cv_brige库转换成OpenCV类型的格式,并创建了一个发布者向"camera/image"话题发布图片消息,这样后面的代码才能拿到我们想要的场景信息进行进一步的图像处理。

2.mycobot_ros/scripts/mycobot/detect_marker.py

在上一步我们发布了摄像头拍到的图并在”camera/image”话题上发布了图片信息,现在我们就可以获取到话题上的图片信息并调用Aruco库中的”detectMarker” API函数检测图中是否有Aruco标志。

从第一行可以看到,如果corners大于0就说明起码检测到一个或以上的Aruco标识。这时候我们就开始对这个Aruco标记进行一系列的转换最后得到在mycobot坐标空间的位置。

这里有几个API比较重要:

“estamatePoseSingleMarkers “ 做了一个评估,获取二维码和相机的相对空间坐标。

“Quaternion_from_euler” 将欧拉角转换为四元数,因为在ros里使用的是四元数。

3.mycobot_ros/scripts/mycobot/following_marker.py

可以看到,在前面的操作里已经拿到了我们实现抓取的真实坐标。那么,现在看看最后一个文件做了什么。

“sendTransform” 进行了空间坐标的转换。得到了我们物体上的Aruco标记相对于机械臂空间坐标的相对位置。

上面的源码,我们可以很清楚的看到该文件中通过 lookupTransform这个方法监听了目标坐标。实例化了一个 Marker,在rviz 仿真环境中创建了一个立方体。如图中效果:

4.mycobot_ros/scripts/mycobot/follow_and_pump.py

看完了launch文件后,我们发现还需要run一个定点吸取物体的脚本。 在这个脚本里主要就是创建一个接收者,监听Aruco标记是否检测到,当检测到标记并获得我们前面已经得到的物体真实坐标,把这个坐标发给机械臂让它行进到坐标点,开动吸泵就大功告成。

 欢迎更多爱好者交流参与,原创文章作者:大象机器人。