简 介: 本文给出了第十六届智能车竞赛裁判系统最终的软件设计和功能实现。并进行了验证,是它可以满足比赛基本计时要求。 最后给出了完整的程序。

关键词智能车竞赛ESP32视觉AI

§01 智能车竞赛裁判系统


  在 基于ESP32智能车竞赛裁判系统第二版硬件调试-6-26 对于 智能车竞赛裁判系统 的第二版本的硬件进行初步调试。下面对于它软件进行实现和设计。

  在 基于ESP32的竞赛裁判系统功能调试-与微机通讯 已经就竞赛软件通信协议进行了初步实现。

1、功能设定

(1)接口定义

  下图显示了主控核心板的外部接口位置和功能。

▲ 图1.1 主控板的外部接口

【表格1-1 主控板外部接口定义】
  端口名称 功能说明 备注
电源接口 提供给出主板电源;
可以外接+5V电源,或者4.8V锂电池
如果USB接口连接到PC机USB,主板电源由USB接口提供
Type-C USB接口 主机与计算机通信 该端口同时提供主板工作电源
功能设定拨码开关 设定模块工作模式以及检测灵敏度 详细参见后面的【表格1-2 主板拨码开关设置】
计时线圈1 连接外部计时线圈1 在工作时计时线圈与光电板只能连接其中一个
计时线圈2 连接外部计时线圈2 在工作时计时线圈与光电板只能连接其中一个
光电板1 连接外部计时光电板1 在工作室计时线圈与光电板只能连接其中一个
光电板2 连接外部计时光电板2 在工作室计时线圈与光电板只能连接其中一个
目标板接口 连接带有激光检测功能的目标板

(2)工作模式

【表1-2 功能设置拨码开关】
  SW1 SW2 SW3 SW4
检测灵敏度设置 功能设置1 功能设置2 功能设置3
● 检测灵敏度设置(SW1):
(1) OFF:灵敏度高
(2) ON:灵敏度低
● 功能设置(SW2,SW3,SW4):
(1) OFF,OFF,OFF:普通计时
(2) ON,OFF,OFF:(待定)
(3) OFF,ON,OFF:(待定)
(4) ON,ON,OFF:(待定)
(5) OFF,OFF,ON:水果激光检测
(6) ON,OFF,ON:动物激光检测
(7) OFF,ON,ON:奇数三岔路口
(8) ON,ON,ON:偶数三岔路口

2、工作模式

  下面对于裁判系统的各个工作模式进行介绍。设定裁判硬件工作模式是通过拨码开关中 SW2,3,4 进行定义的。

  工作模式的初始化有两种方式:

  • 核心模块重新上电;
  • 任何一个拨码开关变动(SW1,SW2,SW3,SW4);
  • LED,SPEAKER显示板后面的复位按钮;详见【1-4-1:增加一个按钮】

注:由于原来的电路板没有设置一个专门的按钮,用来表示模块的初始化,所以建议在后期的裁判系统中设置一个专门的按钮,用来模块的初始化。

  下面给出不同模式的功能描述。其中:

  • 对于检测车模通过的方法有线圈和LED光板两种,它们的功能是相同的,因此在叙述的时候只叙述检测线圈;
  • 检测激光传感器包括中心店和边缘点检测两种;

  关于应用于室内AI视觉组别(水果、动物、数字识别)的相关规则,来自于 AI视觉组基于ESP32的裁判系统第一版本设计要求 中的响应描述,相关文献还包括 第十六届全国大学生智能车竞赛竞速组-室内视觉组补充说明

  工作模式 SW设置 功能描述
普通计时 OFF,OFF,OFF 这种模式应用于普通计时功能。任何一个计时线圈被触发都可以触发计时开始与结束。它们的功能是相同的。
(待定1) ON,OFF,OFF
(待定2) OFF,ON,OFF
(待定3) ON,ON,OFF
水果激光检测 OFF,OFF,ON (1)在初始状态下,中心光电检测到激光,四周光电没有检测到激光表示打靶成功;
(2)但如果四周光电检测到激光,无论中心是否检测到激光都表示打靶失败;
(3)打靶成功和打靶失败进入结果显示状态;五秒钟之后返回初始状态。在状态显示时,不检测激光信号。
(4)打靶成功,绿色LED点亮,蜂鸣器持续响;打败识别,红灯断续闪烁,蜂鸣器断续鸣响,10Hz,占空比50%。
(5)如果两个线圈在前后5秒钟之内相继被触发,但没有打靶(打靶成功,或者失败),红色和绿色LED以及蜂鸣器都同时断续打开,表示车模没有安装要求进行打靶。
动物激光检测 ON,OFF,ON (1)两个检测线圈相继被触发,如果时间小于3秒钟表示停车动作失败,红色LED闪烁,蜂鸣器断续鸣响,时间5秒;
(2)如果时间大于3秒,则表示停车动作成功,绿色灯点亮,蜂鸣器持续鸣响,时间5秒。
(3)如果中心和四周光电检测到信号则表示目标识别错误,红灯闪烁,蜂鸣器断续鸣响;
三岔路口(奇数数字) OFF,ON,ON 同时检测线圈1,线圈2
线圈1被触发,点亮左边绿灯
线圈2被触发,点亮右边红灯
三岔路口(偶数数字) ON,ON,ON 同时检测线圈1,线圈2
线圈1被触发,点亮左边绿灯
线圈2被触发,点亮右边红灯

