移动机器人的自主导航

机器人可以通过多种方式从外界接收信息以进行交互。同样,根据分配给他的任务,处理此信息的方法也有所不同。在本文中,我将描述作为学校项目一部分而进行的工作的主要阶段,其目的是将有关自动机器人导航的各种方法的信息系统化,并将在创建机器人过程中获得的知识应用于“ RTK Cup”竞赛。



介绍


在“ RTK杯”比赛中,必须完成一些任务而无需操作员干预。我相信许多参与者都在不公平地避免执行这些任务,因为创建机器人设计和编写程序看似复杂,将来自其他竞争学科的简化任务隐藏在一个训练场中。在我的项目中,我想展示一些解决此类问题的方法,下面以示例为例。

为了实现项目目标,制定了以下中间任务:

  • “ RTK杯”比赛规则分析
  • 现有的移动机器人自主定向算法分析
  • 软件制作

“ RTK杯”比赛规则分析


在“ RTK杯”比赛中,将为参与者展示一个训练场,在该训练场上模拟不同复杂性的部分。该竞赛旨在激发年轻的机器人技术人员创造出可以在极端条件下工作,克服障碍,在人为控制下或自主运行的设备。



简要介绍组成多边形的元素
«» , . , , (), , (), ..

:



:



– , «» ( ) , . , , , , .

. , , , , , , .

比赛分为两个根本不同的提名:“搜寻者”和“极端”。这是为了确保在年龄和开发机器人系统的经验方面差异最小的参与者之间进行比赛:年龄较小的寻求者和14岁以上年龄的参与者的极限。在Seeker提名中,操作员可以在范围内自由移动并直接与机器进行目光接触,而Extreme提名则假定机器人具有视频通信系统和/或计算机视觉,因为操作员必须仅在迷宫中导航在迷宫中内置在机器人中的摄像头和传感器,同时位于特殊的屏幕后面。

为了参加比赛,机器人必须要么通过任务来操纵机械手,要么执行自主性元素之一。在项目框架中,任务被设置为执行自治任务,因为它们以最低的成本从操作员那里获得最多的积分。自治的要素包括:

  • 沿着带有环境光传感器或视线系统的线行驶
  • 使用距离传感器或视觉系统进行独立信标捕获
  • 使用指南针,陀螺仪,加速度计,视觉系统或组合方法沿一条直线沿着复杂的轨迹(例如,楼梯的上升/下降)移动

此外,如果机器人自主通过障碍物,则克服障碍物的点数也会加倍。

在该项目的框架内,将考虑对第一个任务的解决方案-沿线移动。沿线移动时最常用的方法是光传感器和照相机。传感器的优点包括创建程序的简便性-它们中的许多都装有调谐电阻,因此通过将传感器设置为背景照明,根据是否在线,传感器将发出0或1的信号。由于相同的原因,光传感器对所用控制器的处理能力没有要求。同样,因此,借助光传感器解决问题的成本最低-最简单的传感器的成本为35卢布,并且对于沿线相对稳定的行驶,三个传感器就足够了(一个安装在生产线上,两个安装在侧面)。然而,这种传感器的主要缺点之一是安装限制。理想情况下,传感器应准确安装在中心位置,离地板一小段距离,否则会给出错误的值。在专业比赛中,机器人必须尽可能快地沿着赛道行驶,这不是问题,但是在“ RTK Cup”比赛中,上述所有传感器缺陷都是至关重要的-安装它们首先需要在机器人上安装额外的机械零件,这些零件会抬起并降低传感器,这需要在机器人上留出更多空间,需要单独的引擎来移动传感器,这也是可能造成损坏的地方,并增加了机器人的质量。否则会给出错误的值。在专业比赛中,机器人必须尽可能快地沿着赛道行驶,这不是问题,但是在“ RTK Cup”比赛中,上述所有传感器缺陷都是至关重要的-安装它们首先需要在机器人上安装额外的机械零件,这些零件会抬起并降低传感器,这需要在机器人上留出更多空间,需要单独的引擎来移动传感器,这也是可能造成损坏的地方,并增加了机器人的质量。否则会给出错误的值。在专业比赛中,机器人必须尽可能快地沿着赛道行驶,这不是问题,但是在“ RTK Cup”比赛中,上述所有传感器缺陷都非常关键-安装它们首先需要在机器人上安装额外的机械零件,这些零件会抬起并降低传感器,这需要在机器人上留出更多空间,需要单独的引擎来移动传感器,这也是可能造成损坏的地方,并增加了机器人的质量。所有上述传感器缺陷都可能是至关重要的-安装它们首先需要在机器人上安装额外的机械部件来升高和降低传感器,并且这需要在机器人上留出额外的空间,一个单独的电动机来移动传感器,并且这也是可能造成损坏并增加机器人质量的地方。所有上述传感器缺陷都可能是至关重要的-安装它们首先需要在机器人上安装额外的机械部件来升高和降低传感器,并且这需要在机器人上留出额外的空间,一个单独的电动机来移动传感器,并且这也是可能造成损坏并增加机器人质量的地方。



