机器人制作开源方案 | 网球收纳机器人

2023-12-11 13:45

本文主要是介绍机器人制作开源方案 | 网球收纳机器人,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

作者:孙宇晗、刘子昊、单正扬、李悦、张紫琦

单位:山东大学(威海)

指导老师:庞豹

1. 场景调研

1.1 宏观背景

      体育作为社会经济、政治、文化的重要组成部分,越来越受政府、社会、学校等各阶层的关注。近年来,国家为推进“健康中国”建设、提高人民健康水平,印发并实施《“健康中国2030”规划纲要》和《体育强国纲要》。各大高校为响应国家号召也加强对学生的身体素质的培养,重视体育建设,增加对体育建设的资金投入。

      同时,在机器人成为热门话题的今天,机器人被期待应用于更多领域。其中,体育行业就是机器人可以发挥作用的一片沃土。老牌体育用品公司彪马研发“BeatBot”陪跑机器人,2016年四川省暨成都市科技活动周上成都电子科大的羽毛球机器人产品引起轰动,越来越多机器人将应用于体育行业。目前体育机器人大多作为辅助训练装置,然而体育运动中能运用机器人的场景远不止于此,对于喜爱体育运动的普通消费者,更加渴望一些能更好地服务于日常体育锻炼的机器人的出现。

1.2 应用需求

      目前高校的体育设施配置普遍提升,一般高校都配置有标准网球场,并且开设网球课程。一片标准网球场地的占地面积不小于670平方米,长36.60米,宽18.30米。在这个面积内,有效双打场地的标准尺寸达到23.77米(长)×10.97米(宽),有效单打场地的标准尺寸达到23.77米(长)×8.23米(宽),并且实际上高校的网球场往往是多个连接在一起的一大片空旷场地。而一个标准网球大小在6.541~6.858 cm之间,在训练网球时通常需要使用大量网球,作为网球训练的发球机器人一次可以发出几十个球。由于网球弹性大,每次训练之后,几十个网球散落在场地各个地方,捡球是一件非常麻烦的事。为了给高校网球训练者提供一个更方便、更流畅、更轻松的训练或娱乐体验,我们设计了这一款体育器械智能收纳机器人。

1.3 应用场景

      由于高校消费能力相较于个人更强,网球场广阔,几乎每天使用,并且对于新兴产品的接受度较高。所以,该网球收纳机器人前期主要应用于高校网球场的收纳。机器人轻便小巧,工作能力强,一个机器可以适应与完成不同大小,环境场地网球的收纳,所以机器人在高校的应用趋于稳定后,后期可将其应用于其它网球场区域总体较大、较为平旷、使用率高、具有较高的网球收纳需求的场景,如网球俱乐部、私人网球馆等。

2. 网球收纳机器人介绍

2.1 关于此网球收纳机器人

      该机器人是一款基于“探索者”平台搭建的能够自主识别并收纳体育器械的小型机器人。目前我们主要设想将它运用于高校网球场地上网球的捡拾与收纳。

2.2 与市面上已有网球收集机器对比

      市面上一般的网球机器人体型较大,主要依赖于人将装置带至网球散落处,然后装置将网球收集,整个过程并非全自动,仅仅是简化了人弯腰捡拾起网球这一动作,并没有解放使用者双手。并且由于装置一般体型较大,占地大,机器的收纳与转移较为不便,这使得使用者在装置的保存与转移上需要耗费空间与精力,增加了使用负担。

      而在自动模式下使用机器人时,只需要使用者启动机器人,机器人便可自动完成网球的收纳,几乎完全解放用户双手。即使是手动模式,也只需要使用者操控遥控器,不需要使用者在网球场上来回走动。并且该网球收纳机器人机身小巧,重量较小,可以轻易拿起,无论是收纳或者是将其转移都十分方便,大大利于普通消费者的收纳与使用,不会给用户造成额外的收纳困难与使用烦恼。

3. 机器人技术说明

3.1 主要技术参数

      (1)采用Basra主控板,堆叠BigFish扩展板

      (2)电机转速最高可达70r/min

      (3)前方装有二自由度机械臂,伸长可达30cm,单一维度活动范围0~180°

      (4)底盘距地面6cm

      (5)一个颜色模块,一个超声波测距模块,两个触须模块

3.2 机械结构

      体育器械收纳智能机器人的整体结构及各部分功能如下图所示:

机器人整体结构及各部分功能

3.2.1 底盘结构

      该网球收集机器人主要零件均采用标准件进行装配,车身整体尺寸较小,可灵活穿梭于各类球场中。机器人底盘采用一块7*11孔平板,电机悬挂在外侧的四个3*5双折面板上,既缩小了车身宽度和长度,使其通过弯道时不容易被卡住,又增加了底盘的高度,使机器人通过草地和上台阶和窄桥时越野能力增强。

      机器人采用轮形结构,四驱动力设计,使其能够在复杂地形上获得足够的驱动力。当机器人需要转向或掉头时,左右两侧电机提供不同的转速,利用转速差的原理对小车进行转向或掉头动作,从而实现以极小的转弯半径完成转向及掉头动作。

