【树莓派项目】基于树莓派的校园快递派送智能机器人(完整工程资料源码)

本文主要是介绍【树莓派项目】基于树莓派的校园快递派送智能机器人(完整工程资料源码),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

基于树莓派的校园快递派送智能机器人演示效果

 

基于树莓派的校园快递派送智能机器人

 

前言:

        互联网的快速发展带动了快递行业的空前繁荣,但快递行业仍存在“最后一公里”的资源浪费、效率低下、可靠性不足以及用户体验感差等一系列问题。本文依托物联网技术,构建智能运送机器人派件系统,制造一种具备自动取件和派送功能的机器人。该机器人可以自动循迹送货,亦可按照用户要求到指定位置取件然后再将物品运送至指定位置。从而最大限度地解放劳动力,提升物流运输效率并满足用户急件运输的需求。

关键词:  树莓派,智能运送机器人,控制系统,微信小程序

目录:

目录

基于树莓派的校园快递派送智能机器人演示效果

前言:

目录:

一、项目介绍

1.1 项目的意义与目的:

1.2 项目主要内容

1.3 项目研究范围:

二、系统方案

2.1 系统总体框架

2.2 特色与创新点

2.2.1 项目特色:

2.2.2 项目创新点

2.3 系统基本方案

2.3.1 对作品的总体设计

2.3.2 对机器人进行实验,确保其达到预期的效

2.3.3 对实际应用的场景进行分析

三、功能与指标

3.1 系统硬件指标

3.2 微信小程序功能

3.3 主控芯片

3.4 图像处理模块

3.5 循迹避障模块

3.6 充电功能

3.7 物品取件功能

3.8 系统电源

3.9 OLED显示屏

3.10 矩阵按键

3.11  SG90舵机

四、 系统软件流程设计

4.1 系统运作概述

4.2 系统主程序设计

4.3 微信小程序设计

4.4 主程序部分代码树莓派

4.5 微信小程序 

4.6 获取地址 

4.7 电路原理图

五、结论与展望  

5.1 结论 

5.1.1 项目成果介绍

5.1.2 项目心得

5.2 展望

资源获取链接: 毕设&课设&项目&实训-基于树莓派的校园快递派送智能机器人(完整工程代码用户开发手册).zip_毕设资源-CSDN文库

资源详情: 

总文件夹:

源程序及电路图:

机器人实物图 :

 用户手册:


 

一、项目介绍

1.1 项目的意义与目的:

        现如今,网购已逐渐成为一种新兴的消费方式,而网购的兴起也促进了快递行业的蓬勃发展。但快递量的大幅增长也不可避免地带来一些问题,就目前市场上的区域内快递末端服务来看,主要有以下几类:使用智能快递柜或设立驿站、快递员派送、区域快递存放于附近商家[1]。这些配送模式的缺点体现在:配送成本高、配送效率低、快递人员送货时间与用户时间冲突[2]。加之2020年疫情的到来,给物流行业带来不小的影响,采用更先进更智能化的配送方案,不仅能够降低疫情期间的交叉感染,也能使人们的生活更加智能化、数字化[3]。

        依托此立项背景,为解决校园、小区等小型区域的“最后一公里”问题,制造集智能仓储与物流配送为一体、具备自动取件和派送功能的机器人[4]。该机器人可以自动循迹,按照用户要求到达指定位置后对具有特定特征(快递)的物品进行自动抓取搬 运派送,然后将物品运送至指定位置。智能运送机器人并不是完全脱离人的独立运行,可以实现人机交互。机器人如在自动运行过程中遇到特殊情况,可以采取人工干预方式做出相应处理。通过大数据应用3S+技术可以快速获取和更新智能运送机器人的地理位置信息,在发送用户快递通信信息的同时可以反馈自身信息。智能化技术的引入,解决了配送成本高、配送效率低、快递人员送货时间与用户时间冲突等问题,能够最大限度地解放劳动力,提升物流运输效率,为物流行业的健康发展奠定坚实可靠的技术基础[5]。

1.2 项目主要内容

        项目依托立项背景,制造一种具备有自动取件和派送功能的机器人。该机器人可以自动循迹,按照客户的需求到达指定位置后对具有特定特征(快递)的物品进行自动抓取搬运派送,然后将物品运送至客户指定位置。智能运送机器人并不是完全脱离人的运行,可以实现人机交互。除了自动运行的状态,在机器人遇到特殊情况时,能够人工干预。

        “3S+技术”又称之为地理空间信息科学,它含括有全球定位系统[6](GPS)、地理信息系统[7](GIS)和遥感技术[8](RS)等技术,地理空间信息科学是一门强调与通信、计算机技术融合的综合性集成技术学科。通过3S技术可以快速获取和更新智能运送机器人的地理位置信息和发送客户快递通信信息同时可以反馈自身信息。

        该项目结合机械臂控制、图像处理[9]、3S+、互联网技术,以智能运送机器人为主要研究对象。机械臂用以通过扫描特定特征进行自动抓取、放置货物;摄像头可扫描二维码并记录周围信息实时反馈给云端;智能运送机器人通过红外、超声波模块进行避障在遇到特殊情况下可以自动处理,辅以GPS定位系统进行循迹。通过物联网技术,将计算机与智能运送机器人建立联系,通过小程序发送任务指令智能运送机器人可以实时反馈周围信息,实现远程遥感、实时进行信息交互等功能以此达到自动取件和派送的目的同时客户可根据微信小程序下单,智能运送机器人根据地理位置信息进行派送,到达指定位置后,客户可通过输入矩阵密码取件或扫描微信二维码取件,具体流程如下:
    当客户在小程序上下单后,智能运送机器人在派送过程中会通过通信功能发送取件信息给指定的用户。软件反馈给机器人货物坐标,机器人移动至货物所对应的区域,再通过机械臂将货物取出,然后根据GPS定位规划的路线将货物运至指定地点,在即将到达指定地点时,发送短信给取件人,到达目标点后,取件人需通过扫描二维码或者输入取货密码来取出货物。若还有任务,则继续循迹至下一家。完成任务或是电量低于特定值后自动返回指定区域进行待机或者无线充电。

