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

前言

(1)废话少说,很多人可能无法访问GitHub,所以我直接贴出可能要用的代码。此博客还会进行更新,先贴教程和代码
(2)
<1>视频教程: https://singtown.com/learn/49603/
<2>OpenMV追云台官方Github链接 :https://github.com/SingTown/OpenMV-Pan-Tilt/tree/master/pan-tilt/src
(3)有些人肯定说红点太小了,OpenMV不行精度不够,看这个C站上做出来的阈值代码:https://blog.csdn.net/weixin_52385589/article/details/126334744
(4)赛事方肯定不可能直接让你上现成的玩意,不然比赛的意义在哪里?我看了一下网上的一些讨论。肯定是要用摄像头的,K210好像有官方库,K210的同学可以了解一下。
(5)OpenMV的话需要多训练,建议最好做灯光补偿,毕竟OpenMV对灯光要求很高,环境光线一点要稳定!!!
注意:有网友反馈,官方说不能使用灯光补偿。我没得到相关信息,请各位确认之后再决定要不要使用灯光补偿。
(6)各位,有问题尽量C站私信。因为评论太多了,我容易漏掉。(虽然写评论区可以给我加热度,哭)
(7)这篇博客是会根据情况实时更新的,所以请各位注意刷新。
(8)再次强调,提供的都是伪代码!!!肯定会报错!!!要自己调整!!!我只提供思路,饭都端上来了,还不能吃吗?!
(9)更新日记:
<1>2023年8月2日,上午9点。OpenMV官方的追云台代码,以及相关解读。
<2>2023年8月2日,上午10点。增加C站另一位大佬的调试结果代码。
<3>2023年8月2日,下午2点。更改错别字,增加基础题思路。
<4>2023年8月2日,下午2点10分。增加网友的一些提问。
<5>2023年8月2日,下午2点40分。更改了前言部分,希望各位问问题私信我,因为写在评论区有时候会被刷新掉。
<6>2023年8月2日,下午2点50分。更新了基础题的思路,第四问还有待商榷。
<7>2023年8月2日,下午3点。更新了网友的一些问题
<8>2023年8月2日,下午3点40分。关于OpenMV的鱼眼畸变可能带来的问题,增加了软硬件解决方案。
<9>2023年8月2日,下午4点35分。关于代码报错问题回复,器件选择问题。
<10>2023年8月2日,下午5点30分。更新关于购买推荐的OpenMV云台可能导致的问题,以及据说可行的现成方案。
<11>2023年8月2日,下午6点。更新鱼眼畸变代码报错问题,基础题的第一问和第二问代码给出来了
<12>2023年8月2日,下午6点20分。更新了关于博客视频的资料在哪里,关于代码怎么获取。
<13>2023年8月2日,下午6点40分。关于K210,OpenART mini,OpenMV代码问题回答。
<14>2023年8月2日,下午7点30分。回答网友,舵机抽搐问题,OpenMV与主控通讯,第一问和第二问舵机控制不稳定。
<15>2023年8月2日,下午9点20分。更新推荐舵机,数字舵机比模拟舵机精度更高。
<15>2023年8月3日,12点睡觉前最后一次更新。关于激光和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的输出电流太小,带不动舵机!

在这里插入图片描述

云台购买推荐

(1)一开始我推荐使用这一款。后面根据别人反馈,精度不够。所以我还是推荐我之前吐槽的那个奇奇怪怪的舵机啊。(被打脸了,哈哈哈)

在这里插入图片描述

(2)推荐这一款,虽然不需要这么大的扭矩,但是他是数字舵机,精度更高。

在这里插入图片描述

OpenMV鱼眼畸变

