2019年电赛H题电磁炮实录

前言

你好学弟!这里是学长向你展示他们在2019年夏天搭出来的破烂是如何运行的。老师让我们把这堆破烂留给你们(有些零件缺了你们要自己买 -_-),这边怕你们不懂,完全自愿的给你们写了一篇教程,规避一些我们走过的弯路,也希望你们能把这份精神传承下去,替下下届的接班人们开山铺路。话不多说,先上个实物图。
这是比赛过程中拍的,两部分还没拼起来。。。

硬件

我们搭的这个玩意主要分为两个部分,电磁炮电路部分和控制电路部分,还有一块电源部分,当然其实测试现场是提供学生电源的,我们纯粹是吃饱了撑的。

  1. 电磁炮部分:包括两个开关(一个充电,一个放电),一个高压电容,一个升压模块,一个线圈与炮管。
  2. 控制部分:两个舵机+云台,一块F407(带触控屏),两个继电器,一块OpenMV,一个超声波模块

在这里插入图片描述

电磁炮部分

我们基本是照着这个电路搭建的:

在这里插入图片描述
原理很简单,主要就是控制一个电容的充放电,电磁炮用的是450V/1000uF的高压电容,所以需要用一个升压模块,充电开关就接在电池与升压模块之间。至于放电,把线圈接在电容两边就行了,但是放电开关不能直接接回路里(会烧的),所以加了一个可控硅,也就是一个开关管,当G置高的时候,K&A端就导通了,最后加了一个续流二极管给线圈放电。
现在说起来很简单,当初可是想破了头。。。
上实物图:
在这里插入图片描述
这边贴出详细物料清单:

  • 高压绝缘导线:这边一定要用这种线,用的时候截一段两边套热缩管。 淘宝链接
  • 开关两个: 就普通开关 淘宝链接
  • 航模电池:我买的是3S 2200mah的,额定电压11.1V 淘宝链接
  • 可控硅:型号BTA12-600B 淘宝链接
  • 升压模块:DC-DC直流升压模块 45-390V可调 淘宝链接
  • 电容:450V1000UF 电解电容 淘宝链接

注意事项:

  1. 线圈:其实比赛最主要的就是绕线圈,因为比赛是规定了管子直径的,所以线圈要自己拿漆包线( ϕ \phi ϕ 0.5~0.8)绕,绕的厚度,长度太短太薄都不行。线圈底部用棍子什么的封住,让炮弹头正好与线圈尾部重合,这样可以获得最长的加速距离。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  2. 充电开关和放电开关不能同时按,会短路!!还有每次充电之前都要先按下放电开关给电容放电,确保是从头开始充电的!!
  3. 升压模块:其实这个升压模块还是比较容易坏的,那个保险丝比较容易烧,要多备一些保险丝,模块上面有一个可调电阻可以调节输出电压,一般来讲在相同充电时间下充电电压越高电磁炮平射的距离越远,我们一般调节在100V左右。
    在这里插入图片描述
  4. 涉及到电磁炮射出炮弹的距离,有好几个可以调节的量。例如电容的充电时间,充电电压,炮口仰角。其实电容充电时间和充电电压就是决定的炮口初速度大小,根据我们的计算,电容充电在零点几秒之内就能完成,所以主要就是旋那个调节电阻改变充电电压,然后根据经验得到一个合适的出射速度V。当然这边其实可以在炮口加一个光电门测速,这样更精确一些。
  5. 炮弹:关于炮弹,当初实验室里用各种各样的都有,最基本的是小钢珠,还有小磁铁块,经过验证磁铁块是比小钢珠射的更远一些。不过最后我们选的是无头螺钉,效果也不错。
  6. 续流二极管:我们是直接焊在线圈两端,方向一定不能弄反,挑大规格的买就行。 淘宝链接
    在这里插入图片描述
    在这里插入图片描述

控制部分

理论模型

其实基本模型就是中学的抛体公式:
在这里插入图片描述
假设炮弹初速度为V,炮口相对于地面倾角为α,炮口相对于地面的竖直落差为h,重力加速度为g,取g = 9.8N/kg。
将炮弹的速度分解为水平与竖直两个方向上的分速度,分别为Vx=V *Cosα和Vy = V * Sinα。此时炮弹落地所需时间为:
t = − V y + ( V y 2 + 2 g h ) g t= \frac{-V_y+\sqrt {(V_y^2+2gh)}}{g} t=gVy+(Vy2+2gh)
炮弹在水平方向的距离方程为:
s = V ∗ c o s α ∗ t s =V *cosα * t s=Vcosαt
炮弹在竖直方向的距离方程为:
y = V s i n α − 1 2 g t 2 y=V sinα-\frac{1}{2} gt^2 y=Vsinα21gt2
由此可得出射角度α与距离s的关系式:
− h = s ∗ t a n α − 1 2 g ( s V c o s α ) 2 ( ∗ ) -h=s*tanα- \frac{1}{2} g(\frac{s}{V cosα })^2(*) h=stanα21g(Vcosαs)2
当时我们通过调节升压模块上的可调电阻得到一个确定的电压(90~100V左右)与炮口初速,然后通过调节仰角α来改变距离s。
这边有两种思路:

  • 一种是通过纯数学公式模拟整个模型,得出α(x)与s(fx)的关系式,进而确定每次的仰角。用matlab数值模拟将( ∗ * )式解出,V取平射能达到两米时的初速,h由题目给定。
    在这里插入图片描述
  • 另一种是直接枚举出所有距离下对应的炮口仰角,然后存在程序里调用。这种方式精确度很高,但需要大量的测试,一遍遍的调整角度然后记录距离。在比赛过程中如果时间充裕的话一般都是用枚举,老师可不会关心你用了什么先进的算法模型,而是只关心结果!!