1.3 项目研究范围:

        可行性分析即从各个方面去证明项目或者工程具有必要性、迫切性、科学性、真实性,项目必须在客观存在条件的允许下能够顺利进行并产生较高的经济效益,并具有实际意义。区域性智能快递“车”[10]采用车轮加机械臂的框架设计,针对快递运输,体积小运输精确、节省时间等:区域化设计,在社区或学校使用,便于管理的同时,不会影响外界交通,安全性更高。就目前而言,区域型智能运送“机器人”主要进行的分析有:市场可行性以及经济可行性。

(1)市场可行性分析

        就目前市场上的区域内快递末端服务来看,主要有以下几类:使用智能快递柜或设立驿站、快递员派送、区域快递存放于附近商家、无人车派送快递其优缺点对比。技术的发展,提供了大带宽、低时延、高可靠性的能力,成为视觉识别、云计算和AI等新技术应用的有力保障。在这种形势下,区域性智能运送“机器人”也应运而生,完美的解决了用户便利度和配送成本之间的矛盾,让科技为时间买单。

(2)经济可行性分析

        根据当今的社会的经济走势,随着全面走向小康社会的形态,网上购物一行业不断地兴起,跟随时代的潮流走,也就触发了许多快递行业的兴起。就各大快递业公司而言也想快速的解决仓库的库存,及时派件,同时也会促进广大群众对该快递公司的认可届时与公司的合作也会变得更加的广泛。

二、系统方案

2.1 系统总体框架

        此系统主要包括:树莓派;超声波模块;红外模块;摄像头模块;GPS模块;串口WiFi模块;遥感制动模块;SD卡模块;机械臂模块;太阳能模块;无线充电模块十一部分。

        以树莓派[11]为核心的系统,装取货物时,通过摄像头[12]识别货物二维码,通过软件反馈剩余空格子的位置,并记录其坐标后将其放置在格子中。当客户在小程序上下单后,软件反馈给机器人货物坐标机器人移动至货物所对应的区域,再通过机械臂[13]将货物取出,然后根据GPS定位规划的路线将货物运至指定地点,在即将到达指定地点时,发送短信给取件人,到达目标点后取件人需通过扫描二维码或者输入取货密码来取出货物。若还有任务,则继续循迹至下一家完成任务或是电量低于特定值后自动返回指定区域进行待机或者无线充电。

2.2 特色与创新点

2.2.1 项目特色:

智能运送机器人与传统的快递行业的区别如下:

        (1)降低物流的成本,提高企业利润成本。

        (2)智能运送机器人的快递派送,节省时间,派送效率提高。

        (3)快递派送效率的提高,可以减少仓库在高峰期的储存量。

        (4)依托智能化的前提下,在物流管理方面,智能运输会提高物流管理水平。

        (5)智能的运输,就于“干线运输,区域配送”的模式,枢纽以仓库为配送中心。

智能运送机器人自身功能特色如下:

        (1)电源的应用:通过太阳能充电和无线充电。

        (2)采用3S+技术,运用互联网技术结合通信原理。

        (3)取件的方式应用:通过采用矩阵密码取件和扫描微信二维码取件。

        (4)机器人采用了履带代替轮胎,不容易损坏,并且能够适应多样地形。

        (5)机器人根据派送指令,派送过程中,用户超过取件时间,将自动返程或执行下一个任务。

        (6)智能运送机器人并不是完全脱离人的运行,可以实现人机交互。除了自动运行的状态,在机器人遇到特殊情况时,能够人工干预。

        (7)机器人的抓取依靠摄像头,具有自动抓取的能力。而且单个机器人独立一体不需要与其他设备协同工作,工作方式更灵活。

2.2.2 项目创新点

该项目的创新点介绍如下:

        (1)运用成本较低,可节约大量人工成本和器材设备费用。

        (2)可根据不同情况需要设定对应模式,提高了机器人功能的多样性和实用性。

        (3)在校园的环境下,自动派件功能能够极大的减少人力成本,同时也节省了客户的时间。

        (4)电源应用上:采用了无线充电功能和太阳能充电,机器人只需进入特定区域即可进行无线充电,不需要人工充电。采用太阳充电及在作业过程中可通过太阳能采集给予自身提供电量支持。

        通过使用使用3S+技术,运用GPS定位和遥感技术,GPS技术用于提前给用户提取包裹发送短信,满足客户需求。遥感技术运用于智能快递机器人紧急制动功能,在派送过程中遭遇突发情况时,停止作业或根据实际情况选择人工操作或者安全返回。机器人可发出定位信号,这样来达到寻回机器人目的。

2.3 系统基本方案

2.3.1 对作品的总体设计

(1)了解树莓派及各个模块的使用

        本项目使用树莓派对整个系统进行控制,所以对于树莓派的使用需要熟练掌握。同时,由于本项目中使用到了多个模块,对于不同模块使用了不同的通讯协议[14],因此在电路设计上,需要将不同的模块连接至合适的IO口,以达到硬件资源利用最大化。

(2)熟练掌握智能运送机器人的设计原理及其控制方法

        智能运送机器人主要有传动部分、避障部分、循迹部分及待机模式组成。传动部分由电机电机驱动、车底板、履带组成。当通过驱动对电机赋以不同形式的PWM波电压时小车就具有了前进、后退、转向以及掉头等运动功能。避障部分主要是一个或一组能反馈路线的电子模块,来判定前方是否有障碍物。比如线性CCD模块、红外模块或者超声波模块循迹部分通过GPS定位来规划路线。待机模式即当机器人完成任务或是电量低于特定值后自动返回指定区域进行待机或者无线充电。

