极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1656|回复: 0

机器人制作开源方案 | 网球自动拾取机

[复制链接]
发表于 2023-11-27 13:08:28 | 显示全部楼层 |阅读模式
本帖最后由 机器谱 于 2023-11-27 13:08 编辑

作者:柳文浩、李浩杰、苏伟男、贾思萌、张天芸
单位:西安外事学院
指导老师:胡宝权、陈小虎

1. 产品说明
1.1 设计目的
       近年来,网球运动越来越受到老百姓的欢迎,各种规模的比赛层出不穷。然而由于网球运动极为激烈,运动过程中需要大量的跑动,运动员的体力消耗较大,因此人们在运动时,往往会多带一些网球以节省体力,然而这会导致球场散落大量的网球需要拾取。传统的方式往往是通过球童来拾取网球,然而这种方式劳动强度大、工作效率低,尤其是在正式比赛场合,无法满足竞赛需求。为了解决这一问题,目前市场上出现了一种新的网球拾取器,然而这种拾取器仍然是靠人力来进行驱动,需要依靠人的手臂向下压的动作来完成网球拾取任务。由于这种方式需要多次重复手臂的提拉操作,因此依然存在拾取效率低、工作强度大等问题。基于此,本项目拟开发一款室内网球多功能自动拾取机器人,该机器人具有避障、自动识别、检测、对网球进行抓取、运输和存储等功能,可广泛应用于家庭、体育场、网球训练室和网球游戏场地等环境,可以满足让人们的网球运动日常需求,具有一定的经济效益和社会价值。

1.2 设计背景
      随着现代科学技术的发展,服务类机器人在市场越来越受欢迎,它不仅给人们的生活提供了便利,还优化了人们的生活方式。网球机器人作为一款智能的家庭,体育等众多领域,具备一定的人工智能化,能够自主的进行拾取网球,为此人们解放了双手,提高了工作效率。同时网球机器人作为一项重要智能化技术正在迅速变革,从简单的抓取、搬运和存储等功能正在逐步扩展,增加识别分拣,因此设计一种合理的网球机器人具有重大的研究意义。本产品以网球机器人为研究对象,充分调研了目前网球机器人的研究现状,了解了目前网球机器人的发展趋势以及当前存在的不足,整个项目的最终目标是针对目前网球机器人功能单一、结构复杂等缺点进行改造,设计一种能够自主循迹并且准确收取的多功能智能网球机器人。该机器人可按照特定设计的路线并且绕开障碍物,完成规定的拾取任务。机器人精巧灵活,可以用转盘收集、储存、传输网球。

1.3 设计思路
       根据网球搬运机器人研究现状和需求分析,本设计采用“需求分析-关键技术-设计功能”的总体思路,如下图所示:
功能框图

需求分析:
       因为在网球训练场地,网球覆盖了整个区域,为此拾取网球是一个费时费力的过程,在这种情况下我们设计了一款可以有效拾取网球的机器人,解放人们的双手,减少了劳动力,提高了经济效益。本产品主要使用了超声波,超声波在一定的距离感受到障碍物后会向后退,再向左转继续行驶,本项目设计的网球搬运机器人包括电机驱动模块、避障模块。
       ① 电机驱动模块:该产品使用了3个电机,用PWM调速,其中一个电机驱动风叶来拾取网球,另外两个电机驱动小车运动。
       ② 避障模块:机器人使用一个超声波,该超声波装在机器人的前方,用来检测前方是否有障碍物,检测出有障碍物时,小车会向后退,再向左转以避开障碍物继续行驶。

1.4 物理原理
       在小车向前走时,会碰到网球,由于惯性网球会通过引导板到达转轮处,旋转杆会带动网球向后滚去,最终到达车后里。小车是由铝合金制成,铝合金摩擦因数为0.3,网球直径为67mm,底板离底面高度为35mm,旋转杆长度为95mm,宽度为10mm,足以将网球带进去,经过测量得当小球离开叶片时离斜坡高为11mm,斜坡长度还有18mm,斜坡倾斜角度为38°。
由能量守恒:

将已知物理量代入得出当小球离开叶片时获得的初速度为 0.55。已知初速度,由

可得角速度为1.1rad/s,所以螺旋片的最小转速要大于1.1rad/s才可以达到转动小球,小球可以达到最高高度为35mm,假设与旋转杆发生弹性碰撞没有能量损失。由平抛公式,水平x=vt,竖直s=1/2(g*t^2),经计算最大速度不大于0.54m/s才不会被反弹出去。

