0


机器人制作开源方案 | 智能捡球机器人

作者:王梦荷、范永、全冰艳、李华良、周勍

单位:江汉大学

指导老师:张朝刚

  随着服务类机器人技术研究及应用的不断发展,服务机器人在文体领域的应用需求开始呈现并成为研究热点之一。本项目设计的智能捡球机器人正是顺应这些需求,能够很好的代替人去进行枯燥重复的捡球动作,高效率捡球的同时尽可能解决卡球、伤球的问题,减轻人力负担,相信会有广阔的发展应用前景。

  **关键字:**捡球机器人、超声波测距模块、机械臂、NRF模块

**1. 场景调研 **

**1.1 研究背景 **

  随着体育强国战略的深化,越来越多的人参与到文体活动中来。在球类训练中,球的使用量非常大,频繁捡起随机掉落在大范围内的球是一件耗时耗力的工作,因此高效的智能捡球机器人会为训练者提供时间,节省时间。而且频繁的捡球在日常的球类运动中,也会降低运动的趣味性,且伴随着中国乒乓球队不断取得了优异成绩,吸引着越来越多的人加入到球类运动中来,捡球机器人潜力巨大。

**1.2 国内外研究现状 **

  目前针对小球类物体捡拾机器人的研究成果比较少,国外研究的单位有西班牙University of Minho、美国MIT、英国University of Bradford和荷兰Vrije University等,国内研究单位主要有上海交通大学、东南大学、北京邮电大学、北京理工大学等,研制的机器人主要有高尔夫球、网球、乒乓球和羽毛球等捡拾机器人,按照捡拾工作原理不同可分为机械手式、组合式、清扫式、气吸式、辊轮式、滚筒式和弹簧式等捡拾机器人。

  人工智能应用于文体领域的相关研究刚刚兴起,前人对于捡球机器人的研究工作相对较少。国内对于捡乒乓球机器人的研究还在起步阶段,没有成熟的系统成果,目前的研究主要集中于机器人的机械结构设计和乒乓球的检测识别等几个方面。在捡球机器人这一大类中,国内对于捡网球机器人的研究较多,方向大多集中在机械臂的设计机器视觉和路径规划几个方面,研究内容更多的是球和障碍物的识别分类、路径的选择以及运动控制[1]。

**2. 机器人本体设计 **

**2.1 机器人本体结构 **

  机械结构的设计是探索者机器人,能做出设计者所想功能的基础,此款机器人为智能捡球机器人,可以用于解决体育运动结束后,乒乓球等球散落一地的混乱情景,可以大大降低在乒乓球训练过程中因工人捡球而造成的效率低下等问题。本项目所设计的智能捡球机器人整体结构小巧、灵活多变,主要由机械手臂、超声波测距模块、驱动轮组、收纳盒等构成。机器人正前方有一个超声波测距模块,用来感测小球方位,以及实现对球与小车距离的调整,超声波测距模块的正上方安装一条灵活多变的机械手臂,用于实现对乒乓球等球类的灵活抓取,同时小车后方安装一个收纳盒,用于存放已拾起的小球。

**2.2 机器人本体技术路线 **

  本项目设计的智能捡球机器人采用超声波自主识别为主,遥控为辅。

  首先采用超声波测距模块进行小球位置的识别,通过超声波测距模块感测小车四周是否有球,当检测到多个方向有球时,小车会根据超声波测距模块传输回的不同方向的距离参数,按设定的程序,控制小车的两前轮向着距小车最近的小球行驶(先根据回传的最近的距离参数,粗略计算判断小车行驶到小球附近所需的时间,使小车运行相应时间后,再根据超声波测距模块测得的实时距离进行适当的调整),当小车(小车上的超声波测距模块)与小球之前的距离达到我们设定的一个可以捡球的范围时,触发机械臂夹取小球,捡起小球后,通过机械臂的旋转以及机械臂夹子的张开,小球掉落进小车后方的收纳盒里。

  同时采用NRF模块堆叠Birdmen手柄扩展板,再加上Barsa板,组成一个遥控器,导入相应的程序,可通过遥控器控制小车的两后轮运动。当小车在捡球过程中突发意外时,可以通过遥控器对小车的运动路径进行调整。

3. 作品创新点

