基于STM32的智能巡检小车系统设计
基于STM32的智能巡检小车系统设计--选材篇作者:车邮箱:692604135@qq.com学校:西安工程大学硕士研究生方向:机器视觉、图像分割、深度学习本人毕业设计题目是基于STM32的智能小车巡检系统设计,所以在这里我把我所使用的开发板,各个模块,从各种器件的选择,到安装、连线、测试、代码在这里po出来,有需要的小伙伴在这里自取。
1、这一篇是选材篇,也就是我都用了哪些东西。因为我也是自己做,到现在为止还没有完全把所有要做得功能都实现,所以我会分开把所有的东西发出来,顺便也是记录一下自己第一次自己做软硬件结合课题的经历。
2、本文设计的基于STM32的巡检系统,需利用灰度循迹传感器模块对地面上的黑色赛道进行检测从而实现小车的自动循迹;通过避障模块确保小车的安全循迹;同时,小车会在指定位置停下来,测量此位置的温度并显示在液晶显示屏上。巡检系统可以实现自主循迹、避障、定点测温的功能。系统的具体功能和参数定义如下:(1)本设计中小车需要完成巡检任务,小车在整个过程中的车速要求为0~20cm/s。(2)用来循迹的灰度传感器的探测距离是10~50mm,灰度循迹模块中要求灰度传感器的探测距离是15mm。(3)为了保证顺利测试,本设计需要实现多方位避障,以此来减小外界环境带来的影响,红外避障模块的有效距离范围2~80cm。在本设计中,红外避障模块的探测距离需达到60mm以上。(4)本设计需要实现不同方向的避障,需要用到超声波避障传感器,超声波测距模块可提供2cm~400cm的非接触式距离感测功能,此模块的感应角度小于等于15°,测量精度可高达3mm。(5)红外测温模块需要测量环境中的温度,此模块测量温度范围宽且测量精度高,测量范围为-55℃–+125℃;同时,红外测温模块在-10~+85°C范围内,精度为±0.5°C。(6)红外传感器测量的温度要求在液晶显示屏上进行显示,显示精度要求是小数点后1位。
3、本设计主要有以下几个模块:主控制器、电源模块、电机驱动模块、电机、循迹模块、避障模块、测温模块以及显示模块。基于STM32的巡检系统总体设计组成框图如下图所示:
接下来就切入正题,我会把我需要使用的东西全部展示出来。
我使用的是STM32F407VET6的开发板,具体如下图所示:用到的小车如下:(这个小车是在某宝上购买的,只要搜索小车底盘就会有,回来的时候是零件,安装比较简单,可以联系客服自取)用到的电机驱动板是L298N,我用到了一个这个板子,驱动两个轱辘。虽然一共有四个轱辘,但是我把两个轱辘的电机卸了,也就是后面两个轮子变成了从动的。板子具体如下图所示:这里,我用18650锂电池给L298N进行供电。由于电机的驱动电压是3V-12V,所以我选择12V供电电池组。这个锂电池组是可以充电的,也就是买电池的时候顺便要买一个充电器,要不然就相当于买了一个一次性的电池组(如果店家送的话就不用自己买了)。STM32开发板需要5V供电。由于我是给STM32和L298N分开供电,所以这里我用下面这样的电池组供电。一节是1.2V,四节串联就是4.8V,但是实际上经过测量四节电池串联大概有5.3V左右,给STM32供电是完全足够的。这个电池也是有充电盒可以充电的,要不然就是跟上面一样,买了一次性的电池。(充电的比较环保哦!)电池供电当然需要一个装载它的电池盒,这里的电池盒最好是带开关的,会比较方便,要不然断电的时候就只能把电池扣下来,会比较麻烦。(当然这块我只是建议,大家可以根据需要自己选择)避障模块一共需要两种传感器1>超声波避障传感器:型号是HC-SR04这个主要是测正前方的障碍物。2>红外避障传感器:型号是HJ-IR1这个主要是测下面偏低的障碍物。
还需要一个三路循迹模块,模块大概就是下面如图所示:当然这些只是参考,具体的器件选择还要根据具体情况而定。后面我会把每一个模块每一个出传感器的具体使用方法写出来,包括硬件的连线,测试,软件的代码,还有我做出的成果都会展示出来。有问题的话欢迎给我评论留言,我们一起学习。
【工程训练/水中机器人】水下管道智能巡检【视觉部分】总结
【工程训练/水中机器人】水下管道智能巡检【视觉部分】总结本文为第七届大学生工程训练综合能力竞赛中【水下管道智能巡检赛项】和第十四届国际水中机器人大赛【水下管道智能巡检组】视觉部分总结。
前言我在队伍中主要负责机器人视觉功能的实现,所以在本篇参赛总结中只会涉及视觉功能实现的思路和过程。
提示:下文中所提出的实现方法不一定是最优解,如果有其他更好的建议和想法,我衷心欢迎大家与我交流,一起学习进步!一、规则解读完整规则太多了,这里仅引入一些与视觉部分相关的内容。
水下机器人能够对水下管道上的吸附物进行检测报警及移除清理等,竞赛过程中水下机器人必须全程自主运行。赛场尺寸(长×宽×高)为3000×2000×600(mm)长方形水池,示意图如下:水下管道铺设在水池内,分浅水区、渐变区和深水区。管道上共设置若干(大于5、小于20)个吸附物,分布在管道各处。熟悉规则后,总结视觉任务如下:
管道巡线吸附物检测与识别二、实现思路1.管道巡线硬件采用openmv,寻迹对象为水下白色管道,思路与我的另一篇博文:https://blog.csdn.net/qq_39784672/article/details/121239435?spm=1001.2014.3001.5501中寻迹思路相仿,这里就不赘述了。
2.吸附物检测与识别吸附物在管道上布置方式如下图所示:吸附物为实心黑色物体,其截面为正方形、圆形两种,边长或直径尺寸限制在30~50mm范围,厚度不大于30mm。吸附物截面图如下:
上面为第十四届国际水中机器人大赛的比赛规则,工训的规则和这个相差不大。工训中要求检测并识别出吸附物形状;而水中则只需检测出即可,算是降低了难度。
吸附物检测与识别我们采用了两种方案:
(1)openmv手工特征我们尝试过许多特征,比如色块框像素占比、圆形和矩形查找等。
(2)k210目标检测模型通过制作吸附物的数据集训练yolo目标检测模型,最终部署到k210上进行预测输出吸附物类型和位置,完成检测和识别任务。相关实现方法参加我的另一篇博文:【实战】K210训练与部署YOLO目标检测模型
openmv代码最终比赛代码如下:
importsensor,image,time,pybimportmathfrompybimportUART,Timer#返回参数初始化tube_offset_angle=0#管道偏移角tube_offset_distance=0#管道偏移距离obstacle_shape=0#障碍物形状,取值规则:0:没有障碍物;1:圆形障碍物;2:矩形障碍物#调试参数tube_threshold=(30,100,-128,127,-128,127)#管道LAB阈值obstacle_threshold=(0,18,-7,26,-3,12)#障碍物LAB阈值timer_freg=25#定时器触发间隔(Hz)#定时器回调函数deftimeFunc(timer):time_flag=1#判断障碍块位置#return:0:left1:center2:right3:errordefgetPosition(o_b,t_b):#计算与管道中心的偏移x_offset=(o_b[0]+o_b[2]/2)-(t_b[0]+t_b[2]/2)#print(x_offset)ifabs(x_offset)=250andblob.pixels()max_size:max_blob=blobmax_size=blob.pixels()returnmax_blobsensor.reset()#初始化摄像头sensor.set_pixformat(sensor.RGB565)#格式为RGB565sensor.set_framesize(sensor.QQVGA)#使用QQVGA速度快一些,160*120sensor.skip_frames(n=800)#跳过800s,使新设置生效,并自动调节白平衡sensor.set_auto_gain(False)#关闭自动自动增益sensor.set_auto_whitebal(False)uart=UART(3,115200)#初始化串口通信参数clock=time.clock()#追踪帧率time_flag=0#定时标志位timer=Timer(2)#使用定时器2创建一个定时器对象timer.init(freq=timer_freg)#设置触发间隔timer.callback(timeFunc)#定义定时器回调函数scale=0#图像比例尺(mm/pixel)while(True):clock.tick()img=sensor.snapshot()#识别管道tube_blobs=img.find_blobs([tube_threshold],pixels_threshold=2000)iftube_blobs:tube_flag=1t_b=find_max(tube_blobs)tube_offset_angle=t_b[7]tube_offset_distance=t_b[5]scale=75/t_b[2]#print(scale)img.draw_rectangle(t_b[0:4])#绘制管道方向线#img.draw_line((t_b[5],t_b[6],t_b[5]+int(50*math.cos(t_b[7])),t_b[6]+int(50*math.sin(t_b[7]))),color=(255,255,255))#识别障碍物obstacle_blobs=img.find_blobs([obstacle_threshold],roi=(t_b[0:4]),pixels_threshold=100)ifobstacle_blobs:o_b=find_max(obstacle_blobs)img.draw_rectangle(o_b[0:4])ifabs((o_b[1]+o_b[3]/2)-60)35*scale:#print(o_b[3]-35*scale)obstacle_shape=2else:#print(o_b.density())ifo_b.density()