1.5 难题和解决方法
       轮盘如何准确抓取到物体是一个难点,我们通过不断的实验、测量、计算来最终解决这个准确抓取物体的问题。拾球效果差、拾球不彻底的问题也是一个难点,我们通过旋杆不停地转动来获取网球,用什么设备来进行循迹也是一个难点,通过上网搜索和查阅资料以及不断的试验和测量,决定最后用一个超声波来检测障碍物进行避障。如何按照规划的路线并且准确的完成循迹需要我们查阅资料以及不断的进行试验、调整,完成循迹任务。

1.6 创新点
       在本项目中,自动网球拾取机器人的工作原理参考了直升机螺旋桨的工作原理,即 1/2(m/v^2) = mgh+μmgLcosθ,其中网球质量为57g,直径为67mm,到达的高度为35mm,μ=0.3,θ=35°。

       网球利用动能,然后克服自身的重力势能和摩擦力做功,最后就顺势进入机器人后部盛放网球的地方。而其它的机器人利用吸附类的容易卡住,夹取类的容易夹取不住或滑掉,铲子类的容易滑跑,而我们的则比它们更简单,更容易安装,即使坏了部分结构,只要更换就可以继续使用。本项目机器人采用1个超声波来避障,相比较其它机器人结构简单、取材少、经济性高。

2. 硬件介绍
2.1 主控板设计
       如下图所示为本系统的总体设计框图。本项目采用了一个BASRA主控板,采用的主控板为基于Arduino开源方案设计的Basra开发板,处理器核心是ATmega328, 具有 14 路数字输入/输出口(其中6路可作为 PWM 输出),6路模拟输入,一个16MHz晶体振荡器,一个USB口,一个电源插座,一个ICSP header 和一个复位按钮.如图3所示,控制板尺寸为55*55mm,便于安装。
系统设计总体框架
主控板接口图

2.2 Arduino控制板
       在Arduino控制板上添加电路是一个比较麻烦的事,所以采用了一个专用于机器人的简单扩展板,能将大部分传感器轻松地和arduino控制板连接,即Arduino 2560。它内置了16个模拟传感器和54个数字传感器接口,支持USART和其他通信模式。内置了RTC等功能,如模拟比较器、高级定时器、控制器唤醒机制中断等,16MHz晶钟可获得16 MIBS,同时它省电、快速度。除此之外,还具有5v、3.3v及vin3种电源接口,便于为各类扩展模块供电。如下图所示为Arduino 2560实物图:
Arduino 2560实物图

2.3 超声波传感器
       超声波传感器是将超声波信号转换成其它能量信号(通常是电信号)的传感器。超声波是振动频率高于20kHz的机械波。它具有频率高、波长短、绕射现象小,特别是方向性好、能够成为射线而定向传播等特点。超声波对液体、固体的穿透本领很大,尤其是在阳光不透明的固体中。超声波碰到杂质或分界面会产生显著反射形成反射回波,碰到活动物体能产生多普勒效应。如下图所示为超声波传感器:
超声波传感器正面
超声波传感器背面

2.4 旋转杆
       转盘由三个杆组成,通过驱动模块来驱动伺服电机带动三个齿轮来带动扫把进行连轴转动来收取网球,风叶长95mm宽10mm,能够转动300g网球。

3. 软件设计
       本次设计的自动水车型乒乓球机器人,代码运行环境是基于win10 Arduino1.5.2,直流电机直连5V电源,舵机步进电机接口采用的是A4988。下图为本次作品的系统软件设计总体流程:
系统软件流程图

4. 调试过程
       ① 整体方案确定好以后,项目组成员开始组装基础的零部件。

       ② 将组装好的零部件拼接,以形成各部分的主体结构,然后进行整体拼装。

       ③ 组装好的网球拾取旋转头。

④ 指导老师在帮忙解决组装和调试过程中遇到的问题。

⑤ 项目组成员在进行紧张的编程调试工作。

⑥ 初步组装完成的系统在桌面进行调试。

       ⑦ 调试完成的系统在地面进行试验,达到了预期的效果。在后期设计过程中,本项目将在既有水平的基础上根据项目设计方案进行进一步的优化和调整,以使得我们的产品功能更为完善,性能更为优越。

