2023年电赛---运动目标控制与自动追踪系统(E题)OpenMV方案

news2024/11/15 1:53:34

前言

(1)废话少说,很多人可能无法访问GitHub,所以我直接贴出可能要用的代码。此博客还会进行更新,先贴教程和代码
(2)视频教程: https://singtown.com/learn/49603/
(3)有些人肯定说红点太小了,OpenMV不行精度不够,看这个C站上做出来的阈值代码:https://blog.csdn.net/weixin_52385589/article/details/126334744
(4)赛事方肯定不可能直接让你上现成的玩意,不然比赛的意义在哪里?我看了一下网上的一些讨论。肯定是要用摄像头的,K210好像有官方库,K210的同学可以了解一下。
(5)OpenMV的话需要多训练,建议最好做灯光补偿,毕竟OpenMV对灯光要求很高,环境光线一点要稳定!!!

硬件注意事项

接线问题

(1)我们这里是使用的OpenMV的P8和P7引脚。所以建议引脚如下图引出。
(2)舵机一般是5V供电,所以注意VCC是供5V的电压。而右边那两个GND和VCC是连接OpenMV的。如果右边的VCC是连接OpenMV的VIN引脚,就可以供5V电。如果是连接OpenMV的3.3V引脚,iu只能供3.3V电压。否则OpenMV会被烧掉!
(3)舵机的VCC要直接连接电池,因为如果通过OpenMV连接,OpenMV的输出电流太小,带不动舵机!

在这里插入图片描述

出现Frame capture has timed out. 帧捕获超时了

(1)如果是我贴出来的代码,出现这个bug。你重新开机启动应该就可以了。
(2)如果还不可以,就说明你OpenMV坏了。要快点换一个。

在这里插入图片描述

main.py

代码

import sensor, image, time

from pid import PID
from pyb import Servo  #从内置pyb导入servo类,也就是舵机控制类

pan_servo=Servo(1)  #定义两个舵机,对应P7引脚
tilt_servo=Servo(2) #定义两个舵机,对应P8引脚

pan_servo.calibration(500,2500,500)
tilt_servo.calibration(500,2500,500)

red_threshold  = (13, 49, 18, 61, 6, 47)  #设置红色阈值

pan_pid = PID(p=0.07, i=0, imax=90) #PID参数,只需要调整P量即可,设置P7引脚的PI值
tilt_pid = PID(p=0.05, i=0, imax=90) #PID参数,只需要调整P量即可,设置P8引脚的PI值
#pan_pid = PID(p=0.1, i=0, imax=90)#在线调试使用这个PID
#tilt_pid = PID(p=0.1, i=0, imax=90)#在线调试使用这个PID

sensor.reset() # 初始化摄像头传感器
sensor.set_pixformat(sensor.RGB565) # 使用 RGB565 彩图
sensor.set_framesize(sensor.QQVGA) # 使用 QQVGA 分辨率
sensor.skip_frames(10) #跳过几帧,让新的设置生效。
sensor.set_auto_whitebal(False) # 因为是颜色识别,所以需要把白平衡关闭
clock = time.clock() # 追踪帧率,影响不大

#__________________________________________________________________
#定义寻找最大色块的函数,因为图像中有多个色块,所以追踪最大的那个
def 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_blob

#__________________________________________________________________
while(True):
    clock.tick() # 跟踪快照()之间经过的毫秒数。
    img = sensor.snapshot() # 截取一张图片

    blobs = img.find_blobs([red_threshold]) #识别红色阈值
    if blobs:   #如果找到红色色块
        max_blob = find_max(blobs)  #调用上面自定义函数,找到最大色块
        pan_error = max_blob.cx()-img.width()/2
        tilt_error = max_blob.cy()-img.height()/2

        print("pan_error: ", pan_error)

        img.draw_rectangle(max_blob.rect()) # 在找到最大色块画一个矩形框
        img.draw_cross(max_blob.cx(), max_blob.cy()) # cx, cy

        pan_output=pan_pid.get_pid(pan_error,1)/2
        tilt_output=tilt_pid.get_pid(tilt_error,1) #上面两个都说进行PID运算
        print("pan_output",pan_output)
        pan_servo.angle(pan_servo.angle()+pan_output) #将最终值传入两个舵机中,追踪目标
        tilt_servo.angle(tilt_servo.angle()-tilt_output)# 因为两个舵机方向和摆放位置不同,所以一个是+一个是-