3.2.2 机械臂

      查阅相关资料可知,一般网球直径分布区间为6.541~6.858cm,重量分布区间为56.7~58.5g,按照误差正态分布,在设计时选用直径6.7cm,重量57g作为设计的标准尺寸。为了确保抓取的成功率和可靠性,与网球接触的弧形抓手设计为弦长为80mm,弦高为20mm的圆弧,可以将网球完全包裹。

      为了抓取和放置平地上距车身较远的工件,机器人机械臂模仿人类手臂和手指的构造,使用了三个M04舵机:一个控制机械爪,采用齿轮咬合结构,实现对工件的抓取;中间关节的舵机用于伸展机械臂;根部的M04舵机控制整体机械臂的抬升和降落。

3.3 控制方案

      该网球收纳机器人有自动和手动两种控制模式,两种模式下的控制方案如下图所示:

两种模式下的控制方案

3.3.1 自动模式

      机器人采取全局遍历算法巡回扫场,如下图所示:

实现方式如下:

      1)变量设置:首先,设置一个变量a1作为标记以确定机器人旋转方 向,a1初始值为1。a1值为1为向右旋转,标志为0表示向左旋转。

      其次,设置三个距离常量,D1,D2,D3。D3>D2。

      用变量d1记录机器人每次旋转后直行距离。

      2)具体过程:

      ①当机器人识别到障碍物时,后退距离D1;

      ②a1==1?为真向右旋转否则向左旋转,d1=0;

      ③前进D2

      ④a1==1?向右旋转否则向左旋转,d1=0;

      ⑤前进

      ⑥d1>D3?为真a1取反

      这样设计当机器人前进至防护网或者障碍物处会自动变换方向继续搜索,重复这一过程,可以实现对网球场的遍历并且能够排除行至墙角被困住的情况。

      该算法的优点是复杂性较低、可靠性高,能显著提高网球的收纳率,缺点是机器人可能会在无球区域耗费很多时间。

      机器人通过超声波测距检测有无物体靠近,并确定物体的相对位置,相对位置允许存在6%~10%的误差。若测距结果小于6.5cm,说明有物体靠近,此时读取颜色传感器数据,采用色域识别法对网球进行识别。(色域识别法依靠其简易性在网球识别任务中有很大的优势。)若识别结果为网球,为顺利抓取网球,小车需要缓慢后退,当与网球相距10.3cm时,停止运动并进行抓取。抓取成功后,机械臂伸向车后,机械爪松开将网球抛入框。

      机器人的主体搭建基于一个全方位移动平台,检测系统位于平台前端,用于对网球的识别定位,网球信号确认后,系统控制机械手进行抓取动作,抓取确认成功后机械手松开,网球斜抛入框。

3.3.2 手动模式

      当自动模式失灵或者网球位于机器人扫场盲区时,操作人员可以通过手动模式遥控机器人。手动模式下,机器人和2.4G手柄通过NRF24L01无线通信模块,实现手柄对机器人移动和机械臂抓取的遥控。

3.4 模块功能

3.4.1 颜色传感器模块

      TCS3200是一种全彩的颜色检测器,包括了一块RGB感应芯片TAOSTCS3200和4个白色LED灯,能在一定的范围内检测和测量几乎所有的可见光。

      本机器人采用的图像识别分析模型为HSI颜色空间模型,但由于TCS3200颜色传感器采集的图像是RGB格式,所以需要把RGB模型转换为HSI颜色模型。网球的颜色接近绿色,颜色分量Hue范围在45°到90°之间即有可能为网球。

Hue:

3.4.2 超声波模块

      HC-SR04超声波模块感应角度不大于15°,探测距离2cm-450cm,精度可达0.2cm。当颜色传感器检测到网球,小车缓慢后退,同时超声波模块对网球进行测距,当与网球相距10.3cm时,机器人停止移动并抓取网球。

3.4.3 触碰模块

      触碰模块安装在小车前方,上面有一个按键,可以切换自动模式和手动模式。机器人默认采用自动模式,当自动模式失灵或者网球位于机器人扫场盲区时,操作人员可以通过触碰模块将机器人切换为手动模式。

3.4.4 NRF24L01无线通信模块

      nRF24L01是由NORDIC生产的工作在2.4GHz~2.5GHz的ISM频段的单片无线收发器芯片。首先将机器人和手柄上的无线模块调节到相同的通道,依次打开机器人、手柄,即可实现通过2.4G手柄的按键、摇杆对机器人的移动和机械臂的抓取进行遥控。