(3)计算机与机器人的通信

        通过计算机与机器人的连接以实现多种功能,如远程遥感机器人,实时传输机器人的数据参数及周围的环境信息等。通过计算机发出命令,当命令发出后,机器人移动至仓库特定货物所处的区域,再通过机械臂将货物取出,然后根据GPS定位规划的路线将货物运至指定地点,并根据实际情况进行自我调整或人工干预,直到完成任务。

(4)对智能运送机器人各部件进行测试和组装调试

        进行每个部分的测试与组装调试。机器人组装以履带小车为基础,运用自动控制理论对系统进行分析和控制,通过编程避障算法实现履带小车预期的功能。在小车的基础上加装摄像头和机械臂,对摄像头采集的数据进行处理,然后将处理后的信息交给机械臂由机械臂实现抓取功能。

2.3.2 对机器人进行实验,确保其达到预期的效

        模拟实际不同应用场景,进行抓取运送实验,记录实验结果。通过实验结果分析系统存在不足,为进一步的完善研究提供参考和依据。

2.3.3 对实际应用的场景进行分析

        对实际应用的场景进行分析,比如实际路况、湿度、人为干扰等外在因素。以此来对该机器人的实际应用效果进行分析。

三、功能与指标

3.1 系统硬件指标

        智能运送机器人的硬件组件有:RaspberryPi4树莓派主控核心芯片、HD1313OpenCV摄像头、HC-SR04超声波、四路巡线红外探测、CN3163太阳能光伏板、5HW-225无线充电、JETSON NANO机械臂、MicroSD读写卡、ATK-ESP8266串口WiFi、ATK1218-BD GPS以及PS2无线遥控手柄。各部分器件通过铜柱、打胶以及连线连接。

3.2 微信小程序功能

        当客户在小程序上下单后,智能运送机器人在派送过程中会通过通信功能发送取件信息给指定的用户。软件反馈[15]给机器人货物坐标,机器人移动至货物所对应的区域,再通过机械臂将货物取出,然后根据GPS定位规划的路线将货物运至指定地点,在即将到达指定地点时,发送短信给取件人,到达目标点后,取件人需通过扫描二维码或者输入取货密码来取出货物。若还有任务,则继续循迹至下一家。完成任务或是电量低于特定值后自动返回指定区域进行待机或者无线充电。系统硬件结构设计流程如图3-1所示,实物图如图3-2所示。

8545058de11b4d0cb5c9142e425cd321.png

 图3-1  硬件结构图

a82480775d2c4dea9aca1314b48c54c9.jpeg

 图3-2 实物图

3.3 主控芯片

        树莓派是一款单片机电脑,集成了个人电脑和单片机的I/O功能于一体。树莓派的I/O速度不及单片机,功能也不及主流PC,但它却提供了一个非常强大的平台,允许用户创建复杂的计算机程序,这些程序可以使用Python、Java和c++等常用语言轻松地与硬件进行交互。本系统以树莓派为核心系统作为控制中心,通过树莓派对整个系统进行控制,以实现目标效果。树莓派主控芯片如图3-3所示。

 33dcb86344a94700b03fffdbc3246864.jpeg

图3-3  树莓派主控芯片

3.4 图像处理模块

        使用HD1313OOpenCV摄像头进行图像处理,该摄像头可以通过机器视觉算法处理复杂的输出,从而实现人脸识别、物体识别和追踪功能。此模块主要用于实时监控快递机器人的动向以及对取件人照片的收集,避免后期不必要的损失。HD1313OOpenCV摄像头如图3-4所示。

abfe5cadba5644fd8a170ea06848f653.png

图3-4  HD1313OOpenCV摄像头

 

3.5 循迹避障模块

循迹避障部分包括HC-SR04超声波模块和红外探测模块:(1)HC-SR04超声波模块。小车在行进的过程中,会向外界发出超声波并根据超声波传出及传回的时间来判断前方是否有障碍物,若有障碍物则停下,若无障碍物则继续前行。(2)红外探测模块。我们在小车的模拟行进路线上铺设了黑线,发射管随时发送红外线对外界进行扫描,接收管接收返回的红外信号。当扫描到黑线时,由于大部分红外线被黑线吸收,返回的红外线减少,灯便会熄灭,我们通过灯的亮灭来设计不同情况下机器人的左转右转或其他行为。超声波模块以及红外探测模块如图3-5所示。8192d851c7034eeb98fc9b8f357b2f0f.jpeg

图3-5 超声波模块以及红外探测模块

3.6 充电功能

        充电功能通过5HW-225无线充电模块[16]实现。该模块依据电磁感应原理(即变化的电流流过线圈产生变化的磁场,与紧挨的配对线圈耦合产生相应的电压)对小车进行无线充电。无线充电模块如图3-6所示。

b8db077e92074f42a1c55a9cd4c93c68.jpeg 图3-6  无线充电模块

3.7 物品取件功能

        物品取件功能通过JETSONNANO机械臂实现。我们通过控制机械臂力矩、规划机械臂关节空间运动轨迹使其具有模仿人手动作的功能,从而实现抓取和握紧(吸附)物品等操作。机械臂模块如图3-7所示。

1e53e8e03da349fe8e5c686fab6a2309.jpeg

