APP下载

基于机器视觉的智能物流搬运机器人的设计与研究*

2024-03-08张兴华

南方农机 2024年5期
关键词:右转左转摄像头

张兴华

(广东白云学院智能制造工程学院,广东 广州 510450)

0 引言

第七届全国大学生工程训练综合能力竞赛智能+赛道试题,要求智能物流搬运机器人能够通过扫描二维码、条码或通过Wi-Fi 网络通信等方式领取搬运或放置任务,在指定的工业场景内行走、避障,具有物料位置和颜色识别、物料抓取与载运、路径规划等功能,应按任务要求将物料搬运至指定地点并精准摆放。

任务执行过程描述如下:将机器人放置在出发区,抽签确定物料的搬运顺序任务码和在原料区的摆放顺序。任务编码被设置为1(红)、2(绿)、3(蓝)三个数字的组合,两组三位数之间以+号连接,如213+321。同一场次的任务相同。

机器人移动到二维码显示板前读取二维码,获得所需要搬运物料的搬运顺序(例如:213+321)。这是机器人在最后一个工位的物料摆放样式,如图1所示。

图1 物料摆放样式任务码

机器人到达原料区,从原料区取料,如果看到了如图2 所示的原材料摆放样式,要按照2、1、3 的顺序,即按照绿色、红色、蓝色的顺序取货和摆货。机器人行驶至粗加工区,将携带的物料按照任务码的顺序放置到对应的色环上,即按绿、红、蓝的顺序放置在粗加工区。然后再按绿、红、蓝的顺序将物料依次摆放在半成品区的上层。

图2 原材料摆放样式

1 系统硬件设计

机器人3D 图如图3 所示。车轮采用MECANAM轮,这种车轮可以通过控制车轮的转动方向与转速实现水平左右移动车体的动作[1-10]。整个系统包含了5 个部分:电源部分、主控板模块、OpenMV4 视觉模块、舵机驱动模块、直流电动机驱动部分。机器人使用Arduino Mega 2560 单片机作为主控电路板,使用的OpenMV4 视觉模块如图4 所示。实现视觉追踪与距离检测,由Mega 2560 扩展板(图5)按照Mega 2560 接线图(图6),分别接在两个直流电机驱动模块TB6612FNG(图7)的AIN1、AIN2 和BIN1、BIN2。16 路舵机驱动板PCA9685(图8)驱动4 个舵机的关节型机械臂,实现目标物体的抓取和放置,用两个电压转换模块将电源电压7.4 V转换为5 V和3.3 V。

图3 麦克纳姆轮四轮驱动机器人

图4 OpenMV4 视觉模块

图5 Mega 2560扩展板实物图

图6 Mega 2560单片机接线图

图7 TB6612FNG电机驱动模块接线图

图8 16路舵机驱动板PCA9685

2 搬运算法设计

搬运场地如图9 所示,机器人从右上角出发向前行驶,机器人底部前沿的光电传感器寻找到第三条黑线,暂停行走,摄像头右转90°,扫描二维码,如果二维码的第一个数字为2,就要先搬运绿色物料,向前行进三条线即900 mm 到达原材料区,摄像头寻找绿色物料,此时可能有三种情况:

图9 搬运场地图

1)如果摄像头看到的绿色物料在镜头左边,机械臂左转30°,下去取料。

2)如果摄像头看到的绿色物料在镜头中间,机械臂直接下去取料。

3)如果摄像头看到的绿色物料在镜头右边,机械臂右转30°,下去取料。

然后机器人向左平移,小车底盘下中心位置的传感器如果检测到第三条黑线,说明小车已经左移了900 mm, 到达粗加工区。摄像头左转90°,机械臂左转90°,因为此时搬运的是绿色物料,所以机械臂腰关节右转30°。把绿色物料放下,然后机械臂复位。小车继续向左平移2 格黑线即600 mm 的距离,然后小车后退3 格的距离,来到半成品区,机械臂和摄像头左转90°,把绿色物料摆放在上层左边位置。然后小车前进3 格的距离,再向右平移6 格的距离,到达原料区,摄像头和机械臂右转90°。寻找第二个目标工件蓝色物料,此时可能有三种情况:

1)如果摄像头看到的蓝色物料在镜头左边,机械臂左转30°,下去取料。

2)如果摄像头看到的蓝色物料在镜头中间,机械臂直接下去取料。

3)如果摄像头看到的蓝色物料在镜头右边,机械臂右转30°,下去取料。

然后搬运1 号物料,即红色物料,完成后搬运3号物料,即蓝色物料,完成后,重复执行以上算法,就可以完成6 个物料在原料区的取料、粗加工区的放置、半成品区的摆放。

麦克纳姆轮机器人编写的运动控制函数如下:

char inverse_left = 1; char inverse_right = 0; char

inverse_left2 = 1; char inverse_right2 = 0;

int left_speed; int right_speed; int left_speed2; int

right_speed2;

#define PWMA 12 //A电机转速

#define DIRA1 34

#define DIRA2 35 //A电机方向

#define PWMB 8 //B电机转速

#define DIRB1 37

#define DIRB2 36 //B电机方向

#define PWMC 9 //C电机转速

#define DIRC1 43

#define DIRC2 42 //C电机方向

#define PWMD 5 //D电机转速

#define DIRD1 A4 //26 V1.0 版本

