第十七届智能车竞赛比赛系统软件修改-多车组时间延迟
Posted 卓晴
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第十七届智能车竞赛比赛系统软件修改-多车组时间延迟相关的知识,希望对你有一定的参考价值。
本文记载了用于第十七届全国大学生智能车竞赛竞赛的比赛系统软件修改过程。
§01 比赛计时系统
背景介绍
在十七届智能车竞速组 包含了多车组的比赛,这个组别在计时方面的要求比较特殊,需要对 原来基于ESP32比赛裁判系统 的上位机软件进行修改,使其能够适应多车组的比赛要求。
▲ 图1.1.1 计时器模块以及线圈
计时器硬件
计时器硬件包括有基于 ESP32 硬件电路模块,触发线圈等。使用该模块需要安装 CH340 USB 驱动软件 。
- 安装之后,将硬件模块通过 Type-C USB 接线接入计算机 USB 接口。如果是 Windows7 操作系统, 可以在计算机惯例-设备管理-端口 中看到 USB-SERIAL CH340 (COM n) 。 其中 COMn 是计算机分配给 USB 窗口号。 建议将 COM 号修改到 1 ~ 8 之间。
▲ 图1.1.2 修改USB串口号
计时器软件
下面是存储 2021年7月8日的 ESP32 Python 软件。
D:\\zhuoqing\\DesignCenter\\SmartCar\\2021\\LongQiu\\ESP32-Judge System
下面是定义的程序下载接口。利用Thonny de Firware Installer 更新软件,需要把 除了VCC之外,其它都与下载器的五根线相连。
▲ 图1.1.3 调试接口定义
▲ 图1.1.4 更新ESP32 Fireware
程序升级
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 = 0
if sw2.value() == 0: workmode |= 0x1
if sw3.value() == 0: workmode |= 0x2
if sw4.value() == 0: workmode |= 0x4
return 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_NUM
LASER_THRESHOLD = 50000 # Laser light check threshold
SAMPLE_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 = 0
AD34_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
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 = 0x1a
DSRET_NCHECK = 0x80
DSRET_CHECK = 0x81
DSRET_LAST = 0x82
DSRET_HELLO = 0x90
DSRET_INIT = 0x91
SENDFLAG_LAST = 0x82
SENDFLAG_CHECK = 0x81
SENDFLAG_NOCHECK = 0x80
SENDFLAG_STOP = 0xff
SENDFLAG_SNAPSHOT = 0x83
def receCmd():
if uart1.any() == 0: return DSCMD_NONE,0
framebyte = uart1.read(4)
if len(framebyte) != 4: return DSCMD_NONE, 0
framelist = list(framebyte)
time = int.from_bytes(framebyte[1:3], 'big')
sumnum = sum(framelist[0:3]) & 0xff ^ 0xff
if sumnum != framelist[3]: return DSCMD_NONE, 0
return framelist[0], time
def sendCmd(cmd, time):
senddim = [0x55,cmd]
senddim.extend(list(time.to_bytes(4, 'big')))
sumnum = sum(senddim)&0xff^0xff
senddim.extend([sumnum])
sendbytes = bytes(senddim)
uart1.write(sendbytes)
def procCmd(cmd, time):
global count32,sendflag,delay3s,count32,sendenableflag
global initflag,lastcount32,snapshot32,speakercount,senddelay,sendcount
if cmd == DSCMD_NONE: return
if cmd == DSCMD_HELLO:
sendCmd(DSRET_HELLO, 0x0)
return
if cmd == DSCMD_INIT:
sendCmd(DSRET_INIT, 0x0)
count32 = 0x0
delay3s = time
count3s = time
initflag = 1
lastcount32 = 0
snapshot32 = 0
sendcount = 0
sendenableflag = 1
sendflag = SENDFLAG_STOP
return
if cmd == DSCMD_STARTSEND:
sendCmd(SENDFLAG_LAST, lastcount32)
count3s = delay3s
sendflag = 0x0
sendenableflag = 0x1
senddelay = time
sendcount = 0
return
if cmd == DSCMD_STOPSEND:
sendCmd(SENDFLAG_CHECK, count32)
sendenableflag = 0
sendflag = 0
sendcount = 0
return
if cmd == DSCMD_BEEP:
speakercount = 500
return
if cmd in (DSCMD_SETBEACONSEQUENCY,
DSCMD_BEACONSTART,
DSCMD_BEACONSTOP,
DSCMD_GETBEACONSTATE,
DSCMD_TURNOFFLIGHT,
DSCMD_BEACONINIT):
return
print(cmd, time)
speakercount = 0
flash50mscount = 0
flash50inc = 0
resultflag = 0 # 1 :OK; 2:ERROR; 0:NULL
buzzcount = 00
def resultOK():
global resultflag, speakercount, flash50mscount, flash50inc
resultflag = 1
speakercount = 4500
flash50mscount = 0
flash50inc = 0
def resultERROR():
global resultflag, speakercount, flash50mscount, flash50inc
resultflag = 2
speakercount = 4500
flash50mscount = 0
flash50inc = 0
def speaker1ms():
global resultflag, speakercount, flash50mscount, flash50inc
global detectflag1, detectflag2, detectcount, buzzcount
if detectflag1 != detectflag2:
detectcount += 1
if buzzcount > 0:
buzzcount -= 1
if speakercount > 0:
speakercount -= 1
if speakercount == 0:
if resultflag > 0:
resultflag = 0
rled.off()
gled.off()
flash50mscount += 1
if flash50mscount >= 50:
flash50mscount = 0
flash50inc += 1
if 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,sendflag
if sendflag == SENDFLAG_STOP:
return
if initflag == 0: return
if keepWorkMode > 0:
sendCmd(sendflag, snapshot32)
sendflag = SENDFLAG_STOP
return
timesend = count32
if sendflag == SENDFLAG_LAST:
timesend = lastcount32
elif sendflag == SENDFLAG_CHECK or sendflag == SENDFLAG_NOCHECK:
timesend = count32
elif sendflag == SENDFLAG_SNAPSHOT:
timesend = snapshot32
sendCmd(SENDFLAG_SNAPSHOT, snapshot32)
sendflag = SENDFLAG_NOCHECK
elif keepWorkMode > 0:
timesend = count32
sendCmd(SENDFLAG_SNAPSHOT, snapshot32)
sendflag = SENDFLAG_NOCHECK
sendCmd(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 = 0
detectflag1 = 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,sendcount
global delay3s,count3s,initflag,lastcount32,snapshot32
global speakercount, keepWorkMode
global detectflag1, detectflag2, buzzcount
count32 += 1
speaker1ms()
if keepWorkMode == 0:
if count32 & 0x100:
led1.on()
else: led1.off()
else:
if count32 & 0x80:
led1.on()
else: led1.off()
if sendenableflag != 0:
sendcount += 1
if sendcount >= senddelay:
sendcount = 0
if sendflag == SENDFLAG_STOP:
if count32 < delay3s:
sendflag = SENDFLAG_NOCHECK
else: sendflag = SENDFLAG_CHECK
else:
sendcount += 1
if sendcount >= senddelay:
sendcount = 0
if sendflag == SENDFLAG_STOP:
sendflag = SENDFLAG_CHECK
global ad1dim,ad2dim
global sample_point
global adc1,adc2,adc3, adc4
global ad3average, ad4average, ad34point, ad3sigma, ad4sigma
global ad3checktime, ad4checktime,total_count
global ad3baseline, ad4baseline
total_count += 1
detectflag = 0
if 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 += adc
ad3sigma -= ad3average[ad34point]
ad3average[ad34point] = adc
adc = adc4.read()
ad4sigma += adc
ad4sigma -= ad4average[ad34point]
ad4average[ad34point] = adc
ad34point += 1
if ad34point >= SAMPLE_AVERAGE_LENGTH:
ad34point = 0
value = ad3sigma / SAMPLE_AVERAGE_LENGTH
if ad3baseline == 0:
if ad34point == SAMPLE_AVERAGE_LENGTH - 1:
ad3baseline = value
else: ad3baseline = ad3baseline * (1 - AD34_BASE_ALPHA) +AD34_BASE_ALPHA * value
if abs(value - ad3baseline) > AD34_CHECK_THRESHOLD:
if ad3checktime == 0:
ad3checktime = total_count
detectflag = 1
detectflag1 = 1
if keepWorkMode == 6 or keepWorkMode == 7:
gled.on()
value = ad4sigma / SAMPLE_AVERAGE_LENGTH
if ad4baseline == 0:
if ad34point == SAMPLE_AVERAGE_LENGTH - 1:
ad4baseline = value
else: ad4baseline = ad4baseline * (1 - AD34_BASE_ALPHA) + AD34_BASE_ALPHA * value
if abs(value - ad4baseline) > AD34_CHECK_THRESHOLD:
if ad4checktime == 0:
ad4checktime = total_count
detectflag = 1
detectflag2 = 1
if keepWorkMode == 6 or keepWorkMode == 7:
rled.on()
sample_point += 1
if sample_point >= SAMPLE_NUM:
sample_point = 0
if detectflag > 0:
buzzcount = 100
bz1.on()
if count3s >= delay3s:
if sendenableflag > 0:
if detectflag > 0:
count3s = 1
lastcount32 = count32
snapshot32 = coutn32
if keepWorkMode == 0:
count32 = 0
sendflag = SENDFLAG_LAST
else:
if detectflag > 0:
snapshot32 = count32
count3s = 1
else:
if detectflag > 0:
snapshot32 = count32
count3s += 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, detectcount
global speakercount, flash50mscount, flash50inc, resultflag, buzzcount
speakercount = 0
buzzcount = 50
flash50mscount = 0
flash50inc = 0
resultflag = 0 # 1 :OK; 2:ERROR; 0:NULL
detectflag1 = 0
detectflag2 = 0
detectcount = 0
print("Initialize device:%d,%d"%(keepThreshold, keepWorkMode))
if keepThreshold == 1:
AD34_CHECK_THRESHOLD = AD34_CHECK_THRESHOLD_LOW
else:
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,4
else: sample_mode = 0 # Sample adc3,4
SAMPLE_PERIOD = 1
FREQUENCY_MOD = 125
def angle1(n):
return n*2*3.1415926*SAMPLE_PERIOD / 1000.0 * FREQUENCY_MOD
def wval(w):
if w < SAMPLE_NUM / 2:
return w * 2 / SAMPLE_NUM
else: return (SAMPLE_NUM - w) * 2 / SAMPLE_NUM
cosdim = [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_point
cos_sam = 0
sin_sam = 0
scopy = s.copy()
if sample_point > 0:
scopy = scopy[sample_point:] + scopy[:sample_point多车组软件使用说明