舵机控制

舵机选择

(1)Servo是舵机控制类。因为我们使用from pyb import Servo直接从pyd导入了servo类。所以可以直接写成Servo()。
(2)引脚对应关系:Servo(1)——P7,Servo(2)——P8,Servo(3)——P9。
(3)
<1>因此我们可以知道,pan_servo.calibration就是对P7进行相应的控制,因为pan_servo=Servo(1)。
<2>tilt_servo.calibration就是对P8控制,因为tilt_servo=Servo(2)

在这里插入图片描述

舵机脉冲设置

(1)pan_servo.calibration(500,2500,500) , 这个其实就是设置舵机的脉宽的。因为我们知道,常见的舵机周期都是20ms,脉宽都是再500us到2500us之间。
(2)所以这里的第一个参数是500,第二个参数是2500。第三个参数是舵机0°位置,根据下图可以知道,也是500。最后两个值是可以填可不填的,个人不建议填写。

在这里插入图片描述
在这里插入图片描述

颜色阈值设置

(1)因为我们要追踪红色,所以是使用red_threshold = (13, 49, 18, 61, 6, 47) 进行设置阈值。
(2)颜色阈值设置教程:OpenMV颜色阈值设置

PID的P和I参数设置

(1)注意,因为云台是比较稳定的,不要求高反应速度,所以我猜测只使用了PI,而没有使用PID。因此我们可以看到pan_pid和tilt_pid只有P和I两个参数。
(2)I的参数不需要进行调整!imax是用于积分限幅的,这个也别更改!,如果你的云台抖动厉害,说明P过大了,需要调小。
(3)如果你感觉你云台反应太慢,就需要调高P值。
(4)最佳的P值是,你云台有抖动的前一个值。这个才是P的最优值。但是我认为,P没必要太大,因为云台还是比较稳的。
(5)所以说,只需要调整P值,I值和imax值不需要进行调整!!!

帧率禁用

(1)当OpenMV连接电脑端IDE的时候,运行帧率和不连接电脑端IDE是不一样的。因为我们连接上电脑端IDE的时候,OpenMV会向电脑端IDE传输数据,所以会导致帧率下降。
(2)帧率下降,会导致我们实际脱机跑的时候,PID参数和连接上电脑端IDE时候的PID参数不一样。
(3)所以我们需要点击电脑端右上角的禁用,或者是Disable。被禁用之后,我们的效果就是脱机之后真实运行效果。

在这里插入图片描述

pid.py

(1)这里面的代码我们不需要管,就算PID的代码。
(2)再次强调,这里请别擅自更改,出现问题自己负责。

from pyb import millis
from math import pi, isnan
 
class PID:
    _kp = _ki = _kd = _integrator = _imax = 0
    _last_error = _last_derivative = _last_t = 0
    _RC = 1/(2 * pi * 20)
    def __init__(self, p=0, i=0, d=0, imax=0):
        self._kp = float(p)
        self._ki = float(i)
        self._kd = float(d)
        self._imax = abs(imax)
        self._last_derivative = float('nan')
 
    def get_pid(self, error, scaler):
        tnow = millis()
        dt = tnow - self._last_t
        output = 0
        if self._last_t == 0 or dt > 1000:
            dt = 0
            self.reset_I()
        self._last_t = tnow
        delta_time = float(dt) / float(1000)
        output += error * self._kp
        if abs(self._kd) > 0 and dt > 0:
            if isnan(self._last_derivative):
                derivative = 0
                self._last_derivative = 0
            else:
                derivative = (error - self._last_error) / delta_time
            derivative = self._last_derivative + \
                                     ((delta_time / (self._RC + delta_time)) * \
                                        (derivative - self._last_derivative))
            self._last_error = error
            self._last_derivative = derivative
            output += self._kd * derivative
        output *= scaler
        if abs(self._ki) > 0 and dt > 0:
            self._integrator += (error * self._ki) * scaler * delta_time
            if self._integrator < -self._imax: self._integrator = -self._imax
            elif self._integrator > self._imax: self._integrator = self._imax
            output += self._integrator
        return output
    def reset_I(self):
        self._integrator = 0
        self._last_derivative = float('nan')

