本文素材来源于物理与电子电气工程学院
作者:丁文龙 、王小军、任剑杰、张钊铭
指导老师:康彩
一、项目简介
随着人们对机器人技术智能化本质认识的加深,机器人技术开始源源不断地向人类活动的各个领域渗透。在这其中,服务机器人作为一个重要分支,在国内外研究领域已经得到普遍重视。服务机器人的应用范围很广,主要从事维护保养、修理、运输、清洗、保安、救援、监护等工作。但至目前为止,乒乓球捡拾器在国内外市场上的发展却较为滞后。文中所述的智能捡乒乓球机器人,正是一种应用于兵乓球体育赛事的自主式移动的服务机器人。智能捡乒乓球机器人可以应用在业余或专业的乒乓球训练基地或训练学校,使用智能捡乒乓球机器人可以减轻训练人员回收乒乓球的负担,能够减少训练时的无效训练时间,提高运动员的训练效率,使运动员可以更好的投入到专业的训练当中,从而取得更好的比赛成绩。
智能捡乒乓球机器人利用OpenMV对乒乓球进行定位,接着机器人接收到乒乓球的位置前往捡球,到达位置时,升降台降下捡球筐,利用捡球筐底部弹簧,对乒乓球进行拾取,完成捡球。
本项目涉及机械设计、Solidworks、机械原理等知识以及自动化、传感器、图像处理等先进技术,在实际中应用了Solidworks三维构图,Arduino编程、Python编程和计算机模拟的知识,是多学科综合运用的结果。
现阶段国内外捡乒乓球机器人的研究有两个方向:一是夹持式,二是吸附式。第一类中机械手的设计过于复杂,且机械手与球之间是硬接触,容易对乒乓球造成机械式的损伤。第二类比第一类在技术上更成熟,但由于在拾取后真空泵要持续工作,耗能比大,不符合当下节能减排的思想。本项目设计的机器人在灵活性与节能减排等方面都有很大的提升,经济与实用效益都非常可观。
二、开发过程
本设计完全是基于实践考虑,设计之初进行了详细的前期考察和调研;根据考察的结果制定具体的设计方案和要求,初步设计出整体的布局和结构外形; 使用计算机进行虚拟样机的仿真模拟,并优化;根据优化后的数据制作物理样机;进行捡球实验,最终确定样机形式。
(1) 前期考察调研
各大体育场馆的乒乓球训练、比赛场地进行了实地考察,了解服务人员对捡球车有什么需求和建议,对比目前在用的捡球方法和捡球器械的捡球器械的优缺点。
(2) 捡球车定型
根据考察的结果,选定本设计的捡球机器人利用升降台升降捡球筐捡球。
(3) 乒乓球捡球车的三维机构设计及优化
捡乒乓球机器人机构包括底盘的运动机构、捡球结构、储球机构,通过三维建模确定整车设计可行性,并对各零部件做出优化,最终确定整车的数据。
(4) 乒乓球捡球车运动仿真
利用SolidWorks对所建立的三维模型进行运动仿真,通过软件分析查看整车效果并做优化处理,生成最终的装配图和工程图。
(5) 调试图像识别
利用OpenMV对乒乓球进行识别,通过一定算法,确定位置。
(6) 调试超声波避障
利用超声波模块对障碍物进行避障。
(7) 调试捡球装置
利用升降台升降捡球筐捡球。
(8) 调试程序
对图像识别程序、超声波避障程序、电机驱动程序等一系列程序进行组合,构建OpenMV与Arduino之间的通信。
(9) 乒乓球捡球车的制造
根据零件图和装配图选取探索者套件,完成整机组装,并为捡球车配置整套电控系统,对组装好的捡球车进行调试。
三、程序代码
超声波避障部分代码:
const int TrigPin1 = 22; const int EchoPin1 = 23; const int TrigPin2 = 24; const int EchoPin2 = 25; const int TrigPin3 = 26; const int EchoPin3 = 27; const int TrigPin4 = 28; const int EchoPin4 = 29; const int TrigPin5 = 30; const int EchoPin5 = 31; const int leftMotor1 = 32; const int leftMotor2 = 34; const int RightMotor1 =36; const int RightMotor2 =38; int distance_cm1 = 0; int distance_cm2 = 0; int distance_cm3 = 0; int distance_cm4 = 0; int distance_cm5 = 0; void setup() { pinMode(TrigPin1,OUTPUT); pinMode(EchoPin1,INPUT); pinMode(TrigPin2,OUTPUT); pinMode(EchoPin2,INPUT); pinMode(TrigPin3,OUTPUT); pinMode(EchoPin3,INPUT); pinMode(TrigPin4,OUTPUT); pinMode(EchoPin4,INPUT); pinMode(TrigPin5,OUTPUT); pinMode(EchoPin5,INPUT); pinMode(leftMotor1, OUTPUT); pinMode(leftMotor2, OUTPUT); pinMode(RightMotor1, OUTPUT); pinMode(RightMotor2, OUTPUT); Serial.begin(9600); } void loop() { digitalWrite(TrigPin1,LOW); delayMicroseconds(2); digitalWrite(TrigPin1,HIGH); delayMicroseconds(10); digitalWrite(TrigPin1,LOW); distance_cm1 = pulseIn(EchoPin1,HIGH)/58; digitalWrite(TrigPin2,LOW); delayMicroseconds(2); digitalWrite(TrigPin2,HIGH); delayMicroseconds(10); digitalWrite(TrigPin2,LOW); distance_cm2 = pulseIn(EchoPin2,HIGH)/58; digitalWrite(TrigPin3,LOW); delayMicroseconds(2); digitalWrite(TrigPin3,HIGH); delayMicroseconds(10); digitalWrite(TrigPin3,LOW); distance_cm3 = pulseIn(EchoPin3,HIGH)/58; digitalWrite(TrigPin4,LOW); delayMicroseconds(2); digitalWrite(TrigPin4,HIGH); delayMicroseconds(10); digitalWrite(TrigPin4,LOW); distance_cm4 = pulseIn(EchoPin4,HIGH)/58; digitalWrite(TrigPin5,LOW); delayMicroseconds(2); digitalWrite(TrigPin5,HIGH); delayMicroseconds(10); digitalWrite(TrigPin5,LOW); distance_cm5 = pulseIn(EchoPin5,HIGH)/58; Serial.print(distance_cm1); Serial.print("cm"); Serial.print(" "); Serial.print(distance_cm2); Serial.print("cm"); Serial.print(" "); Serial.print(distance_cm3); Serial.print("cm"); Serial.print(" "); Serial.print(distance_cm4); Serial.print("cm"); Serial.println(" "); Serial.print(distance_cm5); Serial.print("cm\n"); delay(10); if( distance_cm3>25) { if( distance_cm1<25) { right(); delay(250);} if( distance_cm2<20) { right(); delay(200);} if( distance_cm5<25) { left(); delay(250);} if( distance_cm4<20) { left(); delay(200);} } if( distance_cm3<25) { back(); delay(250); right(); delay(250); } else { forward(); delay(50); } } void forward() { digitalWrite(leftMotor1,HIGH); digitalWrite(leftMotor2,LOW); digitalWrite(RightMotor1,HIGH); digitalWrite(RightMotor2,LOW); } void left() { digitalWrite(leftMotor1,HIGH); digitalWrite(leftMotor2,LOW); digitalWrite(RightMotor1,LOW); digitalWrite(RightMotor2,HIGH); } void right() { digitalWrite(leftMotor1,LOW); digitalWrite(leftMotor2,HIGH); digitalWrite(RightMotor1,HIGH); digitalWrite(RightMotor2,LOW); } void stop() { digitalWrite(leftMotor1,LOW); digitalWrite(leftMotor2,LOW); digitalWrite(RightMotor1,LOW); digitalWrite(RightMotor2,LOW); } void back() { digitalWrite(leftMotor1,LOW); digitalWrite(leftMotor2,HIGH); digitalWrite(RightMotor1,LOW); digitalWrite(RightMotor2,HIGH); } |
升降台部分代码:
int x; void setup() { pinMode(6,OUTPUT); pinMode(5,OUTPUT); pinMode(4,OUTPUT); digitalWrite(6,LOW); } void loop() { digitalWrite(4,HIGH); for(x = 0; x < 800; x++) { digitalWrite(5,HIGH); delayMicroseconds(1000); digitalWrite(5,LOW); delayMicroseconds(1000); } delay(100); digitalWrite(4,LOW); for(x = 0; x < 800; x++) { digitalWrite(5,HIGH); delayMicroseconds(1000); digitalWrite(5,LOW); delayMicroseconds(1000); } delay(100); } |
图像识别部分代码:
import sensor, image, time from pyb import UART yellow_threshold = (24, 100, 68, -24, 34, 86) sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.QQVGA) sensor.skip_frames(10) sensor.set_auto_whitebal(False) clock = time.clock() uart = UART(3, 115200) K=1000 while(True): img = sensor.snapshot() blobs = img.find_blobs([yellow_threshold]) if len(blobs) == 1: #if blobs: b = blobs[0] img.draw_rectangle(b[0:4]) img.draw_cross(b[5], b[6]) Lm = (b[2]+b[3])/2 length = K/Lm output_str ="%d" % (length) print('you send:',output_str) uart.write(output_str+'\n') else: print('not found!') |
智能捡乒乓球机器人的详细资料内容请参考智能捡乒乓球机器人
------------------------------------------------------- 完 ---------------------------------------------------