(1)我刚刚上机测试了一下,突然发现OpenMV存在鱼眼畸变。
(2)鱼眼畸变就是,摄像出来的图片就像鱼的眼睛看到的图片一样,不是平的。
(3)这个会不会有影响不清楚。
(4)从硬件上处理办法就是换一个无畸变镜头,官方链接 :
https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w5003-18207055866.1.6b0b1dc1nPB6IZ&id=601956249175&scene=taobao_shop
(5)来不及的话,可以使用软件方法。但是我测试了,好像没有反应。
<1>我们购买的OpenMV的默认镜头是带鱼眼效果的,所以需要进行畸变矫正(注意:此处运算量大,不建议长时间使用OpenMV不然会发烫很严重
<2>因为我们这里没有指定是传入的zoom,x_corr,y_corr的值,所以按照顺序,传入的1.8是给strength。我们可以调节这个值,来查看即便矫正的效果,建议从1.8开始尝试。
<3>zoom就是进行图像缩放,比如10X10的图像,为0.5,就算5X5的图像。建议为默认值,只需要调节strength就行了。
<4>后面这个x和y是什么,官方文档没有解释。
(6)真的太多人不喜欢认真看博客了,说了是伪代码,要自己调整。还要问!我这里还是给这真正0~基础的人,贴出来,别再问了!

import sensor, image
img = sensor.snapshot() # 截取一张图片
img.lens_corr(1.8)  #去除鱼眼畸变

在这里插入图片描述

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

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

在这里插入图片描述

网上所宣传的现成可行方案

(1)我看网上有人说OpenART mini有一个现成的方案。如果会OpenART mini的同学,可以尝试。以下是这个资料
(2)百度网盘资料:
OpenART min模块资料链接:https://pan.baidu.com/s/1yoCNXzci_dfHzW33emxdLA
提取码:mxx8

在这里插入图片描述

(3)关于云台控制:
<1>云台由两个舵机组成,下面的舵机控制偏航角(左右)旋转,上面的舵机控制俯仰角(上下)旋转。
<2>如果在云台上面安装一个激光发射装置,当我们控制单个舵机旋转时,观察激光路径发现是一条直线,并且云台的两个舵机路径分别是一个水平和一个垂直的直线,如果我们同时控制两个舵机旋转的舵机就可以实现在一个面的任意位置激光投影。
<3>若此时我们需要控制舵机按照设定的固定路径移动,当路径为线段时,仅需要知道线段的起点坐标和终点坐标即可(坐标对应舵机的高电平时间,也就是占空比),如果直接将起点和终点输出到云台舵机,会发现虽然到达了起点和终点,但路径并非直线路径,这是由于X轴和Y轴移动距离不一致而产生的,因此需要将这条线段细分,比如通过起点坐标和终点坐标将线段细分为1000份,每次仅移动一份的距离,此时就会发现激光的路径沿着线段逐渐移动了。
<4>如果需要移动的路径为一个闭合矩形,我们仅需得到矩形的四个角的坐标,按照上面线段的分段移动的方式,分别将四条边细分后再控制舵机逐渐移动,即可实现看起来较为丝滑的闭合矩形路径。
<5>在编写控制程序时,如果采用这样分段移动的方式,那么我们可以将程序段放置在周期中断内执行,此时就可以确立单次移动的时间,从而控制整体的移动速度。移动速度的控制是必须的,不管是路径稳定还是点位追踪都需要涉及到移动速度的精准控制。
(4)E题中所涉及到的主控型号赛题没有任何限制,可以使用智能车竞赛中的核心板(例如RT1064、TC264、CH32V307、STC),其中RT1064主板有三个舵机接口,可以比较方便控制云台,激光也没有限制,只要求了光斑大小小于等于1厘米即可。
(4)关于这个方案的相关影像资料:

1

2


5


4

6

基础题思路

(1)以下均为个人思路,仅供参考。
(2)个人认为基础题不需要使用PID,只需要一个OpenMV,两个舵机,一个云台就可以了。
(3)OpenMV控制舵机的教程:OpenMV输出PWM,实现对舵机控制

第一问—复位

(1)这个比较简单,我感觉只需要写入一个固定值,给舵机一个固定的PWM就可以了。
(2)关于按键问题,你们可以使用下面的函数实现。
<1>这里的pyb.Pin第一个参数是你用于读取按键值的。
<2>第二个参数可以获得引脚上的按键值。
<3>按键电路如下,并联上一个104的电容,是用于硬件消抖。

import pyb
p = pyb.Pin("P0", pyb.Pin.IN)
key_value = p.value() # Returns 0 or 1.

在这里插入图片描述

第二问—沿A4纸移动

(1)和第一问一样,我认为写一个死的程序就行了,因为他的屏幕给定了0.5m*0.5m。
(2)有一些人问第一问和第二问切换问题

import pyb, time
p = pyb.Pin("P0", pyb.Pin.IN)
clock = time.clock() # 追踪帧率,影响不大
while True:key_value = p.value() # Returns 0 or 1.if key_value == 1:clock.tick() #开始计时Task1 = 1while key_value == 1: #一直等待松手passif key_value == 0:  #确认松手key_time = clock.avg()if(key_time > 2000) :  #如果按键按下时间超过2s# 进入任务2passelif Task1 == 1 : #如果按键按下时间小于1s# 进入任务1pass

第三问—黑色边框检测

(1)时间太紧急了,我就讲一下思路。
<1>我们使用blobs = img.find_blobs([red_threshold]),找到黑色边框。
<2>调用max_blob = find_max(blobs),找到最大的黑色边框。因为可能存在其他的干扰。
<3>找到边框之后,调用max_blob.x(),max_blob.y(),max_blob.w(),max_blob.h()分别获得识别到的边框左上角的x坐标,y坐标,宽度和长度。
<4>不明白的可以看下面这个图,假设0包含的地方是屏幕,11选中的是黑框内,我们最终返回的值如下图。
(2)有网友提供,说出现了NameError:name img isn’t defined的报错。是因为我只是截取了代码中的一部分。前面的没写,为了方便新手朋友使用,我还是加上。
(3)但是,请各位注意,摄像头的初始化

import sensor, image, timesensor.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([black_threshold])  #识别黑色阈值max_blob = find_max(blobs)  #调用上面自定义函数,找到最大色块max_blob.x()  #返回识别区域左上角的x坐标max_blob.y()  #返回识别区域左上角的y坐标max_blob.w()  #返回识别区域的宽度max_blob.h()  #返回识别区域的长度

在这里插入图片描述

第四问—黑色边框检测

(1)这个和第三问舵机控制有区别,第三问是一个舵机一个舵机的控制。而这一题需要两个舵机同时控制。
(2)这个可以看上面百度网盘的资料。那个方案似乎可行。

main.py

(1)以下为官方的追小球云台代码,我增加了中文注释。
(2)因为GitHub是在外网,所以我直接复制过来了。但是总是有一些网友,硬要官方的GitHub链接。我也贴到了前言部分。

代码

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量即可,设置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)#在线调试使用这个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)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, 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')

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

