机器人制作开源方案 | 智能循迹搬运车

作者:范永晨 杨丽鹏 张东生

单位:唐山学院

指导老师:袁娜

      都说21世纪为物流的天下,物流行业牵扯到各个领域。目前,劳动人口数量下降、老龄化现象加速、工资上涨,土地成本提升,随着市场不断发展,物流企业的压力也逐渐增大,这样的背景下,“机器人”成为降低物流人工成本和提高仓储物流效率的最主要的解决方案。要想缓和市场带来的压力,只有不断的提升自身能力。智能化设备的应用将给物流业带来生机,也给物流业带来更多的收益。作为物流业,各企业的竞争压力也逐渐大,面对压力企业就需要不断给自己升级。物流企业的效率、成本、客户的评价等都很重要。物流搬运机器人作为高智能设备在物流业的作用很明显。最直接的效果就是搬运效率的提升,效率是每个物流企业都很看重的关键,更是客户评价物流公司好坏的指标。如果快递很慢,是不会得到客户好评的。如今物流搬运机器人的出现,无人操作,可以持续的处理各类货物,不用休息,让整个的处理快件的速度大大提升,客户对物流企业的好感在增加,企业的竞争力也在提升。接着是物流成本的下降,物流企业的成本有人工、破损、搬运等诸多项目组成。面对市场竞争的加大降低成本势在必行。物流搬运机器人可以实现无人操作,如此一来,人工成本消失。工作效率提升,那么单位时间创造的利润就增加的。

      基于以上调研,智能物流搬运机器人在物流业中的价值是不可估量的,不但实现的无人操作,还实现了高效低成本的运行,为企业带来利好。

1. 作品功能简介

      一个完整的智能物流搬运系统有很多部分组成,如分拣、搬运、码垛等等,我们设计的智能车主要实现的是搬运这一部分,六电机驱动,四个舵机实现夹取,主要功能如下:

1.1 红外识别夹取

      小车安装红外模块,红外传感器模块对环境光线适应能力强,其具有一对红外发射与接收管,发射管发射出频率的红外线,当检测方向遇到障碍物(反射面)时,红外线反射回来被接收管接收,小车停止,机械臂在红外识别位置对物体进行夹取并放置到小车存储仓,完成这一系列动作后小车继续运行。

1.2 灰度循迹

      采用三灰度循迹传感器,三个灰度传感器排列在车前底部,当只有中间传感器检测到黑色时,小车直行;左边传感器检测到黑色时,小车执行右转指令;右边传感器检测到黑色时,小车执行左转指令。

1.3 智能避障

      避障功能利用了超声波传感器实现,当位于小车前方的超声波传感器检测到小车前方有障碍物时,小车会绕过障碍物,沿着原先路线行驶。

2. 作品实际应用

      我国是工业制造业大国,在诸多产业中都需要搬运大量的生产所需要的物资。我国制造业不断地向智造业转型,工业生产不断地向自动化转型。我们的设计的智能循迹搬运车能够实现自动化搬运货物,据我们的实际调查,我们的智能循迹搬运车可以按照一定的轨迹进行运动,在循迹的同时检测货物,进行货物装载。同时能进行以下场景的工作:

      ① 仓储业,仓储业是较早应用的场所。用于实现出入库的自动搬运,目前应用较多的搬运型智能小车是码垛型小车,码垛型有各种形式的,腾阳公司生产的码垛智能小车有低位码垛机,高位码垛机,立柱式和坐标式码垛小车,全国还有很多不同类型的智能搬运小车,每天在大量的完成出入库货物的码垛和搬运任务。

      ② 制造业,搬运小车目前在制造业中主要用于汽车制造业,它可以随着生产工艺流程的调整而调整,使一条生产线上能够制造出更多种类的产品,并且更加高效、准确、灵活的完成物料的搬运任务。

      ③ 邮局、图书馆、港口码头和机场,在邮局、图书馆、码头和机场等场合,物品的运送存在着作业量变化大,动态性强,作业流程经常调整,以及搬运作业过程单一等特点,搬运小车的并行作业、自动化、智能化和柔性化的特性能够很好的满足上式场合的搬运要求。

      ④ 烟草、医药、食品、化工,对于搬运作业有清洁、安全、无排放污染等要求的烟草、医药、食品、化工等行业中,搬运小车的应用也受到重视。在国内的许多卷烟企业,应用了灰度引导循迹令搬运小车完成托盘货物的搬运工作。