5. 示例程序
  1. #define V_MAX 9600 //步进电机速度

  2. #define ECHOPIN 14

  3. #define TRIGPIN 15

  4. void setup() {

  5.    Serial.begin(9600);

  6.    initMotor();

  7.    pinMode(ECHOPIN, INPUT);

  8.    pinMode(TRIGPIN, OUTPUT);

  9.    //test

  10.    // moveTest();

  11.    }

  12.    

  13.    void loop() {

  14.     //     moveTest();

  15.     digitalWrite(TRIGPIN, LOW);

  16.     delayMicroseconds(2);

  17.     digitalWrite(TRIGPIN, HIGH);

  18.     delayMicroseconds(10);

  19.     digitalWrite(TRIGPIN, LOW);

  20.     float distance = pulseIn(ECHOPIN, HIGH);

  21.     distance= distance/58;

  22.     if (distance >= 20)

  23.     {

  24.       forward();

  25.       }

  26.       if(distance < 20)

  27.       {

  28.         gostop();

  29.         goback();

  30.         goback();

  31.         goback();

  32.         goback();

  33.         turn_left();

  34.         turn_left();

  35.         turn_left();

  36.     }

  37.     delay(50);

  38.     }

  39.     //============================================================

  40.     void moveTest(){

  41.       move( 80, 80, 80, 80); //前进

  42.       move(-80, -80, -80, -80); //后退

  43.       move(-80, 80, 80, -80); //左平移

  44.       move( 80, -80, -80, 80); //右平移

  45.       move(-80, 80, -80, 80); //左转

  46.       move( 80, 80, -80, -80); //右转

  47.     }

  48.     void forward()

  49.     {

  50.       move(80,80,80,0);

  51.       move(80,80,80,0);

  52.       delayMicroseconds(2);

  53.       }

  54.       void turn_left()

  55.       {

  56.         move(80,80,-80,0);

  57.         }

  58.         void turn_right()

  59.         {

  60.           move(80,-80,80,0);

  61.           }

  62.           void gostop()

  63.           {

  64.             move(80,0,0,0);

  65.             }

  66.             void goback()

  67.             {

  68.               move(80,-80,-80,0);

  69.               }

  70.               #include "Arduino.h"

  71.               #include <AccelStepper.h>

  72.               #include <MultiStepper.h>

  73.               #define EN 8

  74.               #define MAIN_STEP 200 //步进电机每圈步数

  75.               #define MICRO_STEP 16 //驱动细分数 (gaile 16->2)

  76.               #define TOTAL_STEP (MAIN_STEP * MICRO_STEP) //16 细分下每圈步数

  77.               #define D_WHEEL 56.5 //车轮直径/mm

  78.               const double CWheel = M_PI * D_WHEEL; //车轮周长/mm

  79.               const double Ratio = TOTAL_STEP / CWheel; //step/mm

  80.               AccelStepper stepper_x(1, 2, 5);      //x

  81.               AccelStepper stepper_y(1, 3, 6);      //y

  82.               AccelStepper stepper_z(1, 4, 7);      //z

  83.               AccelStepper stepper_a(1, 12, 13);    //a

  84.             

  85.               MultiStepper steppers;

  86.               void initMotor(){

  87.                 pinMode(EN, OUTPUT);

  88.                 digitalWrite(EN, LOW);

  89.                 steppers.addStepper(stepper_x);

  90.                 steppers.addStepper(stepper_y);

  91.                 steppers.addStepper(stepper_z);

  92.                 steppers.addStepper(stepper_a);

  93.                 stepperSet(V_MAX);

  94.                 }

  95.                 //x ; y ; w / mm

  96.                 void move(double x, double y, double z, double a){

  97.                   double step_x, step_y, step_z, step_a;

  98.                   x *= Ratio;

  99.                   y *= Ratio;

  100.                   z *= Ratio;

  101.                   a *= Ratio;

  102.                   step_x = x;

  103.                   step_y = -y;

  104.                   step_z = z;

  105.                   step_a = -a;

  106.                   stepperMove(step_x, step_y,step_z,step_a);

  107.                   }

  108.                   void stepperSet(double _v){

  109.                     stepper_x.setMaxSpeed(_v);

  110.                     stepper_y.setMaxSpeed(_v);

  111.                     stepper_z.setMaxSpeed(_v);

  112.                     stepper_a.setMaxSpeed(_v);

  113.                     }

  114.                 void stepperMove(long _x, long _y, long _z, long _a){

  115.                   long positions[4];

  116.                   positions[0] = _x;

  117.                   positions[1] = _y;

  118.                   positions[2] = _z;

  119.                   positions[3] = _a;

  120.                   steppers.moveTo(positions);

  121.                   steppers.runSpeedToPosition();

  122.                   stepper_x.setCurrentPosition(0);

  123.                   stepper_y.setCurrentPosition(0);

  124.                   stepper_z.setCurrentPosition(0);

  125.                   stepper_a.setCurrentPosition(0);

  126.                   }
复制代码

* 本项目更多详情请查看 https://www.robotway.com/h-col-292.html
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-30 23:39 , Processed in 0.042654 second(s), 17 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表