2023年电赛---运动目标控制与自动追踪系统(E题)OpenMV方案
前言
(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, timefrom 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量即可
tilt_pid = PID(p=0.05, i=0, imax=90) #脱机运行或者禁用图像传输,使用这个PID
#pan_pid = PID(p=0.1, i=0, imax=90)#在线调试使用这个PID
#tilt_pid = PID(p=0.1, i=0, imax=90)#在线调试使用这个PIDsensor.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=0for blob in blobs:if blob[2]*blob[3] > max_size:max_blob=blobmax_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()/2tilt_error = max_blob.cy()-img.height()/2print("pan_error: ", pan_error)img.draw_rectangle(max_blob.rect()) # 在找到最大色块画一个矩形框img.draw_cross(max_blob.cx(), max_blob.cy()) # cx, cypan_output=pan_pid.get_pid(pan_error,1)/2tilt_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)因为我们要追踪红色,所以是使用red_threshold = (13, 49, 18, 61, 6, 47) 进行设置阈值。
(2)颜色阈值设置教程:OpenMV颜色阈值设置
帧率禁用
(1)当OpenMV连接电脑端IDE的时候,运行帧率和不连接电脑端IDE是不一样的。因为我们连接上电脑端IDE的时候,OpenMV会向电脑端IDE传输数据,所以会导致帧率下降。
(2)帧率下降,会导致我们实际脱机跑的时候,PID参数和连接上电脑端IDE时候的PID参数不一样。
(3)所以我们需要点击电脑端右上角的禁用,或者是Disable。被禁用之后,我们的效果就是脱机之后真实运行效果。

PID的P和I参数设置
(1)注意,因为云台是比较稳定的,不要求高反应速度,所以我猜测只使用了PI,而没有使用PID。因此我们可以看到pan_pid和tilt_pid只有P和I两个参数。
(2)I的参数不需要进行调整,如果你的云台抖动厉害,说明P过大了,需要调小。
(3)如果你感觉你云台反应太慢,就需要调高P值。
(4)最佳的P值是,你云台有抖动的前一个值。这个才是P的最优值。但是我认为,P没必要太大,因为云台还是比较稳的。
pid.py
(1)这里面的代码我们不需要管,就算PID的代码。
(2)再次强调,这里请别擅自更改,出现问题自己负责。
from pyb import millis
from math import pi, isnanclass 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_toutput = 0if self._last_t == 0 or dt > 1000:dt = 0self.reset_I()self._last_t = tnowdelta_time = float(dt) / float(1000)output += error * self._kpif abs(self._kd) > 0 and dt > 0:if isnan(self._last_derivative):derivative = 0self._last_derivative = 0else:derivative = (error - self._last_error) / delta_timederivative = self._last_derivative + \((delta_time / (self._RC + delta_time)) * \(derivative - self._last_derivative))self._last_error = errorself._last_derivative = derivativeoutput += self._kd * derivativeoutput *= scalerif abs(self._ki) > 0 and dt > 0:self._integrator += (error * self._ki) * scaler * delta_timeif self._integrator < -self._imax: self._integrator = -self._imaxelif self._integrator > self._imax: self._integrator = self._imaxoutput += self._integratorreturn outputdef reset_I(self):self._integrator = 0self._last_derivative = float('nan')
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问:测试场地屏幕是否与外界环境线条分界明显?
答:没有要求。
相关文章:
2023年电赛---运动目标控制与自动追踪系统(E题)OpenMV方案
前言 (1)废话少说,很多人可能无法访问GitHub,所以我直接贴出可能要用的代码。此博客还会进行更新,先贴教程和代码 (2)视频教程: https://singtown.com/learn/49603/ (3&a…...
6G内存运行Llama2-Chinese-7B-chat模型
6G内存运行Llama2-Chinese-7B-chat模型 Llama2-Chinese中文社区 第一步: 从huggingface下载 Llama2-Chinese-7b-Chat-GGML模型放到本地的某一目录。 第二步: 执行python程序 git clone https://github.com/Rayrtfr/llama2-webui.gitcd llama2-web…...
项目经理必备-项目总体计划模板-制式文件,可直接填写使用-公司可用
合同中完整项目名称,黑体,28号字, 居中对齐,项目名称较长时换行填写 当前文档名称,黑体,小初, 居中对齐,文档名称较长时 换行填写 版 本 号 x.x 编制人 日期 20xx年xx月xx日…...
正则表达式系列|(以xx开头xx结尾提取、切分、替换)
正则表达式系列|(以xx开头xx结尾提取、切分、替换) 文章目录 正则表达式系列|(以xx开头xx结尾提取、切分、替换)[TOC] 前言一、以xx开头xx结尾进行数据处理?1.以xx开头xx结尾对文本拆分2.以xx开头xx结尾提取内容3.以xx…...
金融学复习博迪(第1-5章)
第一部分 金融和金融体系 第1章 金融学 金融:资金的流通,即储蓄,信贷、汇兑、股票和证券交易等经济活动的总称。 金融学:研究货币流通的学问。 传统的金融学研究领域大致有两个方向: >宏观层面的金融市场运行理论…...
【前端知识】React 基础巩固(三十七)——自定义connect高阶组件
React 基础巩固(三十七)——自定义connect高阶组件 一、手撸一个自定义connect高阶组件 import { PureComponent } from "react"; import store from "../store";/*** connect的参数:* 参数一: 函数* 参数二: 函数* 返…...
前端PDF导出,使用html2Canvas和jsPDF插件
import html2Canvas from "html2canvas"; import jsPDF from "jspdf"; export function downloadPDF(dom, filename) {const scale 2;window.pageYOffset 0;// 滚动到顶部,避免打印不全document.documentElement.scrollTop 0;document.body.…...
Android 设备兼容性使用详解
和你一起终身学习,这里是程序员Android 经典好文推荐,通过阅读本文,您将收获以下知识点: 一、设备兼容性分类二、硬件设备兼容三、软件 APP 兼容四、兼容不同语言五、兼容不同分辨率六、兼容不同屏幕方向布局七、兼容不同硬件 Feature八、兼容…...
vnc加固
0x00 认识VNC 先我们看看VNC运行的工作流程: VNC客户端通过浏览器或VNC Viewer连接至VNC Server; VNC Server传送一个对话窗口至客户端,要求输入连接密码(可能为空),以及存取的VNC Server显示装置&#…...
Windows下Nginx安装与配置教程
一、前言 1、Nginx是什么? Nginx是一个开源的Web服务器,同时Nginx也提供了反向代理和负载均衡的功能。 Nginx通常作为负载均衡器暴露在外网接受用户请求,同时也使用其反向代理的功能,将用户的请求转发到实际提供服务的内网服务器…...
Iterator迭代器和Generator生成器
Iterator迭代器和for/of循环原理 Iterator迭代器规范 自己创建一个Iterator类,来实现ES6中的迭代器规范: class Iterator {constructor(assemble) {// assemble:需要迭代的数据结构this.assemble = assemble// index:记录迭代的次数(或者索引)this.index = -1}// 必须具…...
Modbus-RTU协议C#实现
1、安装依赖包 System.IO.Ports 2、读协议 /// <summary>/// Modbus-RTU协议读实例/// </summary>private static void Read(){//组装一个请求报文// 01 03 00 00 00 0A C5 CDbyte slave 0x01;//byte function 0x03; //读单个寄存器byte function 0x01; //…...
Redis学习---大数据技术之Redis(NoSQL简介、Redis简介、Redis安装、五大数据类型、相关配置、持久化)
星光下的赶路人star的个人主页 毅力是永久的享受 文章目录 1、NoSQL1.1 NoSQL数据库1.1.1 NoSQL是什么1.1.2 NoSQL的特点1.1.3 NoSQL的适用场景1.1.4 NoSQL的不适场景 1.2 NoSQL家族 2、Redis简介2.1 Redis官网2.2 Redis是什么2.3 Redis的应用场景2.3.1 配合关系型数据库做高速…...
基于组合双向拍卖的共享储能机制研究(Matlab代码实现)
目录 💥1 概述 📚2 运行结果 2.1 算例数据 2.2 买家中标 2.3 卖家中标 🎉3 文献来源 🌈4 Matlab代码实现 💥1 概述 文献来源: 摘要:为满足共享储能中储能用户的互补性和替代性需求、解决常规单…...
服务机器人有哪些品类
服务机器人是指具备自主运动、感知环境、实现人机交互等能力的机器人,它可以被应用于不同的场景,如餐饮、医疗、物流等行业。根据其功能和应用场景的不同,服务机器人可以分为以下几类:1. 餐饮服务机器人 随着社会发展和人们需…...
3.netty和protobuf
1.ChannelGroup可以免遍历由netty提供,覆盖remove方法即可触发删除channel\ 2.群聊私聊 13.群聊私聊简单原理图 3.netty心跳检测机制,客户端对服务器有没有读写(读,写空闲) //IdleStateHandler(3,5,7,TimeUnite.SECONDS)是netty提供的检测状态的处理器,也加到pipeline,读,写,…...
NLP实践——Llama-2 多轮对话prompt构建
NLP实践——Llama-2 多轮对话prompt构建 1. 问题提出2. prompt的正确形式3. 效果测试4. 结尾 1. 问题提出 最近,META开源了Llama-2模型,受到了广泛的关注和好评,然而,在官方给的使用说明中,并没有对使用方法进行特别细…...
《TCP IP网络编程》第十四章
第 14 章 多播与广播 14.1 多播 多播(Multicast)方式的数据传输是基于 UDP 完成的。因此 ,与 UDP 服务器端/客户端的实现方式非常接近。区别在于,UDP 数据传输以单一目标进行,而多播数据同时传递到加入(注…...
网络基础-认识每层的设备和每层的特点用途
目录 网络层次常见设备各层介绍数据链路层网络层传输层应用层 网络层次 常见设备 各层介绍 数据链路层 有了MAC地址。数据链路层工作在局域网中的,以帧为单位进行传输和处理数据。 网络层 网络层有了IP。不同的网络通过路由器连接成为互联网 路由器的功能: …...
【Linux操作系统】深入解析Linux定时任务调度机制-cronat指令
在Linux操作系统中,定时任务调度是一项重要的功能,它可以让用户在指定的时间或周期性地执行特定的任务。这种机制使得用户能够自动化地执行一些重复性工作,提高工作效率。本文将详细介绍Linux定时任务调度的原理、常用指令和代码示例…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...
