iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >K210追小球程序与STM32最小系统板通信(自主学习)
  • 896
分享到

K210追小球程序与STM32最小系统板通信(自主学习)

大数据python嵌入式硬件stm32 2023-08-31 16:08:56 896人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

本人先通过学习OPENMV,再延申到K210中。(主要是OPENMV我还没买屏幕,但是K210有)在OPENMV官网中,有相关追小球的函数,但是是用OPENMV单片机来进行调试的。在网上找到的相关源码,加载到OPENMV后发现帧数很慢。 学

本人先通过学习OPENMV,再延申到K210中。(主要是OPENMV我还没买屏幕,但是K210有)在OPENMV官网中,有相关追小球的函数,但是是用OPENMV单片机来进行调试的。在网上找到的相关源码,加载到OPENMV后发现帧数很慢。

学校实训的要求是要做出能追一定物体的平衡小车,我的小车的机构通过STM32F1Z8T6来进行控制,K210进行识别传输实时数据。

1,通过函数img.draw_rectangle(b[0:4]) ;可以得到画出目标的矩形框中的中心点X轴坐标和矩形框的大小SIZE。这两个数据前者可以用来判断转向环,后者可以用来判断前进和后退。

          x_pos = b[5]#中心位置
          Size = b.area()

通过实验测试,我得到了X:2~320范围,SIZE:2000~15000 

2,但是K210给32发送的是字符串,并且字符串的位数不确定,导致32用于接收到的字符串所存放的数组长度不确定,无法正常的转化数据。

为了方便的使用,我们在K210的发送函数中修改。

将X和SIZE字符串强制转化为固定位数的(在python环境中)

          X = '%03D' % x_pos
          S  = '%05d' % Size

并设置发送出的帧头和帧尾给最终发送的数据DATA

 DATA = 'x' + X + S + 's'

以上情况是当K210'看到'目标的时候进行的操作.

3,若没有找到目标的时候呢??

我是这样操作的:

直接给他X=目标值;SIZE=目标值;  发送到32内部,分别进行了PID计算

在PID程序中 X是转向环的测量值 SIZE是追求环的测量值;

当测量值=期望值的时候,PID相当于一直相等(我的偏见理解就是不计算)

此时就只剩下 直立环和速度环

4,回到之前的问题  用K210的屏幕有什么用呢?

为了更好更方便的调试,我们直接把X和SIZE的数据直接在屏幕LCD中显示出来.

          img.draw_string(2,2, ("X:%03d" %(b[5])), color=(255,255,255), scale=2)
          img.draw_string(2,25, ("S:%04d" %(b.area())), color=(255,255,255), scale=2)

这样在调转向环和追求环的PID中的P时候就会方便很多.

以上放置源码:(针对有屏幕的K210)

