当前位置: 首页 > news >正文

蔬菜视觉分拣机器人的设计与实现(RoboWork参赛方案)

蔬菜视觉分拣机器人的设计与实现

文章目录

  • 蔬菜视觉分拣机器人的设计与实现
    • 1. 技术栈背景
    • 2. 整体设计
    • 3. 机械结构
      • 3.1 整体结构
      • 3.2 底座结构
      • 3.3 小臂结构
      • 3.4 大臂结构
      • 3.5 负载组件结构
      • 3.6 末端执行器结构
    • 4. 硬件部分
      • 4.1 视觉系统
        • 4.1.1 光源
        • 4.1.2 海康工业相机
      • 4.2 传送带系统
        • 4.2.1 传送带装置
        • 4.2.2 光电距离传感器
      • 4.3 机械臂工控机以及机械臂
    • 5. 软件部分
      • 5.1 上料机器人程序设计
        • 5.1.1 上料机器人程序流程图
        • 5.1.2 上料机器人程序描述
        • 5.1.3 上料机器人程序核心代码
      • 5.2 图像获取与坐标转换程序设计
        • 5.2.1 图像获取与坐标转换程序流程图
        • 5.2.2 图像获取与坐标转换程序描述
        • 5.2.3 图像获取与坐标转换程序核心程序
      • 4.3 视觉识别后台程序设计
        • 4.3.1 视觉识别后台程序流程图
        • 5.3.2 视觉识别后台程序描述
        • 5.3.3 视觉识别后台程序核心代码
      • 5.4 分拣机器人程序设计
        • 5.4.1 分拣机器人程序流程图
        • 5.4.2 分拣机器人程序描述
        • 5.4.3 分拣机器人程序核心代码
    • 6 过程总结
      • 6.1 上料与分拣机械臂
      • 6.2 视觉系统

1. 技术栈背景

  硬件:越疆魔术师M1以及提供场地设施
  图像处理:VisionMaster(加密狗6100)、OpenCV
  CAD模型:CrownCAD

2. 整体设计

  在本文设计中,通过基于 TCP/IP 的 CS 通信架构,用于 PC 端和海康视觉套件之间的程序信息传递,海康视觉套件中会开启 4000 端口和 7890 端口的 TCP Server 侦听,PC 端的利用 TCP Client 连接进行信息传递交互,通过传递的字符串以及传送带附带的光电传感器的反馈信号进行工作流程的推进,光电传感器的信号表征上料到传送带的物料是否到达摄像头的景深区域,海康视觉套件与海康工业相机与光源配合,能够准确的捕获传送带上到位水果物料的图像信息并加以处理,为流程处理提供视觉输入信息,而光源采用环形光源,突出物料盒的三维边缘信息,助力于图像的预处理工作。对于上料机械臂的控制由 PC端调用基于 Dbot 动态 DLL 程序库的 Python API 完成信号的传输,传输的方式为 COM 串口绑定传输,分拣机器人由基于海康视觉套件的 Dbot API 实现控制。在机械臂的控制工作流程方面,是通过 TCP 服务端和客户端交互的字符串推进的,字符串的推进工作有四种:

  1. PC 端 TCP 客户端连接 4000 端口发送”arrive”
    当物料在传送带上运输到摄像头能够捕获的景深区域时,光电传感器电阻值骤变,给予工控机的信号量改变,在 PC 端的状态获取 API 中,检测到光电信号有遮挡物时,PC 端通过 TCP 客户端连接 4000 端口向视觉套件发送”arrive”,表征物料在传送带上已到达景深区域,此时终止传送带的运输。
  2. 视觉套件 TCP 服务端回应”ok”
    当视觉套件接收到字符串”arrive”之后,开始通过配置好的参数调用海康工业相机,进行图像的获取工作,对获取到的图像进行物料有无的特征匹配工作,当匹配到物料的边缘特征之后,确定中心点,将中心点的像素坐标通过手眼标定的变换参数转换为物理坐标系的 x、y 坐标,将转换的物理坐标信息更新到视觉套件的全局变量中,以供机械臂的控制使用,同时将采集的图像信息存到本地,以供 PC 端进行水果类型的分类,当参数更新和图像保存结束后,视觉套件程序的 TCP/4000 端口向 PC 端的客户端端口发送”ok”,表征视觉套件对于物料的检测和坐标转换完成。
  3. PC 端 TCP 客户端连接 7890 端口发送”A”或”B”或”C”或”D”
    当 PC 端连接 TCP/4000 的客户端端口接收到”ok”后,开始对采集的图像进行预处理,通过二值化和形态学开运算操作处理图像将图像的边缘变平滑,消除毛刺,之后进行轮廓面积的匹配,找出轮廓面积接近物料盒的区域,对图像进行仿射变换,区域即为物料盒的区域,对仿射变换后的图像信息使用 ResNet-50 深度卷积神经网络进行推理,对水果的类型进行分类,按照比赛要求,需要分别出白菜、胡萝卜、凤梨、梨四种类别的水果,当程序检测出水果的类别之后,PC 端通过 TCP 客户端连接视觉套件 TCP/7890 服务端端口发送对应的”A”、”B”、”C”、”D”类别字符,以表征到位的物料盒中的水果种类。
  4. 视觉套件 TCP 服务端回应”run”
    视觉套件接收到 PC 端发送的种类信息字符之后,根据不同水果的类别将目标位置点设置为水果对应的放置区域物理坐标点位,更新完目标点的参数之后,根据 2)所获取的物料物理坐标系坐标点,给分拣机械臂发送控制信号,使分拣机械臂的移动到水果物料盒的上方,后下移夹取,夹取后根据目标点位的物理坐标信息进行机械臂的运动规划放置,放置成功后,视觉套件给 PC 端 TCP/7890 Client 回应”run”,当 PC 端程序收到”run”之后,计算上料盒的偏移量,开始下一轮的程序循环,转到 1),直到上料的物料和分拣的物料均已完成。
    在这里插入图片描述