3.5 调试与测试结果

      模拟场景大小为1.2m×1.2m。将机器人切换为自动模式,在测试场地内随机放置20个网球,捡球机器人从网球场一角开始搜索测试场地内的网球。在进行了约3min的自动捡球之后,机器人成功将16个网球捡起,自动捡球模式下的捡球效率达到80%;此时,将机器人切换为手动模式,将另外4个网球捡起,自动模式与手动模式搭配使用可使捡球效率达到100%。共约进行200组相同的测试,总的捡球效率均为100%。随机选取其中10次的数据统计,结果如表1所示。

4. 示例程序

4.1 自动模式

int _ABVAR_1_yuzhi1 = 30 ;int _ABVAR_2_yuzhi2 = 0 ;int _ABVAR_3_yuzhi3 = 120 ;bool _ABVAR_4_stop= false ;int _ABVAR_5_state = 0 ;void stop();void xunzhixian();void test();void autocar();void back();void hengxian_right();void push();void forward();void turn_right();void left();void hengxian_left();void right();void turn_left();void youzhuan();void setup(){pinMode( 10, OUTPUT);pinMode( 6, OUTPUT);pinMode( 5, OUTPUT);pinMode( 9, OUTPUT);Serial.begin(9600);_ABVAR_1_yuzhi1 = 150 ;_ABVAR_2_yuzhi2 = 200 ;_ABVAR_3_yuzhi3 = 100 ;_ABVAR_4_stop = HIGH ;forward();}void loop(){autocar();}void hengxian_right(){if (( ( ( analogRead(14) ) >= ( _ABVAR_1_yuzhi1 ) ) && ( ( analogRead(18) ) >= ( _ABVAR_3_yuzhi3 ) ) )){turn_right();_ABVAR_5_state = ( _ABVAR_5_state + 1 ) ;}else{xunzhixian();}}void xunzhixian(){if (( ( analogRead(18) ) >= ( _ABVAR_3_yuzhi3 ) )){right();}else{if (( ( analogRead(14) ) >= ( _ABVAR_1_yuzhi1 ) )){left();}else{forward();}}}void hengxian_left(){if (( ( ( analogRead(14) ) >= ( _ABVAR_1_yuzhi1 ) ) && ( ( analogRead(18) ) >= ( _ABVAR_3_yuzhi3 ) ) )){turn_left();_ABVAR_5_state = ( _ABVAR_5_state + 1 ) ;}else{xunzhixian();}}void left(){analogWrite(10 , 0);analogWrite(9 , 160);analogWrite(6 , 160);analogWrite(5 , 0);}void right(){analogWrite(10 , 160);analogWrite(9 , 0);analogWrite(6 , 0);analogWrite(5 , 160);}void turn_left(){analogWrite(10 , 255);analogWrite(9 , 0);analogWrite(6 , 0);analogWrite(5 , 255);delay( 800 );forward();delay( 1000 );}void autocar(){forward();delay( 6000 );while ( true ){if (( ( _ABVAR_5_state ) == ( 0 ) )){hengxian_left();}if (( ( _ABVAR_5_state ) == ( 1 ) )){push();}if (( ( _ABVAR_5_state ) == ( 2 ) )){hengxian_left();}if (( ( _ABVAR_5_state ) == ( 3 ) )){youzhuan();}if (( ( _ABVAR_5_state ) == ( 4 ) )){youzhuan();}if (( ( _ABVAR_5_state ) == ( 5 ) )){push();}if (( ( _ABVAR_5_state ) == ( 7 ) )){hengxian_left();}if (( ( _ABVAR_5_state ) == ( 8 ) )){youzhuan();}if (( ( _ABVAR_5_state ) == ( 10 ) )){hengxian_right();}if (( ( _ABVAR_5_state ) == ( 11 ) )){push();}if (( ( _ABVAR_5_state ) == ( 12 ) )){hengxian_left();}if (( ( _ABVAR_5_state ) == ( 13 ) )){youzhuan();}if (( ( _ABVAR_5_state ) == ( 14 ) )){youzhuan();}if (( ( _ABVAR_5_state ) == ( 15 ) )){push();}if (( ( _ABVAR_5_state ) == ( 16 ) )){hengxian_left();}if (( ( _ABVAR_5_state ) == ( 17 ) )){youzhuan();}if (( ( _ABVAR_5_state ) == ( 18 ) )){hengxian_right();_ABVAR_5_state = 1 ;}}}void push(){forward();delay( 2000 );back();_ABVAR_5_state = ( _ABVAR_5_state + 1 ) ;}void stop(){analogWrite(10 , 0);analogWrite(9 , 0);analogWrite(6 , 0);analogWrite(5 , 0);}void turn_right(){analogWrite(10 , 0);analogWrite(9 , 255);analogWrite(6 , 255);analogWrite(5 , 0);delay( 800 );forward();delay( 1000 );}void test(){Serial.print(analogRead(14));Serial.println();Serial.print(analogRead(16));Serial.println();Serial.print(analogRead(18));Serial.println();delay( 3000 );}void back(){analogWrite(10 , 0);analogWrite(9 , 105);analogWrite(6 , 0);analogWrite(5 , 105);}void youzhuan(){if (( ( ( ( analogRead(14) ) < ( _ABVAR_1_yuzhi1 ) ) && ( ( analogRead(18) ) >= ( _ABVAR_3_yuzhi3 ) ) ) && ( ( analogRead(16) ) >= ( _ABVAR_2_yuzhi2 ) ) )){turn_right();_ABVAR_5_state = ( _ABVAR_5_state + 1 ) ;}else{xunzhixian();}}void forward(){analogWrite(10 , 100);analogWrite(9 , 0);analogWrite(6 , 100);analogWrite(5 , 0);}