该摄像机又具有以下优点:它具有几乎无限的测量半径(与传感器相比),即只有一个摄像头模块能够同时在机器人正下方并与机器人保持足够的距离同时看到该直线,从而可以例如评估其曲率并选择比例控制动作。同时,摄像头模块不会干扰机器人在垃圾填埋场其他不需要自治的地方的前进,因为摄像头固定在离地面一定距离的位置。摄像机的主要缺点是视频处理需要机器人上强大的计算复杂性,并且正在开发的软件需要进行更精细的调整,因为摄像机从外部世界接收的信息要比三个光传感器多一个数量级,而摄像机和计算机能够处理接收到的信息的能力是三个传感器和“ arduins”的许多倍。

就我个人而言,答案对我来说很明显-在“极端”提名中,机器人必须具有定向摄像机,操作员可以使用该摄像机进行导航。如果使用现成的FPV解决方案,则“传感器”的总成本可能更高,同时需要安装其他设备。此外,具有树莓派的机器人和照相机具有发展自主运动的更大潜力,因为照相机可以解决各种各样的问题,不仅可以用于直线运动,而且不会使设计复杂化。

现有计算机视觉算法分析


计算机视觉是一种创建设备的理论,该设备可以接收现实世界中的对象的图像,处理并使用所获得的数据来解决各种应用问题,而无需人工干预。

计算机视觉系统包括:

  • 一台或多台相机
  • 电脑综合体
  • 提供图像处理工具的软件
  • 用于传输目标和遥测信息的通信通道。

如前所述,有很多方法可以识别我们感兴趣的对象。在沿着一条线行驶的情况下,必须将线本身与对比背景分开(白色背景上的黑线或黑色背景上的白线用于反线)。使用计算机视觉系统的算法可以分为几个用于处理原始图像的“步骤”:

图像获取:直接从相机,从传输到设备的视频流中获取数字图像,或者将其作为单独的图像。像素值通常对应于光强度(彩色或灰度图像),但可以与各种物理测量值相关联,例如热像仪的温度。

初步处理:在将计算机视觉方法应用于视频数据之前,必须进行预处理以引入某些条件,具体取决于所使用的方法。例如:

  • 消除使用过的传感器引起的噪音或失真
  • 图像模糊用于消除照相机操作,减压元件,噪音等过程中出现的细微伪影。
  • 改善对比度,以便更可能检测到正确的信息
  • 更改对作物阴影或高光的曝光
  • 缩放或裁剪以更好地区分图像中的结构。
  • 将图像转换为单色或更改其分辨率以提高系统性能