整体结构

控制系统的总体框图如下:
在这里插入图片描述

  • 主控模块:选用一块STM32F407带一块触控屏作为交互在这里插入图片描述
    在这里插入图片描述
  • 执行模块:用了两个舵机和一个双轴云台架 在这里插入图片描述
  • 测距模块:测距与识别模块用到的是openMV和超声波,openMV用于识别红色目标靶,超声波用于测量与靶子的距离。在这里插入图片描述
    在这里插入图片描述
  • 继电器模块:通过两路继电器模块控制充电与放电开关,这里需要选导通电压12V的
    在这里插入图片描述
  • 电源模块:选用充电宝+USB集线器给OpenMV与F407供电,一块额定电压11V的电池输出两路分别给继电器供电以及到一块降压模块中转成舵机使用的7V
    在这里插入图片描述
  • 降压模块的特写:输入12.31V,输出6.63V,按下on/off开启输出,开启输出后舵机不能再用手硬拨了!
    在这里插入图片描述

器件清单:

软件

代码分为OpenMV部分和STM32部分,OpenMV用于进行色块识别,STM32用于主控以及交互。这边先讲解如何交互,然后再简略讲解一下代码结构。整个工程我也会放上来。

交互操作

所有操作都在这个正点原子电阻屏上完成。一开始进入时需要进行屏幕校准,一般情况下屏幕校准只需要进行一次即可,结果会存到Flash里。这边有一个我们一直没能解决的BUG,开发板上默认是不带24C02的,所以我们焊了一个上去,然而这个24C02在代码里始终无法初始化成功,不知道怎么回事。
在这里插入图片描述
进入程序界面:可选择操作模式,其中模式一用于指定角度与距离的射击,模式二用于识别红色标靶与距离并进行射击,模式三用于摆动射击。下方为调试信息。
在这里插入图片描述
模式一:上方两排分别对应百十个位的加减;Swtch用于切换设置距离或角度;Negti用于设置角度的正负,以炮口正对向前为0度;Start键开始射击;Retrn返回,有时候不太灵,需要重启一下
在这里插入图片描述
模式二:有两个Start,分别对应摄像头测距与超声波测距,点左边那个。红色靶就按题目中给定的做。
在这里插入图片描述
模式三:就一个Start,点击过后会开始从-20°到+20°开始搜寻标靶,当搜寻到时会立即射出炮弹。
在这里插入图片描述

OpenMV

安装OpenMV IDE以及快速入门:参考链接

#提示包未安装的自己找教程安装一下-_-
import sensor, image, time, math
from pyb import UART
import json	
import ustruct

sensor.reset()
sensor.set_framesize(sensor.QVGA)
sensor.set_pixformat(sensor.RGB565)
sensor.skip_frames(time = 2000)
#sensor.set_auto_gain(False) # must be turned off for color tracking
#sensor.set_auto_whitebal(False) # must be turned off for color tracking
#sensor.set_auto_exposure(False,2000);  #控制曝光时间,单位为us
sensor.set_hmirror(True); #控制水平镜像翻转
sensor.set_vflip(True); #控制水平镜像翻转
#sensor.set_windowing((22,7,110,105));

clock = time.clock()
uart = UART(3,115200)   #定义串口3变量    P4 TX<-->PA10  P5 RX<-->PA9
uart.init(115200, bits=8, parity=None, stop=1) # init with given parameters

#binary_threshold = (0, 156)
find_threshold = (51, 77, 34, 67, -33, 50)
K = 12800;  #自己选取一个合适的校准值
def find_max(blobs):    #定义寻找色块面积最大的函数
    blobs.sort(key=lambda x:x.pixels(),reverse=True);
    max_blob={}             #默认为空字典
    length=len(blobs);
    if length>0:
        max_blob=blobs[0];
    return max_blob;