4.2手动模式

① control_mode_code_of_car.ino

#include <Servo.h>int _ABVAR_1__data = 0 ;int servo_pin_4 = 4;int servo_pin_7 = 7;int servo_pin_3 = 3;int _ABVAR3 = 20;int _ABVAR7 = 10;int _ABVAR4 = 0;int _ABVAR_2_i = 0 ;int _ABVAR_3_i = 0 ;int _ABVAR_4_i = 0 ;//20 0//130 100void Right();void Up_Close();void Up_Open();void Select();void Down_Open();void Down_Close();void Mid_Open();void Mid_Close();void Left();void Stop();void Back();void Forward();void servo3();void servo4();void servo7();void setup(){Serial.begin(9600);pinMode( 5 , OUTPUT);pinMode( 6 , OUTPUT);pinMode( 9 , OUTPUT);pinMode( 10 , OUTPUT);// servo_pin_4.attach(4);// servo_pin_7.attach(7);//servo_pin_3.attach(3);pinMode(servo_pin_3,OUTPUT);pinMode(servo_pin_4,OUTPUT);pinMode(servo_pin_7,OUTPUT);servo3(_ABVAR3);servo4(_ABVAR4);servo7(_ABVAR7);_ABVAR_1__data = 0 ;}void loop(){_ABVAR_1__data = Serial.parseInt() ;Select();delay( 1 );}void Select(){Stop();if (( ( _ABVAR_1__data ) == ( 2 ) )){Back();}else if (( ( _ABVAR_1__data ) == ( 1 ) )){Forward();}else if (( ( _ABVAR_1__data ) == ( 0 ) )){Stop();}else if (( ( _ABVAR_1__data ) == ( 4 ) )){Left();}else if (( ( _ABVAR_1__data ) == ( 3 ) )){Right();}else if (( ( _ABVAR_1__data ) == ( 5 ) )){Down_Open();}else if (( ( _ABVAR_1__data ) == ( 6 ) )){Down_Close();}else if (( ( _ABVAR_1__data ) == ( 7 ) )){Mid_Open();}else if (( ( _ABVAR_1__data ) == ( 8 ) )){Mid_Close();}else if (( ( _ABVAR_1__data ) == ( 9 ) )){Up_Open();}else if (( ( _ABVAR_1__data ) == ( 10 ) )){Up_Close();}else if (( ( _ABVAR_1__data ) == ( 11 ) )){Down_Close();}else if (( ( _ABVAR_1__data ) == ( 12 ) )){Down_Open();}else if (( ( _ABVAR_1__data ) == ( 13 ) )){while(_ABVAR3<20){Down_Open();}while(_ABVAR3>20){Down_Close();}while(_ABVAR7<10){Mid_Open();}while(_ABVAR7>10){Mid_Close();}}else if (( ( _ABVAR_1__data ) == ( 14 ) )){while(_ABVAR3<130){Down_Open();}while(_ABVAR3>130){Down_Close();}while(_ABVAR7<100){Mid_Open();}while(_ABVAR7>100){Mid_Close();}}}void Right(){analogWrite(5 , 200);analogWrite(6 , 0);analogWrite(9 , 0);analogWrite(10 , 200);}void Stop(){analogWrite(5 , 0);analogWrite(6 , 0);analogWrite(9 , 0);analogWrite(10 , 0);}void Forward(){analogWrite(5 , 100);analogWrite(6 , 0);analogWrite(9 , 100);analogWrite(10 , 0);}void Back(){analogWrite(5 , 0);analogWrite(6 , 100);analogWrite(9 , 0);analogWrite(10 , 100);}void Left(){analogWrite(5 , 0);analogWrite(6 , 200);analogWrite(9 , 200);analogWrite(10 , 0);}void Down_Open(){if(_ABVAR3<180){_ABVAR3 ++;servo3(_ABVAR3);delay( 6 );}}void Down_Close(){if(_ABVAR3>0){_ABVAR3 --;servo3(_ABVAR3);delay( 6 );}}void Mid_Open(){if(_ABVAR7<180){_ABVAR7 ++;servo7(_ABVAR7);delay( 6 );}}void Mid_Close(){if(_ABVAR7>0){_ABVAR7 --;servo7(_ABVAR7);  delay( 6 );}}void Up_Open(){if(_ABVAR4<150){_ABVAR4 ++;servo4(_ABVAR4);delay( 6 );}}void Up_Close(){if(_ABVAR4>0){_ABVAR4 --;servo4(_ABVAR4);  delay( 6 );}}void servo7(int angle){for(int i=0;i<6;i++){int pulsewidth = (angle * 11) + 500;digitalWrite(servo_pin_7, HIGH);delayMicroseconds(pulsewidth);digitalWrite(servo_pin_7, LOW);delayMicroseconds(20000 - pulsewidth);}}void servo4(int angle){for(int i=0;i<6;i++){int pulsewidth = (angle * 11) + 500;digitalWrite(servo_pin_4, HIGH);delayMicroseconds(pulsewidth);digitalWrite(servo_pin_4, LOW);delayMicroseconds(20000 - pulsewidth);}}void servo3(int angle){for(int i=0;i<6;i++){int pulsewidth = (angle * 11) + 500;digitalWrite(servo_pin_3, HIGH);delayMicroseconds(pulsewidth);digitalWrite(servo_pin_3, LOW);delayMicroseconds(20000 - pulsewidth);}}