关于C站那位做出结果的阈值代码注意事项

图像类型

(1)sensor.set_pixformat设置的图像类型不同。
<1>我拿官方代码和上面贴出来的那个代码进行了对比,发现了一件事情。他的sensor.set_pixformat是设置成GRAYSCALE图像,而我们这里是设置成RGB565图像。
<2>将图像画质设置成GRAYSCALE好处在于,如果只有两个颜色,更容易进行分辨,而且每个像素所占空间也减少了,可以适当的增加分辨率。但是也有缺点,如果是多颜色识别就会出现问题。
<3>本题只有三种颜色,底板白色,追踪的绿点,被追踪的红点。因为只需要追踪一个颜色,所以各位可以尝试将 sensor.set_pixformat(sensor.RGB565) 改成 sensor.set_pixformat(sensor.GRAYSCALE)

在这里插入图片描述

图像分辨率

(2)图像分辨率,sensor.set_framesize(sensor.QQVGA)
<1>官方例程的分辨率是QQVGA,像素点是160x120。而那个博客的分辨率是QVGA,像素点是 320x240。
<2>更高的分辨率,识别效果更好,但是分辨率也别无脑调高,否则颜色阈值方便会很难设置。

在这里插入图片描述

跳过帧数

(3)跳过帧数,sensor.skip_frames(10)
<1>这个就是给OpenMV初始化一个缓冲时间,他那边是设置的跳过900张图片。官方例程是跳过10个图片。
<2>这个选取看你自己,我感觉没必要900,太多了。

在这里插入图片描述

曝光度设置

(4)sensor.set_auto_exposure(False, 1000)
<1>这个是用于设置曝光度的,曝光过度照片看起来会过亮,曝光不足图片看起来会太暗。
<2>官方例程没有调用这个函数,说明曝光是一直打开的。
<3>C站那位是设置的每1ms曝光一次。你们可以根据自己测试结果来设置。

在这里插入图片描述

白平衡和自增益

(5)sensor.set_auto_whitebal(False)和sensor.set_auto_gain(False)
<1>按理来说颜色识别的话,这两个都需要关闭的。C站另外那个博客就是都关闭了。但是官方只关闭了set_auto_whitebal()白平衡。
<2>我个人建议还是先都关闭
在这里插入图片描述

在这里插入图片描述

E题官方解释

1问:E题可以使用openmv吗?
答:E题只禁止笔记本和台式机。其他任意
2问:E题目标运动追踪系统能用树莓派不?
答:同上。
3问:E题,云台和屏幕的高度关系是怎么样的?
答:自定。
4问:请问e题基本要求(1)进行自动复位时屏幕的位置是一直固定吗?
答:当然,只有绿色激光笔可以移动。
5问:E题中主板能用stm32的战舰精英mini版吗?E题中基本要求一测试完之后是否可以复位?
6问:请问E题运动目标控制与自动追踪系统中的屏幕,对材质有什么特殊要求吗?
答:白色。
7问:E题 1. 摄像头模块的摆放位置是否有要求,题目中未提及;2. 现场测试的屏幕材料是否确定,可否提供材料名称?
答:屏幕可自带。其他自定。
8问:E题:封装时屏幕和靶纸要一起封入带去吗?还是测试时由组委会提供所有队伍统一使用的?
答:封箱后自己带。赛区不提供屏幕和靶纸。
9问:E题中的两种激光笔测试开始后是一直要亮着吗?
答:自定。
10问:E题的基础部分第一问里边的“在任意位置按下按键可以复位”任意位置需要我们自己能达到还是说只需要把重点放在能复位?
答:题目已经说的很清楚,光斑处在任意位置都可通过复位功能回到原点
11问:E题屏幕高度有要求么?
答:自定。
12问:E题基础部分第一问的“任意位置都可以复位”我们需要自己写程序让激光笔达到人意位置然后再按下按键复位还是说到哪个位置不需要管只要能做到复位就可以了?
答:题目已经说的很清楚,光斑处在任意位置都可通过复位功能回到原点。
13问:测试场地屏幕是否与外界环境线条分界明显?
答:没有要求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/824490.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大数据技术之Clickhouse---入门篇---数据类型、表引擎