突出显示细节:从视频数据中提取各种难度级别的图像细节。此类细节的典型示例是线条,边界,边缘,单个点,任何要素都具有特征的区域。
检测:在程序工作的某个阶段,与程序相关的信息会与其余图像分开。例如:

  • 选择一组特定的颜色兴趣点,在某种程度上相似的孤立像素数量(图形的曲率,颜色,亮度等)
  • 分割包含特征对象的一个​​或多个图像部分。

高级处理:在此步骤中,来自图像的大量信息被减小到可以轻松处理的大小,例如,一组特定像素或图像中应该放置感兴趣对象的部分的坐标。例如:

  • 按任何条件过滤值
  • 评估诸如对象的物理尺寸,形状,其在框架中或相对于其他特征对象的位置之类的参数
  • 分类

接下来,有必要选择将在其上创建程序的库。我选择的关键因素是:

  • 由于初学者相对容易地学习该语言,该库对Python接口的支持是简单的语法,这对程序的可读性具有有益的影响。
  • 可移植性,即 可以在树莓派pi3上使用此库运行程序。
  • 该库的普遍性保证了一个发达的程序员社区,他们可能已经在工作中遇到问题。

在我研究的选项中,我重点介绍了OpenCV开放式计算机视觉库,因为它支持Python,并具有广泛的在线文档。互联网上有许多文章和说明描述了使用此库的所有细微差别。开发人员有一个官方论坛,任何人都可以提出问题。另外,该库以C / C ++语言实现,可保证系统性能,并且其结构支持可禁用的各种模块以提高性能。

软件开发


在安装了Raspberry pi的操作系统并进行了初始配置之后,但是在开始创建程序之前,必须安装该程序所需的所有软件包。依次使用pip软件包管理器安装了大多数这些软件包(对于Python 3,是pip3)

$ sudo apt install python3-pip

安装了以下库,例如:

  • picamera-使用树莓派相机的库
  • numpy-一个用于处理多维数据数组(如图像)的库

$ sudo pip3 install picamera
$ sudo pip3 install numpy

cmake-用于从源代码自动构建程序的实用程序
cmake-curses-gui-cmake的GUI软件包(图形界面)

$ sudo apt-get install cmake cmake-curses-gui libgtk2.0-dev
$ sudo apt-get install cmake cmake-curses-gui libgtk2.0-dev

用于处理不同图像和视频格式等的库

$ sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev libx264-dev libxvidcore-dev
$ sudo apt-get install libjpeg-dev libpng12-dev libtiff5-dev libjasper-dev
$ sudo apt-get install gfortran libatlas-base-dev

要将视频数据从机器人传输到计算机,将使用GStreamer-一种旨在接收,处理和传输多媒体数据的框架:

$ sudo apt install libgstreamer1.0-0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-doc gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 gstreamer1.0-pulseaudio

下一步是从源代码安装openCV库本身,对其进行配置和构建。为此,将创建一个opencv工作文件夹。

$ mkdir opencv
$ cd opencv

为了下载该库的最新版本,使用了wget -一种用于从网络下载文件的控制台程序。在创建程序时,openCV的最新稳定版本是4.1.0,因此请下载并解压缩源代码:

$ wget https://github.com/opencv/opencv/archive/4.1.0.zip -O opencv_source.zip
$ unzip opencv_source.zip
$ wget https://github.com/opencv/opencv_contrib/archive/4.1.0.zip -O opencv_contrib.zip
$ unzip opencv_contrib.zip

解压缩过程完成后,可以删除源归档。

$ rm opencv_source.zip
$ rm opencv_contrib.zip

创建用于组装和配置的目录。

$ cd /home/pi/opencv/opencv-4.1.0
$ mkdir build
$ cd build

使用cmake实用程序配置构建参数。为此,将所有重要参数与分配的值一起作为实用程序变量传递:

cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D INSTALL_PYTHON_EXAMPLES=ON -D INSTALL_C_EXAMPLES=OFF -D BUILD_opencv_python2=OFF -D WITH_GSTREAMER=ON -D BUILD_EXAMPLES=ON -DENABLE_VFPV3=ON -DENABLE_NEON=ON -DCPU_BASELINE=NEON ..

设置完配置后,该实用程序将显示所有参数。接下来,您需要编译该库。为此,请使用控制台命令make –jN,其中N是编译过程中将涉及的内核数。对于raspberry pi 3,核心数为4,但是您可以肯定的通过在控制台中编写nproc命令来找到此数字。

$ make –j4

由于树莓派的资源有限,编译可能要花费相当长的时间。在某些情况下,树莓甚至可以冻结,但是如果您以后进入build文件夹并重新注册make,则工作将继续。如果发生这种情况,减少所涉及的内核数量是值得的,但是,我的编译没有问题。同样,在此阶段,值得考虑对树莓进行主动冷却,因为即使这样,处理器温度也达到了约75度。

编译成功后,需要安装该库。也可以使用make实用程序完成此操作。然后,我们将使用ldconfig实用程序形成所有必要的连接:

$ sudo make install
$ sudo ldconfig

我们通过以python交互模式编写以下命令来验证安装:

import cv2
print(cv2.getBuildInformation())

该程序的以下结论将表明安装正确:



应当注意,上述库编译过程必须在机器人以及计划从中控制机器人的PC上执行,并且必须在该PC上接收机器人的广播。

创建视频分配方案

在开始编写代码之前,您需要开发一种算法可以根据其起作用的方案。考虑到为参加极端竞赛提名的RTK Cup竞赛而创建的机器人的软件开发,整个程序将分为两个部分:机器人和遥控器,这将由安装了Linux的计算机播放。这里最重要的任务之一是创建一种算法的近似方案,该方案将如何在算法的不同部分之间传输视频数据。 Wi-Fi将用作两个设备之间的通信通道。使用套接字库实现的UDP协议将提供对机器人的控制和反馈数据的数据包从一个设备传输到另一设备。视频数据由于UDP数据包大小的限制,将使用GStreamer进行传输。为了方便调试,将实现两个视频流:

  • 主视频流-将视频数据直接从机器人的相机传输到计算机,以确保最小的控制延迟。
  • 辅助视频流-传输由机器人处理的视频数据,这对于设置和调试实现计算机视觉的程序是必需的。

机器人上将同时激活两个视频流,并且计算机将根据启用的驱动器模式显示所需的图像。反过来,根据自主模式是打开还是关闭,机器人将使用从计算机接收到的或由图像处理器生成的控制数据。



由于机器人和计算机上有两个并行流程,因此将对机器人进行远程控制:

  • 循环中的“控制台”会轮询所有可用的输入设备,并形成一个由数据本身和校验和组成的控制数据包(在对文章进行最终更改时,我拒绝创建校验和以减少延迟,但是在源中,我在代码的末尾列出该代码)-由某个数据集计算得出的某个值,该数据集是通过某种算法来确定传输过程中数据的完整性的
  • 机械手-等待来自计算机的数据访问。解压缩数据,重新计算校验和,并将其与计算机端发送和计算的结果进行比较。如果校验和匹配,则将数据传输到主程序。

在解析线检测算法之前,建议您熟悉机器人的设计功能:

关于机器人
.

— . (3 ) . , . 6 , . . . . , - . «» rasberry pi 3 b — .

, , , , Solidworks petg . , raspberry .

ubiquiti bullet M5 hp. ( ) , . , «» .


: «» thingiverse. , , , , .


, , . , . , , , , . , , , .





- ( - 200 ) , , 90 70 ( ), , « ». , VL53L0X , .


«» , , (rds3115). — , , , , .


, , , :


- , , , . . raspberry, , . , .

, USB. , , .




使用OpenCV库方法创建线检测算法


I.接收数据