代码

原文链接 : https://blog.csdn.net/weixin_52385589/article/details/126334744

感光器初始化代码

sensor.reset()sensor.set_auto_gain(False)sensor.set_pixformat(sensor.GRAYSCALE) # or sensor.RGB565sensor.set_framesize(sensor.  QVGA) # or sensor.QVGA (or others)sensor.skip_frames(time=900) # Let new settings take affect.sensor.set_auto_exposure(False, 1000)#在这里调节曝光度,调节完可以比较清晰地看清激光点sensor.set_auto_whitebal(False) # turn this off.sensor.set_auto_gain(False) # 关闭增益(色块识别时必须要关)

识别激光点代码

def color_blob(threshold):blobs = img.find_blobs(threshold,x_stride=1, y_stride=1, area_threshold=0, pixels_threshold=0,merge=False,margin=1)if len(blobs)>=1 :#有色块# Draw a rect around the blob.b = blobs[0]#img.draw_rectangle(b[0:4]) # rectcx = b[5]cy = b[6]for i in range(len(blobs)-1):#img.draw_rectangle(b[0:4]) # rectcx = blobs[i][5]+cxcy = blobs[i][6]+cycx=int(cx/len(blobs))cy=int(cy/len(blobs))#img.draw_cross(cx, cy) # cx, cyprint(cx,cy)return int(cx), int(cy)return -1, -1 #表示没有找到

颜色阈值

threshold=[(60, 255, -20, 20, -20, 20)]

图像类型