3. 所用主要元件

3.1 灰度传感器

3.1.1 简介

      有一只发光二极管和一只光敏电阻,安装在同一面上。灰度传感器利用不同颜色的检测面,对光的反射程度不同,光敏电阻利用不同检测面返回的光不同、其阻值也不同的原理来进行颜色深浅检测。在有效的检测距离内,发光二极管发出白光,照射在检测面上,检测面反射部分光线,光敏电阻检测此光线的强度并将其转换为机器人可以识别的信号。灰度既可以当作数字量传感器使用,也可以当作模拟量传感器使用。

3.1.2 工作原理

      灰度检测的有效距离在0.7cm~3cm之间,当传感器检测到有深色标记时,将会触发传感器,使其输出口有低电平输出;当传感器检测到浅色标记时,传感器将不会被触发,所以其输出口是高电平输出。

3.2 超声测距模块

3.2.1 简介

      超声测距模块使用HC-SR04 超声波测距模块,可提供2cm-400cm 的非接触式距离感测功能,测距精度可达高到3mm;模块包括超声波发射器、接收器与控制电路。

3.2.2 超声波时序图

      以上时序图表明你只需要提供一个10uS 以上脉冲触发信号,该模块内部将发出8 个40kHz 周期电平并检测回波。一旦检测到有回波信号则输出回响信号。回响信号的脉冲宽度与所测的距离成正比。由此通过发射信号到收到的回响信号时间间隔可以计算得到距离。

公式:uS/58=厘米或者uS/148=英寸;或是:距离=高电平时间*声速(340M/S)/2;建议测量周期为60ms 以上,以防止发射信号对回响信号的影响。

3.2.3 工作原理

      ① 采用IO口TRIG 触发测距,给最少10us 的高电平信呈。

      ② 模块自动发送8 个40khz 的方波,自动检测是否有信号返回。

      ③ 有信号返回,通过IO 口ECHO 输出一个高电平,高电平持续的时间就是波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2。

3.3 近红外传感器

3.3.1 简介

      近红外传感器是一种开关量传感器,它可以检测到前方是否有物体存在,当检测到有物体存在时,传感器输出口会输出低电平;相反在未检测到前方有物体时,传感器输出口会输出一个高电平。主控芯片可根据传感器采集的电平高低做出相应的动作指令。

3.3.2 工作原理

      近红外线传感器是利用红外线的物理性质来进行测量的传感器。红外线又称红外光,它具有反射、折射、散射、干涉、吸收等性质。而近红外传感器正是利用其这一特性工作的,当前方有物体并且在红外线反射范围之内时,传感器会接收到反射的红外线,进而触发近红外传感器。

3.4 小型直流驱动轮

3.4.1. 运动功能说明

      从方向上说有正转、反转两种;从控制方式上说,有数字量输出和模拟量(PWM)输出两种,模拟量输出可以调整速度。

3.4.2 结构说明

      构成本模组的零部件主要是直流电机、1:10模型轮胎,以及配套的直流电机的支架、输出头、联轴器、螺丝、螺母、螺柱等。

3.5 舵机关节模组

3.5.1 运动功能说明

      舵机关节模组的主要运动方式为用舵机带动U型支架摆动,从而模仿生物关节运动的效果。

3.5.2 结构说明

      构成本模组的零部件主要是舵机(行程0度~180度)、舵机支架、舵机输出头、舵机双折弯(U型支架)、螺丝、螺母等。

3.6 舵机夹爪模组

3.6.1 运动功能说明

      夹爪模组的主要运动模式为张开以及闭合。

3.6.2结构说明

      构成本模组的零部件主要是舵机(行程0度~180度)、舵机输出头、舵机支架、齿轮组、连杆组等。

