当前位置: 华文星空 > 知识

一个简陋的人机协作Demo

2022-02-04知识

背景

ABB今年推出了一款新的协作机器人CRB1100,这款机器人本体方面其实和传统的工业机器人是一样的,也就是IRB1100.

之所以说它是协作机器人是在机器人的前面加了一个用于检测是否有东西接近的安全激光, 这个安全激光可以设定不同的检测区域,同时监控机器人速度,位置等信息。当某些区域出现物体时,机器人的速度会降低,甚至停止,从而实现人和机器人在同一空间内工作,不需要围栏,也就是人机协作。

这项技术的应用在ABB已经有超过十年的历史,也就是所谓的SafeMove。应用这项技术,其实不管机器人是小负载的六轴机器人,还是几百公斤负载的机器人都可以允许人接近机器人,在同一空间内工作。

SafeMove - IRC5 Options (IRC5 Controller | ABB Robotics)

激光用于安全检测最普遍的还不是机械臂行业,而是移动机器人甚至是无人驾驶的汽车上。一般来说无论是SLAM还是磁导航的AGV都会配备激光传感器,检测是否有障碍物。

激光检测障碍物是目前最稳定且最成熟的安全解决方案。

另一个安全检测的解决思路是视觉,视觉的优点也很明显:相机成本更低,传递的信息更加丰富(线扫激光只有2维平面),且在极端天气下影响更小。虽然视觉精度比激光低,但是对于检测障碍物来说是够用的。

所以我尝试了用相机来搭一个简单的demo,通过检测相机视野内是否有人,然后发送给机器人。

方案

流程:1)相机不停的拍照片 2)判断图片中是否有人或者有人的身体 3)如果有人则给机器人控制器发送有人,没人则发送没人。

核心就是判断相机有没有人,这我偷了个懒,。。。。用了百度AI平台的一个多物体检测的工具,只需要把图片发到百度云上,百度会返回一个jason数据,返回图片中的有哪些物体。

因为我的目的只是判断有没有人就可以,所以不需要做目标位置检测,只需要做分类就可以。

具体例程可以参考下面的链接,多主体检测这个功能有1w次的免费检测额度。

感谢我侄子最近放暑假在我家,我看他用百度AI平台来做语音转文字,so easy。。所以我才了解到有这个工具。类似的AI平台应该很多,可以挖掘一下。

当然如果真的是用于安全检测,这种云端的方式肯定不行,需要在本地进行部署,而且相机也可能不知一个。

给机器人发送有没有人的信息用的Robotstudio来做仿真,通讯方式就是socket发送信息,所以不需要买一个机器人来实验。

RobotStudio去年免费了一年,今年还是不是免费不太确定。

实现

首先,百度AI平台需要一个鉴权认证,目的是绑定个人的账户,这样后面就知道你用了多少次他们的服务,才好收钱嘛。。。。。具体参考:

通用参考 - 鉴权认证机制 | 百度AI开放平台 (baidu.com)

''' ! Description: ! Detect person and send to robot ! Author: Kaiyuan Cao ! Version: 1.0 ''' # encoding:utf-8 import requests import base64 import pp import json import socket import cv2 #baidu鉴权认证 host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=【官网获取的AK】&client_secret=【官网获取的SK】' response = requests . get ( host ) if response : resp = response . json () access_token = resp [ 'access_token' ]

然后绑定机器人的socket端口,这里相机断作为Server,机器人端做Client, 因为我都是在本机跑的,所以IP用127.0.0.1。port随便写一个,如果和机器人连上了,打印连接的地址。

#connect robotstudio 端口 s = socket.socket() host='127.0.0.1' port=8008 s.bind((host,port)) # 绑定服务端地址和端口 s.listen(5) c, addr = s.accept() # 返回客户端地址和一个新的 socket 连接 print( 'Connected with', addr)

前面import 了cv2主要就是保存个图片用

#选择相机 cap=cv2.VideoCapture(0) i=0 message='nobody'

然后就是循环「检测-->返回检测结果-->判断检测结果-->发送给机器人」

这里相机图片1000ms才存一张,所以看起来会一卡一卡的,主要目的还是省钱。。。。减少检测的次数。。。

检测那部分就是无脑copy就可以了,百度云会返回一长串的jason数据,有兴趣可以看看,我这边只用他result部分,判断里面有没有人,以及可信度多少就可以了。

while ( 1 ): ret , frame = cap . read () cv2 . imshow ( "capture" , frame ) #保存相机图片 if ret == True : gray = cv2 . resize ( frame ,( 640 , 480 )) #图像大小为320*240 cv2 . imwrite ( 'C:/Users/CNKACAO1/Pictures/test picture/Laptop_Carema/environment.jpg' , gray ) i += 1 cv2 . waitKey ( 1000 ) #不断刷新图像,刷新频率1000ms # 二进制方式打开图片文件 f = open ( 'C:/Users/CNKACAO1/Pictures/test picture/Laptop_Carema/environment.jpg' , 'rb' ) img = base64 . b64encode ( f . read ()) #人体检测 request_url = "https://aip.baidubce.com/rest/2.0/image- classify/v2/advanced_general" params = { "image" : img } request_url = request_url + "?access_token=" + access_token headers = { 'content-type' : 'application/x-www-form-urlencoded' } response = requests . post ( request_url , data = params , headers = headers ) if response : result = response . json () . get ( 'result' ) for object in result : if object . get ( 'root' ) == '人物-人物特写' and ( object . get ( 'score' ) > 0.4 ): #如果有人message置1 message = 'Somebody' break else : message = 'Nobody' #如果没人message置0 c . send ( message . encode ( "utf-8" )) #发送给robotstudio print ( message ) print ( result )

实际跑下来,如果人在屏幕中占比比较大的情况下检测效果还是非常不错的,而人一旦比较远就会出现检测不到人的情况,而如果只出现人的一些部位,比如手掌,也可以检测出来,毕竟不是专门用来做人体检测的工具,跑个demo效果还不错。

在robotstudio端需要设置一下socket接口,这里要注意的是,在配置系统的时候,需要在pc-interface这个选项上打勾才能使用socket。

ABB 机器人里用的是rapid语言, 主要是创建一个socket接口,连接一下,然后就等着接收数据。

MODULE Module1 !*********************************************************** ! ! Module : Module1 ! ! Description : ! < Insert description here > ! ! Author : Kaiyuan Cao ! ! Version : 1.0 ! !*********************************************************** !*********************************************************** ! ! Procedure main ! ! This is the entry point of your program ! !*********************************************************** PROC main () VAR socketdev socket1 ; VAR string receive_string ; SocketClose socket1 ; SocketCreate socket1 ; SocketConnect socket1 , "127.0.0.1" , 8008 ; TPWrite "CONNECTED" ; WHILE TRUE DO SocketReceive socket1 \ Str : = receive_string ; TPWrite receive_string ; ENDWHILE ENDPROC ENDMODULE

实际跑下来效果还可以

我用的是我的笔记本摄像头,也不知道为什么会有0.35的score检测到美女,So stupid。。。。

这个demo基本就到这里了。。。

简陋 但是胜在不需要花钱。。。