位置: IT常识 - 正文

2022年电子设计竞赛B题倒库闭环的思考(2022年电子设计大赛F题)

编辑:rootadmin
2022年电子设计竞赛B题倒库闭环的思考 2022年电子设计竞赛B题倒库闭环的思考具有自动泊车功能的电动车(B题)简介误差的获得如何获取初始偏置库内有箭头的搜索方法箭头方位的获得车库边缘位置的确定

推荐整理分享2022年电子设计竞赛B题倒库闭环的思考(2022年电子设计大赛F题),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:2022年电子设计竞赛题目D题,2022年电子设计竞赛,2022年电子设计竞赛题目,2022年电子设计大赛时间,2022年电子设计竞赛题目,2022年电子设计大赛F题,2022年电子设计竞赛题目,2022年电子设计大赛时间,内容如对您有帮助,希望把文章链接给更多的朋友!

2022年我队友FKR带我打电赛。作为智能车队的一员,我们肯定要做和车有关的。 2022年电子设计竞赛B题部分要求如下:

具有自动泊车功能的电动车(B题)简介

设计制作具有自动泊车功能的电动车,可在图1所示的作品测试泊车场地上,分别独立完成“倒车入库/出库”或“侧方入库/出库”的单项操作,也可连续完成这两项入库/出库的操作。 (1)单项倒车入库/出库①:如图2所示,一键启动摆放在“发车区1”内的电动车,电动车以“右侧垂直泊车方式”自动倒车进入库2内居中位置停车(详见图2中库区abcd,此时库1、库3内均停有车辆),倒车入库时间越短越好(定义见本题说明,>30s的测试项成绩记0分)。电动车在库内停车到位5s后,沿车头方向右转出库,车身整体出库时间不超过15s。(20分) 这里就以倒库部分的闭环控制讲解为例。 在如图所示的小车上方加一根杆子,然后添加一个OpenMV摄像头角度略微朝下,能够看到倒库时视角如下图所示 需要注意的是,库内的箭头大小无所谓。我们最需要关注的点就是希望小车能够在库内沿着中轴线前进,也就是说,我们的目标是找到需要停车库的边线位置。

误差的获得

