k210的简单PID巡线

这篇具有很好参考价值的文章主要介绍了k210的简单PID巡线。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1.前言

2.简介

3.代码讲解

1.调用自带的库文件

2.将I/O18和 I/O19分别注册为UART1_TX和UART1_RX功能并设置串口

3.向STM32F103单片机发送数据包

4.基本初始化

5.主程序代码

1.寻找色块部分

2.巡线部分 

3.侦测关键点部分

 4.完整代码


k210的简单PID巡线

1.前言

        最近在复刻电赛送药小车和跟随小车,发现巡线部分使用灰度循迹已经不能很好的完成了,于是开始琢磨摄像头循迹,一开始发现ccd摄像头非常不错,它由一个 1x128 的光电二极管阵列、相关的电荷放大电路以及一个内部像素数据保功能组成。

k210的简单PID巡线

ccd可以直接返回偏差值,价格也合适,准备入手时却发现它只能寻白底黑线,那只能含泪pass。

于是目光就放回了openmv和k210,在一番比较下选择了性价比较高的k210,于是就有了一下的文章。

k210的简单PID巡线

                                    (使用的是Maixpy k210 Dock板,自行安装了一个补光灯) 

2.简介

        本文章主要讲述使用k210完成简单的PID寻线,通过调用 image 模块中现有查找色块方法,得到偏移量和关键点(如十字路口,起停线等)的数据,返回数据给STM32f103单片机进行巡线,本片只涉及k210的代码,后续会更新和stm32f103通讯的代码。

3.代码讲解

1.调用自带的库文件

import sensor, image,lcd
from machine import UART #串口库函数
from fpioa_manager import fm # GPIO重定向函数

2.将I/O18和 I/O19分别注册为UART1_TX和UART1_RX功能并设置串口

fm.register(18, fm.fpioa.UART1_TX, force=True)
fm.register(19, fm.fpioa.UART1_RX, force=True)
uart_A = UART(UART.UART1, 115200, 8, 0, 1, timeout=1000, read_buf_len=4096)

3.向STM32F103单片机发送数据包

def sending_data(x,y,z):
    global uart;
    FH = bytearray([0x2C,0x12,x,y,z,0x5B])
    uart_A.write(FH);

此数据包的格式为2个帧头,3个数据和一个帧尾,STM32F103接收K210数据包的代码以后会更新。

4.基本初始化

green_threshold = ((0, 190))           #黑色
roi1            = [0,100,320,16]       #巡线敏感区
roi2            = [0,180,320,8]        #关键点敏感区
expectedValue   = 160                  #巡线位置期望
err             = 0                    #本次误差
old_err         = 0                    #上次误差
Kp              = 0.046                #PID比例系数
Kd              = 0                    #PID微分系数
Speed           = 0                    #期望速度
Speed_left      = 0                    #左轮速度
Speed_right     = 0                    #右轮速度
Flag            = 0                    #用于关键点标志

lcd.init()
sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.set_framesize(sensor.QVGA)# 320x240
sensor.skip_frames(time = 3000 )#跳过3000张图片
sensor.set_auto_gain(False) # must be turned off for color tracking
sensor.set_auto_whitebal(False) # must be turned off for color tracking
sensor.run(1)

        其中的 sensor.set_pixformat(sensor.GRAYSCALE)  是将像素模式设置为灰度灰度模式对于只有两种颜色的地图可以起到提高帧数,过滤其它颜色的影响,提高了识别的正确率。

       其中的 Kp Kd  是巡线PID的参数没有使用到积分参数,Kd设置为0的原因是因为仅仅调节Kp时巡线就已经很稳定了,如果你的小车仅靠Kp无法达到稳定或者出现了高频振荡,请自行调节Kd。

       其中的 Speed,Speed_left和Speed_right 分别为当偏差量为0时的期望速度,计算后发送给STM32F103的左轮速度,计算后发送给STM32F103的右轮速度。

        其中的 Flag 是用于当检测到如十字路口,起停线等的标志。