3.8 系统电源

        格氏ACE航模电池系列是格瑞普旗下专业的电池品牌,选用2200mAhLiPo锂聚合物电池给该系统供电,放电性能好,可以满足所用模块的正常工作。

        电池供电电压为12V,由于本系统大多用电设备的工作电压均在5V,利用LM2596S DC-DC直流可调降压稳压电源模块板将系统电压稳至5V,该模块同时带有数显,可以显示输入及输出电压,使用方便。我们以此电池和稳压模块对小车与机械臂进行供电。锂聚合物电池实物图如图3-8所示,稳压电源模块板的实物图如图3-9所示。

0bbfc6de7a374ff185517bebd948bbdf.png

图3-8  LiPo锂聚合物电池 

6692b29b764e4fe98d151a598e936100.png

图3-9  LM2596S DC-DC直流可调降压稳压电源模块

3.9 OLED显示屏

        本系统采用4针OLED显示屏。OLED (Organic Light-Emitting Diode)有机发光二极管又称为有机激光显示。OLED显示技术具有自发光的特性,且采用非常薄的有机材料涂层和玻璃基板。当有电流通过时,这些有机材料就会发光,而且OLED显示屏幕可视角大、功耗低、具备自发光、不需背光源、对比度高、厚度薄视角广、反应速度快、可用于挠曲面板,使用温度范围广,结构及制程等优异之特性。先接触的1286屏都是LCD的,需要背光、功耗较高;而OLED的功耗低,更加适合小系统,由于两者发光材料的不同,在不同的环境中,OLED的显示效果好,模块供电可以是3.3v也可以是5V,不需要修改模块电路。OLED屏具有多个控制指令,可以控制OLED的亮度、对比度、开关升压电路等指令、操作方便、功能丰富、可显示汉字、AScH图案等,同时为了方便应用在产品上,预留4个M3固定孔,方便用户固定在机壳上。我们使用此OLED来显示存取件方面的内容。OLED显示屏如图3-10所示。

8bfc389427914b72afc8c590ca239441.jpeg

图3-10  OLED显示屏 

3.10 矩阵按键

        本项目采用了4*4矩阵键盘。矩阵键盘是单片机外部设备中所使用的排布类似于矩阵的键盘组。矩阵式结构的键盘显然比直接法要复杂一些,识别也要复杂一些,列线通过电阻接正电源,并将行线所接的单片机的I/O口作为输出端,而列线所接的I/O口则作为输入。在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式。在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。这样,一个端口(如P1口)就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,这款矩阵键盘体积小,节省空间,使用方便,共计16按键。我们通过此矩阵键盘来实现输入取件码取件的功能。其实物图如图3-11所示。

208ff99ce678496c89a68d34add24dd5.png

图3-11  4*4矩阵键盘

3.11  SG90舵机

        舵机是一种位置(角度)伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。目前,在高档遥控玩具,如飞机、潜艇模型,遥控机器人中已经得到了普遍应用。

        舵机主要是由外壳、电路板、驱动马达、减速器与位置检测元件所构成。其工作原理是由接收机发出讯号给舵机,经由电路板上的 IC驱动无核心马达开始转动,透过减速齿轮将动力传至摆臂,同时由位置检测器送回讯号,判断是否已经到达定位。位置检测器其实就是可变电阻,当舵机转动时电阻值也会随之改变,藉由检测电阻值便可知转动的角度。一般的伺服马达是将细铜线缠绕在三极转子上,当电流流经线圈时便会产生磁场,与转子外围的磁铁产生排斥作用,进而产生转动的作用力。依据物理学原理,物体的转动惯量与质量成正比,因此要转动质量愈大的物体,所需的作用力也愈大。舵机为求转速快、耗电小,于是将细铜线缠绕成极薄的中空圆柱体,形成一个重量极轻的无极中空转子,并将磁铁置於圆柱体内,这就是空心杯马达。我们通过此舵机模块实现柜子的关闭与开启。SG90舵机模块如图3-12所示。

594f4eac42ef41f0a3de7d383a532d7f.jpeg

图3-12  SG90舵机模块 

四、 系统软件流程设计

4.1 系统运作概述

        装取货物时,系统通过摄像头识别货物二维码,处理数据并反馈剩余空格子的位置,树莓派记录其坐标后将其放置在格子中。用户在小程序上下单后,云端[17]接收订单信息后向树莓派发送订单信息,树莓派接收订单信息并反馈给机器人货物坐标,机器人移动至货物所在的区域,用机械臂将货物取出,然后根据GPS定位规划路线[18]将货物运送至指定地点,在即将到达指定地点时,向取件人发送取件短信。机器人到达目标点后,取件人需通过扫描二维码或者是输入取件码的方式取出货物,若还有任务,机器人则继续循迹至下一家,机器人在完成任务(或是电量低于特定值)后将自动返回指定区域,进入待机或无线充电模式。

4.2 系统主程序设计

        系统主程序实现流程如图4-1所示。

152831484da44a3e8543f1a91a4c86ad.png

 图4-1  主程序实现流程

 

4.3 微信小程序设计

        将微信小程序[19]设计为用户可以在上面下单并提交快递信息,当快递件到达时,用户可以通过扫描二维码或输入取件码的方式取件。通过微信小程序和云端控制[20],可以满足用户需求。通信功能实现方式为:用户通过小程序下单,云端接收指令后向智能快递机器人发送指令,机器人控制系统控制机械臂自动识别并抓取货物,如图4-2所示。

f992f5bf05484af0aa3cd5a261b73761.png

              图4-2  机械臂运转流程图

        快递到达指定地点后,用户可通过微信小程序扫码[21]或输入取件码的方式提取快递包裹,云端可通过用户输入的取件码,判断是否为用户所需的快递。如果用户输入的取件码不正确,则取件失败,并且用户可以根据自己的需求发送短信“QJ”指令到云端,云端将会重新为其发送取件码,如图4-3所示。

0a0c2d7da2924934bb68d1f3f58436f8.png

图4-3   用户取件流程图