**3.1 可实现遥控控制 **

  本作品在设计好捡球代码并调试完成之后,又进一步采用了NRF模块堆叠Birdmen 手柄扩展板,再加上Barsa板,组成一个遥控器,在环境干扰较大以及捡球过程中遇到突发意外时,可以通过遥控器对机器人进行控制,调整机器人的运动,保证捡球工作的正常进行。

**3.2 灵活多变的机械臂 **

  在机器人设计的过程中,采用了4个舵机相连的结构,增加了手臂的灵活性,由中间的大舵机作为旋转轴,使得手臂可以180°旋转如下图所示,简便快捷地进行了夹球和放球的步骤。

3.3 稳定抓球的盒状夹子

  在传统的夹子上,本作品进行了新的改进(如下图所示),我们称呼它为**盒状夹子**,能够很好地包裹住小球,有效防止因小球过于光滑而无法夹起或在运输途中的意外掉落的情况,也不会夹伤球(使球变形)。

4. 示例程序

#include <Servo.h>

#include<stdio.h>

#include<stdlib.h>

Servo a1,a2,a3,a4;   

int a1pos;

int a2pos;

int a3pos;

int a4pos;

float t;

#define ECHOPIN 14

#define TRIGPIN 15

void setup()

{

  a1.attach(3);

  a2.attach(8);

  a3.attach(12);

  a4.attach(4);

  pinMode(ECHOPIN, INPUT);

  pinMode(TRIGPIN, OUTPUT);

  pinMode( 10, OUTPUT); //将引脚10设置为输出模式

  pinMode( 9, OUTPUT);   //将引脚9设置为输出模式

  pinMode( 6, OUTPUT); //将引脚6设置为输出模式

  pinMode( 5, OUTPUT);   //将引脚5设置为输出模式

  Serial.begin(9600);

}

float Measure()

{

  digitalWrite(TRIGPIN, LOW);

  delayMicroseconds(2);

  digitalWrite(TRIGPIN, HIGH);

  delayMicroseconds(10);

  digitalWrite(TRIGPIN, LOW);

  float distance = pulseIn(ECHOPIN, HIGH);

  distance= distance/58;

  Serial.println(distance);

  return distance;

}

void Right()

{

  analogWrite(9 , 0);      //前进

  analogWrite(5, 0);       

analogWrite(10 , 180);     

  analogWrite(6 , 255 );

    delay(500);

}

void Left()

{

    analogWrite(9 , 0);     

  analogWrite(5, 0);       

analogWrite(10 , 255);     

  analogWrite(6 , 180 );

    delay(500);

}

void Move()

{

  int distance;

  t=(distance-9.0)/25.0;

  analogWrite(9 , 0);     

  analogWrite(5, 0);       

  analogWrite(10 , 180);     

  analogWrite(6 , 180);

   delay( t );

   digitalWrite(TRIGPIN, LOW);

  delayMicroseconds(2);

  digitalWrite(TRIGPIN, HIGH);

  delayMicroseconds(10);

  digitalWrite(TRIGPIN, LOW);

  distance = pulseIn(ECHOPIN, HIGH);

  distance= distance/58;

  Serial.println(distance);

   if(distance>8.50&&distance<15.00)

  {

  analogWrite(9 , 0);     

  analogWrite(5, 0);       

  analogWrite(10 , 180);     

  analogWrite(6 , 180);

    delay( 1 );

    digitalWrite(TRIGPIN, LOW);

  delayMicroseconds(2);

  digitalWrite(TRIGPIN, HIGH);

  delayMicroseconds(10);

  digitalWrite(TRIGPIN, LOW);

  distance = pulseIn(ECHOPIN, HIGH);

  distance= distance/58;

  Serial.println(distance);

  }

if(distance<7.50)

{

  analogWrite(9 , 160);     

  analogWrite(5, 160);

  analogWrite(10 , 0);     

  analogWrite(6 , 0);

  delay( 2 );

  digitalWrite(TRIGPIN, LOW);

  delayMicroseconds(2);

  digitalWrite(TRIGPIN, HIGH);

  delayMicroseconds(10);

  digitalWrite(TRIGPIN, LOW);

  distance = pulseIn(ECHOPIN, HIGH);

  distance= distance/58;

  Serial.println(distance);

  }

if(distance>7.50&&distance<8.50)

{

  digitalWrite( 9 ,HIGH );   

  digitalWrite( 5, HIGH );  

  digitalWrite( 10 ,HIGH );  

  digitalWrite( 6 , HIGH );

  delay( 5000 );

  }

}