3、用于触发目标板的激光信号

  根据以下博文的工作:

  • 智慧AI组对于激光投影的检测方案
  • 基于ESP32的竞赛裁判系统功能调试-激光信号调试
  • 测试ESP32S基本模块的功能,并验证是否可以应用在AI智能车竞赛检测激光信号中

  用于触发目标板的激光信号需要使用小型的半导体激光器发送的红色调制激光信号,激光信号的调制频率为125Hz。调制的方法是使用方波电压信号驱动激光器。

  下面是在 基于ESP32智能车竞赛比赛系统硬件初步调试-5-6 中使用Arduino Nano驱动的小型半导体激光器产生调制的触发信号。该信号可以使用任何其他的信号源来产生,只要其中包括有125Hz的调制信号即可,占空比也可以不是50% 。

▲ 图1.2 利用Arduino Nano 驱动的小型半导体激光器

  • 利用D2输出125Hz的50%占空比的波形。
/*
**==============================================================================
** TEST2PWM.C:             -- by Dr. ZhuoQing, 2021-06-07
**
**==============================================================================
*/
#define ON(pin)                 digitalWrite(pin, HIGH)
#define OFF(pin)                digitalWrite(pin, LOW)
#define VAL(pin)                digitalRead(pin)
#define IN(pin)                 pinMode(pin, INPUT)
#define OUT(pin)                pinMode(pin, OUTPUT)
const int LED_PIN = 2;
//------------------------------------------------------------------------------
void setup(void) {pinMode(LED_PIN, OUTPUT);
}
//------------------------------------------------------------------------------
void loop(void) {ON(LED_PIN);delay(4);OFF(LED_PIN);delay(4);
}
//==============================================================================
//                END OF FILE : TEST2PWM.C
//------------------------------------------------------------------------------

▲ 图1.3 Arduino PIN2输出的125Hz 的激光驱动调制信号

4、模块硬件、软件修改建议

(1)增加一个按钮

  增加一个按钮,用于以下功能:

  • 用户对于不同功能进行初始化;
  • 进行修改参数;

  将Ai-一体板上的接口上的PIN6(对应 ESP32 GPIO32 )按钮一个按钮。用于作为初始功能使用。

▲ 图1.4 将LED,Speaker板增加一个按钮

▲ 图1.4.1 在AI-一体板上的按钮

§02 软件实现


1、计时功能

  首先将SW开关设置为:

【表2-1 普通计时开关设置】
  SW1 SW2 SW3 SW4
OFF或者ON OFF OFF OFF

注:SW1设置检测灵敏度,它设置ON,OFF都不影响工作模式

  • 硬件配置: 只需要连接一个检测线圈即可。

(1)接入USB

  使用Type-C USB电缆将核心模块接入PC。确认微机设备管理-端口出现USB-SERIAL CH340(COMn)串口。其中COMn中的端口号跟具体微机配置有关系。假设模块对应的USB的串口为COM9

▲ 图2.1 出现USB-SERIAL CH340虚拟串口

(2)测试比赛程序

  打开智能车竞赛比赛系统软件,选择“预赛”控制面板。通过“打开串口”右侧的选择栏选择串口“COM9”,然后按动“打开串口”,可以看到下面信息串口出现“Open COM9:115200 OK !”提示。同时在“当前时间”右侧的时间栏出现时间递增的变化。这说明比赛系统已经能够正常使用了。

▲ 图2.2 通过比赛系统打开串口连接硬件

2、三岔路口

【表2-2 三岔路口检测模式】
  SW1 SW2 SW3 SW4
OFF或者ON ON 或者OFF ON ON

注:SW1设置检测灵敏度,它设置ON,OFF都不影响工作模式;

  • 硬件配置: 需要将两个两个线圈都连接上。将线圈1放置在三岔路口的左侧;将线圈2放置在三岔路口的右侧。