3. 机械结构

  此部分打开官方模型文件使用的是华云三维国产云架构CAD软件CrownCAD,实用便捷,免去了安装的复杂操作,避免了盗版问题,且功能齐全,值得推荐。
https://cad.crowncad.com/account/login

3.1 整体结构

  机械臂的整体外观设计图如下,其按照结构分为底座部分、大臂部分、小臂部分、末端工具部分。
在这里插入图片描述

  机械臂的整体机械结构图如下所示,根据 CAD 软件的模型加载,可以将机械臂的机械结构进行拆解,能够看到机械臂的设计细节。
在这里插入图片描述
  为了满足分拣和上料的任务要求,设计臂长与旋转范围时要充分进行考虑机械臂的工作范围,机械臂的工作范围如下所示。
在这里插入图片描述
在这里插入图片描述
  机械臂的工作空间三维图如下所示,三维模型对于工作空间的表示则更加直观,由于底座空间的限制,导致机械臂的运动空间并非是正的半球形,但工作空间基本满足分拣任务的需要,由于自由度和臂长的限制,其工作空间仅仅能低于底座 15mm,不适用于低于底座的作业。
在这里插入图片描述

3.2 底座结构

  底座设计采用半圆形草图设计,一保证左右底座拼接的包装完整性,二为支撑板提供有效的底部铺垫,提高零部件的稳定性,整体采用梯形凸台的整合方式,利于底座承重。底座设计如下所示:
在这里插入图片描述

3.3 小臂结构

  小臂设计采用的是法兰固定轴连接驱动杆组件进行活动,小臂上留有线材接口和一个按钮用于控制解锁舵机开放示教运动的模式,驱动杆组件拥有一个联轴器,通过联轴器将小臂的部分与底座部分连接起来,完成机械臂两个自由度的连接,小臂上留有电机轴,用于将操作此关节的点击与臂联合起来。小臂机械结构如下所示。
在这里插入图片描述

3.4 大臂结构

  大臂设计与小臂类似,但是大臂长度较短,同时不用连接底座,不需要驱动杆的组件部分,大臂部分仅仅需要一个与小臂电机轴部分同口径的法兰轴承同时作为大臂的电机轴承与小臂进行连接,考虑与前部执行机构的连接,设计联轴器作为与前部执行机构连接的媒介。大臂机械结构的设计如下所示。
在这里插入图片描述

3.5 负载组件结构

  负载组件主要连接末端执行器,负载组件的前置组件为小臂,所以负载组件留有一个小臂连接轴,连接轴的口径与小臂的连接轴相同,同时连接轴又作为电机的承载,由于机械臂的末端执行器一般支持更换的,所以需要考虑设计一个蝶形螺母,用于适配设计的末端执行器。负载组件的机械结构图如下所示。
在这里插入图片描述

3.6 末端执行器结构

  机械结构设计部分此部分为重点部分,在动力系统的设计方面由于在电机不够优秀的情况下,对于参数较小的应用场景下,电机控制的方式不如气动元件的效果好,同时还能节省成本,故动力系统采用气动元件,在机械设计时需要考量气动元件的安放,由于所夹的物料盒为硬质塑料,不必考虑柔性材料夹具,采用钳型夹爪,同时钳型夹爪一侧连接气缸组件,为了是夹爪可动,同时为了重心的稳定性,添加滑动铜套贯穿于夹爪元件。末端执行器的机械结构设计图如下所示。
在这里插入图片描述

4. 硬件部分

4.1 视觉系统

4.1.1 光源

  本次设计采用白色素光光源辅助补偿,产品编号 JHZM-A40-W,数量安排上为 48 壳发光二极管,照度为 40000lux,亮度为连续可调式,调节范围 0~100%,色温不变,光源是机器视觉处理问题的核心,光源是决定图像质量的重要因素。采用发光二极管 LED 在成本和亮度上相比荧光灯、卤素灯来说折衷,但是其稳定性和使用寿命高,本次光源配置采用环形光高角度照射-明场配光,环形光源的最大特点是可以突出物体的三维信息,在本次设计中主要突出物料盒的边缘信息,使得物料盒边缘明显宜于进行模板匹配,突出边缘后的效果图如下所示。
在这里插入图片描述

4.1.2 海康工业相机

  视觉系统的信息采集采用海康工业相机 MV-CE050-30UC,像素为 500 万,数据接口为 USB3.0,由于对于图像采集的实时性没有太高的要求,故无需采用 GigE 接口的相机,以节约不必要的成本,由于待测物料盒为静态非运动场景,故采用 CMOS 传感器而非 CCD面阵相机,同样是为了节约不必要的成本,传感器型号为 AR0521,像元尺寸为 1/2.5’’,那么其对角线为 7.182mm,宽度为 5.760mm,高度为 4.290mm,传感器的尺寸越大,像元尺寸则也会更大,本文视觉系统设计选用了 12mm 定焦镜头,待测物料盒大小规格为48mm48mm45mm,视野大小至少为 60mm*60mm,定精度为 0.02mm,那么需要的像素为600.01×600.01=900000\frac{60}{0.01}\times \frac{60}{0.01}=9000000.0160×0.0160=900000,也即 90 万像素,而一般一个像素表达 3-4 个精度,故相机的像素不低于4 × 90 × 10 4 = 360 × 10 4 ,也即相机分辨率不能低于 360 万像素,故 500 万相机满
