Slovenska izdaja(Vir:3) na kartičnem računalniku je skupek strežnikov, orodij, vaj in projektov za poučevanje in razvoj programov. Resnični Python zahteva večnitno programiranje in krmilno jedro s posebnim načinom pisanja programov.
Ključen je nadzor delujočega jedra s strani uporabnika. Uporabniški program je napisan v Pythonu ali katerem koli drugem orodju, ki želi vplivati na sam program. Za počasne komuniciranje zadostujejo spletne strani. Imate ogromno vaj, projektov za veliko spletnih in drugih tehnologij. Problem nastane, ko si zaželimo komunikacije z odzivi pod sekundo. Tipično je vodenje robotkov z nagibanjem telefona ali recimo spremljanje spremenljivk in izris diagramov med delovanjem krmilnega jedra. UDP telegrami so dobri točno za to. Gre za programsko tolmačenje in odziv na telegram. Če uporabnik pošlje UDP telegram z ukazom ali povpraševanjem, mora strežnik ta telegram razumeti in ustrezno odgovoriti. Za razliko od TCP telegramov tu ne zgubljamo časa s povezovanjem. Dosežene so komunikacije na cca. 20msek., kar je zadosti za tekoče vodenje robotka npr. Poglejmo si kako so UDP komunikacije rešene v slovenski izdaji. Vse rešitve so odprte in združene v vaje po sklopih ali projektih.
Ta vsebina je samo za naročnike
UDP(User Datagram Protocol) telegrami
So telegrami dolžine do malo več kot 1400 bytov. So nepovezani telegrami, ko ga pošljemo, mora program (aplikacija) na drugi strani sprejeti, tolmačiti in odgovoriti na telegram (Vir:4). TCP telegrami so povezani, kjer programsko zagotovimo preverjanje dospelosti in ponovitve v primeru izgube. Uporablja se za podatkovne tokove.
Programe, glede na komunikacije delimo na strežniške in uporabniške. Oba programa se lahko vrtita na isti napravi ali pa sta povezana preko internetnega omrežja.
Strežnik, kot že ime pove, čaka na prispeli telegram, ga tolmači in odgovori na prispeli telegram. Enostaven primer (Vir:4) je bil zgled za nadgradnjo v komunikacijske zahteve pri krmilnem jedru. Slovenska izdaja(Si) uporablja UDP strežnik v samem krmilnem jedru. Razloženo in uporabljeno je na Python in Android aplikacijah, ki komunicirajo s krmilnim jedrom.
Krmilno jedro
Krmilno jedro je zanka, ki se mora izvajati čim hitreje. Za rutine znotraj osnovne zanke je značilno, da se morajo čim hitreje zaključit in imeti morajo linearno časovno odvisnost od količine podatkov. Funkcija UDP strežnika se izvaja v posebni niti. Preden nadaljujemo je dobro vedeti, da se Python program izvaja v več opravilnem operacijskem sistemu. Obe niti krmilnega jedra, samo jedro in UDP strežnik sta lahko kadarkoli prekinjani, s strani dodeljevalca opravil, ki tiči v samem jedru operacijskega sistema. Imamo pa znotraj programa relativno uro, ki je izredno natančna. Gre seveda za vgrajene časovnike, ki jih pri programih s krmilnim jedrom veselo izkoriščamo.
UDP strežnik
Koda je del knjižnice Python.py. Ob zagonu programa , se ob prvem klicu funkcije konec() zažene ukaz, ki požene novo nit.
t = threading.Thread(target = UDP_server); t.start()
UDP_server() z ukazom try: poskuša rezervirati vrata 20001 za poslušanje. Če je uspešen pade v neskončno zanko while not konec1: , dokler je konec1 enak True sprejema telegrame ki prispejo na vrata 20001. Sprejeti telegram je kodiran po standardu UTF-8 imenik. Ena od obveznih značk imenika je »ukaz«.
sprejem=json.loads(s[0].decode()) ukaz=sprejem.get(“ukaz”)
sedaj sledi tolmačenje ukaza in klicanje ostalih značk, ki se razlikujejo odvisno od ukaza. Sproti postavljamo globalne spremenljivke, ki vplivajo na krmilno jedro(ali iz krmilnega jedra nosijo informacije) in odgovor UDP uporabniku.
oddaja=json.dumps({“ukaz”:”ne znan”})
server.sendto(oddaja.encode(), s[1])
Po odgovoru se UDP strežnik vrne na začetek večne zanke in čaka na naslednji »ukaz«. V odgovor lahko vključimo poljubno število značk, ki nosijo informacijo k uporabniku.
___________________________________
KODA:
def UDP_server():
global konec1,pavza,g1s,g2s,g3s,g4s,cikli,staricas,wlanip4,ethip4
global azimut,naklon,zasuk
server = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
try:
#server.bind((‘127.0.0.1’, 20001))
server.bind((”, 20001))
while not konec1:
server.settimeout(0.1)
try:
azimut=1.2
s = server.recvfrom(1024)
sprejem=json.loads(s[0].decode())
ukaz=sprejem.get(“ukaz”)
if ukaz==’tipalo’:
……..
elif ukaz==’g’:
parameter=sprejem.get(“parameter”)
if parameter==’1′:g1s=True
if parameter==’2′:g2s=True
if parameter==’3′:g3s=True
if parameter==’4′:g4s=True
oddaja=json.dumps({“ukaz”:ukaz+parameter})
elif ukaz==’s’:
……..
elif ukaz==’Status’:
……..
else:
oddaja=json.dumps({“ukaz”:”ne znan”})
server.sendto(oddaja.encode(), s[1])
except socket.timeout:
i=1
except:
i=1
___________________________________
UDP Python uporabnik
IDE za Python je razvojno orodje za resnični (realni) Python. Na levi strani se vidi program, ki se izvaja, na desni strani imamo ukaze za nadzor krmilnega jedra. Na levi strani v deseti vrstici vidite knjižnico Python.py. Na desni strani se vidi odziv na gumb »Status«. Cikel: 0.1676 ms pomeni, da se krmilno jedro izvaja skoraj 8000-krat na sekundo. Nas zanimajo komunikacije.
udp_ukaz.py
UDP uporabnik je program, ki pošlje UDP telegram, čaka na odgovor in se zaključi. Program udp_ukaz najprej preveri koliko je vhodnih parametrov. Recimo, da imamo 4 parametre, potem se vse dogodi znotraj če stavka
if parametrov==4:
Najprej sestavimo oddajni seznam z značko »ukaz« in ji dodamo vrednost sys.argv[2], torej drugi parameter. Dodamo tudi značko »parameter«, ki ji dodamo vrednost sys.argv[3], torej tretji parameter. Nato pošljemo UDP telegram primerno zakodiran seznam na vrata 20001 in IP sys.argv[1], torej prvi parameter. Na odgovor čakamo omejen čas. Če odgovora ni več kakor 1 sekundo se program zaključi in izpiše »Program se ne odzove«.
sudo python3 udp_ukaz.py 127.0.0.1 g 1 je samo primer, kako nadziramo krmilno jedro s pomočjo UDP uporabnika. Ta ukaz deluje na funkcijo tap(g1), ki reagira kot tap na gumb g1. Kako to uporabljamo v krmilnem jedru, si poglejte v številnih primerih (npr. PythonàNapraveàtipke.py). Namesto IP naslova 127.0.0.1, kar pomeni lokalni IP naslov, lahko napišemo poljubni IP naslov in tako kontroliramo krmilno jedro kjerkoli na mreži. Kako sedaj uporabimo udp_ukaz.py iz spletne strani, si poglejte odprte spletne programe, s katero je napisana slovenska izdaja. Spletne strani tvori HTML, CSS, JavaScript in predvsem PHP v povezavi s spletnim strežnikom.
___________________________________
import socket,sys,json
uporabnik = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
parametrov=len(sys.argv)
if parametrov==3:
……..
if parametrov==4:
oddaja=json.dumps({“ukaz”:sys.argv[2],”parameter”:sys.argv[3]})
uporabnik.sendto(oddaja.encode(), (sys.argv[1], 20001))
uporabnik.settimeout(1)
try:
s = uporabnik.recvfrom(1024)
sprejem=json.loads(s[0].decode())
ukaz=sprejem.get(‘ukaz’)
print(ukaz)
except socket.timeout:
print(‘Program se ne odzove.’)
___________________________________
UDP AppInventor uporabnik
MIT App Inventor(Vir:5) je razvojno orodje za android in iO aplikacije. Slovenska izdaja ponuja projekte in aplikacije (Vir:6), ki učijo osnove in znajo izkoriščati standardna tipala pametnega telefona. Aplikacija Si ponuja udp uporabnika. Ideja je , da se v aplikaciji ponovijo funkcije Python uporabnika. Dodano je hitro pošiljanje stanja tipala za orientacijo(Hallovo 3D tipalo), in ob odgovoru še sprejem stanj GPIO.
Slika kaže Designer v AppInventorju, kjer na zaslone postavimo standardne objekte. Na desni strani je zaslon mojega Samsung s7 pametnega telefona. Raspberry in pametni telefon morata biti povezana na isto brez žično omrežje. Če primerjate spletno stran slovenske izdaje in aplikacijo Si, opazite, da na aplikaciji manjkata gumb Status in Konec. Status je velika pomoč pri razvoju. Konec zaključi program. Ne eno ne drugo ni potrebno pri vodenju npr. robota. Seveda je na slovenski izdaji tako aplikacija, kakor projekt, zato lahko vedno aplikacijo predelate po svojih željah. Še mogoče o knjižnicah, ki jih pišejo uporabniki portala. Za UDP komunikacije sem izbral razvijalca pod virom 7. Tam dobite projekt v izvorni kodi če želite.
V Blocks opišemo dogodke in nastavimo lastnosti. Zanimiva je metoda OrientationSensor1.OrientationChanged. Najprej sestavimo zelen telegram. Z metodo make a dictionary sestavimo slovar iz imen in vrednosti. Zelen telegram spustimo skozi metodo(filter) JetsonTextDecode. Dobljene ustrezno predelane podatke pošljemo v metodo UrsaAI2UDP.Xmit(Vir:7), ki pošlje UDP telegram na IP in port UDP strežnika. UDP strežnik, kakor smo že zapisali, za ukaz »tipalo« v odgovoru pošlje digitalna stanja za GPIO. Ustrezne bloke moramo ponoviti za vsak gumb.
Vizija
Slovenska izdaja najavlja novo mehatroniko, krmilno jedro, Python programiranje in odprte strojne rešitve. Ne gre drugače . V prihodnjih številkah bom poleg novosti (še vedno je na mesec več novosti, kakor jih uspemo zapisati), opisal izkušnje iz specializirane učilnice, ker s pomočjo MS teamsov, raspberryjev in razvitih učil delamo na delovnem mestu, ki stane 250€ in povprečno potroši okoli 15W moči z monitorjem vred. V ceno je vštet material za postavitev minimalnega učila, ki je trenutno RPi4 2Gbyte, 4 x kapacitivne tipke in koračni motor s krmilnikom, ki ima 4 LED-ice in 4 x tranzistorske izhode. Vem, da zgleda grozno, pa vendarle gre za veliko poenostavitev vsega. Pridni bodite in skrbite za kondicijo med korona krizo. Če bo zanimanje lahko pripravimo google učilnice in posvete na daljavo. Drugače pa, kaj predlagam, kupite si RPi4 in začnite raziskovati. V odprti kodi se je znanje kopičilo dobesedno desetletja.
Naslednjič si bomo pogledali minimalno učilo, tehnologija izdelave, instalacijo slovenske izdaje in prvi koraki k uporabi. Vabljeni!
- https://www.Python.org/
- http://suhel.happyforever.com/
- https://sites.google.com/view/slovenska-izdaja
- https://pythontic.com/modules/socket/udp-client-server-example
- https://appinventor.mit.edu/
- http://suhel.raspberryip.com/appinventor/
- https://ullisroboterseite.de/android-AI2-UDP-en.html
Avtor: Boštjan Šuhel
email: bostjan.suhel@gmail.com
2020_291_53