朱成彪 ,张陆翔 ,2,赵奉奎
(1.南京林业大学,江苏 南京 210037; 2.南京奥联新能源有限公司,江苏 南京 210037)
随着国家大力支持研发和使用智能设备,AGV(Automated Guided Vehicle)小车凭借其智能化、自动化和高柔韧性等优点,应用范围越来越广。 除了物流行业,AGV 小车还被广泛地应用在汽车、医药、化工等行业中。 AGV 小车的运用,有利于优化产业结构,提高生产效率和加快物流等产业的升级。
AGV 小车智能高效的运作离不开可靠的引导方式, 目前主流的引导方式主要包括电磁引导[1]、惯性引导[2]、激光引导[3]和视觉引导。 Hyunhak Cho等人(2017)提出了利用磁编码器的电磁引导AGV系统[4]。 李照和舒志兵(2017)提出利用模糊算法来调控AGV 两个主动轮速度从而优化电磁引导AGV 系统[5]。 Ti-chun Wang(2020)提出了基于多传感器的惯性引导AGV 系统[6]。张东等人(2019)提出利用模糊 PID 算法优化惯性引导 AGV 系统[7]。Kyunghoon Jung(2014)提出利用无迹卡尔曼滤波器和模糊推理系统进行定位改进的激光引导AGV 系统[8]。 王心越(2019)等人设计了用于汽车防撞预警的激光引导 AGV 系统[9]。刘康婷(2021)等人研究了基于视觉引导的AGV 系统[10]。 与前三种引导方式相比,视觉引导具有设备成本低、识别能力强、不易积累误差和高柔韧性等特点[11-12]。
本文从引导线检测和转向控制两方面入手,设计了基于视觉引导的AGV 系统, 并通过试验证明搭载该系统的小车可以完成自动引导。
如图1 所示是AGV 小车的结构图, 小车包括Jetson Nano 主板、散热器、摄像头、无线网卡、天线、碳纤维底盘、橡胶轮胎、电机、舵机和避震器等部分。图2 是AGV 系统的基本框架,小车通过摄像头获取前方路径的图像信息, 将信息传入Ubuntu 操作系统中,在Ubuntu 操作系统内利用Python 语言对图像信息进行处理和分析。 Ubuntu 操作系统运行在Nvidia Jetson Nano 主板中, 程序将根据图像信息处理结果将AGV 转向和驱动命令通过IIC 发送给驱动板, 驱动板则对舵机和电机进行驱动,实现AGV 小车的循迹行驶。
图1 AGV 小车结构图Figure 1 AGV Car structure diagram
图2 AGV 系统的基本框架Figure2 Basic framework of AGV system
引导线检测是本系统设计的基础,检测流程如图3 所示。 首先通过 Canny 算法,对摄像头获取的图像信息进行边缘检测, 检测出图像中的边缘信息;再利用ROI 函数进行剔除操作,将车道外的边缘信息剔除,只保留需要的区域,通过霍夫变换将该区域内的边缘信息进行整合分类,利用离群值过滤去除分类里误差较大的边缘信息;最后通过最小二乘拟合将处理好的边缘信息进行拟合,并使用画线函数将拟合得到的线段在图像上绘制出来以便后续操作。
图3 边缘检测流程图Figure 3 Flow chart of edge detection
进行引导线检测的第一步就是通过边缘检测将图片的边缘信息提取出来,之后再判断这些边缘是否属于引导线, 所以说边缘检测是很重要的环节。 机器视觉上进行边缘检测,一个通用的算法为Canny 算法。Canny 算法的基本步骤依次为:利用高斯模糊去除噪声、计算梯度的方向和大小、对梯度幅值进行非极大值抑制、选择阈值、检测和连接边缘等[13-14]。 Canny 算法中梯度方向 θ 和大小 M 的计算公式如式1 所示。
Canny 算法是通过求取图像上每一个像素点周围像素变化的梯度来确定这个点是不是边缘[15]。图4 是Canny 边缘检测示例图,图中横向为梯度方向,沿着梯度方向有三个点:C,A 和B,可以很明显看到A 点是处在边缘上的点,B 点和C 点没有处在边缘上。沿着梯度方向对这三个点周边的像素值求梯度,会发现C 点左右像素值大致相等,沿着横向方向的梯度接近于0,B 点同理。 而对于A 点,其左右像素值相差较大,对其左右两边的像素值求梯度,A 点处的梯度值会非常大。因此,可以通过求某点周围像素值的梯度来反映其是否是边缘点,如果该点左右两边梯度值较大,则该点便极大概率为一个边缘点。
图4 Canny 边缘检测示例图Figure 4 Flow chart of edge detection
在实际的引导线检测过程中,往往还会受到许多其他因素影响,例如光照、摄像头像素等。受到这些因素的影响,会导致检测出现错误,此时就需要利用Canny 算法对梯度设上阈值和下阈值,如图5所示。
图5 上下阈值示例图Figure 5 Example diagram of upper and lower thresholds
对于一些梯度超过上阈值的点, 如图中的A点,则认为A 点是个边缘点。 然后对于那些梯度小于下阈值的点,如图中D 点,则认为D 点不是一个边缘点。然而还有一些点的梯度正好介于上阈值和下阈值之间,如图中B 点和C 点,这两点有可能是边缘点,也有可能不是边缘点,无法对B 点和C 点进行准确判断。 对此,Canny 算法中应用了关联讨论:将梯度高于上阈值的点称为强边缘点,如强边缘A 点; 将梯度在上阈值和下阈值之间的点称为弱边缘点,如弱边缘B 点和弱边缘C 点。 任何一个弱边缘点,如果它与强边缘点相连,如图中弱边缘B 点与强边缘A 点相连, 此时就认为B 点是真正的边缘点;如果弱边缘不与强边缘相连,如图中C点,则认为C 点不是一个边缘点。 通过这种方式,即可实现弱边缘的检测处理。 本论文调用OpenCV函数库中的cv2.Canny 函数对图像进行Canny 算法检测。Canny 边缘检测结果如图6 所示,图6a)为原始图片,图6b)为Canny 边缘检测的结果。 由图可知,利用Canny 边缘检测可以准确提取出图像中的边缘信息。
图6 Canny 边缘检测结果图Figure 6 Canny edge detection result graph
通过前文的Canny 边缘检测算法,成功提取图像中的边缘信息,这些边缘信息里,既包括小车运行车道的边缘信息,也包括其他车道部分的边缘信息。 图像中其他车道部分的边缘信息,对于检测引导线来说是没有意义的,会造成干扰,所以需要把这些无关的信息剔除。因为本文检测数据集的特殊性,小车运行车道的图像信息一直分布在图像中一个类似梯形的区域内,如图7 所示。
图7 感兴趣区域示例图Figure 7 Example map of the region of interest
此时需要使用 ROI(Region of Interest)函数,把图像中这个梯形区域以外的那些边缘信息剔除掉,只保留梯形区域里的信息,这样就实现了对这些无关信息的过滤剔除。本论文通过调用OpenCV 函数库中的 cv2.fillPoly 函数, 并结合图 7 中 1 号点、2号点、3 号点和4 号点的像素坐标进行感兴趣区域提取。 感兴趣区域提取结果如图8 所示。
图8 感兴趣区域提取结果Figure 8 Region of interest
通过前文感兴趣区域的提取获取了图中两条引导线所在的梯形区域。下一步将利用这个梯形区域,从中提取出属于引导线的线段,从而得到这两条引导线的具体位置, 此时就需要用到霍夫变换。霍夫变换的基本原理是利用点和线的对偶性,即在原始二维图像坐标系下的一个点对应了参数坐标系中的一条直线;同样,参数坐标系的一条直线对应了原始二维坐标系下的一个点,原始坐标系下直线上所有的点,它们的斜率和截距是相同的,所以它们在参数坐标系下对应于同一个点。这样在将原始坐标系下的各个点投影到参数坐标系下之后,看参数坐标系下有没有聚集点,类似的聚集点就对应了原始坐标系下的直线[15-16]。
因为引导线分为左引导线和右引线,两条引导线存在差异,所以在进行霍夫变换前需要先定义一个按照斜率分类的函数,将检测出来的线段按照斜率分成两类,即一类是左引导线,另一类是右引导线。 本文通过调用OpenCV 函数库中 cv2.Hough LinesP 函数进行霍夫变换。霍夫变换检测结果为左引导线分类里有77 条线段,右引导线分类里有74条线段。利用霍夫变换成功将感兴趣区域中的线段进行整合分类。
利用霍夫变换成功将所有感兴趣区域内的线段按照斜率分成了左引导线和右引导线两类,但是其中可能会有一些误差线段。霍夫变换一共识别出151 条线段,这些线段并不全属于左引导线或右引导线,其中可能包含无用的线段,例如噪点的连线也会被识别成一条线段。 这些点需要过滤掉。 通过对Canny 边缘检测结果图的观察可以发现引导线共同的一个特征,就是属于引导线的线段的斜率应该是大致相同的。 对此,可以求梯形内所有的线段集合,取斜率,找那些斜率与平均斜率相差特别大的线段,即为不属于需要检测的引导线。 在此就需要使用离群值过滤函数。
本论文通过使用函数reject_abnormal_lines(lines,threshold=0.2),函数中 threshold 参数的阈值设置为0.2, 即如果某条线段的斜率与平均斜率相差超过0.2 就会被检测出来。 利用剔除函数将被检测出来的线段进行剔除, 通过不断循环此函数,直到所有线段的斜率与平均斜率相差都小于或等于0.2,就完成了离群值过滤,利用保留下来的线段完成后续检测。离群值过滤检测结果为左引导线分类里保留69 条线段, 右引导线分类里保留52 条线段。通过使用离群值过滤可以成功将斜率误差较大的线段去除,与霍夫变换检测结果相比,共去除了30 条线段。
通过离群值过滤去除了分类里的误差线段,保留了符合检测要求的线段,此时需要使用最小二乘拟合将左引导线和右引导线分类里的线段各拟合成一条线段[16]。本论文通过调用函数np.polyfit 进行最小二乘拟合,并利用画线函数将拟合得到的线段在原图上绘制出来以便后续操作,绘制结果如图9所示。
图9 引导线检测结果Figure 9 Leading line detection results
利用检测出的引导线信息可实现小车在车道内的直线运行,但对于一个AGV 系统,还需要考虑小车的自动转向问题。 对此,需要在上文的引导线检测基础上,再添加检测一条辅助线,来帮助实现AGV 智能小车的转向控制。 本论文中选择通过检测AGV 小车行驶路径上一段连续路径的中心线,并将检测得到的线段作为辅助线, 图10 为转向辅助线检测结果。 当路径发生转向时,中心线也会发生偏移,检测出来的辅助线也会发生偏移,而辅助线偏移的方向就是AGV 智能小车行驶路径前方路段的变化方向。
图10 转向辅助线检测图Figure 10 Inspection diagram of steering assist line
通过对路径中心线的检测,得到了用于辨别方向变化的辅助线, 但是AGV 智能小车的转向控制还需要得到偏移角度,对此需要求出转向辅助线的斜率。 在普通的二维坐标系中,想要得到一条线的斜率,只需要这条线上的两点就可以完成,在图像的像素坐标系中也是类似。 利用坐标检测函数,对转向辅助线两个顶点进行检测, 得到这条线段两个顶点的像素坐标 P1(X1,Y1)和 P2(X2,Y2),利用这两个顶点坐标就可以求出这条辅助线的斜率K。考虑到AGV 智能小车实际行驶的路径情况,有一部分的路线是直线,此时没有转向的需求,因此需要在求取斜率时检测两个顶点坐标的第一个值是否相同。
本论文通过使用IF 判断函数, 用以判断两顶点像素坐标的第一个数值的差是否为0, 即判断(X2-X1)是否为 0。 如果为 0 则代表 AGV 智能小车运行前方路径没有发生转向,后续转向控制就不需要执行;如果不为0,则代表AGV 智能小车运行前方路径发生转向,需要执行后续转向控制。 本文使用函数 K=(y2-y1)/(x2-x1)求取斜率,利用该方法成功得到转向辅助线的斜率K。
利用两个顶点像素坐标成功求得转向辅助线斜率K 之后, 此时就需要使用反三角函数中的反正切函函数,如图11 所示,利用公式S=arctanK 得到辅助线与像素坐标中X 轴的夹角S,然后再利用D=90°-S 就可以得到AGV 智能小车行驶前方路径相对于小车当前行驶方向的偏转角度。
图11 偏移角度示例图Figure 11 Example diagram of offset angle
通过利用辅助线得到AGV 智能小车的偏移角度,AGV 智能小车就可以利用这个数据进行方向修正以实现转向。 但在方向修正之前,还需要进一步处理, 因为AGV 智能小车本身行驶时可能会有一个初始转向系数。 这里用A 表示这个转向系数,A0表示初始转向系数, 正常情况下转向系数A 的取值区间为(-1,1),其中-1 和 1 表示小车完全向左转和完全向右转。 如果直接用这个初始值A0加上前文得到的偏移角度D,会因为两个数据类型不同而产生错误,无法实现方向修正。因此,需要使用AGV 智能小车自带的PID 控制将前文得到的偏移角度转化为实际的转向系数A1, 将转向系数A1输入AGV 智能小车舵机驱动控制系统中替换初始值A0,让舵机调整小车行驶方向,从而完成转向控制。PID 比例微分积分控制, 其公式如式2 所示。 PID控制器的参数选择必须考虑动态和静态性能指标的要求。 通过试验得到优化的Kp、Ki和Kd三个参数值,从而完成转向控制。
通过引导线检测和转向控制两部分的设计,便完成了基于机器视觉引导的AGV 系统, 将系统传入小车开始试验。AGV 小车运作流程如图12 所示。
图12 AGV 小车运作流程图Figure 12 Operation flow chart of AGV trolley
摆好并启动小车后, 驱动电机控制小车向前行驶,车载摄像头会不断获取前方路径图像信息,然后将信息传入Jetson Nano 主板中。 主板会根据代码指令对图像信息进行分析处理, 得到小车当前的行驶数据和小车运行前方的路径信息, 并通过这些数据判断小车是否需要转向。 如果需要转向, 就会将利用辅助线计算得到的偏移角度发送给小车里的PID 控制,PID 控制利用偏移角度计算得到小车需要的转向系数, 将转向系数传给小车的舵机驱动,舵机驱动控制舵机使小车完成转向。如果不需要转向就判断小车是否需要停车, 如果需要停车就停止驱动电机,使小车结束运行;如果不需要停车, 就再通过摄像头获取新的路径信息进行数据处理和后续的判断操作。 通过不断循环收集数据、处理信息和判断执行等操作,以此完成小车的自动引导。
本文主要介绍了基于视觉引导的AGV 系统设计,系统主要通过引导线检测和转向控制两部分实现。系统试验中引导线检测程序能够准确检测并提取引导线,信息分析程序能够对提取到的引导线信息进行正确分析处理,并且控制程序能使小车自动沿引导线行驶。 试验结果表明基于机器视觉的AGV 小车能够实现自动引导功能。