由于图像处理器不是直接从相机而是从主流接收视频数据,因此有必要将其从转换格式转换为图像处理格式,即由红色值组成的numpy数组。 ,每个像素的绿色和蓝色。为此,您需要初始数据-从树莓派相机模块接收的帧。

从相机c获取帧以进行进一步处理的最简单方法是使用picamera库。开始之前,您需要允许通过raspi-config->界面连接选项camera->选择“是”来访问摄像机。

sudo raspi-config

下一部分代码将连接到树莓相机,并以给定频率的周期接收阵列形式的帧,以供opencv库使用。

from picamera.array import PiRGBArray
from picamera import PiCamera
import cv2
#   
camera = PiCamera()
camera.resolution = (640, 480) 
camera.framerate = 30
cap = PiRGBArray(camera, size=(640, 480))

for frame in camera.capture_continuous(cap , format="bgr", use_video_port=True):
	new_frame = frame.array
	cap.truncate(0)
	if False: #   -   
		break

值得注意的是,这种捕获帧的方法虽然最简单,但却有一个严重的缺点:如果您需要通过GStreamer广播帧,那么这种方法不是很有效,因为这需要多次重新编码视频,这降低了程序的速度。获得图像的更快方法是应图像处理器的请求从视频流中输出帧,但是,图像处理的其他阶段将不取决于所使用的方法。

未经处理的来自机器人头部的摄像头的图像示例:


二。预处理

在直线上行驶时,最容易与背景颜色形成鲜明对比的点区域分开是最简单的。此方法非常适合RTK杯比赛,因为它在白色背景上使用黑线(或在反面部分使用黑色背景上的白线)。为了减少需要处理的信息量,可以对其应用二值化算法,即将图像转换为单色格式,其中只有两种类型的像素-暗和亮。在此之前,应将图片转换为灰度,并对其进行模糊处理,以消除相机操作过程中不可避免出现的细微缺陷和噪点。为了使图像模糊,使用了高斯滤波器。

gray = cv2.cvtColor(self._frame, cv2.COLOR_RGB2GRAY)
blur = cv2.GaussianBlur(gray, (ksize, ksize), 0)

其中ksize是高斯核的大小,增大ksize可以增加模糊度。

灰度和模糊翻译后的示例图像:


三,选择细节

将图像灰度转换后,有必要在给定的阈值下将其二值化。此操作使您可以进一步减少数据量,此阈值将在机器人每次离开新地点之前或在光照条件发生变化时进行调整。理想情况下,校准的任务是确保在图像上定义了线条的轮廓,但是同时,图像上不应有不是线条的其他细节:

thresh = cv2.threshold(blur, self._limit, 255, cv2.THRESH_BINARY_INV)[1]

在此,所有比阈值(self._limit)暗的像素均被替换为0(黑色),而较亮的像素被替换为255(白色)。

处理后,图像如下所示:


如您所见,该程序已识别出图像中最暗的几个部分。但是,已经校准了阈值以便完全“捕捉”耳机后,屏幕上还会出现其他白色元素。当然,您可以微调阈值,并且在竞争性的训练场上,相机将往下看,不允许不必要的元素进入画面,但我认为我有必要将这条线与其他所有线分开。

四,检测

在二值化图像中,我应用了边界搜索算法。为了确定独立点并将其转换为组成边界的点的坐标值的便捷数组是需要的。在opencv的情况下,如文档中所写,用于查找循环的标准算法使用Suzuki85算法(除了opencv文档之外,我无法在其他任何地方找到对该名称的算法的引用,但我将假定这是Suzuki-Abe算法)。

contours = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)[0]

这是在此阶段获得的框架:


五,高级处理