先考虑库内没有箭头的情况 首先,我们需要明确几个概念:当小车沿着库内中线走的时候,那么在后视镜看到的视角当中库边侧两条线应该是沿着自身滑动的,即在视野中是相对静止的。因此我们可以通过寻找跳变沿,即像素点从黑变白的位置处作为库边缘的位置。我们在屏幕中选择一条水平的基准线,那么如果在没有箭头,而且车身沿着库内平行于库边的直线倒退的时候,该基准线上的黑变白的跳变沿的位置应该是不变的。 以屏幕中心为起始点,向外侧扫描跳变沿,左侧的距离为r1r_{1}r1​,右侧的距离为r2r_{2}r2​,由于摄像头的位置可能不是非常正好的正中央,所以当车身沿着平行于库边缘的中心线后退的时候,应满足如下两个式子: {r1+r2=W1r2−r1=b1\left\{\begin{matrix} r_{1} + r_{2} = W_{1}\\ r_{2} - r_{1} = b_{1} \end{matrix}\right.{r1​+r2​=W1​r2​−r1​=b1​​ 其中W1W_{1}W1​是给定扫描行下库边缘的宽度,b1b_{1}b1​是车沿着平行于库边缘的中心线后退的时候由于摄像头初始位置不是完全的视野中心而造成的初始偏置。 如果车身并没有沿着中心线运行的话,我们就取误差如下: e=r2−r1−b1e=r_{2} - r_{1} - b_{1}e=r2​−r1​−b1​

很容易理解,该量具有极性。当车身偏向左侧时,r1r_{1}r1​增大,r2r_{2}r2​减小,eee减小,甚至过零变负,反之亦然。将该量作为小车舵机PIDPIDPID控制的输入量就可以实现入库闭环自校正。

如何获取初始偏置

获取初始偏置的方法建议手动调试。即给舵机上电且机械调零后,舵机就可以稳定在机械零点的位置。这时手扶着小车在库中线前后移动,在不触碰边线的情况下如果r2−r1r_{2} - r_{1}r2​−r1​在车移动的过程中保持恒定了,这证明小车走的路径确实是沿着平行于库边缘的直线运行。这时在视觉上车身就是在车库中线上运行时且r2−r1r_{2} - r_{1}r2​−r1​仍保持恒定,记录r2−r1=b1r_{2} - r_{1} = b_{1}r2​−r1​=b1​作为初始偏置。

库内有箭头的搜索方法箭头方位的获得2022年电子设计竞赛B题倒库闭环的思考(2022年电子设计大赛F题)

首先对OpenMV进行初始化:

import pybimport sensor, image, time, mathfrom math import *from machine import UARTfrom pyb import Pinsensor.reset()sensor.set_pixformat(sensor.GRAYSCALE)sensor.set_framesize(sensor.QQVGA) # we run out of memory if the resolution is much bigger...sensor.set_brightness(2000) # 设置图像亮度 越大越亮sensor.skip_frames(time = 20)sensor.set_auto_gain(False) # must turn this off to prevent image washout...sensor.set_auto_whitebal(False) # must turn this off to prevent image washout...clock = time.clock()

这里面的画幅大小模式为sensor.QQVGA,即160*120大小。 我们先定义几个变量:

DIRECTFLAG = 0 # 扫线模式,0左1右ROUTE_WID = 40 # 赛道宽,按经验取FIRSTFLAG = 0 # 第一次运行循环标志位LINE_SCAN = 75 # 扫线位置BAIS = 16 # 后倒库角度偏置WID_THRES = 90 # 判断左右探索大于多少判定为车库边界的阈值CHECK_MODE = 0 # 查线方式判断箭头偏向镜头哪一侧JUMPGATE = 30 # 探索跳变沿的跳变沿阈值

我们采用的扫描方式只是简单的单行扫描,如果只是静态的扫描我们无法获得箭头的真实位置。如下图所示 在这幅图中,扫描行上检测出了三个跳变点。但是单凭这一时刻的跳变沿位置我们是无法判断这三个跳变沿究竟哪个是箭头,哪个是车库边缘。由于箭头在车库中心,因此这三个跳变沿之间的距离应该十分接近。既有可能是左侧两个是车库边缘,中间是箭头;又有可能是中间是车库边缘,两侧是箭头。为了区分上面两个矛盾,我们必须要找到跳变沿的变化规律。 我们将视野分成两部分,左侧(红色)为视野偏左侧的跳变沿,其大小为与中线的距离,越靠近左侧其值越大,右侧(蓝色)同理 当小车开始进入库内的时候,基准线两侧扫描到的第一个跳变沿之间的距离就应该是库的宽度。当箭头出现在画幅偏左侧的时候,从基准线中央向左侧扫描获得的第一个跳变沿会有一个剧烈的减小,这个阈值我们设置为JUMPGATE ,定义为30个像素宽。如果我们检测到基准线左侧跳变沿的第一个跳变有下降沿,那么我们断定箭头在视野偏左侧的位置,即基准线中心在箭头右侧;若基准线右侧跳变沿有一个下降沿,那么我们断定基准线中心在箭头左侧;若基准线左侧、右侧跳变沿均有一个下降沿,则基准线中心在箭头内部。

车库边缘位置的确定

我们在基准线中心分别向左右两侧寻找跳变沿,然后存放在两个列表当中:

# 从中心向外扫描边界,捕获黑变白上升沿 img_Llist = [] # 存储从中心点向左侧存储的跳变沿,中心点为0 img_Rlist = [] # 存储从中心点向右侧存储的跳变沿,中心点为0

然后根据阈值WID_THRES ,依次选择 ∣imgLlist[]−imgRlist[]∣\left |img_Llist[0]- img_Rlist[0] \right |∣imgL​list[0]−imgR​list[0]∣

∣imgLlist[1]−imgRlist[]∣\left |img_Llist[1]- img_Rlist[0] \right |∣imgL​list[1]−imgR​list[0]∣

∣imgLlist[1]−imgRlist[1]∣\left |img_Llist[1]- img_Rlist[1] \right |∣imgL​list[1]−imgR​list[1]∣

∣imgLlist[2]−imgRlist[1]∣\left |img_Llist[2]- img_Rlist[1] \right |∣imgL​list[2]−imgR​list[1]∣

∣imgLlist[2]−imgRlist[2]∣\left |img_Llist[2]- img_Rlist[2] \right |∣imgL​list[2]−imgR​list[2]∣ ……………… 当某一个值大于WID_THRES时,确定该时刻的差值就是车库边缘宽度。 但是这里有一个非常关键的问题,那就是第一次究竟应该先探索哪一侧,即应该是先左后右还是先右后左。上面的例子展示的是左侧探索优先。但是如果箭头在扫描中心的右侧,左侧探索优先一定会首先探测到左侧旁侧库的箭头位置,进而误认为两库内部箭头为库的边缘线了,这并不是我们想要的。 相反,如果我们采用右侧探索优先,就能够得到正确的车库边缘 因此这里我们就需要上一步得到的箭头的方位。如果箭头的位置在扫描基准行中心点左侧,则采用左侧探索优先,若箭头的位置在扫描基准行中心点右侧,则采用右侧探索优先。 完整代码如下,供大家参考学习:

import pybimport sensor, image, time, mathfrom math import *from machine import UARTfrom pyb import Pinfrom math import atansensor.reset()sensor.set_pixformat(sensor.GRAYSCALE)sensor.set_framesize(sensor.QQVGA) # we run out of memory if the resolution is much bigger...sensor.set_brightness(2000) # 设置图像亮度 越大越亮sensor.skip_frames(time = 20)sensor.set_auto_gain(False) # must turn this off to prevent image washout...sensor.set_auto_whitebal(False) # must turn this off to prevent image washout...clock = time.clock() # 加载模型WIDTH, HEIGHT = 160, 120 # 画幅宽高CARCENTER_X, CARCENTER_Y = 80, -40 # 车中心坐标KTHETA = 40 # 角度pTHRESHOLD = (0,100) # 灰度二值化阈值DIRECTFLAG = 0 # 扫线模式,0左1右ROUTE_WID = 40 # 赛道宽,按经验取FIRSTFLAG = 0 # 第一次运行循环标志位WAVETHRES = 30 # 限幅滤波幅值LINE_SCAN = 75 # 扫线位置BAIS = 16 # 后倒库角度偏置WID_THRES = 90 # 判断左右探索大于多少判定为车库边界的阈值CHECK_MODE = 0 # 查线方式判断箭头偏向镜头哪一侧JUMPGATE = 30 # 探索跳变沿的跳变沿阈值lastimg_L, lastimg_R = [], []lastimg_RDIS, lastimg_LDIS = 0, 0uart = UART(3, 115200)THETA = 0img_LDIS, img_RDIS = 0, 0LASTSTEER_THETA = 0#img = sensor.snapshot()#for i in range(WIDTH*HEIGHT - 1):counter = 0while(True): clock.tick() img = sensor.snapshot().lens_corr(strength = 1.5, zoom = 1.0) img.replace(vflip=True)#.lens_corr(strength = 1.8, zoom = 1.0) #print(img[120]) #img.bilateral(3, color_sigma=0.1, space_sigma=1) img.binary([THRESHOLD]) ################################################################## # 扫线 # img reshape,img_MAT[第几行][0表示最左侧边沿,1表示最右侧边沿] # 初始全部设为-1表示缺线,当检测边沿全部完成后未改变的仍未-1 img_MAT = [] for i in range(int(HEIGHT/INTER)): img_MAT.append([-1,-1,-1]) # 从中心向外扫描边界,捕获黑变白上升沿 img_Llist = [] # 存储从中心点向左侧存储的跳变沿,中心点为0 img_Rlist = [] # 存储从中心点向右侧存储的跳变沿,中心点为0 #img_LDIS, img_RDIS = int(WIDTH/2), int(WIDTH/2) FLAGL, FLAGR = 0, 0 for i in range(int(WIDTH/2)+1): # 对称搜索的角标,i1为从中心点向左数的列数,i2为从中心点向右数的列数 i1 = int(WIDTH/2 - 1 - i) i2 = int(WIDTH/2 - 1 + i) # 视野中心就是白,则默认该处为跳变沿 if i == 0 and img[int(LINE_SCAN*WIDTH + i1)] > 0: img_Llist.append(0) img_Rlist.append(0) # 左侧跳变沿,若左侧该点像素值为黑,下一个为白,该点为跳变点 if i < int(WIDTH/2) - 1 and img[int(LINE_SCAN*WIDTH + i1)] == 0 and\ img[int(LINE_SCAN*WIDTH + i1 - 1)] > 0: img_Llist.append(i) # 右侧跳变沿,若左侧该点像素值为黑,下一个为白,该点为跳变点 if i < int(WIDTH/2) - 1 and img[int(LINE_SCAN*WIDTH + i2)] == 0 and\ img[int(LINE_SCAN*WIDTH + i2 + 1)] > 0: img_Rlist.append(i) # 边缘处仍为黑色,默认黑变白跳变在视野边缘 if i == int(WIDTH/2) - 1 and img[int(LINE_SCAN*WIDTH + i1)] == 0: img_Llist.append(int(WIDTH/2)) if i == int(WIDTH/2) - 1 and img[int(LINE_SCAN*WIDTH + i2)] == 0: img_Rlist.append(int(WIDTH/2)) # 设置阈值输出宽度 # 循环两次调整数线模式 lb_l_bia, lb_r_bia = 0, 0 for j in range(2): for i in range(int(len(img_Llist) + len(img_Rlist))): if i%2 == 0: lb_l0 = int(i/2) lb_r0 = int(i/2) else: # 左向探索优先 if CHECK_MODE == 1: lb_l0 = int((i-1)/2) lb_l0 = lb_l0 + 1 # 右向探索优先 elif CHECK_MODE == 0: lb_r0 = int((i-1)/2) lb_r0 = lb_r0 + 1 lb_l = lb_l0# + lb_l_bia lb_r = lb_r0# + lb_r_bia # 探索方式为从中心点开始,一次向左,一次向右,并比较查看的两个跳变沿之间距离与阈值的关系 # 逐次比较,当某一侧探索完毕后补上某侧列表最后元素 if lb_l >= len(img_Llist): if len(img_Llist) == 0: img_LDIS = int(WIDTH/2) else: img_LDIS = img_Llist[len(img_Llist) - 1] else: img_LDIS = img_Llist[lb_l] if lb_r >= len(img_Rlist): if len(img_Rlist) == 0: img_RDIS = int(WIDTH/2) else: img_RDIS = img_Rlist[len(img_Rlist) - 1] else: img_RDIS = img_Rlist[lb_r] # 当中心探索区域大于某阈值弹出获得偏差 if img_LDIS + img_RDIS > WID_THRES: THETA = img_RDIS - img_LDIS# - BAIS break # 过滤噪点 if len(img_Llist) >= 2 and\ lb_l < len(img_Llist)-2 and\ abs(img_Llist[lb_l] - img_Llist[lb_l+1]) < 4: lb_l_bia += 1 if len(img_Rlist) >= 2 and\ lb_r < len(img_Rlist)-2 and\ abs(img_Rlist[lb_l] - img_Rlist[lb_l+1]) < 4: lb_r_bia += 1 if len(img_Llist) >= 2 and\ len(img_Rlist) >= 2 and\ img_Rlist[0] + img_Rlist[0] < 4: lb_l_bia += 1 lb_r_bia += 1 # 改变搜索方式 if j == 0 and FIRSTFLAG == 1 and \ img_Llist != [] and img_Rlist != [] and\ lastimg_L != [] and lastimg_R != []: # 捕获跳变沿 # 箭头在视野偏左侧出现,捕获左侧探索的下降沿,左侧探索优先 if img_Llist[0] - lastimg_L[0] < -30: CHECK_MODE = 1 # 箭头在视野偏右侧出现,捕获右侧探索的下降沿,右侧探索优先 if img_Rlist[0] - lastimg_R[0] < -30: CHECK_MODE = 0 # 箭头在视野偏左侧消失,捕获左侧探索的上升沿,右侧探索优先 if img_Llist[0] - lastimg_L[0] > 30: CHECK_MODE = 0 # 箭头在视野偏右侧消失,捕获右侧探索的上升沿,左侧探索优先 if img_Rlist[0] - lastimg_R[0] > 30: CHECK_MODE = 1 uart.write(str(int(THETA))+'\r\n') print(THETA,img_Llist,img_Rlist,CHECK_MODE) FIRSTFLAG = 1 lastimg_L = img_Llist lastimg_R = img_Rlist lastimg_RDIS = img_RDIS lastimg_LDIS = img_LDIS LASTSTEER_THETA = THETA img.draw_line(0, LINE_SCAN, 159, LINE_SCAN, color = (255, 255, 0), thickness = 2)
本文链接地址:https://www.jiuchutong.com/zhishi/297718.html 转载请保留说明!

上一篇:最通俗易懂的LSTM讲解,一个例子理解通透!!(最通俗易懂的电动力学教材)

下一篇:现代信号处理——时频分析与时频分布(小波变换)(现代信号处理张贤达)

  • 教你六种增强网店销售的经典促销的方法(怎样可以增强网络)

    教你六种增强网店销售的经典促销的方法(怎样可以增强网络)

  • 手机QQ怎么弄厘米秀(手机上怎么弄qq)

    手机QQ怎么弄厘米秀(手机上怎么弄qq)

  • qq戳一戳图片老是出现在相册(qq戳一戳怎么没了)

    qq戳一戳图片老是出现在相册(qq戳一戳怎么没了)

  • 淘宝换货一次还能在换吗(淘宝换货一次还能换吗)

    淘宝换货一次还能在换吗(淘宝换货一次还能换吗)

  • 固态硬盘做剪辑会快吗(固态硬盘剪视频)

    固态硬盘做剪辑会快吗(固态硬盘剪视频)

  • iphone连接手表后手机收不到提醒(iphone连接手表后手机不提醒消息)

    iphone连接手表后手机收不到提醒(iphone连接手表后手机不提醒消息)

  • 闲鱼未拆封机怎么验货(闲鱼未拆封机可信吗)

    闲鱼未拆封机怎么验货(闲鱼未拆封机可信吗)

  • 荣耀30pro带红外功能吗(荣耀30pro带红外线功能吗)

    荣耀30pro带红外功能吗(荣耀30pro带红外线功能吗)

  • 微信可以分身用吗(微信分身用的是主微信的流量吗)

    微信可以分身用吗(微信分身用的是主微信的流量吗)

  • 华为荣耀30pro支持无线充电吗(华为荣耀30Pro支持无线充电功能吗)

    华为荣耀30pro支持无线充电吗(华为荣耀30Pro支持无线充电功能吗)

  • 怎么快速筛选大量数据(怎么快速筛选出大量数据)

    怎么快速筛选大量数据(怎么快速筛选出大量数据)

  • 微博下的安装包怎么删(安卓微博下载的安装包在哪)

    微博下的安装包怎么删(安卓微博下载的安装包在哪)

  • 中塔和全塔机箱的区别(中塔和全塔机箱哪个好)

    中塔和全塔机箱的区别(中塔和全塔机箱哪个好)

  • 带pro是什么意思(pro是啥意思啊)

    带pro是什么意思(pro是啥意思啊)

  • ipadpro怎么备份(ipad怎么备份procreate)

    ipadpro怎么备份(ipad怎么备份procreate)

  • 手机淘宝怎么看天猫积分(手机淘宝怎么看自己的星级)

    手机淘宝怎么看天猫积分(手机淘宝怎么看自己的星级)

  • 手机怎么给手机充话费(手机怎么给手机传软件)

    手机怎么给手机充话费(手机怎么给手机传软件)

  • 唯品会买东西怎么免运费(唯品会买东西怎么看有没有运费险)

    唯品会买东西怎么免运费(唯品会买东西怎么看有没有运费险)

  • 电脑微信提示操作频率过快请稍后再试(电脑版微信提示)

    电脑微信提示操作频率过快请稍后再试(电脑版微信提示)

  • 苹果xsmax是不是2k屏

    苹果xsmax是不是2k屏

  • 华为p30pro支持sd卡么(华为p30pro支持双系统吗)

    华为p30pro支持sd卡么(华为p30pro支持双系统吗)

  • 三星s9有nfc功能吗(三星s9+nfc)

    三星s9有nfc功能吗(三星s9+nfc)

  • qq音乐可以多设备登录吗(qq音乐可以多设备放一首歌吗)

    qq音乐可以多设备登录吗(qq音乐可以多设备放一首歌吗)

  • 怎么将QQ里面的聊天背景改成一样(怎么将qq里面的小世界删除)

    怎么将QQ里面的聊天背景改成一样(怎么将qq里面的小世界删除)

  • 照片怎么显示时间和位置(照片怎么显示时间地点)

    照片怎么显示时间和位置(照片怎么显示时间地点)

  • 微信公众号秒回是什么(微信公众号回复的消息在哪里看)

    微信公众号秒回是什么(微信公众号回复的消息在哪里看)

  • 最近通话记录怎么恢复(最近通话记录怎么同步)

    最近通话记录怎么恢复(最近通话记录怎么同步)

  • windows密钥在哪里找(windows密钥在哪个文件)

    windows密钥在哪里找(windows密钥在哪个文件)

  • 计提税金账务处理
  • 上年多做收入今年可以直接冲减吗
  • 兼职是属于劳动报酬吗
  • 无票收入是否要交税
  • 捐赠的费用放在什么科目
  • 预提费用在资产负债表哪个科目
  • 利润表中的其他综合收益
  • 发票领回来了怎么读入发票
  • 土地增值税清算利息扣除规定
  • 外商投资企业合并
  • 分公司成立时的法人是谁
  • 产品报废怎么做账
  • 机械租赁增值税税率2022年
  • 原材料购入和转出做账
  • 委托加工几个点
  • 资产负债表里所有者权益合计为负数正常吗
  • 个人遗失的定义
  • 公司车辆怎么申请
  • 已抵扣的发票怎么开红字发票申请单
  • 小规模纳税人定额发票累计领用金额
  • 建筑公司工地买空调
  • 增值税的征收范围包括在中华人民共和国境内
  • win11界面不停刷新
  • 企业三大期间费用是什么
  • 如何降低融资成本率
  • mac catalina系统怎么样
  • 员工加班车费会计分录
  • windows11正式版本
  • 怎么让win7不锁定
  • 酒店行业存货周转率多少合适
  • HTML布局方式
  • 多品种生产能力计算公式
  • 企业要缴哪些税种
  • 企业预缴所得税怎么算
  • win10日历点不开
  • 消费积分如何做账
  • Python中tkinter的 Variable类
  • 银行存款利息的会计科目
  • 技术服务费该怎么收
  • 药品进销差价会计科目
  • 营改增后个人所得税计税依据实例
  • 库存商品盘亏计哪个科目
  • 信用减值损失在利润表怎么填列
  • 存货核算科目设置
  • 收到违约金如何做账
  • 开了假发票什么后果?
  • 企业接受供应单位提供劳务而发生的应付账款
  • 美元利息结汇时结汇项目是什么
  • 已认证抵扣增值税怎么撤回申报
  • 给对方承兑对方不承认怎么办
  • 小企业如何建立党支部
  • 深入浅出意思
  • mysql5.5.62安装教程图解
  • MySQL5.7中 performance和sys schema中的监控参数解释(推荐)
  • 更新最新版win11,任务栏不见了
  • centos7服务器配置
  • 在win7操作系统中通过什么可以查看计算机的配置
  • winxp家庭版和专业版的区别
  • win10推送win11
  • win7任务栏显示预览窗口
  • winxp系统优化
  • win10通讯
  • newdot.exe - newdot是什么进程 有什么用
  • 如何使用u盘安装linux
  • 微软在中国的代理公司
  • win10小娜无法启动语音识别
  • linux系统开发环境
  • linux强大的网络功能
  • linux用root登录
  • node 内存泄漏
  • Node.js中的事件循环是什么
  • python解析函数
  • javascript的弹窗
  • JavaScript中的方法名不区分大小写
  • 发布python程序
  • javascript原型
  • android 内部存储
  • 河北省国家税务局电子税务局登录
  • 内蒙古税务局发票认证
  • ssr服务器地址端口密码
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设