5.主程序代码

1.寻找色块部分

while True:
    img=sensor.snapshot()
    statistics1 = img.find_blobs([green_threshold],roi=roi1,area_threshold=200,merge=True)
    statistics2 =img.find_blobs([green_threshold],roi=roi2,area_threshold=120,merge=True,margin=120)
    if statistics1:
        for b in statistics1:
            tmp=img.draw_rectangle(b[0:4])
            tmp=img.draw_cross(b[5], b[6])
            c=img.get_pixel(b[5], b[6])

            #PID计算

            actualValue=b[5]
            err=actualValue-expectedValue
            Speed_left = Speed - (Kp*err+Kd*(err-old_err))
            Speed_right = Speed + (Kp*err+Kd*(err-old_err))
            old_err= err
            print("Speed_left,Speed_right")
            print(int(Speed_left),int(Speed_right))
    if statistics2:
        for b in statistics2:
            tmp=img.draw_rectangle(b[0:4])
            tmp=img.draw_cross(b[5], b[6])
            c=img.get_pixel(b[5], b[6])
            if b[2] >50:
                Flag = 1
    sending_data(int(Speed_left),int(Speed_right),Flag)

        通过find_blobs函数可以找到色块,其中的[green_threshold]寻找目标是颜色的阈值,阈值可以通过Maixpy IDE工具栏中的工具 -> 机器视觉 -> 阈值编辑器获得。

       其中的 roi1 和 roi2 分别是寻线部分和关键的感兴趣区,就是在要处理的整张图像中提取出的要处理的区域,寻找色块只在下图红框里分别进行。k210的简单PID巡线

        area_threshold 是面积阈值,如果色块被框起来的面积小于这个值,会被过滤掉,减少干扰提高巡线准确度。

        merge=True 将所有重叠的blob合并为一个。

       margin为边界,如果设置为1,那么两个blobs如果间距1一个像素点,也会被合并。此参数只在检测关键点寻找色块函数中运用,可以更明确的侦测出关键点,如Y型路口。

       statistics = img.find_blobs[ ] 对象返回的是多个blob的列表,列表类似与C语言的数组,一个blobs列表里包含很多blob对象,blobs对象就是色块,每个blobs对象包含一个色块的信息。b就是很多色块。可以用for循环把所有的色块找一遍。

for b in statistics:

        返回色块的外框的x坐标(int),也可以通过b[0]来获得
        返回色块的外框的y坐标(int),也可以通过b[1]来获得
        返回色块的外框的宽度w(int),也可以通过b[2]来获得
        返回色块的外框的高度h(int),也可以通过b[3]来获得
        返回色块的像素数量(int),也可以通过b[4]来获得
        返回色块的外框的中心x坐标(int),也可以通过b[5]来获得
        返回色块的外框的中心y坐标(int),也可以通过b[6]来获得

        tmp=img.draw_rectangle(b[0:4])和tmp=img.draw_cross(b[5], b[6]) 分别为画出找到色块的外框和中心十字

k210的简单PID巡线

2.巡线部分 

        由上我们可得b[5]为返回外框中心x的值,而且拍摄的画面为320x240,X方向的中间为160,所以线与摄像头中心的偏移量err,就为实际值actualValue 也就是b[5]减去期望expectedValue(160)。对应代码为:

actualValue=b[5]
err=actualValue-expectedValue

        得到了偏差值就可以进行PID计算了。

Speed_left = Speed - (Kp*err+Kd*(err-old_err))
Speed_right = Speed + (Kp*err+Kd*(err-old_err))

old_err= err

        当偏差小于零时说明小车向右偏,需要增加左轮的速度,减小右轮的速度,反之亦然。

3.侦测关键点部分

        当要经过十字路口,y型路口,起停线时,可以关注blob的列表中的b[2],其反回的值为返回色块的外框的宽度w。因为正常巡线时寻找到的色块外框宽度w的值是小于关键点部分的值。