找到框架中的所有轮廓后,将选择面积最大的轮廓作为线的轮廓。知道该轮廓的所有点的坐标,即可找到其中心的坐标。为此,使用所谓的“图像矩”。弯矩是轮廓的总特征,通过将轮廓的所有像素的坐标相加得出。时刻有几种类型-直到三阶。对于此问题,仅需要零阶矩(m00)-组成轮廓的所有点的数量(轮廓的周长),一阶矩(m10)是所有点的X坐标之和,而m01是所有点的Y坐标之和。通过将沿一个轴的点的坐标之和除以它们的数目,可以得到算术平均值-轮廓中心的近似坐标。接下来,计算机器人与路线的偏差:路线“直接”对应于沿X的中心点的坐标,该坐标接近于帧宽度除以2。如果线中心的坐标接近框架的中心,则控制动作将最小化,因此,机器人将保留其当前路线。如果机器人偏离一侧,则将引入与偏差成比例的控制动作,直到返回为止。

mainContour = max(contours, key = cv2.contourArea)
M = cv2.moments(mainContour)
if M['m00'] != 0:#     (..   -  )
    cx = int(M['m10']/M['m00'])
    cy = int(M['m01']/M['m00'])

下面是机器人相对于直线和框架的位置的示意图,程序的结果叠加在它们上:“主”轮廓,穿过轮廓中心的线以及位于中心的点以估计偏差。使用以下代码添加这些元素:

