Lego EV3 a továrna na droidy

S připraveným prostředím ev3dev můžeme kostku Lego EV3 pohodlně programovat v jazyce Python.

Jednoduchá konstrukce pásového dopravníku poslouží jako trenažér, na kterém vyzkoušíme motor, dotykový a barevný senzor. Pásový dopravník představuje závěrečnou část výrobní linky, z které sjíždějí hotoví droidi Obchodní federace — droidi světlí a droidi tmaví. Linka se musí nejprve kalibrovat, aby rozpoznala tmavého droida od světlého, a pak může počítat, kolik kterých protne paprsek barevného senzoru.

Továrna na droidy



Popis rozhraní knihovny ev3dev pro Python je na GitHub. Použijeme knihovnu a funkci sleep().

import ev3dev
from time import sleep
		

Připravíme funkce pro řízení motoru.

#motor control
def motorstop(m):
    m.stop()

def motorrun(m):
    m.connected
    m.run_forever(duty_cycle_sp=20)	
		

Připravíme funkci zajišťující kalibraci barevného senzoru. Ta je nezbytná kvůli proměnlivé úrovni okolního osvětlení.

def calibrate(t, c, l):
    l.clear()
    l.draw.text((2, 8), 'light droid first...')
    l.update()
    while (t.value() == 0):
        l.draw.rectangle([2,20,100,28],fill="white")
        l.draw.text((2, 20), 'color = ' + str(c.value()))
        l.update()
    l.update()
    dlight = c.value()
    ev3dev.Sound.beep()
    time.sleep(2.0)
    l.clear()
    l.draw.text((2, 8), 'dark droid next...')
    l.update()
    while (t.value() == 0):
        l.draw.rectangle([2,20,100,28],fill="white")
        l.draw.text((8, 20), 'color = ' + str(c.value()))
        l.update()
    l.update()
    ddark = c.value()
    ev3dev.Sound.beep()
    return [dlight, ddark]
		

Před „spuštěním“ továrny nastavíme potřebné proměnné a vypíšeme informaci na displej.

t = ev3dev.TouchSensor()
c = ev3dev.ColorSensor()
c.mode = 'COL-REFLECT'
l = ev3dev.LCD()
l.clear()
calvalues = calibrate(t,c,l)
l.clear()
l.draw.text((2,20),str(calvalues[0])+' : '+str(calvalues[1]))
l.update()
time.sleep(3.0)
l.clear()
l.draw.text((2,20),'FACTORY IS READY TO RUN!')
l.update()
ev3dev.Sound.beep()
time.sleep(0.25)
ev3dev.Sound.beep()
		

Po stisku tlačítka spustíme motor.

#wait for button press
while (t.value() == 0):
    time.sleep(0.01)
time.sleep(0.5)
#prepare variables
dlight = 0  #counter for light droids
ddark = 0   #counter for dark droids
factoryclosed = False
#then run motor driven belt
m = ev3dev.LargeMotor('outD')
motorrun(m)
		

Necháme otáčet pás, dokud se před senzor nedostane droid nebo není stisknuto tlačítko.

while (not factoryclosed):
    #wait for droid or button press
    isnewdroid = c.value()
    wasbuttonpressed = t.value()
    while (isnewdroid < calvalues[1]) and (wasbuttonpressed == 0):
        isnewdroid = c.value()
        wasbuttonpressed = t.value()
		

Stisk tlačítka zastaví celou továrnu.
Při rozlišování tmavého a světlého robota je třeba zastavit pás a poskytnout senzoru chvíli na správné určení intenzity odraženého světla.

    #what happened?
    l.clear()
    if (wasbuttonpressed):
        l.draw.text((2,8), 'STOP!')
        l.update()
        motorstop(m)
        factoryclosed = True
    else:
        #necessary to stop and properly scan the droid color
        motorstop(m)
        time.sleep(0.25)
        isnewdroid = c.value()
        if (isnewdroid <= calvalues[1]+4):
            l.draw.text((2,20), 'dark one '+str(isnewdroid)+'-'+str(calvalues[1]))
            ddark += 1
        else:
            l.draw.text((2,20), 'light one '+str(isnewdroid)+'-'+str(calvalues[0]))
            dlight +=1
        l.draw.text((2,8),'L = '+str(dlight)+' | D = '+str(ddark))
        l.update()
        motorrun(m)
        time.sleep(0.4)
		

Po uzavření továrny stiskem tlačítka se vypíše celková statistika „výroby“.

#factory is closing
time.sleep(2.0)
l.clear()
l.draw.text((2,8), 'FACTORY CLOSED')
l.draw.text((2,20), 'overall production:')
l.draw.text((2,32),'L = '+str(dlight)+' | D = '+str(ddark))
l.update()
time.sleep(3.0)
		


Multiprocessing

Za vyzkoušení stojí také aplikace běžící ve více vláknech. Program spustí motor a ten běží, dokud se nestiskne tlačítko, nebo se před barevným senzorem neobjeví světlý objekt.
Potřebovat budeme knihovnu multiprocessing.

import ev3dev
from time import sleep
from multiprocessing import Process
		

Připravíme funkce, které poběží v samostatných vláknech.

def sensorcheck():
    c = ev3dev.ColorSensor()
    c.mode = 'COL-REFLECT'
    while (c.value() < 10):
        sleep(0.01)
    m = ev3dev.LargeMotor('outD')
    m.connected
    m.stop()
    
def buttoncheck():
    t = ev3dev.TouchSensor()
    while (t.value() != 1):
        sleep(0.01)
    m = ev3dev.LargeMotor('outD')
    m.connected
    m.stop()    
		

Rozběhneme motor a spustíme dva samostatné procesy.

m = ev3dev.LargeMotor('outD')
m.connected
m.run_forever(duty_cycle_sp=20)
p1 = Process(target = sensorcheck)
p1.start()
p2 = Process(target = buttoncheck)
p2.start()
		

Zdrojové kódy jsou k dispozici ke stažení.

přispět:
Lego EV3 a IPy Notebook