(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>我个人建议还是先都关闭

在这里插入图片描述

在这里插入图片描述

网友提问

激光是不是安装在OpenMV上面?会不会有偏差?

答:
<1>肯定的,一开始我认为是只要一个OpenMV就可以了。后面发现发挥题和基础题的追踪激光颜色不一样。所以需要使用两个OpenMV,激光都固定在OpenMV上面。
<2>激光和摄像头的摆放位置肯定会产生造成偏差,所以这个要你自己调整好PWM

第一问和第二问舵机控制不稳定

答:
实在不行用PID,是伪代码,需要微调。

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)
max_blob = find_max(blobs)  #调用上面自定义函数,找到最大色块
pan_error = max_blob.cx()-img.width()/2    #获取中心位置x坐标
tilt_error = max_blob.cy()-img.height()/2  #获取中心位置y坐标
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)# 因为两个舵机方向和摆放位置不同,所以一个是+一个是-

OpenMV与主控通讯

答:
看我OpenMV专栏

舵机抽搐问题

答:
<1>先拿示波器测试OpenMV的PWM输出是否正常。
<2>那万用表测试接线是否正常,如果万用表显示没问题,再焊接一下。
<3>如果上面两个都测试通过,说明舵机坏了

关于K210,OpenART mini,OpenMV代码问题

答:
刚刚我尝试了一下,发现OpenART mini可以直接放在OpenMV上跑。所有建议各位,先拿着百度网盘现成的代码尝试跑一下。如果提示bug,就把有bug的部分注释了。应该是可行的。

有完整代码吗?

答:
<1>K210的资料没有!没有!没有!认真看字!
<2>OpenMV没有完整代码,所有代码都是在博客里面了!
<3>博客视频不算使用的OpenMV,是OpenART mini,认真看字!代码在我分享的百度网盘里面!

为什么要OpenMV控制舵机,主控控制舵机不行吗?

答:可以的,但是OpenMV控制的话,官方已经提供了PID控制代码。我们只需要调整P值就可以了。而我们用主控控制舵机的话,还需要自己调整PID,又现成的用现成的比较好。

舵机那个需要多少v还是12v直接给他,单片机那个是12v转5v对吧?

答:
<1>舵机看你选择的是多少V的,如果你的舵机VCC要求12V,那么就供12V的电压。但是我推荐常规的mg90s舵机,sg90舵机也可以。
<2>单片机的供电,要看你的单片机VDD要求多少,如果是MSP430,STM32这种,一般供电都是3.3V。如果你是使用的STC89系列单片机,就需要供5V电压。
<3>舵机,电池,OpenMV,单片机的GND都要连接在一起。这就是系统需要供电,提供基准电压。

只有一个OpenMV,引脚不够用吧?

答:
<1>我简单看了一下题目,个人认为如果只做基础题只要一个OpenMV就可以了。如果不行,可以通过OpenMV和主控进行通讯实现引脚扩展。
<2>相关教程:OpenMV串口通讯详解

pid.py和main.py是要写在一个py文件里面吗?

答:不是的一个是main.py,一个是pid.py。都放在OpenMV的根目录。(也就是插上OpenMV自动打开的那个目录)

在这里插入图片描述

我们测评的时候不能改代码,那么每一问应该怎么搞?

答:
这个肯定就需要你们自己处理好了,肯定不能一个题目一个代码。我只是提供思路,所以这些你需要自己整合好。

大佬,有代码吗?

答:
我没有实物,只是这个之前刚刚做过,就提供出来思路。没有代码!!!

步进电机和舵机的区别

答:
本人已和百度,bing达成高度合作,有些问题可以直接百度或者bing上搜索!
个人建议使用舵机

知道黑框位置之后,怎么追踪?

答:
希望各位仔细看博客,都说了,看OpenMV控制舵机的教程:OpenMV输出PWM,实现对舵机控制这篇博客。别再问这种问题了!!!

为什么我复制了博客中的代码会报错?

答:
我提供的都是伪代码,需要自己进行相应的调整。不能直接跑!!!

我要用几个摄像头,几个主控?材料推荐

答:
<1>个人认为只需要一个OpenMV即可,因为OpenMV上有图像处理单元,有RGB灯,有两路舵机控制。至于最终结果是不是这样,还不清晰。因为我没有实操。但是我还是认为一个OpenMV就可以做完这道题目。
<2>除了一个OpenMV以外,我个人建议最好用上无畸变镜头。购买链接:
https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w5003-18207055866.1.6b0b1dc1nPB6IZ&id=601956249175&scene=taobao_shop