应用界面如图4-4所示。

3ce711894a404957bc697ff0868cc2ad.jpeg

图4-4  用户下单界面图

4.4 主程序部分代码树莓派

Camera.py(摄像头设置)
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
cap.set(3,640) # set width
cap.set(4,480) # set heightwhile True:ret, frame = cap.read()frame = cv2.flip(frame, -1) # flip camera verticallygray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)cv2.imshow('frame',frame)
#   cv2.imshow('gray',gray)k = cv2.waitKey(30) & 0xffif k == 27: # press 'ESC' to quitbreak
cap.release()
cv2.destroyALLWindows()She.py(摄像头调用)
import cv2
import timecv2.NamedWindow("camera", 1)capture = cv2.CaptureFromCAM(0)while True:img = cv.QueryFrame(capture)cv2.ShowImage("camera", img)if cv2.WaitKey(10) == 27:break
cv2.destroyAllWindows()Hongwai.py(红外)
#coding=utf-8
import RPi.GPIO as GPIO
import time
import dianji
#定义红外循迹传感器GPIO口
L1=33
L2=31
L3=35
L4=37
def init():#设置接触警告#GPIO.setwarnings(False)#设置引脚模式为物理模式#GPIO.setmode(GPIO.BOARD)#红外循迹传感器引脚初始化,设置为输入,接受红外信号GPIO.setup(L1,GPIO.IN)GPIO.setup(L2,GPIO.IN)GPIO.setup(L3,GPIO.IN)GPIO.setup(L4,GPIO.IN)
#红外循迹函数
def track():init()#接收4红外传感器的信号L11=GPIO.input(L1)L22=GPIO.input(L2)L33=GPIO.input(L3)L44=GPIO.input(L4)  #liang- falseif L11==L22==L33==L44==True:for i in range(2):dianji.qd(2,750)if L11==L44==True and L22==L33==False:for i in range(2):dianji.qd(1,1)if L11==L22==L33==L44==False:for i in range(2):dianji.qd(0)time.sleep(1)dianji.qd(4,1)time.sleep(0.6)breakif L11==L44==L22==True and L33==False:for i in range(2):dianji.qd(4,1)if L11==L33==L44==True and L22==False:for i in range(2):dianji.qd(3,1)if L11==L22==L33==False and L44==True:for i in range(2):dianji.qd(3,1)if L11==L22==False and L33==L44==True:for i in range(2):dianji.qd(3,1)if L11==False and L22==L33==L44==True:for i in range(2):dianji.qd(3,1)if L11==L33==False and L22==L44==True:for i in range(2):dianji.qd(3,1)if L11==L22==L44==False and L33==True:dianji.qd(2,1)if L11==L22==True and L33==L44==False:for i in range(2):dianji.qd(4,1)if L11==True and L22==L33==L44==False:for i in range(2):dianji.qd(4,1)if L11==L22==L33==True and L44==False:for i in range(2):dianji.qd(4,1)if L11==L33==True and L22==L44==False:for i in range(2):dianji.qd(4,1)dianji.py(电机)
# -*- coding: utf-8 -*-                 #通过声明可以在程序中书写中文
import RPi.GPIO as GPIO                 #引入RPi.GPIO库函数命名为GPIO
import time                             #引入计时time函数
#import wiringPidef qd(k,p=50):s=10#接口定义INT1 = 32INT2 = 36INT3 = 38INT4 = 40GPIO.setmode(GPIO.BOARD)                #将GPIO编程方式设置为BOARD模式# 无视警告,开启引脚GPIO.setwarnings(False)# 设置引脚为输出GPIO.setup([INT1,INT2,INT3,INT4],GPIO.OUT)pwm1,pwm2,pwm3,pwm4=GPIO.PWM(INT1,p),GPIO.PWM(INT2,p),GPIO.PWM(INT3,p),GPIO.PWM(INT4,p)# 启动pwmpwm1.start(0)pwm2.start(0)pwm3.start(0)pwm4.start(0)pwm1.ChangeDutyCycle(s)pwm2.ChangeDutyCycle(s)pwm3.ChangeDutyCycle(s)pwm4.ChangeDutyCycle(s)if k==0:#stopGPIO.output([INT1, INT2], GPIO.HIGH)GPIO.output([INT3, INT4], GPIO.LOW)elif k==1:#qianjin# 让小车前进GPIO.output([INT1, INT3], GPIO.HIGH)GPIO.output([INT2, INT4], GPIO.LOW)elif k==2:#houtuiGPIO.output([INT1, INT3], GPIO.LOW)GPIO.output([INT2, INT4], GPIO.HIGH)elif k==3:#LGPIO.output([INT2, INT3], GPIO.HIGH)GPIO.output([INT1, INT4], GPIO.LOW)elif k==4:#RGPIO.output([INT1, INT4], GPIO.HIGH)GPIO.output([INT2, INT3], GPIO.LOW)csb.py(超声波)
#!/usr/bin/env python3
import time
import RPi.GPIO as GPIO
trigger_pin =16
echo_pin =18
GPIO.setmode(GPIO.BOARD)
GPIO.setup(trigger_pin,GPIO.OUT)
GPIO.setup(echo_pin,GPIO.IN)
#TRIG 负责发射超声波,Echo 负责接收超声波
def send_trigger_pulse():#发送超声波,一直发GPIO.output(trigger_pin,1)# 为了防止错误,因为紧接着就需要把发射端置为高电平time.sleep(0.0001)#发射端置为高电平GPIO.output(trigger_pin,0)
#ECHO 负责接收超声波
def wait_for_echo(value,timeout):count = timeout#通过该代码持续获取ECHO的状态while GPIO.input(echo_pin)!= value and count>0:count = count-1
#计算距离
def get_distance():# 发射send_trigger_pulse()# 接收高电平 1/Truewait_for_echo(True,10000)# 等待start = time.time()#接收低电平wait_for_echo(False,10000)finish = time.time()pulse_len = finish-startdistance_cm = pulse_len/0.000058print("cm = %f"%distance_cm)return distance_cmlanya.py(蓝牙)
import serial
while 1:ser = serial.Serial("/dev/ttyAMA0",115200) #开启串口,波特率为9600ser.write("1".encode()) #写入一个字符“1”ser.write("10.111".encode())ser.close() #关闭串口main.py(主函数)
import dianji  #  0\1\2\3\4  stop\qianjin\houtui\L\R
import time
import csb
import hongwai as hw
while True:dianji.qd(1,50)hw.track()if csb.get_distance()<20:while True:dianji.qd(0)if csb.get_distance()>20:break//**********************机械臂********************
主函数
import os
import sys
import getopt
import socketif __name__ == "__main__":host = '0.0.0.0'port = 8000addr = (host, port)udpServer = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)udpServer.bind(addr)while True:data, addr = udpServer.recvfrom(1024)msg = str(data, encoding = 'utf-8')print(msg)if msg == "YAHBOOMARM_FIND":udpServer.sendto(bytes("Dofbot_Pi_V1.0", encoding='utf-8'), addr)print("send ok")
摄像头
# !/usr/bin/env python
# encoding:utf-8
import cv2 as cvif __name__ == '__main__':capture = cv.VideoCapture(0)while 1:_, img = capture.read()img = cv.resize(img, (640, 480), )cv.imshow("img", img)action = cv.waitKey(10) & 0xffif action == 27:breakcv.destroyAllWindows()#coding=utf-8
# camera.py
import cv2class VideoCamera(object):def __init__(self):# Using OpenCV to capture from device 0. If you have trouble capturing# from a webcam, comment the line below out and use a video file# instead.self.video = cv2.VideoCapture(0)self.video.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter.fourcc('M', 'J', 'P', 'G'))self.video.set(cv2.CAP_PROP_BRIGHTNESS, 30) #设置亮度 -64 - 64  0.0self.video.set(cv2.CAP_PROP_CONTRAST, 50) #设置对比度 -64 - 64  2.0self.video.set(cv2.CAP_PROP_EXPOSURE, 156) #设置曝光值 1.0 - 5000  156.0self.video.set(3, 640)self.video.set(4, 480)self.video.set(5, 30)  # 设置帧率# If you decide to use video.mp4, you must have this file in the folder# as the main.py.# self.video = cv2.VideoCapture('video.mp4')def __del__(self):self.video.release()def get_frame(self):success, image = self.video.read()# We are using Motion JPEG, but OpenCV defaults to capture raw images,# so we must encode it into JPEG in order to correctly display the# video stream.if(success == False):print ("Read Error!")return bytes({1});return imagedef get_frame2(self):success, image = self.video.read()# We are using Motion JPEG, but OpenCV defaults to capture raw images,# so we must encode it into JPEG in order to correctly display the# video stream.if(success == False):#print ("Read Error!")return bytes({1});ret, jpeg = cv2.imencode('.jpg', image)# 对于 python2.7 或者低版本的 numpy 请使用 jpeg.tostring()return jpeg.tobytes()
货物识别
import smbus
import time
bus = smbus.SMBus(1)addr = 0x0d
rgb_off_reg = 0x07
Max_LED = 3def setRGB(num, r, g, b):if num >= Max_LED:bus.write_byte_data(addr, 0x00, 0xff)bus.write_byte_data(addr, 0x01, r&0xff)bus.write_byte_data(addr, 0x02, g&0xff)bus.write_byte_data(addr, 0x03, b&0xff)elif num >= 0:bus.write_byte_data(addr, 0x00, num&0xff)bus.write_byte_data(addr, 0x01, r&0xff)bus.write_byte_data(addr, 0x02, g&0xff)bus.write_byte_data(addr, 0x03, b&0xff)bus.write_byte_data(addr, rgb_off_reg, 0x00)
time.sleep(1)
setRGB(Max_LED, 0, 0, 255)import smbus
import time
import os
bus = smbus.SMBus(1)addr = 0x0d
fan_reg = 0x08
state = 0
temp = 0
level_temp = 0
rgb_off_reg = 0x07
Max_LED = 3def setRGB(num, r, g, b):if num >= Max_LED:bus.write_byte_data(addr, 0x00, 0xff)bus.write_byte_data(addr, 0x01, r&0xff)bus.write_byte_data(addr, 0x02, g&0xff)bus.write_byte_data(addr, 0x03, b&0xff)elif num >= 0:bus.write_byte_data(addr, 0x00, num&0xff)bus.write_byte_data(addr, 0x01, r&0xff)bus.write_byte_data(addr, 0x02, g&0xff)bus.write_byte_data(addr, 0x03, b&0xff)while True:cmd = os.popen('vcgencmd measure_temp').readline()CPU_TEMP = cmd.replace("temp=","").replace("'C\n","")print(CPU_TEMP)temp = float(CPU_TEMP)if abs(temp - level_temp) >= 1:if temp <= 45:level_temp = 45setRGB(Max_LED, 0x00, 0x00, 0xff)elif temp <= 47:level_temp = 47setRGB(Max_LED, 0x1e, 0x90, 0xff)elif temp <= 49:level_temp = 49setRGB(Max_LED, 0x00, 0xbf, 0xff)elif temp <= 51:level_temp = 51setRGB(Max_LED, 0x5f, 0x9e, 0xa0)elif temp <= 53:level_temp = 53setRGB(Max_LED, 0xff, 0xff, 0x00)elif temp <= 55:level_temp = 55setRGB(Max_LED, 0xff, 0xd7, 0x00)elif temp <= 57:level_temp = 57setRGB(Max_LED, 0xff, 0xa5, 0x00)elif temp <= 59:level_temp = 59setRGB(Max_LED, 0xff, 0x8c, 0x00)elif temp <= 61:level_temp = 61setRGB(Max_LED, 0xff, 0x45, 0x00)elif temp >= 63:level_temp = 63setRGB(Max_LED, 0xff, 0x00, 0x00)time.sleep(.5)OLED:
import time
import osimport Adafruit_SSD1306from PIL import Image
from PIL import ImageDraw
from PIL import ImageFontimport subprocess# Raspberry Pi pin configuration:
RST = None     # on the PiOLED this pin isnt used# 128x32 display with hardware I2C:
disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST)# Initialize library.
disp.begin()# Clear display.
disp.clear()
disp.display()# Create blank image for drawing.
# Make sure to create image with mode '1' for 1-bit color.
width = disp.width
height = disp.height
image = Image.new('1', (width, height))# Get drawing object to draw on image.
draw = ImageDraw.Draw(image)# Draw a black filled box to clear the image.
draw.rectangle((0,0,width,height), outline=0, fill=0)# Draw some shapes.
# First define some constants to allow easy resizing of shapes.
padding = -2
top = padding
bottom = height-padding
# Move left to right keeping track of the current x position for drawing shapes.
x = 0# Load default font.
font = ImageFont.load_default()def getCPULoadRate():f1 = os.popen("cat /proc/stat", 'r')stat1 = f1.readline()count = 10data_1 = []for i  in range (count):data_1.append(int(stat1.split(' ')[i+2]))total_1 = data_1[0]+data_1[1]+data_1[2]+data_1[3]+data_1[4]+data_1[5]+data_1[6]+data_1[7]+data_1[8]+data_1[9]idle_1 = data_1[3]time.sleep(1)f2 = os.popen("cat /proc/stat", 'r')stat2 = f2.readline()data_2 = []for i  in range (count):data_2.append(int(stat2.split(' ')[i+2]))total_2 = data_2[0]+data_2[1]+data_2[2]+data_2[3]+data_2[4]+data_2[5]+data_2[6]+data_2[7]+data_2[8]+data_2[9]idle_2 = data_2[3]total = int(total_2-total_1)idle = int(idle_2-idle_1)usage = int(total-idle)print("idle:"+str(idle)+"  total:"+str(total))usageRate = int(float(usage  / total) * 100)return "CPU:"+str(usageRate)+"%"while True:# Draw a black filled box to clear the image.draw.rectangle((0,0,width,height), outline=0, fill=0)# Shell scripts for system monitoring from here : https://unix.stackexchange.com/questions/119126/command-to-display-memory-usage-disk-usage-and-cpu-load# cmd = "top -bn1 | grep load | awk '{printf \"CPU:%.0f%%\", $(NF-2)*100}'"# CPU = subprocess.check_output(cmd, shell = True)CPU = getCPULoadRate()cmd = os.popen('vcgencmd measure_temp').readline()CPU_TEMP = cmd.replace("temp=","Temp:").replace("'C\n","C")cmd = "free -m | awk 'NR==2{printf \"RAM:%s/%s MB \", $2-$3,$2}'"MemUsage = subprocess.check_output(cmd, shell = True )cmd = "df -h | awk '$NF==\"/\"{printf \"Disk:%d/%dMB\", ($2-$3)*1024,$2*1024}'"Disk = subprocess.check_output(cmd, shell = True )cmd = "hostname -I | cut -d\' \' -f1"IP = subprocess.check_output(cmd, shell = True )# Write two lines of text.draw.text((x, top), str(CPU), font=font, fill=255)draw.text((x+56, top), str(CPU_TEMP), font=font, fill=255)draw.text((x, top+8), str(MemUsage),  font=font, fill=255)draw.text((x, top+16), str(Disk),  font=font, fill=255)draw.text((x, top+24), "wlan0:" + str(IP),  font=font, fill=255)# Display image.disp.image(image)disp.display()time.sleep(.1)