② control_mode_code_of_controller.ino

int _ABVAR_1_Ctrl_Val_1 = 0 ;int _ABVAR_2_Ctrl_Val_2 = 0 ;int _ABVAR_3_A0Value = 0 ;int _ABVAR_4_A1Value = 0 ;int _ABVAR_5_A2Value = 0 ;int _ABVAR_6_A3Value = 0 ;void VAL_caculate();void ADGet();void SerialPrint();void setup(){Serial.begin(9600);}void loop(){ADGet();VAL_caculate();SerialPrint();delay( 50 );}void SerialPrint(){if( ( _ABVAR_1_Ctrl_Val_1 ) == ( 9 ) ){if( ( _ABVAR_2_Ctrl_Val_2 ) == ( 3 ) ){Serial.print("0");Serial.println();}else if( ( _ABVAR_2_Ctrl_Val_2 ) == ( 1 ) ){Serial.print("1");Serial.println();}else    if( ( _ABVAR_2_Ctrl_Val_2 ) == ( 2 ) ){Serial.print("2");Serial.println();}else      if( ( _ABVAR_2_Ctrl_Val_2 ) == ( 4 ) ){Serial.print("3");Serial.println();}else     if( ( _ABVAR_2_Ctrl_Val_2 ) == ( 5 ) ){Serial.print("4");Serial.println();}         }if ( ( _ABVAR_1_Ctrl_Val_1 ) == ( 6 ) ){if ( ( _ABVAR_2_Ctrl_Val_2 ) == ( 2 ) ){Serial.print("5");Serial.println();}else if ( ( _ABVAR_2_Ctrl_Val_2 ) == ( 1 ) ){Serial.print("6");Serial.println();}}if ( ( _ABVAR_1_Ctrl_Val_1 ) == ( 10 ) ){if( ( _ABVAR_2_Ctrl_Val_2 ) == ( 2 ) ){Serial.print("7");Serial.println();}else if ( ( _ABVAR_2_Ctrl_Val_2 ) == ( 1 ) ){Serial.print("8");Serial.println();}}if   ( ( _ABVAR_1_Ctrl_Val_1 ) == ( 7 ) ){if( ( _ABVAR_2_Ctrl_Val_2 ) == ( 1 ) ){Serial.print("9");Serial.println();}else if( ( _ABVAR_2_Ctrl_Val_2 ) == ( 2 ) ){Serial.print("10");Serial.println();}   }if ( ( _ABVAR_1_Ctrl_Val_1 ) == ( 10 ) ){if( ( _ABVAR_2_Ctrl_Val_2 ) == ( 4 ) ){Serial.print("11");Serial.println();}else if( ( _ABVAR_2_Ctrl_Val_2 ) == ( 5 ) ){Serial.print("12");Serial.println();}else if( ( _ABVAR_2_Ctrl_Val_2 ) == ( 3 ) ){Serial.print("0");Serial.println();}}if( (digitalRead(2)) == ( 0 ) ){Serial.print("13");Serial.println();}if( (digitalRead(3)) == ( 0 ) ){Serial.print("14");Serial.println();}}void VAL_caculate(){if (( ( ( _ABVAR_3_A0Value ) == ( 0 ) ) && ( ( _ABVAR_4_A1Value ) == ( 1 ) ) )){_ABVAR_1_Ctrl_Val_1 = 7 ;}if (( ( ( _ABVAR_3_A0Value ) == ( 1 ) ) && ( ( _ABVAR_4_A1Value ) == ( 0 ) ) )){_ABVAR_1_Ctrl_Val_1 = 9 ;}if (( ( ( _ABVAR_3_A0Value ) == ( 1 ) ) && ( ( _ABVAR_4_A1Value ) == ( 1 ) ) )){_ABVAR_1_Ctrl_Val_1 = 8 ;}if (( ( ( _ABVAR_3_A0Value ) == ( 1 ) ) && ( ( _ABVAR_4_A1Value ) == ( 2 ) ) )){_ABVAR_1_Ctrl_Val_1 = 10 ;}if (( ( ( _ABVAR_3_A0Value ) == ( 2 ) ) && ( ( _ABVAR_4_A1Value ) == ( 1 ) ) )){_ABVAR_1_Ctrl_Val_1 = 6 ;}if (( ( ( _ABVAR_5_A2Value ) == ( 4 ) ) && ( ( _ABVAR_6_A3Value ) == ( 5 ) ) )){_ABVAR_2_Ctrl_Val_2 = 2 ;}if (( ( ( _ABVAR_5_A2Value ) == ( 5 ) ) && ( ( _ABVAR_6_A3Value ) == ( 4 ) ) )){_ABVAR_2_Ctrl_Val_2 = 4 ;}if (( ( ( _ABVAR_5_A2Value ) == ( 5 ) ) && ( ( _ABVAR_6_A3Value ) == ( 5 ) ) )){_ABVAR_2_Ctrl_Val_2 = 3 ;}if (( ( ( _ABVAR_5_A2Value ) == ( 5 ) ) && ( ( _ABVAR_6_A3Value ) == ( 6 ) ) )){_ABVAR_2_Ctrl_Val_2 = 5 ;}if (( ( ( _ABVAR_5_A2Value ) == ( 6 ) ) && ( ( _ABVAR_6_A3Value ) == ( 5 ) ) )){_ABVAR_2_Ctrl_Val_2 = 1 ;}}void ADGet(){_ABVAR_3_A0Value = analogRead(14) ;_ABVAR_4_A1Value = analogRead(15) ;_ABVAR_5_A2Value = analogRead(16) ;_ABVAR_6_A3Value = analogRead(17) ;_ABVAR_3_A0Value = map ( _ABVAR_3_A0Value , 0 , 1024 , 0 , 3 )   ;_ABVAR_4_A1Value = map ( _ABVAR_4_A1Value , 0 , 1024 , 0 , 3 )   ;_ABVAR_5_A2Value = map ( _ABVAR_5_A2Value , 0 , 1024 , 4 , 7 )   ;_ABVAR_6_A3Value = map ( _ABVAR_6_A3Value , 0 , 1024 , 4 , 7 )   ;}