4. 作品难点及解决方案

      ① 在用红外识别快递,小车停车定点夹取时,由于小车的惯性,在识别到物体时,往往会继续向前行驶一小段距离,造成小车和物体位置与先前识别的位置有偏差,机械臂不能准确夹取物体。为了使小车稳定停止后机械臂能准确夹取,经过反复实验,确定了小车红外识别到物体准备停车到小车稳定停车这一段距离,将红外传感器位置从原先位置提前了同样的距离,最终小车能准确识别夹取。

      ② 在用灰度传感器循迹时,由于晚上灯光较暗,加上起初车轮底盘较低,遮光造成循迹识别不准确,车辆难以按原轨道行驶,为解决以上问题,我们前轮选用直径更大的车轮以增高底盘,增大透光。

      ③ 小车在爬坡时,经常性的卡在坡上,为了满足场景的各种可能外在因素,保障小车稳定运行,我们选择改变小车结构,增大底盘的同时,将小车后轮变为可活动型,使其能顺利通过小坡。

5. 软件设计

      在小车的设计中,我们根据开发板的具体情况使用arduino软件,采用主流设计语言C语言对开发板进行编程实现各项功能。C语言功能丰富,表达能力强,目标程序效率高,可移植性好,既有高级语言的优点,又有低级语言的许多特点,应用十分广泛。

5.1 智能循迹搬运车总体流程

      此部分是小车运行的核心部分,起着控制小车运行状态的作用,具有导向和决策的功能。

      ① 首先要对小车进行初始化,在这个阶段小车会通过红外传感器和超声波传感器检测物体,同时在循迹。

      ② 接着当开发板判断是否有物体,如果前进道路上有物体存在,小车进行基于超声波的避障程序,避开障碍后按原路路线前进,若红外传感器识别到物体则,小车停止前进,启动机械臂自动夹取的程序,对物体进行夹取。

      ③ 当夹取完毕之后,小车会继续循迹,当遇到下一个物体的时候,小车会再次停下,对物体进行夹取。程序控制流程图如下所示:

5.2 小车功能代码

① 小车避障代码

#define Trig A1 //引脚Tring 连接 A1

#define Echo A0 //引脚Echo 连接   A0

int pin[3] = {A2, A4, A3};

byte value;

byte value_his = 0;

float cm; //距离变量

float temp; //记录上一次的传感器值

void setup()

{

  Serial.begin(9600);

  pinMode(Trig, OUTPUT);

  pinMode(Echo, INPUT);

  pinMode( 5 , OUTPUT);

  pinMode( 6 , OUTPUT);

  pinMode( 9 , OUTPUT);

  pinMode( 10 , OUTPUT);

  analogWrite(9,1);   //analogWrite values from 0 to 255

  analogWrite(10,1);   //analogWrite values from 0 to 255

  analogWrite(5,1);   //analogWrite values from 0 to 255

  analogWrite(6,1);   //analogWrite values from 0 to 255  

}

void loop()

{ get_echo();

  if(cm<20){    //距离小于20cm就执行下面的动作

      //执行相应的动作

     Back ();

  delay(500);

  Left();

  delay(300);

  Forwards();

  delay(1300);

  Right();

  delay(900);

  Forwards();

  delay(1000);

     }

     else   //距离不小于20cm就执行这个动作

  {

value = 0;

for(int i=0; i<3; i++)

{

value |= (digitalRead(pin[i]) << i);

}

if(value == 0x07){ //当传感器都没有触发时默认为上一次的值

value = value_his;

}

switch (value)

{

case 0x00: //全部触发

Forwards();

break;

case 0x01: //触发右边两个

while(digitalRead(pin[1])){ //通过while 循环使小车回到跑道中间

Right();

}

break;

case 0x03: //触发右边一个

while(digitalRead(pin[1]))

{

Right();

}

break;

case 0x04: //触发左边两个

while(digitalRead(pin[1]))

{

Left();

}

break;

case 0x05: //触发中间一个

Forwards();

break;

case 0x06: //触发左边一个

while(digitalRead(pin[1]))

{

Left();

}

break;

default:

Stop();

}

value_his = value;

}

}