cv2.line(frame, (cx, 0), (cx, self.height), (255, 0, 0), 1)    #    
cv2.line(frame, (0, cy), (self.width, cy), (255, 0, 0), 1)                  
cv2.circle(frame, (self.width//2, self.height//2), 3, (0, 0, 255), -1) #  
cv2.drawContours(frame, mainContour, -1, (0, 255, 0), 2, cv2.FILLED) #   

为了方便调试,将所有先前描述的元素添加到原始帧:





因此,通过处理算法驱动帧后,我们获得了我们感兴趣的对象中心的X和Y坐标以及调试图像。接下来,示意性地示出了机器人相对于线的位置,以及已经通过处理算法的图像。


程序的下一步是将上一步获得的信息转换为两个电机的功率值。

转换色点中心相对于框架中心的偏移之间的差异的最简单方法是比例调节器(也有一个继电器调节器,但是由于其操作特性,它不太适合沿线驱动)。这种算法的操作原理是,控制器根据误差的大小对对象产生控制动作。除比例控制器外,还有一个积分控制器,随着时间的流逝,积分组件会“累积”误差和微分,其原理是基于对调节变量的充分改变而施加的调节影响。实际上,这些最简单的P,I,D控制器被组合为PI,PD,PID类型的控制器。

值得一提的是,在我的机器人上,我试图“启动” PID控制器,但与通常的比例控制器相比,使用PID并没有带来任何明显的优势。我承认我无法适当地调节调节器,但是在重型机器人无法实际发展高速的情况下,调节器的优势也可能不太明显。在编写本文时,该程序的最新版本使用了一个简单的比例调节器,但具有一个小的功能,使您可以使用来自摄像机的更多信息:生成误差值时,不仅考虑了光斑中点的水平位置,而且还考虑了垂直方向,这允许采用不同的方式响应线元素位于“远处”并紧挨着机器人的前方或下方(机器人的航向摄像机具有巨大的视角,因此将其向下倾斜45度,您已经可以看到机器人下方的重要区域)。

error= cx / (self.width/2) - 1  
#  ( 0   )  [-1; 1]
error*= cy / self.height + self.gain #

大多数情况下,在“ RTK杯”比赛的条件下,参赛者使用所谓的“坦克赛道”-一个或多个引擎控制机器人的一侧,它既可以在轨道上工作,也可以在轮子上工作。使用此方案,您可以摆脱复杂的传动元件,从而增加断裂的可能性(差速器或万向轴),并获得尽可能小的转弯半径,这在受限的多边形中具有优势。该方案涉及并行控制两个“边”,以沿着复杂路径运动。为此,程序使用两个变量-左右电动机的功率。此功率取决于基本速度(BASE_SPEED),范围从0到100。错误(error)-框架中心与线中间坐标之间的差以及比例效应系数(self._koof),由操作员进行校准。它的绝对值会影响机器人尝试使其与直线对齐的速度。由于在一个发动机上从基本速度中减去控制动作,而在另一发动机上将其添加的事实,则在偏离航向时进行转弯。可以通过更改self._koof变量的符号来调整执行反转的方向。另外,您可能会注意到,由于下一个代码部分的出现,幂值可能会出现大于100的值,但是在我的程序中,此类情况会在以后进行额外处理。它的绝对值会影响机器人尝试使其与直线对齐的速度。由于在一个发动机上从基本速度中减去控制动作,而在另一发动机上将其添加的事实,则在偏离航向时进行转弯。可以通过更改self._koof变量的符号来调整执行反转的方向。另外,您可能会注意到,由于下一个代码部分的出现,幂值可能会出现大于100的值,但是在我的程序中,此类情况会在以后进行额外处理。它的绝对值会影响机器人尝试使其与直线对齐的速度。由于在一个发动机上从基本速度中减去控制动作,而在另一发动机上将其添加的事实,则在偏离航向时进行转弯。可以通过更改self._koof变量的符号来调整执行反转的方向。另外,您可能会注意到,由于下一个代码部分的出现,幂值可能会出现大于100的值,但是在我的程序中,此类情况会在以后进行额外处理。在其中进行反转的情况下,您可以通过更改self._koof变量的符号来进行调整。另外,您可能会注意到,由于下一个代码部分的出现,幂值可能会出现大于100的值,但是在我的程序中,此类情况会在以后进行额外处理。在其中进行反转的情况下,您可以通过更改self._koof变量的符号来进行调整。另外,您可能会注意到,由于下一个代码部分的出现,幂值可能会出现大于100的值,但是在我的程序中,此类情况会在以后进行额外处理。

#if lineFound:
leftSpeed = round(self.base_speed + error*self.koof)
rightSpeed = round(self.base_speed - error*self.koof)

结论


测试了结果程序之后,我可以说设置程序的主要困难时刻是针对照明功能对算法进行校准。由于撰写本文的阶段与宣称的自我隔离相吻合,因此我不得不制作一个视频,在一个小房间里演示工作。这给我带来了以下困难:

  • -, , ( , ), . , , , . , , , ,
  • -, — , ,

尽管在实际比赛中都不存在这两个问题,但我将采取措施以确保计划的工作最少地取决于外部因素。
此外,将来计划继续使用计算机视觉方法实施算法,创建能够通过本文第一部分中所述的其余自治元素(自主信标捕获,沿着复杂路径移动)的软件。计划通过添加其他传感器来扩展机器人的功能:测距仪,陀螺仪加速度计,指南针。尽管这篇文章的发表将终止我作为必修课程的该项目的工作,但我计划在此继续描述发展的进一步阶段。因此,我希望收到有关这项工作的评论。

在执行了解决项目问题的所有步骤之后,可以肯定地说,在竞赛阶段,使用计算机视觉算法及其编程和调试的所有相对复杂性将带来最大的收益。由于摄像机的尺寸较小,因此它在软件开发方面具有巨大的潜力,因为摄像机使您可以一次更换多个“传统”传感器,同时从外界接收到令人难以置信的更多信息。可以实现该项目的目标-创建一个程序,该程序使用计算机视觉来解决“ RTK Cup”竞赛条件下机器人的自主导航问题,并描述创建程序的过程和图像处理的主要阶段。

正如我之前所说,不可能重新创建房屋线的复杂轨迹,并且此示例显示了算法如何实现转弯。此处的线的粗细与根据规定的粗细相对应,并且转弯的大部分曲线大致反映了多边形上90度旋转的曲率:


如果继续,您可以在我的github或此处查看程序代码,并监视该项目的进一步工作

All Articles