5. 作品创新点

5.1 技术创新点

5.1.1 防碰撞安全系统-超声波与颜色传感器的使用

      机器人在使用过程中可能会与人员或障碍物发生碰撞,为了提高安全性,减少损伤,我们增加了超声波模块,在机器人运动时进行物体的检测。当机器人前方出现物体时,超声波模块检测出遮挡,颜色传感器进行识别,确认物体非网球,则机器人进行避障操作,有效防止因碰撞而造成的损失,更有利于机器人在实际场景进行工作,提高机器人应用的稳定性。

5.1.2 基于颜色传感器与超声波传感器的物体识别与测距

      为了完成对目标物体的识别与抓取,我们在机器人前方安装了探索者套件中的颜色传感器。颜色传感器将物体颜色同前面已经示教过的参考颜色进行比较来检测颜色,当前方物体颜色与内设颜色(这里就是网球的颜色)在一定的误差范围内相吻合时,输出检测结果。如果前方物体颜色与内置颜色符合则进行抓取操作,不符合则进行避障操作。在识别到网球后,我们利用超声波传感器进行与目标物体距离的检测,从而能有效控制机器人与网球的距离,使对网球的抓取能够成功。

      由于网球场的环境较为空旷,场景物品较少,场景颜色较为单一,所以在这一场景下利用颜色模块进行物体检测这一设计可以在尽可能降低成本并且保证准确率的情况下实现对物体的识别与检测。这一设计相较于其他如利用红外检测进行识别更具分辨性,更符合只识别收集网球的要求,并且相比于利用相机进行检测的方式成本更低。

5.1.3 自动+手动双模式

      针对自动模式下可能遗漏部分角落处网球问题,我们加入了手动模式。在手动模式下,可以遥控机器人进行网球收纳,实现场地全识别,不遗漏任何网球。自动为主,手动为辅,两模式双辅双成,实现目标100%检测收纳。