def sending_data(cx_max,cy_max):
    global uart;
    #frame=[0x2C,18,cx%0xff,int(cx/0xff),cy%0xff,int(cy/0xff),0x5B];
    #data = bytearray(frame)
    data = ustruct.pack("<bbhhb",              #格式为俩个字符俩个短整型(2字节)
                   0x2C,                       #帧头1
                   0x12,                       #帧头2
                   int(cx_max), # up sample by 4    #数据1
                   int(cy_max), # up sample by 4    #数据2LCD_ShowStringLCD_ShowString
                   0x5B);
    uart.write(data);   #必须要传入一个字节数组

while(True):
    clock.tick()
    img = sensor.snapshot()#.lens_corr(1.45);
    #img.binary([binary_threshold], invert = 1)
    blobs = img.find_blobs([find_threshold],area_threshold=150)

    if blobs:	#如果找到的话
        max_blob=find_max(blobs)
        img.draw_rectangle(max_blob.rect(),color=(0,0,255))
        img.draw_cross(max_blob.cx(), max_blob.cy(),color=(0,0,255))
        img.draw_cross(160, 120,color=(0,0,255)) # 在中心点画标记
        img.draw_line((160,120,max_blob.cx(),max_blob.cy()), color=(0,0,255));

        phi = (max_blob.w() + max_blob.h())/2;
        length = K/phi; #获得距标靶距离

        #print('position:',max_blob.cx(),max_blob.cy())
        if(max_blob.pixels()>1000):	#滤除像素过小的干扰
            sending_data(max_blob.cx(),length); #发送点位坐标
            #print(max_blob.pixels())
        print("Length=",length);
    else:
        sending_data(10000,10000);
    #print(clock.fps())

STM32

开发环境:Keil v5以及相应的F4XX器件包,Keil v4不知道会不会报错。

//这里就简要的说明一下各个文件的内容
//具体工程我放到百度云里了

/*
main.c:
包含所有的变量定义,所有的初始化,
主循环while(1)用于模式切换以及数据通信
主要控制逻辑中断函数void TIM3_IRQHandler(void)频率50Hz,用于处理各个模式下的具体执行

usart2.c:
用于处理与OpenMV的通信

timer.c:
定时器3的初始化

pwm.c:
定时器14,11,4的初始化

Control.c:
对串口2接收的数据进行处理
对舵机的PID控制函数

Interface.c:
各个模式交互界面的编写

jidianqi.c:
继电器的初始化

US100.c:
超声波的所有相关

24cxx.c
ctiic.c
myiic.c
touch.c
ft5206.c
gt9147.c
ott2001.c
*/

相关资料

工程链接:
百度云:https://pan.baidu.com/s/1Z5I1Z38kK1VSa_iRjeXQYQ 提取码:wbrp

CSDN:https://download.csdn.net/download/qq_43243338/11938761

模块资料:
找淘宝店家要…

  • 190
    点赞
  • 924
    收藏
    觉得还不错? 一键收藏
  • 46
    评论
引用\[1\]:2019电赛电磁炮目要求电磁炮能够将弹丸射出炮口,并且能够根据键盘输入的距离和角度自动瞄准射击环形靶,按击中环数计分。此外,还有一个发挥部分的要求,即在指定范围内任意位置放置环形靶,电磁炮能够自动搜寻目标并炮击环形靶,按击中环数计分,完成时间不超过30秒。\[2\]这个目使用了STM32F103作为主控模块,外接触摸屏实现人机交互。以舵机云台搭载电磁炮和标靶测量模块,实现两自由度转动。电磁炮模块采用斩波升压和大电容作为驱动,通过激光测距模块识别和测量标靶距离。\[1\]在电磁炮发射瞬间时,为了避免电容对电感放电产生持续的大电流,引入了继电器控制充电电源的通断,使充电电源在发射瞬间处于断开状态。\[3\] 问: 2019电赛电磁炮目有哪些要求和设计特点? 回答: 2019电赛电磁炮目要求电磁炮能够将弹丸射出炮口,并且能够根据键盘输入的距离和角度自动瞄准射击环形靶,按击中环数计分。此外,还有一个发挥部分的要求,即在指定范围内任意位置放置环形靶,电磁炮能够自动搜寻目标并炮击环形靶,按击中环数计分,完成时间不超过30秒。\[1\]这个目使用了STM32F103作为主控模块,外接触摸屏实现人机交互。以舵机云台搭载电磁炮和标靶测量模块,实现两自由度转动。电磁炮模块采用斩波升压和大电容作为驱动,通过激光测距模块识别和测量标靶距离。\[2\]在电磁炮发射瞬间时,为了避免电容对电感放电产生持续的大电流,引入了继电器控制充电电源的通断,使充电电源在发射瞬间处于断开状态。\[3\] #### 引用[.reference_title] - *1* *2* *3* [【立创EDA开源推荐】005期 | 2019电赛H 电磁炮(激光版)](https://blog.csdn.net/OSHWHub/article/details/116046626)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 46
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值