(1)测试步骤

  使用测试磁铁分别划过两个线圈,可以看到指示板上的红色和绿色的LED被分别点亮。按动背面的按钮可以将它们熄灭。

▲ 图2.3 测试三岔路口功能

3、水果标靶

  工作模式SW设置如下表所示:

【表2-3 水果标靶设置】
  SW1 SW2 SW3 SW4
ON或者OFF OFF OFF ON
  • 硬件配置: 将两个线圈布置在Apriltag码前后各50厘米的位置;

(1)车模直通

  车模通过两个检测线圈,并没有停止完成靶标射击;此时指示牌显示错误,也就是红灯闪烁;

下图显示了手持磁铁连续通过两个线圈,并没有停留打靶,指示牌显示错误。

▲ 图2.4.1 手持磁铁直接通过两个线圈,没有停留

(2)车模射击到靶标中心

  车模在Apriltag区域停止,直接瞄准靶标射击;在此过程中,没有射击到靶标边缘;此时指示牌显示成功,绿灯点亮;

  在绿灯点亮的过程中,即使激光再次投射到靶标边缘,也不会报错;

下面显示了激光直接照射靶心的光电管,指示板显示正确。

▲ 图2.4.2 使用激光直接照射靶心光电管,指示板显示正确

(3)车模射击到靶标边缘

  车模在经过Apriltag区域,使用激光射击到靶标边缘,指示板显示错误,即红灯闪烁。

下图显示了激光照射到靶标的边缘,引起指示牌显示错误。

▲ 图2.4.3 激光照射到靶标边缘,引起指示板显示错误

4、动物标靶

  工作模式SW的设置如下:

【表2-4 动物标靶工作模式开关设置】
  SW1 SW2 SW3 SW4
ON或者OFF ON OFF ON
  • 硬件配置: 将两个线圈布置在Apriltag码前后各50厘米的位置;

(1)车模直通

  车模通过两个检测线圈,并没有在两个线圈之间停留够3秒钟;此时指示牌显示错误,也就是红灯闪烁;

下图手持磁铁直接通过两个线圈,模拟车模没有停留超过三秒,此时指示板显示错误。

▲ 图2.4.1 手持磁铁直接通过两个线圈,没有停留

(2)车模停留三秒钟

  车模通过第一个线圈,在Apriltag区域停留超过三秒钟(小于六秒钟),然后在通过第二个线圈,指示牌显示正确,绿灯点亮;
  如果停留时间超过6秒钟,通过第二个线圈,指示牌不显示,也不报错。

下图显示了 手持磁铁经过第一个线圈,停留超过3秒在经过第二个线圈,指示板显示正确。

▲ 图2.4.2 手持磁铁经过第一个线圈,停留超过3秒在经过第二个线圈

(3)车模射击到靶标中心

  车模在Apriltag区域停止,直接瞄准靶标射击;在此过程中,没有射击到靶标边缘;指示板显示错误,即红灯闪烁。

  下图显示了 靶标中心被激光照射,靶标显示错误的过程。

▲ 图2.5.1 靶标中心被激光照射,靶标显示错误

(4)车模射击到靶标边缘

  车模在经过Apriltag区域,使用激光射击到靶标边缘,指示板显示错误,即红灯闪烁。这个过程与上面的靶标中心被激光照射的效果一样。

▌附件


1、ESP32程序