足要求

4.2 传送带系统

4.2.1 传送带装置

  传送带的运行负载为 500g,有效运载长度为 600mm,其最大运转速度为 120mm/s,最大加速度为 1200mm/s2,尺寸为 700mm215mm60mm,重量为 4.2kg,考虑到检测物料的重量小于 500g,可以采用此传送带装置作为传输系统的载体,在运转的速度方面,120mm/s的最大速度也满足赛程的要求,速度过快会由于电信号通过工控机连接个人 PC 端传输的效率问题导致物料的到位检测不及时,从而使得物料掉落,使得图像采集信息失准,传送带的宽度为 215mm,能够较为宽松的放置物料盒。传送带的结构图如下所示:
在这里插入图片描述

4.2.2 光电距离传感器

  光电距离传感器在本次设计中起到了物料盒到位检测的辅助作用,光电距离传感器单元的距离测量范围为 20~150mm 之间,而传送带的边缘与光电距离传感器的距离大于20mm,故采用此型号的光电距离传感器可以满足需求,另外光电距离传感器的信号为模拟信号输出,由机械臂的工控机接收处理,通过其结构提供给 PC 端的 API 调用获取光电距离传感器的状态,供电电压为 4.5V-5.5V。光电传感器的安装示意图如下所示:
在这里插入图片描述

4.3 机械臂工控机以及机械臂

  机械臂的控制源为机械臂底座下的工控机中的 MCU 板载程序,为驱控一体化设备,其内部硬件与源程序暂未开放,其具有一个复位按键和一个功能按键,用于执行脱机程序和回零操作,其主板后留有一个 10pinUART 接口用于通信,可以连接蓝牙、WIFI 模块,其通信协议采用 Dobot 协议标准,工控机还留有一个 USB 接口,用于连接 PC 进行通信,同时留有 6 个外部接口用于连接气泵、挤出机、传感器等外部设备。工控机的通信编程遵顼 Dobot 通信协议,Dobot 通信协议采用不定长帧,一般帧由包头、负载帧长、负载帧、校验部分组成;为了区别接收帧之后短时间内再次接收控制帧对于机械臂的不同控制表现,指令分为立即指令和队列指令,立即指令将在接收控制帧后立即做出响应,而队列指令则将指令帧加入执行队列,以免造成执行结果异常,命令的参数使用小端模式,帧头以 0xAA 0xAA 作为起始,之后为帧长数据段,表征帧的数据长度,帧负载中包含 ID 号、控制状态和参数部分,最后是校验和部分,以表征接收到的帧是否完整,控制状态中包含读/写状态位和是否为队列指令状态,Dobot 协议也侧面说明了工控机的程序通过串口通信实现,工控机将机械臂的控制程序、位姿估计、轨迹规划等功能以后台程序的形式托管到后台,通过接收串口指令来进行相应的控制。Dbot 协议的示例如下所示:
在这里插入图片描述
  机械臂的机械结构已在章节 3 中提及,机械臂的自由度和关节运动的关节在于机械结构设计,在硬件方面在每个关节预留的电机连接轴进行步进电机和舵机的连接,用于接收信号量用于驱动电机转动相应的偏移,后台程序通过电机驱动获取各电机和舵机的实时状态用于位姿估计和轨迹规划。在机械臂的小臂上预留了接口的输出位,可以拓展功能,其中一个接口是 R 轴舵机接口,也可以复用为用户自定义接口,R 轴接口用于连接末端执行器,本文中的末端执行器为钳型夹具,R 轴的旋转范围为-90°~90°,末端执行器的实际旋转情况与安装的初始位置有关,而 R 轴的电机所能运动的范围仅靠此接口的输出量。

5. 软件部分

5.1 上料机器人程序设计

5.1.1 上料机器人程序流程图

在这里插入图片描述

5.1.2 上料机器人程序描述

  上料机器人的程序总体是完成水果物料盒的上料任务,作为整个赛程任务的伊始,其在首次上料的时候不需要有任何的逻辑控制,当第一轮次的循环完毕之后,再次开始下一次循环必须经由分拣机器人的活动反馈来开启,PC 端程序接收到”run”字符串的时候,开启下一轮次的上料工作,根据赛规,上料物料盒数量为两层,每层 8 个,每层 2 列,每列4 个,我们在每次上料后使用三个变量进行位置映射,其分别代表层数、列数、行数,通过三个变量的逻辑控制精准的表达当前操作的物料盒,由于上料机器人没有视觉参考系统,故我们需要使用调试软件确定目标点位的机械臂坐标系坐标点位信息,以物料盒的宽度作为偏移量,进行目标点的配置,使用 Dbot 提供的 API SetPTPCmdEx 进行机械臂的位移控制,当物料成功放到传送带的时候,使用 API SetMotorEx 开启传送带的电机,然后程序进入到位检测的阶段,使用 API GetInfraredSensor 获取光电距离传感器的状态,当光电距离传感器的状态为 1 时,也即光电距离传感器检测到物料到达摄像头景深区域时,设置传送带电机停止,此时进行通信工作,上料机器人的程序创建了绑定 TCP/4000 端口的客户端对象,客户端发送字符串”arrive”,告知服务端,物料盒已经到达分拣区域。