4.5 微信小程序 

  /**点提交时将新的数据获取过来 赋给info对象*/async submit() {let info = {userAddr: this.data.userAddr,size: this.data.selectedSize,remark: this.data.remark,price: this.data.price,time: this.data.times[this.data.times_index],store: this.data.stores[this.data.stores_index],number: this.data.number[this.data.number_index]}let infoOld = await wx.getStorage({key: "info"                 /**从缓存中异步获取info */}).catch(_=>{})if (infoOld) {let infoNew = infoOld.datainfoNew.push(info)wx.setStorage({    /**缓存新的信息 */key: "info",  /**本地缓存指定key,data指存储的新的信息 */data: infoNew})} else {wx.setStorage({key: "info",data: [info]})}console.log(await wx.getStorage({key: "info"}));wx.showToast({title: 'ok!',})wx.navigateBack({       /**返回当前页面 */delta: 1})},

4.6 获取地址 

async chooseLocation() {let location = await wx.chooseLocation().catch(_=>{})console.log(location);if(!location){return}this.setData({userAddr: location.address || ""})},
/**扫码 */addGoosInfo: function() {var that = this;var show;/**使用api,调用微信的扫一扫 */wx.scanCode({success: (res) => {this.show = "结果:" + res.result;console.log(this.show)that.setData({addName: this.show})wx.showToast({title: '扫码成功',icon: 'success',duration: 2000})},fail: (res) => {wx.showToast({title: '扫码失败',icon: 'success',duration: 2000})},complete: (res) => {}})},