#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TESTALL.PY                  -- by Dr. ZhuoQing 2021-06-13
#
# Note:
#============================================================from machine                import UART,Pin,Timer,ADC,PWM
import time
import machine, math#------------------------------------------------------------
machine.freq(240000000)#------------------------------------------------------------
adc1 = ADC(Pin(36))
adc2 = ADC(Pin(39))
adc3 = ADC(Pin(34))
adc4 = ADC(Pin(35))adc1.atten(ADC.ATTN_6DB)
adc2.atten(ADC.ATTN_6DB)
adc3.atten(ADC.ATTN_6DB)
adc4.atten(ADC.ATTN_6DB)#------------------------------------------------------------
button = Pin(32, Pin.IN, Pin.PULL_UP)
sw4 = Pin(15,   Pin.IN, Pin.PULL_UP)
sw3 = Pin(2,    Pin.IN, Pin.PULL_UP)
sw2 = Pin(19,   Pin.IN, Pin.PULL_UP)
sw1 = Pin(4,    Pin.IN, Pin.PULL_UP)
led1 = Pin(5, Pin.OUT)
led2 = Pin(18, Pin.OUT)led1.off()
led2.off()
bz1 = Pin(21, Pin.OUT)
bz1.off()gled = Pin(25, Pin.OUT)
rled = Pin(33, Pin.OUT)
speaker = Pin(26, Pin.OUT)gled.off()
rled.off()
speaker.off()def sw1234Read():workmode = 0if sw2.value() == 0: workmode |= 0x1if sw3.value() == 0: workmode |= 0x2if sw4.value() == 0: workmode |= 0x4return sw1.value(), workmode#------------------------------------------------------------
WORKMODE_TIMER      =   0           # Check two line
WORKMODE_NULL1      =   1           #
WORKMODE_NULL2      =   2           #
WORKMODE_NULL3      =   3           #
WORKMODE_FRUIT      =   4           # Target is fruit,  check laser
WORKMODE_ANIMAL     =   5           # Target is Animal, check laser
WORKMODE_DIGIT1     =   6           # Target is digit,  check first pass
WORKMODE_DIGIT2     =   7           # Target is digit,  check first pass#------------------------------------------------------------SAMPLE_NUM = const(500)
ad1dim = [0] * SAMPLE_NUM
ad2dim = [0] * SAMPLE_NUMLASER_THRESHOLD = 50000             # Laser light check thresholdSAMPLE_AVERAGE_LENGTH   = 40
ad3average = [0] * SAMPLE_AVERAGE_LENGTH
ad4average = [0] * SAMPLE_AVERAGE_LENGTH
ad34point = 0
ad3sigma = 0
ad4sigma = 0#------------------------------------------------------------
AD34_BASE_ALPHA         = 0.0005
ad3baseline = 0
ad4baseline = 0AD34_CHECK_THRESHOLD_LOW    = 250
AD34_CHECK_THRESHOLD_HIGH   = 500
AD34_CHECK_THRESHOLD        = AD34_CHECK_THRESHOLD_HIGH
ad3checktime = 0
ad4checktime = 0#------------------------------------------------------------
sample_mode = 0                     # 0 : sample adc3, adc4# 1 : sample adc1, adc2#------------------------------------------------------------
sample_point = 0
stop_flag = 0
total_count = 0#------------------------------------------------------------
uart1 = UART(2, baudrate=115200, rx=16, tx=17, timeout=10)#------------------------------------------------------------
DSCMD_NONE          = 0xff
DSCMD_HELLO         = 0x00
DSCMD_INIT          = 0x01
DSCMD_STARTSEND     = 0x10
DSCMD_STOPSEND      = 0x11
DSCMD_BEEP          = 0x12
DSCMD_SENDSNAPSHOT  = 0x13
DSCMD_TURNOFFLIGHT  = 0x14
DSCMD_SETCONTINUECHECK = 0x15
DSCMD_SETBEACONSEQUENCY = 0x16
DSCMD_BEACONSTART   = 0x17
DSCMD_BEACONSTOP    = 0x18
DSCMD_GETBEACONSTATE = 0x19
DSCMD_BEACONINIT    = 0x1aDSRET_NCHECK        = 0x80
DSRET_CHECK         = 0x81
DSRET_LAST          = 0x82
DSRET_HELLO         = 0x90
DSRET_INIT          = 0x91SENDFLAG_LAST       = 0x82
SENDFLAG_CHECK      = 0x81
SENDFLAG_NOCHECK    = 0x80
SENDFLAG_STOP       = 0xff
SENDFLAG_SNAPSHOT   = 0x83#------------------------------------------------------------
def receCmd():if uart1.any() == 0: return DSCMD_NONE,0framebyte = uart1.read(4)if len(framebyte) != 4: return DSCMD_NONE, 0framelist = list(framebyte)time = int.from_bytes(framebyte[1:3], 'big')sumnum = sum(framelist[0:3]) & 0xff ^ 0xffif sumnum != framelist[3]: return DSCMD_NONE, 0return framelist[0], time#------------------------------------------------------------
def sendCmd(cmd, time):senddim = [0x55,cmd]senddim.extend(list(time.to_bytes(4, 'big')))sumnum = sum(senddim)&0xff^0xffsenddim.extend([sumnum])sendbytes = bytes(senddim)uart1.write(sendbytes)#------------------------------------------------------------
def procCmd(cmd, time):global count32,sendflag,delay3s,count32,sendenableflagglobal initflag,lastcount32,snapshot32,speakercount,senddelay,sendcountif cmd == DSCMD_NONE: returnif cmd == DSCMD_HELLO:sendCmd(DSRET_HELLO, 0x0)returnif cmd == DSCMD_INIT:sendCmd(DSRET_INIT, 0x0)count32 = 0x0delay3s = timecount3s = timeinitflag = 1lastcount32 = 0snapshot32 = 0sendcount = 0sendenableflag = 1sendflag = SENDFLAG_STOPreturnif cmd == DSCMD_STARTSEND:sendCmd(SENDFLAG_LAST, lastcount32)count3s = delay3ssendflag = 0x0sendenableflag = 0x1senddelay = timesendcount = 0returnif cmd == DSCMD_STOPSEND:sendCmd(SENDFLAG_CHECK, count32)sendenableflag = 0sendflag = 0sendcount = 0returnif cmd == DSCMD_BEEP:speakercount = 500returnif cmd in (DSCMD_SETBEACONSEQUENCY,DSCMD_BEACONSTART,DSCMD_BEACONSTOP,DSCMD_GETBEACONSTATE,DSCMD_TURNOFFLIGHT,DSCMD_BEACONINIT):returnprint(cmd, time)#------------------------------------------------------------
speakercount = 0
flash50mscount = 0
flash50inc = 0
resultflag = 0                      # 1 :OK; 2:ERROR; 0:NULL
buzzcount = 00def resultOK():global resultflag, speakercount, flash50mscount, flash50incresultflag = 1speakercount = 4500flash50mscount = 0flash50inc = 0def resultERROR():global resultflag, speakercount, flash50mscount, flash50incresultflag = 2speakercount = 4500flash50mscount = 0flash50inc = 0#------------------------------------------------------------
def speaker1ms():global resultflag, speakercount, flash50mscount, flash50incglobal detectflag1, detectflag2, detectcount, buzzcount#--------------------------------------------------------if detectflag1 != detectflag2:detectcount += 1#--------------------------------------------------------if buzzcount > 0:buzzcount -= 1#--------------------------------------------------------if speakercount > 0:speakercount -= 1if speakercount == 0:if resultflag > 0:resultflag = 0rled.off()gled.off()#----------------------------------------------------flash50mscount += 1if flash50mscount >= 50:flash50mscount = 0flash50inc += 1if resultflag == 0:speaker.on()elif resultflag == 1:gled.on()speaker.on()elif resultflag == 2:if flash50inc & 0x1 == 0:rled.on()speaker.on()else:rled.off()speaker.off()#------------------------------------------------------------
def sendTime():global count32,snapshot32,lastcount32,sendflagif sendflag == SENDFLAG_STOP:   returnif initflag == 0:               returntimesend = count32if sendflag == SENDFLAG_LAST:timesend = lastcount32elif sendflag == SENDFLAG_CHECK or sendflag == SENDFLAG_NOCHECK:timesend = count32elif sendflag == SENDFLAG_SNAPSHOT:timesend = snapshot32sendCmd(SENDFLAG_SNAPSHOT, snapshot32)sendflag = SENDFLAG_NOCHECKsendCmd(sendflag, timesend)sendflag = SENDFLAG_STOP#------------------------------------------------------------
count32 = 0                         # Global 1ms counter
sendflag = SENDFLAG_STOP            # send flag
sendenableflag = 0                  # Enable send
senddelay = 100                     # Everay send period
sendcount = 0                       # count for send delay
delay3s = 3000                      # No check delay
count3s = 3000                      # count for no check delay
initflag = 0
lastcount32 = 0
snapshot32 = 0detectflag1 = 0                     # Stand for line1 check
detectflag2 = 0                     # Stand for line2 check
detectcount = 0                     # Count the detectflag1 detectflag2 no equal#------------------------------------------------------------
def ADC4Sample(_):global count32,sendenableflag,sendflag,senddelay,sendcountglobal delay3s,count3s,initflag,lastcount32,snapshot32global speakercount, keepWorkModeglobal detectflag1, detectflag2, buzzcount#--------------------------------------------------------count32 += 1speaker1ms()#--------------------------------------------------------if count32 & 0x100:led1.on()else: led1.off()#--------------------------------------------------------if sendenableflag != 0:sendcount += 1if sendcount >= senddelay:sendcount = 0if sendflag == SENDFLAG_STOP:if count32 < delay3s:sendflag = SENDFLAG_NOCHECKelse: sendflag = SENDFLAG_CHECKelse:sendcount += 1if sendcount >= senddelay:sendcount = 0if sendflag == SENDFLAG_STOP:sendflag = SENDFLAG_CHECK#--------------------------------------------------------global ad1dim,ad2dimglobal sample_pointglobal adc1,adc2,adc3, adc4global ad3average, ad4average, ad34point, ad3sigma, ad4sigmaglobal ad3checktime, ad4checktime,total_countglobal ad3baseline, ad4baselinetotal_count += 1#--------------------------------------------------------detectflag = 0if sample_mode == 1:ad1dim[sample_point] = adc1.read()ad2dim[sample_point] = adc2.read()if sample_mode == 0 or sample_mode == 1:adc = adc3.read()ad3sigma += adcad3sigma -= ad3average[ad34point]ad3average[ad34point] = adcadc = adc4.read()ad4sigma += adcad4sigma -= ad4average[ad34point]ad4average[ad34point] = adcad34point += 1if ad34point >= SAMPLE_AVERAGE_LENGTH:ad34point = 0#----------------------------------------------------value = ad3sigma / SAMPLE_AVERAGE_LENGTHif ad3baseline == 0:if ad34point == SAMPLE_AVERAGE_LENGTH - 1:ad3baseline = valueelse: ad3baseline = ad3baseline * (1 - AD34_BASE_ALPHA) +AD34_BASE_ALPHA * valueif abs(value - ad3baseline) > AD34_CHECK_THRESHOLD:if ad3checktime == 0:ad3checktime = total_countdetectflag = 1detectflag1 = 1if keepWorkMode == 6 or keepWorkMode == 7:gled.on()value = ad4sigma / SAMPLE_AVERAGE_LENGTHif ad4baseline == 0:if ad34point == SAMPLE_AVERAGE_LENGTH - 1:ad4baseline = valueelse: ad4baseline = ad4baseline * (1 - AD34_BASE_ALPHA) + AD34_BASE_ALPHA * valueif abs(value - ad4baseline) > AD34_CHECK_THRESHOLD:if ad4checktime == 0:ad4checktime = total_countdetectflag = 1detectflag2 = 1if keepWorkMode == 6 or keepWorkMode == 7:rled.on()#--------------------------------------------------------sample_point += 1if sample_point >= SAMPLE_NUM:sample_point = 0#--------------------------------------------------------if detectflag > 0:buzzcount = 100bz1.on()if count3s >= delay3s:if sendenableflag > 0:if detectflag > 0:count3s = 1lastcount32 = count32count32 = 0snapshot32 = 0x0sendflag = SENDFLAG_LASTelse:if detectflag > 0:snapshot32 = count32count3s = 1else:if detectflag > 0:snapshot32 = count32count3s += 1#------------------------------------------------------------
time0 = Timer(0)
time0.init(period=1, mode=Timer.PERIODIC, callback=ADC4Sample)#------------------------------------------------------------
showcount = 0#------------------------------------------------------------
keepThreshold,keepWorkMode = sw1234Read()
def initDevice():global sample_mode, detectflag1, detectflag2, detectcountglobal speakercount, flash50mscount, flash50inc, resultflag, buzzcountspeakercount = 0buzzcount = 50flash50mscount = 0flash50inc = 0resultflag = 0                      # 1 :OK; 2:ERROR; 0:NULLdetectflag1 = 0detectflag2 = 0detectcount = 0print("Initialize device:%d,%d"%(keepThreshold, keepWorkMode))if keepThreshold == 1:AD34_CHECK_THRESHOLD        = AD34_CHECK_THRESHOLD_LOWelse:AD34_CHECK_THRESHOLD        = AD34_CHECK_THRESHOLD_HIGH#--------------------------------------------------------led1.off()led2.off()bz1.off()gled.off()rled.off()speaker.off()#--------------------------------------------------------if keepWorkMode in (4, 5):sample_mode = 1             # Sample adc1,2,3,4else: sample_mode = 0           # Sample adc3,4#------------------------------------------------------------
SAMPLE_PERIOD = 1
FREQUENCY_MOD           = 125def angle1(n):return n*2*3.1415926*SAMPLE_PERIOD / 1000.0 * FREQUENCY_MODdef wval(w):if w < SAMPLE_NUM / 2:return w * 2 / SAMPLE_NUMelse: return (SAMPLE_NUM - w) * 2 / SAMPLE_NUMcosdim = [int(math.sin(angle1(a)) * wval(a) * 0x7ff) for a in range(SAMPLE_NUM)]
sindim = [int(math.cos(angle1(a)) * wval(a) * 0x7ff) for a in range(SAMPLE_NUM)]#------------------------------------------------------------
def sample_amp(s):global cosdim,sindim,sample_pointcos_sam = 0sin_sam = 0scopy = s.copy()if sample_point > 0:scopy = scopy[sample_point:] + scopy[:sample_point]cos_sum = sum([s*w for s,w in zip(scopy,cosdim)]) / SAMPLE_NUMsin_sum = sum([s*w for s,w in zip(scopy,sindim)]) / SAMPLE_NUMreturn math.sqrt(cos_sum**2 + sin_sum**2)#------------------------------------------------------------
initDevice()#------------------------------------------------------------
while True:#--------------------------------------------------------threshold, workmode = sw1234Read()if threshold != keepThreshold or workmode != keepWorkMode:keepThreshold = thresholdkeepWorkMode = workmodeinitDevice()#--------------------------------------------------------if button.value() == 0:time.sleep(0.01)if button.value() == 0:initDevice()while button.value() == 0:speakercount = 10time.sleep(.01)#--------------------------------------------------------if keepWorkMode == 4:           # Fruit modecheck1 = sample_amp(ad1dim)check2 = sample_amp(ad2dim)print((check1, check2))if check1 > LASER_THRESHOLD:if resultflag == 0:resultOK()detectflag1 = 0detectflag2 = 0if check2 > LASER_THRESHOLD:if resultflag == 0:resultERROR()detectflag1 = 0detectflag2 = 0if detectcount > 10000:detectflag1 = 0detectflag2 = 0detectcount = 0bz1.on()buzzcount = 200if detectflag1 > 0 and detectflag2 > 0:if resultflag == 0:resultERROR()detectflag1 = 0detectflag2 = 0detectcount = 0if keepWorkMode == 5:           # Animal modecheck1 = sample_amp(ad1dim)check2 = sample_amp(ad2dim)if check1 > LASER_THRESHOLD:resultERROR()if check2 > LASER_THRESHOLD:resultERROR()if detectcount > 6000:detectflag1 = 0detectflag2 = 0detectcount = 0bz1.on()buzzcount = 200elif detectcount > 3000:bz1.on()buzzcount = 50if detectflag1 > 0 and detectflag2 > 0:if detectcount < 2500:resultERROR()else: resultOK()detectflag1 = 0detectflag2 = 0detectcount = 0if resultflag != 0:detectflag1 = 0detectflag2 = 0detectcount = 0#--------------------------------------------------------if speakercount == 0:speaker.off()if buzzcount == 0:bz1.off()#--------------------------------------------------------showcount += 1if showcount > 50:showcount = 0#--------------------------------------------------------cmd,tm = receCmd()if cmd != DSCMD_NONE:led2.on()procCmd(cmd, tm)led2.off()sendTime()#--------------------------------------------------------time.sleep_ms(1)#------------------------------------------------------------
#        END OF FILE : testtime.PY
#============================================================