5.1.3 上料机器人程序核心代码

def pileup():
global row,col,floor
#  每次上料前检测拍照位是否有物料
#  默认释放夹爪
dType.SetEndEffectorGripper(api, 1, 0, isQueued=1)
#  抓取( 按照行列式)
#  一层
dType.SetPTPCmdEx(api, 0, (266.9784 - col * 47.7121), (-137.4335 + row * 46.2313), (43.4128 - floor * 43.4128), -39.6240, isQueued=1)
#  抓取
dType.SetEndEffectorGripper(api, 1, 1, isQueued=1)
#  延时 1000ms
dType.dSleep(500)
#  放置
dType.SetPTPCmdEx(api, 0, -22.6245, -258.4785, 65.3683, -44.9279, isQueued=1)
#  释放
dType.SetEndEffectorGripper(api, 1, 0, isQueued=1)
#  抬起
dType.SetPTPCmdEx(api, 0, -25, -270, 105, -44.9279, isQueued=1)
#  传送带动作 7500pulse/s
dType.SetEMotorEx(api, 0, 1, 16500, isQueued=1)
#  提前到达下一个货物的上方
dType.SetPTPCmdEx(api, 0, (266.9784 - col * 47.7121), (-137.4335 + row * 44.2313), 60, -39.6240, isQueued=1)
#  夹爪未使能
dType.SetEndEffectorGripper(api, 0, 0, isQueued=1)
#  传送带动作 7500pulse/s
# dType.SetEMotorEx(api, 0, 1, 7500, isQueued=1)
#  光电物料到位阻塞检测,限时 25s
target_reach()
#  传送带停止,触发相机拍照定位
dType.SetEMotorEx(api, 0, 0, 0, isQueued=1)
socket_client.send("arrive".encode('utf-8'))
#  光电物料离位阻塞检测,限时 25s
# 2*4  矩阵( 一层)
if col < 1 and row <= 3:
col += 1
elif col >= 1 and row < 3:
col = 0
row += 1
elif col >= 1 and row >= 3 and floor < 1:
col = 0
row = 0
floor += 1
else:
print(' 机械臂结束上料')
sys.exit()

5.2 图像获取与坐标转换程序设计

5.2.1 图像获取与坐标转换程序流程图

在这里插入图片描述

5.2.2 图像获取与坐标转换程序描述

  此部分程序的功能主要是辅助获取物料盒的图像信息,用于后续的分类判断,另外一个作用就是找出物料盒的中心点,这个过程使用的是海康 VisionMaster的特征模板匹配算子,特征模板匹配是传统的模式匹配算法,在这种静态工业视觉场景中,相比深度学习方法的识别要快很多,深度学习的图像目标检测一般用于检测物呈现多样性的情况,并且根据机械臂与摄像头的手眼标定文件将像素坐标系中的物料盒中心点转换为物理坐标系坐标点,转换到分拣机械臂的坐标系中,坐标转换的过程是将像素坐标系下的坐标点通过手眼标定的参数文件转换为机械臂坐标系下的坐标点的过程,实际上手眼标定的过程就是确定一个旋转平移矩阵拟合两个坐标系下坐标点的换算关系,一般使用经典的棋盘格标定法又成张正友标定法,当图像获取以及标定转换工作做完之后,转换后的坐标点信息更新到VisionMaster 的全局变量中,供给后续程序使用,最终将摄取的图像保存在指定位置,以提供给图像分类识别使用VisionMaster 工具开启通信管理,通信管理中在 TCP/7890 开启服务端侦听,存储图像结束后,向 TCP/7890 端口客户端发送”ok”表征图像获取和标定转换、图像存储的功能完结。

5.2.3 图像获取与坐标转换程序核心程序

程序为VisionMaster图形化编程处理过程:
在这里插入图片描述

4.3 视觉识别后台程序设计

4.3.1 视觉识别后台程序流程图

在这里插入图片描述

5.3.2 视觉识别后台程序描述

  视觉识别后台程序开启 TCP/7890 端口客户端侦听数据,当收到服务端的回应”ok”时,程序推进,对采集的物料盒的图像进行裁剪,由于原相机的视野较大且每次物料盒停止的位置并没有太大偏移,故对原图像进行裁剪,裁剪后进行图像预处理,预处理工作中首先对图像进行灰度处理,灰度处理的目的主要是对数据降维,由三通道数据降维到单通道,之后进行二值化处理,将灰度阈值在 100~230 以内和以外的区域二值化处理,主要是将区域分割开,再对图像进行图像的开运算,将轮廓的边缘平滑处理,消除毛刺,之后进行轮廓的提取,物料盒轮廓有两个特点,一是经过调试物料盒的轮廓有 340000 左右,二是其他区域轮廓要么小要么非封闭,故每次提取出的轮廓提取 300000 以上的,取出其区域的坐标,对原通道图像进行仿射变换,经过仿射变换,能够将物料盒以及内部的水果精准的提取出来,为了防止 opencv空载报错,当不存在满足要求的轮廓存在时,返回原图,对仿射变换后的图像进行基于 Resnet-50 的模型分类推理,Resnet 时经典的残差结构卷积神经网络,其实对于 4 分类且特征差别明显的任务,各种典型的神经网络均可优秀地完成任务,考虑使用 Resnet 网络主要是考量其能够在卷积操作之后可以兼顾原图特征,模型推理结束后根据产生的分类结果向 TCP/7890 的服务端发送类型对应的字符,对应关系为:A-大白菜、B-胡萝卜、C-梨、D-凤梨,紧接着使用 opencv 的窗口工具对推理结果进行展示,根据赛程要求,需要将推理结果展示3秒。