5.2 设计创新点

      目前机器人的研究已经十分深入,机器人技术与机器人产品已十分成熟,人们现在迫切需要的是如何将现有的机器人产品与技术应用于实际生活生产,将机器人产品产业化。我们基于此,细心观察生活细节,立足于大众日常生活,发现了将机器人运用于器械收纳这一方面的空白与应用价值。

      基于高校的网球场地大且空旷,网球较小且弹力大,训练时使用量大,每次打完网球后会有大量网球散布场地各地不方便检拾,这一令网球爱好者与网球训练者头疼的问题提出了自动网球收纳机器人这一想法。区别于市面上需要人员推动找到网球所在地的“半自动化”网球收纳机器人,该网球收纳机器人可以在无人指挥情况下进行自主器械收纳,具有高度自主性,彻底解放用户。并且,机器人的手动与自动两挡模式可以针对自动模式下的未识别物体进行遥控抓取收纳,更好的实现网球收纳不遗漏,高质量完成场地网球收纳任务。

      外观设计上,我们在机器人的前端安装了两个向斜外方向延伸的直杆,这样设计可以在机器人运动时将前方区域物体带至前方检测区。在方便机器人检测的同时,增大了机器人扫场检测的检测范围,能够更好的提高机器人工作效率。机器人整体材质坚硬,结构坚固,机身小巧,方便运输,不易损坏,可很好的适用于多种场地,多种环境,具有优秀的环境适用性与稳定性。立足于体育领域,将机器人应用于器械收纳的这种创新性想法可以大大方便人们的体育活动生活,提升体育运动幸福度。

6. 作品难点及解决方案

6.1 遇到的问题

6.1.1 机器人全局遍历问题

      首先,由于场地相对于机器人来说较大,网球散落点多且不定,所以需要机器人具有良好的全局遍历能力才能对场地实现较好的搜索,识别到场地上全部散落网球。但是如何规划,才能让机器人在成本较低,没有安装摄像头,没有导航的情况下实现良好的全局遍历这是一个棘手的问题。

6.1.2 目标物体识别问题

      在不依赖摄像头的情况下,实现对目标物体也就是网球的识别,这同样是一个难题。由于目标物体体积较小,且运动自由度高,对目标物体的识别难度较高。

6.1.3 物体抓取问题

      在目标物体成功识别之后,如何使机械臂抓取到目标物体也是一大难题。

6.1.4 自动模式下,部分网球未识别问题

      在自动模式下,小车进行遍历,检测场地内所有目标物体,但是有时仍可能出现场地部分角落位置网球遗落问题。

6.2 解决方案

6.2.1 对于机器人遍历问题的解决

      在基于网球场地的环境调研与思考以后,我们想到了利用好环境特点。由于网球弹力较大,所以网球场几乎全部在四周安装防护网,以防止球被打击至网球场外部区域,对于高校,网球场区域的防护措施做得更为完善。我们实地考察了几所高校,山东大学(威海)、哈工大(威海)、重庆大学,在校园网球场四周都设置有防护网。

      所以,基于这种环境特点,我们决定在机器人身上安装超声波传感器,当机器人检测到前方有遮挡时,颜色传感器进行检测,当颜色非绿色时,识别物体为障碍物,启动避障措施。机器人后退,旋转一定角度,前进一小段距离,向后旋转,再继续前进的动作。为了确定具体旋转方向,这里我们设置一个变量作为标记,初始小车行驶时标志为1,表示向右旋转。0表示向左旋转。当遇到障碍物时,后退,根据标志数值进行旋转,前进一小段距离D1,旋转,继续前进。当继续前进距离大于一定距离时(这段距离大于D1)将标志取反。这样设计当机器人前进至防护网或者障碍物处时会自动变换方向继续搜索,重复这一过程,可以实现对网球场的遍历。这样的设计也能防止机器人运动至墙角被困住。

6.2.2 对于目标识别问题的解决方案

      由于网球场场地空旷,场地物体较少,场地颜色单一,所以我们提出了基于颜色传感器进行目标物体检测的想法。我们利用颜色传感器,内设目前物体网球的颜色信息,让机器人能够通过检测目标物体颜色来实现目标物体的检测。同时,针对网球体积小不利于检测这一问题,我们将颜色传感器安装于机器人前端较低位置处,由于机器人本身体积小巧,这样的安排可以使得机器人能够更为灵敏地识别到地上物体颜色,完成对于地上网球的识别。

6.2.3 对物体抓取问题的解决方案

      我们在机器人前端放置了超声波传感器,由于超声波传感器可以检测与物体距离,所以利用超声波传感器检测机械臂与目标物体的距离,超声波传感器将距离信息实时传输,算法调整机械臂位置姿态,直至触碰目标物体,进行抓取。

6.2.4 对部分网球遗漏问题的解决方案

      针对自动识别模式下可能出现的部分网球遗落问题,我们加入了手动模式。追加遥控功能辅助,在部分网球未识别成功时,进行手动识别。利用遥控器操控机器人到达遗漏网球处,进行抓取。