void get_echo() {

  //给Trig发送一个低高低的短时间脉冲,触发测距

  digitalWrite(Trig, LOW); //给Trig发送一个低电平

  delayMicroseconds(2);    //等待 2微妙

  digitalWrite(Trig,HIGH); //给Trig发送一个高电平

  delayMicroseconds(10);    //等待 10微妙/

  digitalWrite(Trig, LOW); //给Trig发送一个低电平

 

  temp = float(pulseIn(Echo, HIGH)); //存储回波等待时间

    //pulseIn函数会等待引脚变为HIGH,开始计算时间,再等待变为LOW并停止计时

    //返回脉冲的长度

 

  cm = (temp * 17 )/1000; //把回波时间换算成cm

    //声速是:340m/1s 换算成 34000cm / 1000000μs => 34 / 1000

    //因为发送到接收,实际是相同距离走了2回,所以要除以2

    //距离(厘米)   =   (回波时间 * (34 / 1000)) / 2

    //简化后的计算公式为 (回波时间 * 17)/ 1000  

 

  Serial.print("Echo =");

  Serial.print(temp);//串口输出等待时间的原始数据

  Serial.print(" | | Distance = ");

  Serial.print(cm);//串口输出距离换算成cm的结果

  Serial.println("cm");

}

void Left()

{

digitalWrite( 5 , HIGH );

digitalWrite( 6 , LOW );

digitalWrite( 9 , LOW );

digitalWrite( 10 ,HIGH   );

}

void Right()

{

digitalWrite( 5 , LOW );

digitalWrite( 6 , HIGH );

digitalWrite( 9 , HIGH );

digitalWrite( 10 , LOW );

}

void Forwards()

{

digitalWrite( 5 , HIGH );

digitalWrite( 6 , LOW );

digitalWrite( 9 , HIGH );

digitalWrite( 10 , LOW );

}

void Stop()

{

digitalWrite( 5 , LOW );

digitalWrite( 6 , LOW );

digitalWrite( 9 , LOW );

digitalWrite( 10 , LOW );

}

void Back() //后退函数

{

  digitalWrite(5, LOW);

  digitalWrite(6, HIGH);

  digitalWrite(9, LOW);

  digitalWrite(10, HIGH);

}

② 机械臂夹取代码

#include<Servo.h>     //调用舵机库

#define Servo_duo1 4   //定义舵机串口

#define Servo_duo2 7

#define Servo_duo3 11

#define Servo_duo4 12

//舵机1   

#define Angle_1 30

#define Angle_2 150

//舵机2

#define Angle_3 60

#define Angle_4 100

//舵机3

#define Angle_5 75 //设置舵机转动的角度为75度

#define Angle_6 60 //设置舵机转动的角度为60度

//舵机4

#define Angle_7 100

#define Angle_8 0

Servo myservo1;        //声明舵机对象

Servo myservo2;   

Servo myservo3;

Servo myservo4;

Servo myservo5;

Servo myservo6;  

Servo myservo7;

Servo myservo8;

int pin[3] = {A2, A4, A3};//定义灰度传感器串口

byte value;

byte value_his = 0; //记录上一次的传感器值

void setup()

{ Serial.begin(12500);//开启串口,并设置波特率为12500

  pinMode( 5 , OUTPUT);

  pinMode( 6 , OUTPUT);

  pinMode( 9 , OUTPUT);

  pinMode( 10 , OUTPUT);

  pinMode(14, INPUT);

 

}

void loop()

{

  if(!(digitalRead(14)))

  { Stop();

  jixiebi();  

  }

  else{

   xunji();

}}

void Left()

{

digitalWrite( 5 , HIGH );

digitalWrite( 6 , LOW );

digitalWrite( 9 , LOW );

digitalWrite( 10 , HIGH );

}

void Right()

{

digitalWrite( 5 , LOW );

digitalWrite( 6 , HIGH );

digitalWrite( 9 , HIGH );

digitalWrite( 10 , LOW );

}

void Forwards()

{

digitalWrite( 5 , HIGH );

digitalWrite( 6 , LOW );

digitalWrite( 9 , HIGH );

digitalWrite( 10 , LOW );

}

void Back()

{

digitalWrite( 5 , LOW );

digitalWrite( 6 , HIGH );

digitalWrite( 9 , LOW );

digitalWrite( 10 , HIGH );

}

void Stop()

{

digitalWrite( 5 , LOW );

digitalWrite( 6 , LOW );

digitalWrite( 9 , LOW );

digitalWrite( 10 , LOW );

}

void jixiebi()