在这里插入图片描述

5.3.3 视觉识别后台程序核心代码

#  图像预处理
def image_pre(image_source):
#  图像处理:灰度化
dst = cv2.cvtColor(image_source,cv2.COLOR_RGB2GRAY)
# cv2.imshow("dst",dst)
#  图像处理:二值化
ret,dst_2=cv2.threshold(dst,100,230,cv2.THRESH_BINARY)
# cv2.imwrite('./image/thresh.jpg', dst_2)
# cv2.imshow("dst_2", dst_2)
#  图像处理:形态学开运算
kernel = np.ones((3,3),np.uint8)
opening = cv2.morphologyEx(dst_2, cv2.MORPH_OPEN, kernel)
# cv2.imshow("opening", opening)
# cv2.imwrite('./image/opening.jpg', opening)
#  图像处理:包络轮廓
# binary,contours,hierarchy = cv2.findContours(opening,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
contours,binary = cv2.findContours(opening,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
#  如果找不到轮廓,则返回原图,防止空载报错
src_roi = image_source
for i in range(0,len(contours)):
#  打印轮廓面积
area = cv2.contourArea(contours[i])
print(area)
#  如果提取的轮廓面积少于 300000 ,跳过,继续寻找轮廓
if area<300000:
continue
#  左上角坐标(x_l,y_l) 、宽、高
x_l, y_l, w, h = cv2.boundingRect(contours[i])
#  中心点坐标
x = (x_l+h)/2;
y = (y_l+w)/2;
#  获取所有轮廓(Blob  连通区)最小外接矩形的(中心(x,y), ( 宽, 高),  旋转角度)数据对象 rect
rect = cv2.minAreaRect(contours[i])
#  获取最小外接矩形的 4  个顶点坐标( 左上角、左下角、右下角、右上角)
box = cv2.boxPoints(rect)
#  数据类型转换
box = np.int64(box)
#  根据最小外接矩形的中心坐标与角度,构建一个旋转矩阵 rot_img
#  输入目标轮廓矩形中心点坐标 center = rect[0] ,矩形角度 angle = rect[2]
rot_img = cv2.getRotationMatrix2D(rect[0], rect[2], 1.0)
#  使用前面获得的四个矩形顶点坐标数组[box] ,在原图层绘制轮廓
cv2.drawContours(image_source, [box], 0, (0, 255, 0), 1)
#  利用旋转矩阵 rot_img, 原图层 img  实现中心仿射变换,变换后的图层尺寸保持不变
# height = image_source.shape[0] ,width = image_source.shape[1]
img_waf = cv2.warpAffine(image_source, rot_img, (image_source.shape[0],image_source.shape[1]))
#  仿射变换后得到 img_waf  图层中心点坐标和目标轮廓最小外接矩形中心点一致,
#  根据数据对象 rect  提取出矩形中心点坐标和宽高 x ,y ,w ,h ,分别得到矩形行(x) 和列(y) 的起始点和结束点
# 在 在 img_waf  中剪裁出纠正角度后的目标图层 src_roi
#  语句原型(img_waf[y-int(h/2): y+int(h/2)+4, x-int(w/2): x+int(w/2)+4])
src_roi = img_waf[int(rect[0][1])-int((rect[1][1])/2)+4:int(rect[0][1])+int((rect[1][1])/2)-4,
int(rect[0][0])-int((rect[1][0])/2)+4:int(rect[0][0])+int((rect[1][0])/2)-4]
cv2.imwrite('./image/img.jpg', src_roi)
break
return src_roi

5.4 分拣机器人程序设计

5.4.1 分拣机器人程序流程图

在这里插入图片描述

5.4.2 分拣机器人程序描述

  分拣机器人部分主要工作是将物料盒分拣到每个水果的指定存放区域,这个结果要依托于前面程序的工作,当夹取传送带上的物料时,立即给 PC 端侦听的 TCP/4000 端口的客户端发送”run”以节省时间,开启上料的下一轮次的循环。当开始换算分拣区域的物理坐标系点时,采用 VisionMaster的脚本功能,插入逻辑代码,语言采用 C#的形式,A、C 类的区域相对于机械臂坐标系来说,并非顺应 x 轴、y 轴的存在,其对应关系如下所示:
在这里插入图片描述
在这里插入图片描述
  图中的 ABCD 表示四个物料盒的摆放位置,我们仅需要获得 A 点的位置,剩下的点均可以采用偏移量的形式移动,根据根据等腰三角形的勾股定理,偏移量为1800\sqrt{1800}1800约为 43,那么进行偏移量的分析如下所示
在这里插入图片描述
  经过分析,设轮次为 n,设偏移量 43 为 x,则对于坐标 X 的拟合序列为 0,x,-x,0,根据计算,推断出拟合多项式为:
t(n)=(n%3==0)?0:1×(−1)n+1xt(n)=(n\%3==0)?0:1\times(-1)^{n+1}x t(n)=(n%3==0)?0:1×(1)n+1x
  对于坐标 Y 的拟合序列为 0,x,x,2x,根据推演,拟合的多项式为:
t(n)=nx2n−1+⌊n3⌋×54xt(n)=\frac{nx}{2^{n-1}}+\lfloor \frac{n}{3}\rfloor \times \frac{5}{4}x t(n)=2n1nx+3n×45x
  根据 A 区域的分析同理可以得到 C 区域的位置关系,对于 B 区域的分析则较为简单,B 区域相对于机械臂坐标系的相对位置如下所示。
经过分析,偏移量分析表如下所示:
在这里插入图片描述
  设轮次为 n,设偏移量 60 为 x,对于 X 的拟合结果为:
t(n)=⌊n2⌋xt(n)=\lfloor \frac{n}{2} \rfloor x t(n)=2nx
  对于 Y 的拟合结果为:
t(n)=(nmod2)xt(n)=(n\quad mod\quad2)x t(n)=(nmod2)x

5.4.3 分拣机器人程序核心代码

  主要流程已经由海康图形流程给出,此处主要实现多项式拟合位置的C#脚本

using System;
using System.Text;
using System.Windows.Forms;
using Hik.Script.Methods;
SetFloatValue("placeXB", xB - cntB / 2 * 60);
SetFloatValue("placeYB", yB - cntB % 2 * 60);
SetFloatValue("placeXA", (float)(xA + (cntA%3==0 ? 0 : 1) * Math.Pow(-1, cntA + 1) * 43));
SetFloatValue("placeYA", (float)(yA + cntA * Math.Sqrt(1800) / Math.Pow(2, cntA - 1) + (int)(cntA / 3) * 1.25F * 43));

6 过程总结

6.1 上料与分拣机械臂

  对于上料与分拣机械臂的开发过程中主要是理顺机械臂的三种运动模式的区别以及点位的设置,在点位设置方面需要使用官方工具进行示教摆放,摆放完成后记录 xyzr 坐标便于在程序中进行设置,由于机械臂的运动范围非正半球形,故有一些位姿虽然手动摆放可以达到,但是实际机械臂的坐标系中并不包含此处,在不同的运动模式中,轨迹规划的方式不相同,MOVJ 运动模式是整个关节进行协同趋近,速度较快,但是其规划不考虑自身关节的约束,所以其规划失败率很高,在调试中采用了增加中间过度点的方式来避免这
种错误。
  在调试速度中,发现当速度过快时会出现一些坐标系漂移以及关节异响的问题,本质上仍然是关节的协同运动不协调,适当抬高起始点的高度或者降低速度解决。对于分拣点的数学表达式的拟合是通过特定数据的补偿归纳得到,其并不具有泛化使用性,但对于小数据量的表达上仍然是具有意义的。

6.2 视觉系统

  海康视觉系统的难点在于软件的陌生和相机的选型,相机和镜头的选型要考虑物料盒和视野的大小,同时要考虑成本和通信问题,在镜头的选型上要计算出相机分辨率和 FOV进行计算,同时对于定焦和变焦要考虑,在静态场景下一般选择定焦,同时仅仅测一个物件,并不需要一个变焦的镜头,对于光源的选择需要一定的光学知识和数字图像处理知识,光源是补偿图像的作用,此次的目的是进行边缘的突出,采用环形光 LED 能够满足要求,在调试的过程中,曝光时间也同样重要,调焦距和光圈让图像清晰,在曝光时间上让图像的亮度达标,使得图像处理的工作容易进行。
  在分类识别后台的设计上难点在于有效的利用图像,进行预处理,由于视野中的物料盒并不是中心矩形的排布,所以图像中的冗余信息很多,对于图像的预处理使用形态学的处理寻找轮廓是一个好的选择,类似的方法还是划定区域直方图检测等等,这样的方法仍然也用在了采集数据进行训练的过程,在特定的任务下使用特定的数据进行训练的拟合度是最高的,这种方法并不是一种投机取巧,机器视觉的任务往往就是针对特定的场景。Resnet-50 并非难点,经典的深度学习网络结构用于分类任务是特别常见的。

相关文章:

蔬菜视觉分拣机器人的设计与实现(RoboWork参赛方案)

蔬菜视觉分拣机器人的设计与实现 文章目录蔬菜视觉分拣机器人的设计与实现1. 技术栈背景2. 整体设计3. 机械结构3.1 整体结构3.2 底座结构3.3 小臂结构3.4 大臂结构3.5 负载组件结构3.6 末端执行器结构4. 硬件部分4.1 视觉系统4.1.1 光源4.1.2 海康工业相机4.2 传送带系统4.2.1…...

【LVGL移植】STM32F1基于STM32CubeMX配置硬件SPI驱动1.8寸TFT ST7735S跑LVGL图形demo

【LVGL移植】STM32F1基于STM32CubeMX配置硬件SPI驱动1.8寸TFT ST7735S屏幕跑LVGL图形demo&#x1f3ac;运行LVGL 按键组件demo ✨基于STM32CubeMX配置工程是因为方便移植&#xff0c;只要是STM32芯片&#xff0c;拿到我的这个工程源码就可以根据自己的stm32芯片&#xff0c;自…...

写给20、21级学生的话

写给20、21级学生的话前言一、关于招聘变招生&#xff0c;你怎么看&#xff1f;二、对于即将实习/已经实习的学生&#xff0c;你有什么建议&#xff1f;1.学习方面2.提升方面三、思想成年真的很重要前言 最近&#xff0c;有一些同学遇到的实习问题&#xff0c;我统一回复下&…...

功能测试用例多次录制后,我丢掉了selenium,选择龙测AI-TestOps云平台

目录一、如何使用龙测AI-TestOps云平台1、进入龙测AI-TestOps云平台2、新建项目3、新建流程图4、创建任务5、查看任务状态6、查看报告、图片7、下载流程图、测试报告、excel用例二、龙测AI-TestOps云平台AI功能介绍1、NLP2、视频AI转流程图三、总结功能测试用例多次录制后&…...

【C++知识点】C++20 常用新特性总结

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4da;专栏地址&#xff1a;C/C知识点 &#x1f4e3;专栏定位&#xff1a;整理一下 C 相关的知识点&#xff0c;供大家学习参考~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;…...

数据库体系结构概念--集中式数据库、分布式数据库

数据库模式 前言&#xff1a; 平时我们接触的‘数据库’一般指的是DBMS&#xff0c;数据库管理系统&#xff0c;DBMS是软件如&#xff1a;mysql、oracle、dm等等都是集中式数据库&#xff0c;但它们不能代表整个数据库&#xff0c;只是通过这些软件来管理相应的数据内容&#…...

PyQt5数据库开发2 5.2 QSqlRelationalTableModel

目录 一、Qt窗体设计 1. 新建Qt项目 2. 添加组件 3. 添加资源 4. 添加Action 5. 添加工具栏 6. 添加菜单项 7. 添加退出功能 二、SQL Server下建表插数据 1. 建立表 2. 插入数据 3. 单表数据 4. 联合查询 三、代码实现 1. 新建项目目录 2. 编译窗体文件和资…...

树莓派——智能家居第一步

辛辛苦苦配了成功让树莓派开始工作了&#xff0c;开始搞智能家居&#xff01;大体思路&#xff1a;基于工厂模式&#xff0c;分模块来实现上图分为三部分&#xff1a;主控、外设、控制主控我采用的是树莓派的4b4G版本&#xff0c;外设包括四个区域的灯&#xff08;我的和上图有…...

【Golang】Golang基础入门级教程 -- 0基础安装搭建Go语言开发环境

目录 安装和下载GO语言 下载 下载地址 版本的选择 安装 Windows安装 Linux下安装 Mac下安装 检查 GOROOT和GOPATH GOPROXY Go开发编辑器 VS Code介绍 下载与安装 配置 Go扩展 第一个Go程序 Hello World go mod init 编写 编译 VSCode切换默认终端 本篇文章…...

MATLAB | 如何解决实验数据散点图重叠问题(overlap)

本期部分实验效果&#xff1a; 这期讲一下如果数据重合严重该咋办(overlap)&#xff0c;事先说明&#xff0c;本文中的绘图均使用一个几行的简单小代码进行了修饰&#xff1a; function defualtAxes axgca;hold on;box on ax.XGridon; ax.YGridon; ax.XMinorTickon; ax.YMinor…...

Kubernetes 一键部署利器:kubeadm

文章目录集群部署痛点kubeadm 的工作原理kubeadm init 的工作流程kubeadm join 的工作流程kubeadm 的部署配置参数集群部署痛点 Kubernetes 的部署一直以来都是挡在初学者前面的一只“拦路虎”。尤其是在 Kubernetes 项目发布初期&#xff0c;它的部署完全要依靠一堆由社区维护…...

[jS 事件循环理解] 主线程 宏任务 微任务 - 执行顺序优先级理解

最近看了一个帖子 事件循环机制-宏任务-微任务 把js单线程中 , 主线程 | 宏任务 | 微任务 的调用顺序讲解的很直白精巧 , 记录一下以供查阅 1.主线程, 可以理解为从上到下顺序执行的一个js线程 2. 宏任务 script / setTimeOut /setInterval等 3. 微任务主要有promise等 4. 热…...

顺序表和链表的比较

这两个结构各有优势&#xff0c;相辅相成。 顺序表&#xff1a; 优点&#xff1a; 1.支持随机访问。 2.CPU高速缓存命中率更高。(物理空间连续) 缺点&#xff1a; 1.头部和中部插入和删除时间效率低(O(n))。 2.连续的物理空间&#xff0c;空间不够后需要增容&#xff1a…...

Java为什么只能单继承???

目录 先屡清楚继承和实现的区别&#xff1a; 分析原因&#xff1a; 多继承虽然能使子类同时拥有多个父类的特征&#xff0c;但是其缺点也是很显著的&#xff0c;主要有两方面&#xff1a; (1)如果在一个子类继承的多个父类中拥有相同名字的实例变量&#xff0c;子类在引用该…...

数据安全-分类分级 调研分析报告

目录 前言一、数据分类分级概述1.数据分类2.数据分级二、数据分类分级原则三、数据分类分级的框架和方法1.数据分类分级的框架2.分类标准分类常见的方法2.1 MECE2.2 线分法和面分法及混合分法2.3 数据主题域2.4 技术选型维度2.5 以业务应用维度2.6 信息安全隐私方面的分类法3.分…...

浏览器对象详解

文章目录浏览器对象详解一、参考资料二、认识浏览器运行态下的 js1.问&#xff1a;是否了解浏览器的执行态&#xff08;分层设计&#xff09;&#xff1f;2.BOM1.[location](https://developer.mozilla.org/zh-CN/docs/Web/API/Location)拓展方向&#xff1a;2.[History](https…...

异步电路后端实现流程(cdc signOff 后端做什么)

一种后端异步电路的signOff流程同步电路和异步电路分别signOff对于同步电路&#xff0c;后端会分析sta setup/hold&#xff0c;这里不在赘述。在该scenario下 异步电路是不会分析&#xff0c;也不会关注异步电路之间的走线在cdc scenario(mode)下sdc有一下设置&#xff1a;将所…...

Linux网络编程实战介绍

文章目录 前言一、Linux网络编程介绍二、文章目录总结前言 本专栏将为大家讲解Linux网络编程的知识,本专栏只需要有C语言基础即可学习,学习本专栏将大大提高你的C语言水平,当然了我也还会在ARM板子上进行实验将Linux驱动也和网络编程联系起来,方便大家去实现自己的项目。我…...

C++概述 课堂笔记

函数的重载在C语言中函数名是唯一的&#xff0c;不可以重复定义&#xff0c;当我们利用函数执行&#xff0c;功能相似的函数&#xff0c;我们也不能使用同一个函数&#xff0c;比如说&#xff0c;求整型的函数&#xff0c;不能用来求浮点型、字符型。在C中引入函数重载的概念&a…...

一文读懂SpringBoot整合Elasticsearch(一)

&#xff08;本篇文章主要介绍Spring Boot如何整合Elasticsearch&#xff0c;包括基本配置、数据操作、搜索功能等方面。&#xff09; 一、前言 Elasticsearch是一款全文搜索引擎&#xff0c;可用于快速、准确地存储、搜索和分析大量数据。而Spring Boot是一款快速开发框架&a…...

(数论)(枚举)(前缀和)1230. K倍区间

目录 题目链接 一些话 切入点 流程 套路 ac代码 题目链接 1230. K倍区间 - AcWing题库 &#xff5e;数&#xff5e;啦&#xff01;我草&#xff0c;又~在&#xff5e;水&#xff5e;字&#xff5e;数&#xff5e;啦&#xff01;我草&#xff0c;又~在&#xff5e;水&…...

万字带你深入理解 Linux 虚拟内存管理(下)

接上文&#xff1a;万字带你深入理解 Linux 虚拟内存管理&#xff08;上&#xff09; 6. 程序编译后的二进制文件如何映射到虚拟内存空间中 经过前边这么多小节的内容介绍&#xff0c;现在我们已经熟悉了进程虚拟内存空间的布局&#xff0c;以及内核如何管理这些虚拟内存区域&…...

【iOS】—— JSONModel源码学习

JSONModel 文章目录JSONModel关于JSONModel的用法initWithDictionary等方法load方法实现load方法调用时机init方法__setup__方法__inspectProperties:方法__doesDictionary方法__importDictionary方法关于JSONModel的用法 可以参考之前写的博客&#xff1a;【iOS】—— JSONMo…...

单片机怎么实现真正的多线程?

所谓多线程都是模拟的&#xff0c;本质都是单线程&#xff0c;因为cpu同一时刻只能执行一段代码。模拟的多线程就是任务之间快速切换&#xff0c;看起来像同时执行的样子。据说最近有多核的单片机&#xff0c;不过成本应该会高很多。对于模拟的多线程&#xff0c;我知道的有两种…...

【LeetCode】剑指 Offer(23)

目录 题目&#xff1a;剑指 Offer 46. 把数字翻译成字符串 - 力扣&#xff08;Leetcode&#xff09; 题目的接口&#xff1a; 解题思路&#xff1a; 代码&#xff1a; 过啦&#xff01;&#xff01;&#xff01; 写在最后&#xff1a; 题目&#xff1a;剑指 Offer 46. 把…...

[免费专栏] 汽车威胁狩猎之不应该相信的几个威胁狩猎误区

也许每个人出生的时候都以为这世界都是为他一个人而存在的&#xff0c;当他发现自己错的时候&#xff0c;他便开始长大 少走了弯路&#xff0c;也就错过了风景&#xff0c;无论如何&#xff0c;感谢经历 汽车威胁狩猎专栏长期更新&#xff0c;本篇最新内容请前往&#xff1a; …...

LinuxFTP文件传输服务和DNS域名解析服务

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a;小刘主页 ♥️每天分享云计算网络运维课堂笔记&#xff0c;努力不一定有收获&#xff0c;但一定会有收获加油&#xff01;一起努力&#xff0c;共赴美好人生&#xff01; ♥️夕阳下&#xff0c;是最美的绽放&#xff0…...

二叉搜索树原理及底层实现

二叉搜索树BST 概念 二叉搜索树又称二叉排序树&#xff0c;它可以是一棵空树&#xff0c;或者是具有以下性质的二叉树&#xff1a;若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值&#xff1b;若它的右子树不为空&#xff0c;则右子树上所有节点的值都…...

python自动化办公(一)

本文代码参考其他教程书籍实现。 文章目录文件读写open函数读取文本文件写入文本文件文件和目录操作使用os库使用shutil库文件读写 open函数 open函数有8个参数&#xff0c;常用前4个&#xff0c;除了file参数外&#xff0c;其他参数都有默认值。file指定了要打开的文件名称&a…...

LeetCode - 198 打家劫舍

目录 题目来源 题目描述 示例 提示 题目解析 算法源码 题目来源 198. 打家劫舍 - 力扣&#xff08;LeetCode&#xff09; 题目描述 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装…...