■ 相关文献链接:

  • 基于ESP32智能车竞赛裁判系统第二版硬件调试-6-26
  • AI视觉组基于ESP32的裁判系统第一版本设计要求
  • 基于ESP32的竞赛裁判系统功能调试-与微机通讯
  • 第十六届全国大学生智能车竞赛竞速组-室内视觉组补充说明
  • 智慧AI组对于激光投影的检测方案
  • 基于ESP32的竞赛裁判系统功能调试-激光信号调试
  • 测试ESP32S基本模块的功能,并验证是否可以应用在AI智能车竞赛检测激光信号中
  • 基于ESP32智能车竞赛比赛系统硬件初步调试-5-6

● 相关图表链接:

  • 图1.1 主控板的外部接口
  • 表格1-1 主控板外部接口定义
  • 表1-2 功能设置拨码开关
  • 图1.2 利用Arduino Nano 驱动的小型半导体激光器
  • 图1.3 Arduino PIN2输出的125Hz 的激光驱动调制信号
  • 图1.4 将LED,Speaker板增加一个按钮
  • 图1.4.1 在AI-一体板上的按钮
  • 表2-1 普通计时开关设置
  • 图2.1 出现USB-SERIAL CH340虚拟串口
  • 图2.2 通过比赛系统打开串口连接硬件
  • 表2-2 三岔路口检测模式
  • 图2.3 测试三岔路口功能
  • 表2-3 水果标靶设置
  • 表2-4 动物标靶工作模式开关设置