k210的简单PID巡线

                                         正常巡线

k210的简单PID巡线

                                         r型路口

k210的简单PID巡线

                                          起停线

k210的简单PID巡线

                                          十字路口

        只需要判断是否大于正常色块外框宽度就可以侦测关键点。

if b[2] >50:
   Flag = 1

 4.完整代码

# Untitled - By: User - 周三 4月 19 2023

import sensor, image,lcd
from machine import UART #串口库函数
from fpioa_manager import fm # GPIO重定向函数

fm.register(18, fm.fpioa.UART1_TX, force=True)
fm.register(19, fm.fpioa.UART1_RX, force=True)
uart_A = UART(UART.UART1, 115200, 8, 0, 1, timeout=1000, read_buf_len=4096)

green_threshold = ((0, 190))           #黑色
roi1            = [0,100,320,16]       #巡线敏感区
roi2            = [0,180,320,8]        #关键点敏感区
expectedValue   = 160                  #巡线位置期望
err             = 0                    #本次误差
old_err         = 0                    #上次误差
Kp              = 0.046                #PID比例系数
Kd              = 0                    #PID微分系数
Speed           = 0                    #期望速度
Speed_left      = 0                    #左轮速度
Speed_right     = 0                    #右轮速度
Flag            = 0                    #用于关键点标志

def sending_data(x,y,z):
    global uart;
    FH = bytearray([0x2C,0x12,x,y,z,0x5B])
    uart_A.write(FH);

lcd.init()
sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.set_framesize(sensor.QVGA) # 320x240
sensor.skip_frames(time = 3000 )#跳过3000张图片
sensor.set_auto_gain(False) # must be turned off for color tracking
sensor.set_auto_whitebal(False) # must be turned off for color tracking
sensor.run(1)

while True:
    img=sensor.snapshot()
    statistics1 = img.find_blobs([green_threshold],roi=roi1,area_threshold=200,merge=True)
    statistics2 = img.find_blobs([green_threshold],roi=roi2,area_threshold=120,merge=True,margin=120)
    if statistics1:
        for b in statistics1:
            tmp=img.draw_rectangle(b[0:4])
            tmp=img.draw_cross(b[5], b[6])

            #PID计算

            actualValue=b[5]
            err=actualValue-expectedValue
            Speed_left = Speed - (Kp*err+Kd*(err-old_err))
            Speed_right = Speed + (Kp*err+Kd*(err-old_err))
            old_err= err
            print("Speed_left,Speed_right")
            print(int(Speed_left),int(Speed_right))
    if statistics2:
        for b in statistics2:
            tmp=img.draw_rectangle(b[0:4])
            tmp=img.draw_cross(b[5], b[6])
            if b[2] >50:
                Flag = 1
    sending_data(int(Speed_left),int(Speed_right),Flag)

如果报错说缺少相对应的库,请自行去MaixPy官网下载openmv api的固件,这篇文章的第三部分有教你如何安装固件。                                                                                                                    文章来源地址https://www.toymoban.com/news/detail-443834.html