#define DIRD2 A5 //D 电机方向27 V1.0版本

#define MOTORA_FORWARD(pwm)

do{digitalWrite(DIRA1,LOW);

digitalWrite(DIRA2,HIGH);analogWrite(PWMA,p

wm);}while(0)

#define MOTORA_STOP(x)

do{digitalWrite(DIRA1,LOW);

digitalWrite(DIRA2,LOW);

analogWrite(PWMA,0);}while(0)

#define MOTORA_BACKOFF(pwm)

do{digitalWrite(DIRA1,HIGH);digitalWrite(DIRA2,L

OW); analogWrite(PWMA,pwm);}while(0)

#define MOTORB_FORWARD(pwm)

do{digitalWrite(DIRB1,HIGH);

digitalWrite(DIRB2,LOW);analogWrite(PWMB,p

wm);}while(0)

#define MOTORB_STOP(x)

do{digitalWrite(DIRB1,LOW);

digitalWrite(DIRB2,LOW);

analogWrite(PWMB,0);}while(0)

#define MOTORB_BACKOFF(pwm)

do{digitalWrite(DIRB1,LOW);digitalWrite(DIRB2,HI

GH); analogWrite(PWMB,pwm);}while(0)

#define MOTORC_FORWARD(pwm)

do{digitalWrite(DIRC1,LOW);

digitalWrite(DIRC2,HIGH);analogWrite(PWMC,p

wm);}while(0)

#define MOTORC_STOP(x)

do{digitalWrite(DIRC1,LOW);

digitalWrite(DIRC2,LOW);

analogWrite(PWMC,0);}while(0)

#define MOTORC_BACKOFF(pwm)

do{digitalWrite(DIRC1,HIGH);digitalWrite(DIRC2,L

OW); analogWrite(PWMC,pwm);}while(0)

#define MOTORD_FORWARD(pwm)

do{digitalWrite(DIRD1,HIGH);

digitalWrite(DIRD2,LOW);analogWrite(PWMD,p

wm);}while(0)

#define MOTORD_STOP(x)

do{digitalWrite(DIRD1,LOW);

digitalWrite(DIRD2,LOW);

analogWrite(PWMD,0);}while(0)

#define MOTORD_BACKOFF(pwm)

do{digitalWrite(DIRD1,LOW);digitalWrite(DIRD2,HI

GH); analogWrite(PWMD,pwm);}while(0)

int pwm_a = 0; int pwm_b = 0; int pwm_c = 0; int

pwm_d = 0;

void run(int left_speed, int right_speed) {

if (inverse_left == 1) left_speed = (-left_speed);

if (inverse_right == 1) right_speed = (-right_speed);

if (left_speed < 0) {

pwm_a = abs(left_speed);

MOTORA_FORWARD(pwm_a);

}

else {

pwm_a = abs(left_speed);

MOTORA_BACKOFF(pwm_a);

}

if (right_speed < 0) {

pwm_b = abs(right_speed);

MOTORB_BACKOFF(pwm_b);

}

else {

pwm_b = abs(right_speed);

MOTORB_FORWARD(pwm_b);

}

}

void run2(int left_speed2, int right_speed2) {

if (inverse_left2 == 1) left_speed2 = (-left_speed2);

if (inverse_right2 == 1) right_speed2 = (-right_

speed2);

if (left_speed2 < 0) {

pwm_c = abs(left_speed2);

MOTORC_FORWARD(pwm_c); }

else {

pwm_c = abs(left_speed2);

MOTORC_BACKOFF(pwm_c); }

if (right_speed2 < 0) {

pwm_d = abs(right_speed2);

MOTORD_BACKOFF(pwm_d); }

else {

pwm_d = abs(right_speed2);

MOTORD_FORWARD(pwm_d);

}

}

Void strafe_left() { run(-32, 32);

run2(32, -32);}

void strafe_right() { run(32, -32);

run2(-32, 32);}

OpenMV 串口通信程序:

import sensor, image, time

import json

from pyb import UART

sensor.reset() # Initialize the camera sensor.

sensor.set_pixformat(sensor.RGB565)

sensor.set_framesize(sensor.QQVGA)

sensor.skip_frames(10) # Let new settings take #affect.

sensor.set_auto_whitebal(False) # turn this off.

clock = time.clock() # Tracks FPS.

uart = UART(3, 19200)

while(True):

clock.tick() # milliseconds snapshots().

img = sensor.snapshot() # Take a picture

img.lens_corr(1.5)

for code in img.find_qrcodes():

message = code.payload()

uart.write(message)

print(code)

else:print(“not found!”)

Mega 2560端的串口通信程序设计:

void setup( ) { Serial.begin(19200);

pinMode(7, OUTPUT);}

void loop( ){

if(Serial.available()){

Serial.write(Serial.read()); }}

3 结论

经实际测试,搬运机器人能高质量地完成搬运任务。

猜你喜欢

右转左转摄像头
交叉口借道左转方案的交通安全仿真研究
浙江首试公路非现场执法新型摄像头
基于车流拥挤检测的“借道左转”自适应智能控制*
日出(外一首)
摄像头连接器可提供360°视角图像
不能左转
基于车让人的右转专用相位设置条件研究
道路交叉口“借道左转”的优化控制
基于太赫兹技术的新一代摄像头及其在安防领域的应用探讨
基于农村主路交叉路口优先右转汽车的碰撞预警系统初步设计