我想使用stm32来控制舵机,OpenMV用来识别,可行吗?工作量会不会大一点?

答:
<1>可行,但是和上面一样,我还是建议只用一个OpenMV。如果你硬要用stm32控制,我也不拦着,这个是OpenMV串口通讯教程:OpenMV串口通讯详解
<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.mzph.cn/news/19167.shtml

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

相关文章

Eureka 学习笔记6:服务端实例缓存

版本 awsVersion ‘1.11.277’ 缓存类型registryConcurrentHashMap<String, Map<String, Lease<InstanceInfo>>>AbstractInstanceRegistry成员变量readWriteCacheMapLoadingCacheResponseCacheImpl成员变量readOnlyCacheMapConcurrentMap<Key, Value>…

k8s kubeedge安装metrics-server监控节点cpu内存使用情况

k8s kubeedge安装metrics-server监控节点cpu内存使用情况 官方安装地址: https://kubeedge.io/en/docs/advanced/metrics/ k8s的master节点上安装metrics-server #在k8s的master节点上执行#创建目录 mkdir metrics-server #下载deploy文件 wget https://github.com/kubernet…

JavaWeb 项目实现(四) 验证旧密码

1.验证旧密码 步骤很简单&#xff0c;从Session中取到当前密码&#xff0c;和修改密码界面得到的旧密码对比&#xff0c;判断是否相等。 特别之处在于实现用到了Ajax&#xff0c;可以不刷新整个页面的情况下与Web服务器进行通信。 2.Ajax Ajax&#xff08;Asynchronous Java…

正则表达式在格式校验中的应用以及包装类的重要性

文章目录 正则表达式&#xff1a;做格式校验包装类&#xff1a;在基本数据类型与引用数据类型间的桥梁总结 在现代IT技术岗位的面试中&#xff0c;掌握正则表达式的应用以及理解包装类的重要性是非常有益的。这篇博客将围绕这两个主题展开&#xff0c;帮助读者更好地面对面试挑…

无涯教程-jQuery - Menu组件函数

小部件菜单功能可与JqueryUI中的小部件一起使用。一个简单的菜单显示项目列表。 Menu - 语法 $( "#menu" ).menu(); Menu - 示例 以下是显示菜单用法的简单示例- <!doctype html> <html lang"en"><head><meta charset"utf-…

Vue2 第十节 内置指令和自定义指令

1.之前学过的指令 2. 内置指令 3. 自定义指令 一.之前学过的指令 指令名用法v-bind单项绑定解析表达式&#xff0c;可以简写为:xxxv-model双向绑定v-for遍历数组/对象/字符串v-on 绑定监听事件&#xff0c;可以简写为v-if条件渲染&#xff08;动态控制节点是否存在&#xf…

基于ANACONDA安装用于Python编程的Spyder集成开发环境的方法步骤详解

基于ANACONDA安装用于Python编程的Spyder集成开发环境的方法步骤详解 Python作为一种当下流行的编程语言&#xff0c;其编辑器有很多种&#xff0c;本文介绍基于ANACONDA的安装Spyder编辑器的方法步骤。Spyder集成开发环境&#xff0c;和其他的Python开发环境相比&#xff0c;…

C++——类与对象(中)

目录 类的6个默认成员函数构造函数析构函数拷贝构造函数赋值运算符重载const成员函数取地址及const取地址操作符重载 1.类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&#xff1f;并不是&#xff0c;任何类在什么都不写时…

TCP三次握手与四次断开

TCP三次握手机制 三次握手是指建立一个TCP连接时&#xff0c;需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。 1、客户端发送建立TCP连接的请求报文&#xff0c;其…

物理分代垃圾回收器

内存结构 内存分配 堆上分配 大多数情况在eden【年轻代中的一个区域】上分配&#xff0c;偶尔会直接在old【老年代】上分配&#xff0c;细节取决于GC的实现。栈上分配&#xff08;发生了指针逃逸&#xff0c;又叫指针逃逸分析——JVM优化&#xff09; 原子类型的局部变量。 G…