到了这里,关于k210的简单PID巡线的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • K210学习笔记(二) K210与STM32进行串口通信,K210收,STM32发

    想用STM32通过串口给K210发数据,并在屏幕上显示,看了好几篇博客,终于搞通了,大家感兴趣也可以看看。 K210学习笔记(一) K210与STM32串口通信相关 接线,STM32的串口引脚比较固定,而K210就牛比了,任意映射,懒人福音。这里我找了两个没有被复用的IO,IO9和IO10 STM32 K210 GND

    2023年04月08日
    浏览(41)
  • K210学习笔记(七)——MAIX BIT(K210)拍照

    MAIX BIT使用的是OV5642,像素为500w,但实际使用只有30w,但对于物体检测,人脸识别是够用的,用maix bit进行拍照,所得照片可以直接用于后面的数据集训练,减少了图片格式转换这一步骤。 参数说明: freq : 设置摄像头时钟频率,频率越高帧率越高,但是画质可能更差。默认

    2024年02月15日
    浏览(37)
  • 【K210】K210学习笔记四——定时器的使用

    本人大四学生,电赛生涯已经走到尽头,一路上踩过不少坑,但运气也不错拿了两年省一,思来想去,决定开始写博客,将电赛经验分享一二,能力有限,高手轻喷。 往期的博客讲述了 K210 的感光元件模块 sensor 的配置,机器视觉模块 image 中部分函数的使用(目前是用 find

    2024年02月03日
    浏览(90)
  • 【K210】K210学习笔记三——按键、LCD、LED的使用

    本人大四学生,电赛生涯已经走到尽头,一路上踩过不少坑,但运气也不错拿了两年省一,思来想去,决定开始写博客,将电赛经验分享一二,能力有限,高手轻喷。 往期的博客讲述了 K210 的感光元件模块 sensor 的配置,机器视觉模块 image 中部分函数的使用(目前是用 find

    2024年02月11日
    浏览(49)
  • K210人脸追踪

    老样子了先看视频 K210人脸追踪 你需要准备一个人脸识别模型 然后一个云台就行了 代码附上了,模型直接去01科技官网或者sipeed的官网上下载就行。

    2024年02月14日
    浏览(37)
  • K210使用记录

    本文算是对K210使用的一个记录吧,这样以后方便后面的学弟学妹快速学习了解K210的基本知识和入门使用 官网(嘉楠堪智) https://canaan-creative.com/product/kendryteai 常用的使用一般有两种,这里从适用性的角度优先使用第一种,资料齐全,上手会快很多 1、使用micro python进行开发

    2024年02月04日
    浏览(44)
  • K210——声源定位、声音识别

    来了,K210的声源定位。 2022电赛] 声源定位跟踪系统(E题)k210 麦克风阵列效果实测! sipeed官方做的,效果还不错。 sipeed家的声源定位模块,K210常用的都可以用 将麦克风阵列模块与 pyAI-K210 使用 FPC 10P 排线进行连接,接口在开发板背部(排线金手指下接)。 麦克风阵列扩

    2024年02月16日
    浏览(78)
  • K210串口接收数据包

    目录 1.前言 2.代码部分 1.调用自带的库文件 2.将I/O19设置为UART1_RX功能并设置串口 3.数据接收函数 4.主程序             之前更新了K210与STM32之间的串口通信,是K210发送信息STM32接收信息,这篇博客讲解一下K210 DOCK接收数据包。  在使用 uart1 前,我们需要使用 fm 来对芯片引脚

    2024年02月15日
    浏览(47)
  • k210———图像处理函数

    以下是在学习过程中遇到的一些比较高级的图像处理 openmv官方解释为👇 image.erode(size[, threshold[, mask=None]]) 从分割区域的边缘 删除像素 。 这一方法通过卷积图像上 ( ( s i z e ∗ 2 ) + 1 ) x ( ( s i z e ∗ 2 ) + 1 ) ((size*2)+1)x((size*2)+1) (( s i ze ∗ 2 ) + 1 ) x (( s i ze ∗ 2 ) + 1 ) 像素的核来实

    2024年02月12日
    浏览(38)
  • 树莓派视觉小车 -- OpenCV巡线(HSL色彩空间、PID)

    目录 试错 试错1:形态学处理 试错2:HSV色彩空间 基础理论 1、HSV与HSL色彩空间 2、PID调节 一、OpenCV图像处理 1、在HSL色彩空间下得到二值图 2、 对二值图形态学处理 3、找出线的轮廓和中心点坐标 二、PID 三、运动控制 总代码 一开始用的形态学处理,自行改变阈值,调试之后

    2024年02月04日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包