星光下的赶路人star的个人主页 今天没有开始的事&#xff0c;明天绝对不会完成 文章目录 1、数据类型1.1 整型1.2 浮点型1.3 布尔型1.4 Decimal型1.5 字符串1.6 枚举类型1.7 时间类型1.8 数组 2、表引擎2.1 表引擎的使用2.2 TinyLog2.3 Memory2.4 MergeTree2.4.1 Partition by分…

华为OD机试真题 JavaScript 实现【取出尽量少的球】【2023Q1 200分】,附详细解题思路

目录 一、题目描述游戏规则如下&#xff1a;限制规则一&#xff1a;限制规则二&#xff1a; 二、输入描述三、输出描述四、解题思路五、JavaScript算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 刷的越多&#xff0c;抽中…

《golang设计模式》第一部分·创建型模式-04-抽象工厂模式(Abstract Factory)

文章目录 1. 概述1.1 角色1.2 类图 2. 代码示例2.1 设计2.2 代码2.3 类图 1. 概述 1.1 角色 AbstractFactory&#xff08;抽象工厂&#xff09;&#xff1a;它声明了一组用于创建产品的方法&#xff0c;每一个方法对应一种产品。ConcreteFactory&#xff08;具体工厂&#xf…

phpstudy 进行 composer 全局配置

背景 因为注意到&#xff0c;使用 phpStudy 进行环境搭建时&#xff0c;有时需要使用 composer 每次都需要查找资料进行配置&#xff0c; 在此进行记录笔记&#xff0c;方便有需要的道友借鉴 配置 版本&#xff1a;composer1.8.5&#xff08;phpStudy8 当前只能安装这一个版本…

CAD批量转PDF的简单方法,三个步骤轻松完成转换

PDF格式的图纸可以在各种设备和软件上打开&#xff0c;因为PDF是一种跨平台的格式&#xff0c;不受操作系统或软件版本的影响。这意味着CAD图纸可以更容易地在不同的设备和操作系统之间传输&#xff0c;而无需担心兼容性问题&#xff0c;可以使图纸更易于共享、浏览和保护&…

Vue进阶(幺叁陆): transition标签实现页面跳转动画

文章目录 一、前言二、方案实现三、延伸阅读 transition标签四、拓展阅读 一、前言 在Vue项目开发过程中&#xff0c;应用全家桶vue-router实现路由跳转&#xff0c;且页面前进、后退跳转过程中&#xff0c;分别对应不同的切换动画。vue-router 切换页面时怎么设置过渡动画&am…

Pytorch深度学习-----神经网络之非线性激活的使用(ReLu、Sigmoid)

系列文章目录 PyTorch深度学习——Anaconda和PyTorch安装 Pytorch深度学习-----数据模块Dataset类 Pytorch深度学习------TensorBoard的使用 Pytorch深度学习------Torchvision中Transforms的使用&#xff08;ToTensor&#xff0c;Normalize&#xff0c;Resize &#xff0c;Co…

Doccano工具安装教程/文本标注工具/文本标注自己的项目/NLP分词器工具/自然语言处理必备工具/如何使用文本标注工具

这篇文章是专门的安装教程&#xff0c;后续的项目创建&#xff0c;如何使用&#xff0c;以及代码部分可以参考这篇文章&#xff1a; NER实战&#xff1a;(NLP实战/命名实体识别/文本标注/Doccano工具使用/关键信息抽取/Token分类/源码解读/代码逐行解读)_会害羞的杨卓越的博客-…

【uniapp 样式】使用setStorageSync存储历史搜索记录

<template><view><view class"zhuangbox u-flex"><u--inputplaceholder"请输入关键字搜索"border"surround"shapecircleprefixIcon"search"prefixIconStyle"font-size: 22px;color: #909399"v-model&q…

vSphere ESXI 7.0 网络规划