import sensor, lcd, timeimport sensor, timefrom machine import UART,Timerfrom fpioa_manager import fmfrom Maix import GPIOfrom fpioa_manager import fmfm.register(12, fm.fpioa.GPIO0)LED_B = GPIO(GPIO.GPIO0, GPIO.OUT) #构建LED对象LED_B.value(0) #点亮LED#摄像头初始化sensor.reset()sensor.set_pixformat(sensor.RGB565)sensor.set_framesize(sensor.QVGA)sensor.set_vflip(1) #后置模式,所见即所得sensor.run(1)sensor.skip_frames(30)from machine import UART,Timerfrom fpioa_manager import fm#映射串口引脚fm.register(7 , fm.fpioa.UART1_RX, force=True)fm.register(30, fm.fpioa.UART1_TX, force=True)#初始化串口uart = UART(UART.UART1, 115200, read_buf_len=4096)#lcd初始化lcd.init()clock=time.clock()color_threshold = (23, 100, 31, 51, 6, 43)size_threshold = 2000max_Size = 10def find_max(blobs):    max_size=0    for blob in blobs:        if blob[2]*blob[3] > max_size:            max_blob=blob            max_size = blob[2]*blob[3]    return max_blobLED_B.value(0) #点亮LEDwhile(1):    clock.tick()    img = sensor.snapshot()    blobs = img.find_blobs([color_threshold],area_threshold=50,pixels_threshold=50)    if blobs:      #for b in blobs:          b = find_max(blobs)          img.draw_rectangle(b[0:4])  # circle          img.draw_cross(b[5], b[6], color=(0, 0, 255))          x_pos = b[5]#中心位置          Size = b.area()          X = '%03d' % x_pos          S  = '%05d' % Size          DATA = 'x' + X + S + 's'          img.draw_string(2,2, ("X:%03d" %(b[5])), color=(255,255,255), scale=2)          img.draw_string(2,25, ("S:%04d" %(b.area())), color=(255,255,255), scale=2)          uart.write(DATA)          print(DATA)    else          uart.write('x')          uart.write('1')          uart.write('6')          uart.write('0')          uart.write('0')          uart.write('2')          uart.write('0')          uart.write('0')          uart.write('0')          uart.write('s')          img.draw_string(2,2, ("X:%03d" %(160)), color=(255,255,255), scale=2)          img.draw_string(2,25, ("S:%04d" %(2000)), color=(255,255,255), scale=2)    lcd.display(img)     #LCD显示图片

在以上的函数中  我们会发现 定义了一个函数:find max

为什么要定义这个函数呢??

因为  当我们要求找到最大的目标色块,给它进行画框.不然会出现很多目标小点点.多个目标矩形框会导致串口终端发送的数值有不寻常的跳变.

下面针对没有屏幕的OPENMV:

OPENMV中与K210有些不同在于:

(1) 串口的设置  OPENMV的串口是固定的,不需要引脚映射.但是K210需要.

(2) 在OPENMV中,最大的色块可以直接通过Bolb[]来确定,不需要find max函数建立.

OPENMV是在官网的例程程序中修改的(确保帧速,不让他这么卡)

uart = UART(3, 115200)uart.init(115200, bits=8, parity=None, stop=1, timeout_char=1000) # 使用给定参数初始化# Only blobs that with more pixels than "pixel_threshold" and more area than "area_threshold" are# returned by "find_blobs" below. Change "pixels_threshold" and "area_threshold" if you change the# camera resolution. "merge=True" merges all overlapping blobs in the image.while(True):    clock.tick()    img = sensor.snapshot()    for blob in img.find_blobs([thresholds[threshold_index]], pixels_threshold=200, area_threshold=200, merge=True):        # These values depend on the blob not being circular - otherwise they will be shaky.        if blob.elongation() > 0.5:            img.draw_edges(blob.min_corners(), color=(255,0,0))            img.draw_line(blob.major_axis_line(), color=(0,255,0))            img.draw_line(blob.minor_axis_line(), color=(0,0,255))        # These values are stable all the time.        #画框        img.draw_rectangle(blob.rect())        #画十字        img.draw_cross(blob.cx(), blob.cy())        # Note - the blob rotation is unique to 0-180 only.        #特征点识别        img.draw_keypoints([(blob.cx(), blob.cy(), int(math.degrees(blob.rotation())))], size=20)        #返回x轴中心点位置,blob.cx() 返回色块的外框的中心x坐标(int),也可以通过blob[5]来获取        x = blob[5]        #blob.area() 返回色块的外框的面积。应该等于(w * h)        s = blob.area()        #发送数据        #data = bytearray([0x11,x,s,0x00])        X = '%03d'%(x)        S = '%05d'%(s)        data = 'x' + X  + S+ 's'        #串口发送        uart.write(data)   # print(clock.fps())        print(data)

来源地址:https://blog.csdn.net/qq_60043905/article/details/125655140

--结束END--

本文标题: K210追小球程序与STM32最小系统板通信(自主学习)

本文链接: https://www.lsjlt.com/news/386216.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作