4.7 电路原理图

99350ffafa2348d4bfedabd4b710869e.png

五、结论与展望  

5.1 结论 

5.1.1 项目成果介绍

        (1)该项目研究的主要成果:设计并制作完成智能小车的取件派件功能,促进快递“取送”过程工业化,提高快递业的工作效率,实现取送件过程的智能化。微信小程序能够实现扫码取件、快递下单、订单信息追踪等功能;电压监测及无线充电的功能使得小车每次出发前都能保证充足的电力;同时通过摄像头模块能够实时拍照和监测在电脑上同步显示功能。

        (3)主要结论:该项目综合利用应用电子技术、传感器技术、树莓派技术完成了对智能快递小车的研究和设计。前期,学习部分模块并编写相应功能实现代码,同时进行小程序的设计,基本功能实现后,开始进行硬件电路的焊接。最后进行系统性地调试,将软硬件相互配合,以确保该系统能够正常工作,并观测其调试结果是否符合设计要求。同时逐渐优化代码及硬件设施,完善系统功能,提高项目可行性。

        (4)应用情况:该项目基于自助寄取快递系统,融入模块化、集成化的设计理念,可实现工序间的相互配合,促进快递“取送”过程工业化,提高快递业的工作效率,实现取送件过程的智能化,有较好的推广应用价值。具有广阔的应用前景和发展空间。