基于ESP32的智能车竞赛新版裁判系统的软件功能要求与实现相关推荐

  1. 智能车竞赛自动裁判系统

    综 述   在推文"听说第十三届比赛现场不再会有裁判了?"中提到了标准化智能车比赛过程.应用自动比赛裁判系统对于车模比赛时间以及是否冲出赛道进行客观测量,省去现人工法裁判过程.这不 ...

  2. 逐飞关于第15届智能车竞赛相关工作

    卓老师您好: 昨天从卓老师微信公众号的推文里得知今年的比赛终于要办了,虽然我已不参加比赛,但依然很开心.一是因为自己的确希望大赛能在困难之中继续前进,这一部分的确是对智能车竞赛的热爱:二是比赛还在的话 ...

  3. 智能车竞赛计时系统感应线圈放在节能充电线圈上输出电压会多大?

    简 介: 直接将计时系统的感应线圈放置在节能充电线圈上,可以测到得到300 ~ 400 V的高频电压. 关键词: 智能车竞赛,裁判系统,高频,高压 #mermaid-svg-NvfujY80O2qyY ...

  4. 基于ESP32智能车竞赛比赛系统硬件初步调试-5-6

    简 介: 给出了对于基于ESP32设计的智能车竞赛的の比赛系统的硬件调试过程.基本上验证了硬件设计的合理与正确性.在第一部分的"修改建议"中也给出了硬件电路的修改意见. 关键词: ...

  5. 第十六届全国大学生智能车竞赛线上全国总决赛裁判手册

    简 介: 2021年全国大学生智能车竞赛全国总决赛采用线上比赛的形式.本文给出了线上比赛裁判用于控制比赛流程与判罚与得分标准. 关键词: 智能车竞赛,裁判 §01 分工和职责   在进行线上比赛过程, ...

  6. 开源的关于智能车竞赛光电起始点方案

    ▌01 起始点检测 这是在 规与矩,实与虚 给出的由佟超提出并设计的基于光电二极管的智能车竞赛起始点检测方案.他在www.znczz.com对其进行了开源. 原始设计程序也在 CSDN资源 中可以下载 ...

  7. 全国大学生智能车竞赛相关培训汇总

    §01 单片机培训 一.Infineon单片机 1.2020年4月培训 培训时间: 4月15日14:00~17:00 4月16日14:00~17:15 训回放链接: ① 英飞凌汽车电子生态圈: htt ...

  8. 第十六届全国大学生智能车竞赛裁判员手册

    简 介: 智能车竞赛中现场裁判是维持比赛顺畅进行.保证比赛公平公正.积极回应参赛队伍诉求的关键因素.本文给出了智能车竞赛关于裁判工作的基本要求. 关键词: 智能车竞赛,裁判 §01 分工和职责 一.裁 ...

  9. 来自SeekFree的智能车竞赛系统

    简 介: 对于刚刚接收到的SeekFree的比赛系统进行初步查验,这也为今年暑期竞赛规范打下基础. 关键词: 智能车竞赛,比赛系统 比赛硬件计时系统 竞赛系统 目 录 Contents 智能视觉组数据 ...