{//舵机4开

   Serial.begin(9600);//开启串口,并设置波特率为9600

   myservo4.attach(Servo_duo4);//设置舵机引脚

   myservo4.write(Angle_7); //4号引脚舵机直接转到0度

   delay(1000); //等待1秒

   

   //舵机1夹

   myservo1.attach(Servo_duo1);//设置舵机引脚

   myservo1.write(Angle_1); //1号引脚舵机直接转到30度

   delay(1000); //等待1 秒

   //舵机3夹

   myservo3.attach(Servo_duo3);//设置舵机引脚

   myservo3.write(Angle_5); //11号引脚舵机直接转到75度

   delay(1000); //等待1秒

   //舵机2夹

   myservo2.attach(Servo_duo2);//设置舵机引脚

   myservo2.write(Angle_3); //4号引脚舵机直接转到60度

   delay(1000); //等待5秒

   

   //舵机4夹

   myservo4.attach(Servo_duo4);//设置舵机引脚

   myservo4.write(Angle_8); //4号引脚舵机直接转到0度

   delay(1000); //等待1秒

   

   //舵机2放

   myservo2.attach(Servo_duo2);//设置舵机引脚

   myservo2.write(Angle_4); //4号引脚舵机直接转到100度

   delay(2000); //等待2秒

   //舵机1放

   myservo1.attach(Servo_duo1);//设置舵机引脚

   myservo1.write(Angle_2); //4号引脚舵机直接转到150度

   delay(1000); //等待1秒

   

   //舵机3放

   myservo3.attach(Servo_duo3);//设置舵机引脚

   myservo3.write(Angle_6); //11号引脚舵机直接转到60度

   delay(1000); //等待1秒

   //舵机4开

   myservo4.attach(Servo_duo4);//设置舵机引脚

   myservo4.write(Angle_7); //4号引脚舵机直接转到100度  

}

void xunji()

{value = 0;

for(int i=0; i<3; i++)

{

value |= (digitalRead(pin[i]) << i);

}

if(value == 0x07){ //当传感器都没有触发时默认为上一次的值

value = value_his;

}

switch (value)

{

case 0x00: //全部触发

Forwards();

break;

case 0x01: //触发右边两个

while(digitalRead(pin[1])){ //通过while 循环使小车回到跑道中间

Right();

}

break;

case 0x03: //触发右边一个

while(digitalRead(pin[1]))

{

Right();

}

break;

case 0x04: //触发左边两个

while(digitalRead(pin[1]))

{

Left();

}

break;

case 0x05: //触发中间一个

Forwards();

break;

case 0x06: //触发左边一个

while(digitalRead(pin[1]))

{

Left();

}

break;

}

value_his = value;

}

6. 结束语

      我们的循迹搬运车由于设计并不复杂,我们没有在电路中增加冗余的功能,但是我们保存了各种硬件接口和软件子程序接口,方便以后的扩展和进一步的开发。在本次设计中,通过我们共同的努力,我们完成了循迹搬运小车的设计与制作,本设计中的循迹搬运车能完成了题目要求的大局部功能,同时也提高了我们的创新意识和团队合作意识,培养了我们认真分析问题、独立解决问题的能力,稳固了我们对所学理论的实际运用。还锻炼了我们的动手实践能力,使我们更有信心在电子行业中继续学习下去。

参考文献

【1】王秋爽,曾兆龙单片机开发根底与经典设计实例。2021年3月第一版

【2】肖洪兵、等,跟我学用单片机,北京:北京航空航天大学出版社,2002:154-162.

【3】华成英童诗白模拟电子技术根底第四版高等教育出版社

【4】吴锤红 MCS -51微机原理与接口技术厦门大学出版社

【5】张毅刚单片机原理及应用2003年12月第一版高等教育出版社

【6】江新,李华军,刘东俊,单片机程序设计及应用从根底到时间,北京,电力电子出版社,2006年3月第一版

【7】李正军,计算机控制系统,北京:机械工业出版社,2005:57-106。

【8】机械工业出版社北京,李朝青,单片机& DSP 外围数字 IC 技术手册,北京:北京航空航天大学出版社,2002:I-48

【9】文艳,谭鸿。 Protel 99 SE 电子电路设计,北京:机械工业出版社,2006:2-110。

【10】元增民,张文希,单片机原理与应用根底,长沙:国防科技大学出版社,2006:1-30。

【11】李朝青,单片机原理及接口技术,第3版,北京:航空航天大学出版社,2005:39-231。

【12】童诗白、华成英。模拟电子技术根底,北京:高等教育出版社,2003,(5):41-245

更多详情请见:【S044】智能循迹搬运车

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值