5.1.2 项目心得

        (1)团队意识:一个好的团队,应该有共同认可的明确目标、合理的分工协作、良好的信息沟通、队员之间的相互信任以及积极主动的参与心。在我们研究项目的过程中,按质按量按时完成各自分配的任务,是团队中我们每个人应该承担的责任。同时,作为一个团队,成员之间应当互帮互助,相互鼓励相互学习,不断的互相激励,这样才能使大家共同进步。

        (2)沟通能力::在团队成员相互磨合,共享任务进度,分享学习内容,遇到问题时相互交流,获取新的思想,我们的沟通能力都得到了极大的提高。在定期向指导老师汇报项目进度的时候,在交流的过程中也提高了表达能力。

        (3)自主学习能力:这是参加大学生创新训练项目最大的收获之一。在项目中,遇到的问题往往需要宽广的知识面及一定的开发经历解决,没有人能直接的告诉你问题原因所在。在这种情况下,自己就要能够分析出问题可能出现的原因,并通过网络资源及相关书籍进行学习,与自己的实验条件等信息进行比较,经不断地修改调试去解决问题,在不断的失败与探索中,我们的自主学习能力都有了显著的提升。

        (5)创新能力:是个人在学习工作和事业上的永久的活力源泉。在本次项目开展的过程中,项目组成员的创新能力得到明显提升,针对项目的功能,每个人都有自己的思考和实现想法,试想在此基础上能结合怎样的理论知识研究出新的成果。

5.2 展望

        回顾这个系统的设计过程,前期,学习部分模块并编写相应功能实现代码,基本功能实现后,开始进行硬件电路的焊接。最后进行系统性地调试,将软硬件相互配合,以确保该系统能够正常工作,并观测其调试结果是否符合设计要求。在不断地调试中,需要模拟不同条件下的存取件情况,以及应对突发情况,逐渐优化代码及硬件设施,完善系统功能,提高项目可行性。

        但是在研究的整个过程中,只考虑了一些简单的情况,在灵活地应对复杂的外界情况依然是一个令人深思的问题。单片机的开发率还不够,我们并没有把单片机的真正的优点展示出来,只知单片机的皮毛,所以还有待继续深究。在新的科技时代到来,有望通过大数据应用3S技术可以快速获取和更新智能运送机器人的地理位置信息和发送客户快递通信信息同时可以反馈自身信息。通过智能化,落实了解决配送成本高、配送效率低、快递人员与用户送货时间冲突等问题。

 

资源获取链接: 毕设&课设&项目&实训-基于树莓派的校园快递派送智能机器人(完整工程代码用户开发手册).zip_毕设资源-CSDN文库

资源详情: 

总文件夹:

8bb51429d8224e4f9c6e080b52babbb4.png

源程序及电路图:

5ad93f804f4845d9b31886ef39bfee47.png

1.机械臂代码:

c41e4bcb067b4b2990fef0c231c5b16b.png

 2.微信小程序代码:

1a8c17df719247d599e01ced20c6d8a3.png

3.机器人代码: 

95bd1836c9454e2b883964a7daa9d962.png

4. 电路图:

336deb93af344a45ab54f0ac3c3f764a.png

机器人实物图 :

e6a9e7f84269423ba690853f2b64d3b0.png

 用户手册:

ca9a05c8b8ae4005bcf76bf6bf47998f.png

 

 

这篇关于【树莓派项目】基于树莓派的校园快递派送智能机器人(完整工程资料源码)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

如何用Docker运行Django项目

本章教程,介绍如何用Docker创建一个Django,并运行能够访问。 一、拉取镜像 这里我们使用python3.11版本的docker镜像 docker pull python:3.11 二、运行容器 这里我们将容器内部的8080端口,映射到宿主机的80端口上。 docker run -itd --name python311 -p

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

在cscode中通过maven创建java项目

在cscode中创建java项目 可以通过博客完成maven的导入 建立maven项目 使用快捷键 Ctrl + Shift + P 建立一个 Maven 项目 1 Ctrl + Shift + P 打开输入框2 输入 "> java create"3 选择 maven4 选择 No Archetype5 输入 域名6 输入项目名称7 建立一个文件目录存放项目,文件名一般为项目名8 确定

Java ArrayList扩容机制 (源码解读)

结论:初始长度为10,若所需长度小于1.5倍原长度,则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义         1:数组默认长度         2:这是一个共享的空数组实例,用于明确创建长度为0时的ArrayList ,比如通过 new ArrayList<>(0),ArrayList 内部的数组 elementData 会指向这个 EMPTY_EL

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get