7. 机器人目前不足与后续改良

      目前机器人的主要不足在于避障与物体识别功能基于一些传感器,虽然可以完成规定任务但是智能性可以进一步提高。后续可以加上摄像模块,通过摄像头记录场景信息,并且通过模式识别算法识别筛选出网球位置,计算出目标距离,向机器人发送运动与后续指令。

8. 后续应用发展

      前期,该网球收纳机器人主要设想在对新智能技术包容与接受度较高的高校进行使用,但如果前期发展良好,一段时间后可以将目光投向其他网球使用环境,如网球俱乐部,网球训练基地等。由于机器人本身轻便、方便转移的特点,可以实现在多个场地的切换,大大地提高其利用率。

将机器人应用于体育行业,将智能技术融入体育生活这一想法是未来体育行业的一大期待趋势,其发展潜力无限。并且,只需要稍微的改动,机器人也可应用于对羽毛球与乒乓球等其他小型球类的收纳,但由于羽毛球与乒乓球等收纳困难度相较于网球较小,所以这一领域可以在后续机器人的应用已初具规模,成本进一步下降的时候涉及。

      最后,我们的机器人不止可以收纳网球,只需要作进一步的算法与设备调整(如加装摄像头,加入模式识别算法),机器人可以检测并收集人们希望收集的小型物品,如地面上被丢弃的垃圾,有害物品等,实现向更多领域的突破。

*更多资料请见:【S036】网球收纳机器人

这篇关于机器人制作开源方案 | 网球收纳机器人的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/480897

相关文章

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

高效+灵活,万博智云全球发布AWS无代理跨云容灾方案!

摘要 近日,万博智云推出了基于AWS的无代理跨云容灾解决方案,并与拉丁美洲,中东,亚洲的合作伙伴面向全球开展了联合发布。这一方案以AWS应用环境为基础,将HyperBDR平台的高效、灵活和成本效益优势与无代理功能相结合,为全球企业带来实现了更便捷、经济的数据保护。 一、全球联合发布 9月2日,万博智云CEO Michael Wong在线上平台发布AWS无代理跨云容灾解决方案的阐述视频,介绍了

阿里开源语音识别SenseVoiceWindows环境部署

SenseVoice介绍 SenseVoice 专注于高精度多语言语音识别、情感辨识和音频事件检测多语言识别: 采用超过 40 万小时数据训练,支持超过 50 种语言,识别效果上优于 Whisper 模型。富文本识别:具备优秀的情感识别,能够在测试数据上达到和超过目前最佳情感识别模型的效果。支持声音事件检测能力,支持音乐、掌声、笑声、哭声、咳嗽、喷嚏等多种常见人机交互事件进行检测。高效推

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

金融业开源技术 术语

金融业开源技术  术语 1  范围 本文件界定了金融业开源技术的常用术语。 本文件适用于金融业中涉及开源技术的相关标准及规范性文件制定和信息沟通等活动。

安全管理体系化的智慧油站开源了。

AI视频监控平台简介 AI视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。用户只需在界面上进行简单的操作,就可以实现全视频的接入及布控。摄像头管理模块用于多种终端设备、智能设备的接入及管理。平台支持包括摄像头等终端感知设备接入,为整个平台提

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

JavaFX应用更新检测功能(在线自动更新方案)

JavaFX开发的桌面应用属于C端,一般来说需要版本检测和自动更新功能,这里记录一下一种版本检测和自动更新的方法。 1. 整体方案 JavaFX.应用版本检测、自动更新主要涉及一下步骤: 读取本地应用版本拉取远程版本并比较两个版本如果需要升级,那么拉取更新历史弹出升级控制窗口用户选择升级时,拉取升级包解压,重启应用用户选择忽略时,本地版本标志为忽略版本用户选择取消时,隐藏升级控制窗口 2.

如何选择SDR无线图传方案

在开源软件定义无线电(SDR)领域,有几个项目提供了无线图传的解决方案。以下是一些开源SDR无线图传方案: 1. **OpenHD**:这是一个远程高清数字图像传输的开源解决方案,它使用SDR技术来实现高清视频的无线传输。OpenHD项目提供了一个完整的工具链,包括发射器和接收器的硬件设计以及相应的软件。 2. **USRP(Universal Software Radio Periphera

MiniGPT-3D, 首个高效的3D点云大语言模型,仅需一张RTX3090显卡,训练一天时间,已开源

项目主页:https://tangyuan96.github.io/minigpt_3d_project_page/ 代码:https://github.com/TangYuan96/MiniGPT-3D 论文:https://arxiv.org/pdf/2405.01413 MiniGPT-3D在多个任务上取得了SoTA,被ACM MM2024接收,只拥有47.8M的可训练参数,在一张RTX