eclipse 最新版没有navigator视图如何解决

使用project exploere视图可以显示类似navigator视图 1.显示project exploere视图 window---->show view --->project exploere 2.project exploere视图转换为类似navigator视图 第一步&#xff1a;点击视图右上角三个点或者倒三角&#xff0c;点击fiters and custom…

3DEXPERIENCE用户角色 | Structural Mechanics Engineer 结构力学工程师

真实条件下实施复杂的线性和非线性分析 直观验证设计并更快地做出产品决策 Structural Mechanics Engineer 在基于云的 3DEXPERIENCE 平台上构建&#xff0c;您可对产品行为执行结构线性和非线性静态、低速和高速动态和热仿真。具备材料校准功能&#xff0c;有助于确保材料行为…

Python教程(6)——Python变量的基础类型。|整数类型|浮点数类型|字符串类型|布尔类型|

学习编程语言&#xff0c;不得不忽视变量这个概念。Python 中的变量是用于存储数据的名称&#xff0c;你可以将值赋给变量&#xff0c;并在程序的其他地方使用该变量来引用该值。变量在程序中起到存储和操作数据的作用。 如果学过C/C语言的同学&#xff0c;定义了变量后&#…

无涯教程-Lua - repeat...until 语句函数

与 for 和 while 循环(它们在循环顶部测试循环条件)不同&#xff0c;Lua编程中的 repeat ... until 循环语言在循环的底部检查其条件。 repeat ... until 循环与while循环相似&#xff0c;不同之处在于&#xff0c;保证do ... while循环至少执行一次。 repeat...until loop - …

单机,集群和分布式概念

单机的局限性&#xff1a; 1.受限于硬件资源&#xff0c;单机所能承受的用户并发量太少&#xff1b; 2.一个系统有多个模块&#xff0c;任意模块的修改都会导致整个项目代码重新编译、部署&#xff1b; 3.系统中&#xff0c;有些模块是CPU密集型&#xff0c;有些模块是I/O密…

通过案例实战详解elasticsearch自定义打分function_score的使用

前言 elasticsearch给我们提供了很强大的搜索功能&#xff0c;但是有时候仅仅只用相关度打分是不够的&#xff0c;所以elasticsearch给我们提供了自定义打分函数function_score&#xff0c;本文结合简单案例详解function_score的使用方法&#xff0c;关于function-score-query…

InnoDB引擎底层逻辑讲解——架构之内存架构

1.InnoDB引擎架构 下图为InnoDB架构图&#xff0c;左侧为内存结构&#xff0c;右侧为磁盘结构。 2.InnoDB内存架构讲解 2.1 Buffer Pool缓冲池 2.2 Change Buffer更改缓冲区 2.3 Adaptive Hash Index自适应hash索引 查看自适应hash索引是否开启&#xff1a; show variable…

6.s081(Fall 2022)Lab2: system calls

文章目录 前言其他篇章参考链接0. 前置准备1. System call tracing (moderate)简单分析Hint 1Hint 2Hint 3Hint 4Hint 5测试 2. Sysinfo (moderate) 前言 好像没啥前言 其他篇章 环境搭建 Lab1:Utilities 参考链接 官网链接 xv6手册链接&#xff0c;这个挺重要的&#xff…

Spring Data Elasticsearch - 在Spring应用中操作Elasticsearch数据库

Spring Data Elasticsearch 文章目录 Spring Data Elasticsearch1. 定义文档映射实体类2. Repository3. ElasticsearchRestTemplate3.1 查询相关特性3.1.1 过滤3.1.2 排序3.1.3 自定义分词器 3.2 高级查询 4. 索引管理4.1 创建索引4.2 检索索引4.3 修改映射4.4 删除索引 5. 异常…

GO学习之 多线程(goroutine)

GO系列 1、GO学习之Hello World 2、GO学习之入门语法 3、GO学习之切片操作 4、GO学习之 Map 操作 5、GO学习之 结构体 操作 6、GO学习之 通道(Channel) 7、GO学习之 多线程(goroutine) 文章目录 GO系列前言一、并发介绍1.1 进程和线程和协程1.2 并发和并行 二、goroutine介绍三…