ESXi 网络 业务网络、Vmotion&#xff08;漂移&#xff09;、管理网络、存储网络 ESXi 管理网络 vCenter Server 管理网络 vCenter Server SSO域名 Single Sign-on域名&#xff1a;在没有指定的情况下&#xff0c;默认填写 vsphere.local VMware vSphere整体解决方案和网络…

uniapp点击图片放大预览

阐述 有些时候我们在用uniapp显示图片时&#xff0c;有的不宜全部显示到屏幕上&#xff0c;uniapp提供了一个非常好用的api。 实现方式如下&#xff1a; <template><view class"content"><image class"logo" src"/static/images/a.…

Nacos 持久化实例 删不掉问题( Please unregister instance first )

文章目录 一、报错现象&#xff1a;二、问题解决过程&#xff1a;三、最终解决方案&#xff1a;四、注销实例API&#xff1a; &#x1f50e;请直接看第三部分&#x1f50e; 一、报错现象&#xff1a; 二、问题解决过程&#xff1a; 尝试将服务下线&#xff1a; 再次点击删除按…

如何在水务行业运用IPD?

水务行业&#xff0c;包括自来水的生产和供应、水务及其再生利用和其他水的处理、利用与分配。水务行业主要环节分布包括原水生产与供应、自来水生产和供应、污水收集、水务、中水与再生水利用等。 我国水务行业的产业链包括上游、中游、下游。上游包括科研和规划设计、设备及材…

英雄的力量【力扣2681】

1、解题思路 将数组按从大到小的顺序排列&#xff0c;i<j&#xff0c;那么以nums[i]开始&#xff0c;nums[j]结尾&#xff0c;i----j中的任意数&#xff0c;组成的排列&#xff0c;其英雄力量都是nums[i]*nums[i]*nums[j]&#xff1b; 若ij&#xff0c;则只有一种排列组合…

SOC FPGA之流水灯设计

一、DS-5简介 Altera Soc EDS开发套件的核心是Altera版ARM Development Studio 5(DS-5)工具包&#xff0c;为SoC器件提供了完整的嵌入式开发环境、FPGA自适应调试和对Altera工具的兼容。 1.1 DS-5 eclipse破解 首先下载破解器 然后进入cmd运行&#xff0c;进入到破解器所在文…

AndroidBanner - ViewPager

解决banner 不可见依旧轮播的问题 思考一下&#xff1a;什么时候可以轮播&#xff0c;什么时候不可以轮播 当Banner添加到屏幕上&#xff0c;且对用户可见的时候&#xff0c;可以开始轮播 当Banner从屏幕上移除&#xff0c;或者Banner不可见的时候&#xff0c;可以停止轮播 当…

排序进行曲-v2.0

小程一言 这篇文章是在排序进行曲1.0之后的续讲&#xff0c; 0之后的续讲,英语在上一篇讲的排序的基本概念与分类0之后的续讲, 英语在上一篇讲的排序的基本概念与分类这片主要是对0之后的续讲,英语在上一篇讲的排序的基本概念与分类这 篇主要是对几个简单的排序进行细致的分析…

Mr. Cappuccino的第55杯咖啡——Mybatis一级缓存二级缓存

Mybatis一级缓存&二级缓存 概述一级缓存特点演示前准备效果演示在同一个SqlSession中在不同的SqlSession中 源代码怎么禁止使用一级缓存一级缓存在什么情况下会被清除 二级缓存特点演示前准备效果演示在不同的SqlSession中 源代码怎么关闭二级缓存 一级缓存&#xff08;Spr…

【css】css调整文本间距

text-indent 属性用于指定文本第一行的缩进letter-spacing 属性用于指定文本中字符之间的间距line-height 属性用于指定行之间的间距&#xff1a;word-spacing 属性用于指定文本中单词之间的间距&#xff0c;这个和letter-spacing类似white-space 属性指定元素内部空白的处理方…

Java面向对象之方法的使用

文章目录 一、什么是方法二、方法的声明格式三、方法的分类四、方法的调用五、方法的注意点六、方法的重载七、可变形参的方法八、方法参数的值传递机制九、递归方法 一、什么是方法 方法(method)是类或对象行为特征的抽象&#xff0c;用来完成某个功能操作。在某些语言中也称…