最新文章

  1. 工艺仿真软件_【技术简讯】电解抛光仿真软件Elsyca EPOS技术简介
  2. LeetCode Linked List Random Node(蓄水池采样算法)
  3. c语言浮点乘法 溢出,浮点加减乘除运算各在什么情况下会发生溢出?
  4. 【阿里妈妈营销科学系列】第二篇:消费者行为分析
  5. 中小企业虚拟化解决方案-VMware vSphere 6.5-日常管理入口v0.0.1
  6. 车牌识别之车牌定位(方案总结)
  7. 上位机与1200组态步骤_组态王与 I/O 设备
  8. 【51Nod - 1094】和为k的连续区间 (前缀和,二分查找)
  9. ajax 跨站返回值,jquery ajax 跨域问题
  10. 飞线5根连接图_手机主板焊盘掉点飞线维修方法
  11. Linux操作系统下SSH默认22端口修改方法
  12. ABTest灰度发布
  13. QQ概念版(WPF制作)
  14. 国内外最好的语料库汇总
  15. 手写Spring框架
  16. 基于C++实现DBSCAN聚类算法
  17. gitbook 入门教程之还在搞公众号互推涨粉?gitbook 集成导流工具,轻轻松松躺增粉丝!
  18. 【数据分析】系列-Python分析淘宝4200款Bra(没错,就是文胸)后,发现最好卖的款式居然是。。。
  19. 微信扫付款后,付错款,不是好友也能联系到收款方
  20. Gstore官网学习三:快速入门

热门文章

  1. .net分布式系统架构的思路
  2. 巧用伪元素和伪类让我们的html结构更清晰合理
  3. php之cookie
  4. 滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(4月7日)...
  5. 线上应用故障排查之二:高内存占用
  6. 《iPhone与iPad开发实战—iOS经典应用剖析》连载二
  7. 注册页面所涉及的知识
  8. 《笑傲网湖》第三回 三层交换
  9. easyui combogrid分页加载默认值时无法自动跳转到相应页的解决方案
  10. mysql主从复制错误:Last_SQL_Error: Error #39;Duplicate entry #39;327#39; for key #39;PRIMARY#39;#39; ...