第十七届智能车竞赛比赛系统软件修改-多车组时间延迟

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多车组软件使用说明

第十七届全国大学生智能车竞赛智能视觉组总结

第十七届全国大学生智能车竞赛完全模型组比赛细则-最终方案

第十七届智能车竞赛赛题规划

第十七届全国大学生智能车竞赛线上比赛直播链接

第十七届全国大学生智能车竞赛线上比赛赛道设计