void Catch()

{

  for(a3pos=120;a3pos>50;a3pos-= 1)  

  {                               

    a3.write(a3pos);           

    delay(30);                 

  }

  for(a1pos =100;a1pos <160; a1pos+=1)     

  {                               

    a1.write(a1pos);         

    delay(30);         

  }

    for(a3pos=50 ;a3pos <120; a3pos+=1)

  {                               

    a3.write(a3pos);         

    delay(30);               

  }

    for(a2pos=210;a2pos>0;a2pos-= 1)  

  {                           

    a2.write(a2pos);         

    delay(30);                 

  }

  for(a1pos =160;a1pos>100;a1pos-= 1)

  {                               

    a1.write(a1pos);             

    delay(30);               

  }

  for(a2pos=0;a2pos<210;a2pos+= 1)  

  {                           

    a2.write(a2pos);         

    delay(30);                 

  }

}

void loop()

{

  a1.write(100);

  a2.write(210);

  a3.write(120);

  a4.write(75);

  delay(1000);

  int distance;

  Measure();

  int dis1=distance;

  delay(1000);

  for(a4pos=75;a4pos>45;a4pos-=1)

  {

    a4.write(a4pos);             

    delay(30);

  }

  Measure();

  int dis2=distance;

  delay(1000);

  for(a4pos=45;a4pos<105;a4pos+=1)

  {

    a4.write(a4pos);             

    delay(60);

  }

  Measure();

  int dis3=distance;

  delay(1000);

  for(a4pos=105;a4pos>75;a4pos-=1)

  {

    a4.write(a4pos);             

    delay(30);

  }

  if(dis1<dis2&&dis1<dis3)

  {

    distance=dis1;

    Move();

    Catch();

  }

  else if(dis2<dis1&&dis2<dis3)

  {

    distance=dis2;

    Right();

    Measure();

    Catch();

  }

  else if(dis3<dis1&&dis3<dis2)

  {

    distance=dis3;

    Left();

    Measure();

    Catch();

  }

}

**5. 作品难点及解决方案 **

**5.1 小球的识别 **

  在使用超声波识别球类物体进行捡球时,通常会有距离难以调整,角度难以控制的问题,以及在其他物体出现干扰时,往往会出现识别错误导致捡球失误等的问题,因此我们提出了以下方案:以超声波自主识别为主要方式,摇杆为辅。

  当场地空旷且无较大干扰因素时,可以采用超声波自主识别进行捡球。该模式可以实现超声波扫描三个方向,根据就近原则,选择离小车最近的球并智能调整距离,调整到合适范围后机械臂自动夹球,以此减少人力的消耗。

  在各种适宜小车运动的情况下,我们皆可以采用摇杆控制小车的前进与转向。且在小车在捡球过程中突发意外时,也可以通过遥控器对小车的运动路径进行调整。

**5.2 小球的抓取 **

  传统的夹子会有掉球、伤球等问题。所以我们对夹子进行了改良,将其体积扩大,做成了盒子的形状,夹取小球时相当于将球“装入了”夹子中,将球整个包裹到夹子中,以此来达到不卡球、伤球的目的。

**6. 简述与总结 **

  本项目机器人是基于探索者机器人的零件套件,加上硬纸板等,加以设计拼接所得到的捡球机器人。主要使用solidworks完成机器人的建模,使用Arduino来编写程序,控制机器人的走动及捡球等动作。机器人采用超声波测距模块捕获球体目标及感知环境,用机械臂实现球类的抓取,以及对传统的夹子进行了改良,将其做成“盒状”,达到不卡球、不伤球,在突发情况下还可通过遥控手柄调整小车运动路径。

参考文献

[1]任云青.智能乒乓球自动捡球机器人的设计与实现[A]. 硕士电子期刊出版,2021:10-11.

更多详情请见:【S060】智能捡球机器人


本文转载自: https://blog.csdn.net/Robotway/article/details/135727546
版权归原作者 Robotway 所有, 如有侵权,请联系我们删除。

“机器人制作开源方案 | 智能捡球机器人”的评论:

还没有评论