A drónok katonai alkalmazása mamár széles körben elterjedt. Földön vízben levegőben. Alacsony áron kaphatók, nincs veszélyben ember élet, és képesek működni autonóm módon,korlátozott emberi beavatkozással. Folyamatosan javuló mobilitási és navigációs tulajdonságaik mellett, a drónok különféle terheket hordozhatnak, bombákat szenzorokat és aktorok, valamint nagy teljesítményű számítástechnikai és kommunikációs berendezéseket is. Bár a napjainkban egyre divatosabbá váló drónok vezérlése ugyan elméletileg a hagyományos, általános célú programozási nyelvek bármelyikével is megoldható, de ezek nyilvánvalóan nem képeznek ideális eszközt erre a feladatra. Különösen problémássá válik a velük való munka olyan esetekben, amikor már nem egyetlen önálló drón, hanem azok egész csoportjának vezérlését kell meghatározni és összehangolni.Ez mostantól jóval egyszerűbbé válik egy új programozási nyelv segítségével, amit kifejezetten erre a célra dolgoztak ki megalkotói. A Buzz-ban ugyanis már akár pár sorból meg lehet fogalmazni egy önmaga szervezésére alkalmas drónraj működési logikáját, amiben minden egyes tag folyamatosan figyeli szomszédjait is, és azokhoz igazítja, illetve azokkal együtt alakítja ki saját viselkedését is. Ez magában foglalja a szenzoradatok megosztását is, amire szintén képessé válnak a drónok a rajon belül.A Buzz maga egy JavaScript-hez hasonló szintaxist használ, ami egyszerűvé teszi a kódolást benne. A programok ugyanakkor nem közvetlenül ebben a formájukban, hanem egy fordító által előfeldolgozott formában kerülnek futtatásra, bájtkódként, a drónokon működő Buzz virtuális gép által. A drónoknak nem kell azonos típusúnak lenniük, és a raj elemei különböző logika szerint is működhetnek.A Buzz egy nyelv heterogén robotrajok programozására. Hasonló A TeCoLa, az egyes robotok erőforrásai metódushívásokon keresztül érhetők el. Ezen kívül lehetséges hogy egy robot szomszédságában található erőforrások alapján rajokat hozzanak létre, és a Az alkalmazás raj szintű és robot szintű műveleteket is meghívhat. Az egyik fő különbség az hogy a Buzz decentralizált megközelítést követ, ahol a rajképzést és az ellenőrzést végzik peer-to-peer módon, míg a TeCoLa-ban ezt a folyamatot a koordinátor irányítja. Továbbá, míg a Buzz lehetővé teszi, hogy egy robot megossza a kiválasztott állapotinformációkat a rajjal, ez explicit módon kell végrehajtani, speciális broadcast-szerű műveletekkel (virtuális stigmetria). Sőt, a teljes küldetésprogramot előre telepíteni kell minden robotra, ami ezt teszi nehezebb igény szerint robotokat alkalmazni, vagy ugyanazt a robotot különböző vagy nagyon dinamikus célokra használni alkalmazás küldetések átprogramozása nélkül.
A rajrobotika egy olyan tudományág, amely teljesen decentralizált megközelítéseket tanulmányoz nagyméretű robotcsapatok ( rajok ) koordinálására . Az ezen a területen végzett kutatások ambiciózusak: a robotrajokat olyan forgatókönyvekre képzelik el, amelyekre a megoldások ma már kivitelezhetetlenek, túl veszélyesek vagy nem léteznek.
A drónoktól az önvezető autókig a dolgok internete fejlődésének köszönhetően a robotrajok elterjednek, és számos alkalmazásban felhasználják majd. Ilyen alkalmazások például a kutatási és mentési műveletek, az ipari és mezőgazdasági ellenőrzések, az összehangolt járművek csoportosítása, az űrkutatás, valamint az orvosi vagy sebészeti tevékenységek. Olyan világot képzelünk el, ahol a tervezők meghatározhatják a robotok heterogén csoportjainak viselkedését, és ezt a viselkedést egy olyan alkalmazásba csomagolhatják, amely több robotrendszerre is telepíthető. Valószínűleg a raj-alapú megoldások alkotják majd az önvezető autók jövőbeli infrastruktúrájának gerincét, és lehetővé teszik a széles körben elterjedt robotika megvalósítását.
Noha természetesnek tűnik, hogy a robotrajokat a klasszikus elosztott rendszer egy újabb példányaként kezeljük, fontos szempontok különböztetik meg az előbbit az utóbbitól. A robotrajok dinamikáját a térbeli és hálózati szempontok elválaszthatatlan elegye jellemzi. A térbeli szempontok közé tartozik az a tény, hogy a robotok mozognak és módosítják környező környezetüket, míg a hálózati szempontok közé tartozik a hatótávolságra korlátozott, pletyka alapú üzenettovábbításon alapuló kommunikációs modalitás, valamint a robotok környezetében történő navigációja miatt folyamatosan változó topológia. Ennek eredményeként a rajszintű követelmények és az egyéni műveletek közötti leképezés olyan probléma, amelynek megoldása meghaladja az elosztott rendszertervezés jelenlegi megközelítéseit. A rajviselkedés megtervezése és fejlesztése ma lassú próba-hiba folyamaton keresztül valósul meg,
Ebben az oktatóanyagban bemutatjuk a Buzz programozási nyelvet, amelyet úgy terveztek, hogy megfelelő szintű absztrakciót biztosítson ahhoz, hogy a fejlesztők kényelmesen kifejezhessék az összetett raj-algoritmusokat. Két ellentétes megközelítést javasoltak a rajrobotikában:
Az alulról felfelé építkező megközelítés, amelyben a hangsúly az egyes robotokon és azok alacsony szintű interakcióin van; és
A felülről lefelé irányuló megközelítés, amelyben a rajt folyamatos, egyedi entitásként kezelik (pl. aggregált programozás vagy térbeli számítástechnika).
Míg az alulról felfelé építkező megközelítés biztosítja a tervezés teljes ellenőrzését, a fejlesztő számára elérhető részletek mennyisége gyakran elsöprő. Ezzel szemben a felülről lefelé irányuló megközelítés a raj egyszerű absztrakcióját mutatja be, de megakadályozza, hogy a fejlesztő finomhangolja az egyes robotok viselkedését.
A Buzz azon az elgondoláson alapul, hogy a fejlesztőnek mindkét absztrakciós szintet fel kell kínálnia , és hogy a nyelv szintaxisának lehetővé kell tennie az alulról felfelé és felülről lefelé irányuló konstrukciók zökkenőmentes keverését. A Buzz számos olyan konstrukciót tartalmaz, amelyet kifejezetten a felülről lefelé haladó raj szintű fejlesztésre terveztek, mint például a csoportalakítás és -menedzsment, a helyi kommunikáció és a globális konszenzus primitívumai. A Buzzt úgy tervezték, hogy kis rendszerekkel működjön (a dolgok internetéhez), és virtuális gépe 12 kB-nál kevesebb memóriába fér.
Iterációk ciklusok fűggvények struktúrák, adatbázisok, tömbök, paraméterek szenzorok értékek, irányítás vezérlés automatizálás, tipusok változók származtatott értékek mint a többi programozási nyelvben.
Programozásuk finomhangolásuk és precizitásuk exponenciálisan fejlődött az utóbbi 10 évben. A következő programrészletből láthatjuk, hogy a szokásos protokollal programozhatók;
: Crop spraying application.
1 # team al r e a d y c r e a t e d , a s u s u al
2
3 for s e c t i n i t w p in c r op [ s e c t i d ] :
4 team . M o bili t y S v c . r e l a t i v e g o t o ( s e c t i n i t w p )
5 cond = [ [ team . M o bili t y . ge tRelDis tanceFromTarget , ”<” , 1 . 0 ] ]
6 mc. w ai t ( cond , 1 0 , 2 0 0 )
7
8 mc. c h e c k p oi n t ( )
9
10 s p o t s = g e tP r o bl em a ti c S p o t s ( s e c t i d )
11 s p o t s i t e r = i t e r t o o l s . c y c l e ( s p o t s )
12
13 while len ( s p o t s ) > 0 : ismerős parancsok a pythonból!
14 wp = next ( s p o t s i t e r )
15 team . M o bili t y S v c . r e l a t i v e g o t o (wp)
16 cond = [ [ team . M o bili t y . ge tRelDis tanceFromTarget , ”<” , 1 . 0 ] ]
17 mc. w ai t ( cond , 1 0 , 2 0 0 )
18
19 wind = teams . Weather . getWindCnd ( )
20
21 i f checkWind ( wind . speed , wind . d i r e c t i o n ) :
22 team . Spray . sp r ay (PESTICIDE AMOUNT/ team . s i z e ( ) )
23 s p o t s . remove (wp)
24 s p o t s i t e r = i t e r t o o l s . c y c l e ( s p o t s )
def scannersTeamUpdate ( team , added , removed ) :
2 # update pl an and g e t nex t waypoint
3 s c n pl a n = updateScanPlan ( s c n pl a n , c o n f i g . area , c o n f i g . a l t i t u d e , team .
s i z e ( ) )
4 sc anp o s = next ( s c n pl a n . wps )
5
6 # c a l c u l a t e and s e t o f f s e t f o r each member
7 p o s l i s t = c a l c S c a n P o s i t i o n s ( scanpos , c o n f i g . a l t i t u d e , team . s i z e ( ) )
8 p o s i t e r = i t e r t o o l s . c y c l e ( p o s l i s t )
9 for n in team
10 pos = next ( p o s i t e r )
11 o f f s e t= c a l c O f f s e t ( scanpos , pos ) ;
12 n . M o bili t y S v c . s e t P o s O f f s e t ( o f f s e t )
13
14 # move t o nex t sc an waypoint
15 team . M o bili t y S v c . r e l a t i v e g o t o ( sc anp o s ) ;
16 cond = [ [ team . M o bili t y S v c . ge tRelDis tanceFromTarge t , < , 1 . 0 ] ]
17 s e l e c t c n d s . append ( [ ”SCN IN POS” , cond ] )
1 def s c a n n e r s I nP o s ( ) :
2 # move t o nex t sc an waypoint
3 s c a n n e r s . M o bili t y S c v . r e l a t i v e g o t o ( next ( s c n pl a n . wps ) )
4 cond = [ [ s c a n n e r s . M o bili t y . ge tRelDis tanceFromTarge t , ”<” , 1 . 0 ] ]
5 s e l e c t c n d s . append ( [ ”SCN IN POS” , cond ] )
6
7 # r e t u r n a check−f i r e l a b e l when a c e r t a i n di s t a n c e i s c o v e r e d
8 s c a n n e r s . M o bili t y S c v . r e s e tDi s t a n c eM e t e r ( )
9 cond = [ [ s c a n n e r s . M o bili t y . ge tDi s t anceMe te r , ”>” , s c n pl a n . d i s t ] ]
10 s e l e c t c n d s . append ( [ ”SCN CHK FIRE” , cond ] )
------------------------
def c h e c kF o rFi r e ( ) :
2 # g e t d e t e c t i o n r e s u l t s
3 d e t e c t e d s p o t s = s c a n n e r s . Fi r e D e t e c t o r . d e t e c t ( )
4
5 # r e t u r n a check−f i r e l a b e l when a c e r t a i n di s t a n c e i s c o v e r e d
6 s c a n n e r s . M o bili t y S c v . r e s e tDi s t a n c eM e t e r ( )
7 cond = [ [ s c a n n e r s . M o bili t y . ge tDi s t anceMe te r , ”>” , s c n pl a n . d i s t ] ]
8 s e l e c t c n d s . append ( [ ”SCN CHK FIRE” , cond ] )
9
10 i f d e t e c t e d s p o t s i s not None
11 # update the pl an f o r the f i r e e x t i n g u i s h e r team
12 e x t pl a n = u p d a t eFi r eE x ti n g ui s hPl a n ( e x t pl a n , d e t e c t e d s p o t s )
13 i f e x t i n g u i s h e r s i s None
14 # c r e a t e f i r e e x t i n g u i s h e r team and all ow e x t r a nodes t o j o i n
15 e x t i n g u i s h e r s = mc. createTeam ( [ any ] , [ any ] , [ SpraySvc ] )
16 e x t i n g u i s h e s . se tUpd a teH andle r ( fireExtTeamUpdate )
def fireExtTeamUpdate ( team , added , removed ) :
2 # g e t nex t sp r ay waypoint
3 sp r a yp o s = next ( e x p pl a n . wps )
4
5 # c a l c u l a t e and s e t o f f s e t f o r each member
6 p o s l i s t = c a l c L i n e P o s i t i o n s ( sp raypos , c o n f i g . d e n si t y , team . s i z e ( ) )
7 p o s i t e r = i t e r t o o l s . c y c l e ( p o s l i s t )
8 for n in team
9 pos = next ( p o s i t e r )
10 o f f s e t= c a l c O f f s e t ( sp raypso , pos ) ;
11 n . M o bili t y S v c . s e t P o s O f f s e t ( o f f s e t )
12
13 # move t o nex t sp r ay waypoint
14 team . M o bili t y S v c . r e l a t i v e g o t o ( sp r a yp o s ) ;
15 cond = [ [ team . M o bili t y S v c . ge tRelDis tanceFromTarge t , < , 1 . 0 ] ]
16 s e l e c t c n d s . append ( [ ”FEXT SPRAY POS” , cond ] )
1 def fi r e E x t I n S p r a y P o si ti o n ( ) :
2 # sp r ay f i r e s p o t
3 e x t i n g u i s h e r s . Spray . sp r ay ( )
4
5 e x t i n g u i s h e r s . M o bili t y S v c . r e l a t i v e g o t o ( e x t pl a n . l o a d p o s ) ;
6 cond = [ [ team . M o bili t y S v c . ge tRelDis tanceFromTarge t , < , 1 . 0 ] ]
7 s e l e c t c n d s . append ( [ ”FEXT LOAD POS” , ex t wp cnd ] )
def fi r eE x t I n L o a dP o si ti o n ( ) :
2 # l o a d
3 e x t i n g u i s h e r s . Spray . l o a d ( )
4
5 i f e x t pl a n . sp ray wp s :
6 # move t o nex t sp r ay waypoint
7 e x t i n g u i s h e r s . M o bili t y S c v . r e l a t i v e g o t o ( next ( e x t pl a n . wps ) )
8 cond = [ [ e x t i n g u i s h e r s . M o bili t y . ge tRelDis tanceFromTarge t , ”<” , 1 . 0 ] ]
9 s e l e c t c n d s . append ( [ ”FEXT LOAD POS” , cond ] )
10 e l s e :
11 # teams r e t u r n s t o b a se and l a n d s
12 e x t i n g u i s h e r s . M o bili t y S r v . r t l ( )
13 # d e s t r o y team
14 mc. d e s t r ( e x t i n g u i s h e r s )
------------
Algorithm 2 Basic request-reply protocol
1: function RequestReply(dsts, data, procT )
2: replies ← ∅
3: seqno ← seqno + 1
4: rmask ← setBits(dsts myid)
5: while rmask 6= 0 do
6: broadcast(REQ[myid, seqno, rmask, data])
7: wt ← MsgT + procT+ bitsSet(rmask)∗MsgT
8: await(rmask = 0, wt)
9: end while
10: return (replies)
11: end function
12: function OnRecv(REQ[pid, k, rmask, data])
13: if isBitSet(rmask, myid) then
14: if k 6= seqno then
15: seqno ← k
16: reply ← ProcessRequest(data)
17: end if
18: myturn ← false
19: wt ← posBit(rmask, myid)∗MsgT
20: await(myturn = true, wt)
21: broadcast(RP L[myid, seqno, reply])
22: end if
23: end function
24: function OnRecv(RP L[pid, k, data])
25: if k = seqno then
26: if myid = coordid then
27: replies ← replies ⊕ (pid, data)
28: rmask ← clearBit(rmask, pid)
29: else
30: myturn ← nxtBit(rmask, pid, myid)
31: end if
32: end if
33: end function
-----------
Algorithm 3 Join protocol
1: function Join
2: state ← JOIN
3: await(state = NORMAL)
4: end function
5: function CheckJoin(joinT)
6: broadcast(JP OLL[myid])
7: wt ← 2 ∗ MsgT + joinT
8: sleep(tw)
9: if new(grp) 6= ∅ then
10: ViewPush(old(grp))
11: for each p ∈ sort(new(grp)) do
12: ViewPush({p})
13: end for
14: end if
15: end function
16: function OnRecv(JP OLL[pid])
17: if state = JOIN then
18: unicast(pid, JOIN[myid])
19: end if
20: end function
21: function OnRecv(JOIN[pid])
22: t ← nxtTicket(grp)
23: grp ← grp ⊕ (pid, t)
24: GroupUpdated(grp)
25: end function
--------------
Algorithm 4 Leave protocol
1: function ForceLeave(pids)
2: rmask ← setBits(pids mypid)
3: while rmask 6= 0 do
4: broadcast(LREQ[mypid, rmask])
5: wt ← MsgT+ bitsSet(rmask)∗MsgT
6: await(rmask = 0, wt)
7: end while
8: for each p ∈ pids do
9: OnProcessFailure(p)
10: end for
11: end function
12: function OnRecv(LREQ[pid, rmask])
13: if isBitSet(rmask, myid) then
14: myturn ← false
15: wt ← posBit(rmask, myid)∗MsgT
16: await(myturn = true, wt)
17: broadcast(LACK[mypid])
18: state ← LEF T
19: end if
20: end function
21: function OnRecv(LACK[pid])
22: if myid = coordid then
23: rmask ← clearBit(rmask, pid)
24: else
25: myturn ← nxtBit(rmask, pid, myid)
26: end if
27: end function
------------
25: function OnRecv(V ACK[pid])
26: if myid = coordid then
27: rmask ← clearBit(rmask, pid)
28: else
29: myturn ← nxtBit(rmask, pid, myid)
30: end if
31: end function
----------
Algorithm 6 Fault handling and coordinator election
1: function OnProcessFailure(pid)
2: grp ← grp (pid, ∗)
3: if myid = coordid then
4: rmask ← clearBit(rmask, pid)
5: GroupUpdated(grp)
6: else if pid = coordid then
7: coordid ← minTicket(grp)
8: if myid = coordid then
9: BecameCoord(grp)
10: if new(grp) 6= ∅ then
11: ViewPush(old(grp))
12: for each p ∈ sort(new(grp)) do
13: ViewPush({p})
14: end for
15: end if
16: end if
17: end if
18: end function
----------
Listing 7.1: Experiment configuration/startup procedure.
1 # C re a te AeroLoop manager proxy o b j e c t
2 a e r ol o o p = z e r o r p c . Cli e n t ( )
3 a e r ol o o p . c onnec t (CONNECTION STRING)
4 # R e gi s t e r sim ul a t o r e n t i t i e s
5 a e r ol o o p . r e gi s t e r vm (VUAV A, ” vuav ” )
6 a e r ol o o p . r e gi s t e r vm (VUAV B, ” vuav ” )
7 a e r ol o o p . r e gi s t e r vm (WNS VM, ” w i f i n e t ” )
8 a e r ol o o p . r e gi s t e r vm (VCS VM, ” camsrvc ” )
9 a e r ol o o p . r e gi s t e r vm (GCS VM, ” g c s ” )
10 # S t a r t sim ul a t o r e n t i t i e s
11 a e r ol o o p . s t a r t vm (VUAV A)
12 a e r ol o o p . s t a r t vm (VUAV B)
13 a e r ol o o p . s t a r t vm (WNSVM)
14 a e r ol o o p . s t a r t vm (VCS VM)
15 a e r ol o o p . s t a r t vm (GCS VM)
16 # C o n fi g u r e w i r e l e s s network
17 a e r ol o o p . c r e a t e w i f i s e g m e n t ( )
18 a e r ol o o p . c r e a t e g h o s t n o d e (VUAV A)
19 a e r ol o o p . c r e a t e g h o s t n o d e (VUAV B)
20 a e r ol o o p . c r e a t e g h o s t n o d e (GCS VM)
21 # Se t home p o s i t i o n s
22 a e r ol o o p . s e t v u a v h om e p o s (VUAV A, HOME POS)
23 a e r ol o o p . s e t v u a v h om e p o s (VUAV B, HOME POS)
24 a e r ol o o p . s e t v u a v h om e p o s (GCS VM, HOME POS)
25
26 a e r ol o o p . s e t g h o s t n o d e p o s (VUAV A, HOME POS)
27 a e r ol o o p . s e t g h o s t n o d e p o s (VUAV B, HOME POS)
28 a e r ol o o p . s e t g h o s t n o d e p o s (GCS VM, HOME POS)
29 # S t a r t sim ul a ti o n e n gi n e s / s e r v i c e s
30 a e r ol o o p . s t a r t v u a v (VUAV A)
31 a e r ol o o p . s t a r t v u a v (VUAV B)
32 a e r ol o o p . s t a r t w i f i n s 3 s i m ( )
33 a e r ol o o p . s t a r t v c s (URBAN IMAGES COLLECTION)
--------
Listing 7.2: Simulated wind configuration.
1
2 # Se t sim ul a t e d wind
3 a e r ol o o p . s e t v u a v wi n d di r (VUAV A, 1 8 0 )
4 a e r ol o o p . s e t v u a v wi n d s p d (VUAV A, 3 0 )
5 . . .
6 # Rese t sim ul a t e d wind s e t t i n g s
7 a e r ol o o p . r e s e t v u a v wi n d (VUAV A)
--------
A Buzz egy dinamikus gépeléssel rendelkező kiterjesztési nyelv. Szintaxisát a JavaScript, a Lua és a Python ihlette. Alapértelmezés szerint minden Buzz utasítást minden robot külön-külön hajt végre. Különleges parancsok léteznek, amelyek lehetővé teszik a raj szintű programozást. A különböző rajokhoz különböző feladatokat lehet hozzárendelni. Rajok létrehozhatók, feloszlathatók, egyesíthetők, metszhetők és kivonhatók. A Buzz futásideje automatikusan adatokat gyűjt a közeli robotokról. A térbeli adatok mozgásalapú viselkedést tesznek lehetővé, például mintaképzést és vezetőkövetést. A kommunikáció lehetővé teszi az adatok sugárzását és összesítését, az egész rajra kiterjedő konszenzust. A Buzz tartalmaz egy adatstruktúrát, amely lehetővé teszi a raj számára, hogy megállapodjon a párok halmazában (key,value). Ezt a struktúrát virtuális stigmergynek nevezik , a fészeképítő társas rovarok által használt környezet által közvetített kommunikációs mód után.A Buzz új parancsokkal és adatstruktúrákkal bővíthető. Ily módon integrálhatja a Buzzt más robotikai keretrendszerekkel, például a ROS-szal.
Hozzárendelési és aritmetikai műveletek
a = 3 + 7
Hurkolás
i = 0
míg (i < a) i = i + 1
Elágazás,
ha (a == 10) i = 0
Táblázatok
t = {}
tb = 9
Függvénydefiníciós
függvény f (a) {
return a
}
Függvényhívás
x = f (9)
Saját azonosítónyomtatás nyomtatása
( "Az azonosítóm '", id, "'")
Folyamatérzékelő adatok
t = hőmérséklet. kap ()
maxt = matematika . max (t, maxt)
Motion
set_wheels (5, 5)
Raj létrehozása 1 azonosítóval
s = raj . létrehozás (1)
Csatlakozz a rajhoz, ha a robot azonosítója páros
s. kiválasztás ( id % 2 == 0)
Hagyja el a rajt, ha az id nagyobb, mint 5
s. kijelölés törlése ( azonosító > 5)
Rendeljen feladatot egy rajhoz
. exec ( függvény () { ... })
Hozzon létre új rajt az a és b rajhoz tartozó robotokkal
i = raj . kereszteződés (100, a, b)
A közeli robotokkal való interakció kiszámítása
var dir = szomszédok . csökkenteni (force_sum_kin, {x = 0, y = 0})
dir.x = dir.x / szomszédok . számolni ()
dir.y = dir.y / szomszédok . számolni ()
Adatszomszédok adása/hallgatása . broadcast ("forrás_forrás", mydist)
szomszédok . listen ("dist_to_source",
function (vid, value, rid) {
mydist = matematika . min (mydist, szomszédok . get (szabad).távolság + érték)
})
Hozzon létre egy új virtuális stigmergyet
v = stigmergy . létrehozás (1)
Írjon egy (kulcs, érték) bejegyzést
v. put ("a", 6)
Érték olvasása
x = v. kap ("a")
buzzvm_pusht (vm);
buzzobj_t pt = buzzvm_stack_at (vm, 1);
buzzvm_pop (vm);
Leolvasások tárolása a táblázatban
for (int i = 0; i < 8; ++i) {
buzzvm_push (pt);
buzzvm_pushi (vm, i);
buzzvm_pushi (vm, prox[i]);
buzzvm_tput (vm);
}
Tábla exportálása globális szimbólumként "prox"
buzzvm_pushs (
vm, buzzvm_string_register (vm, "prox"));
buzzvm_push (pt);
buzzvm_gstore (pt);
--------------------------
Forrás;
https://arxiv.org/pdf/1507.05946v1.pdf
https://github.com/buzz-lang/Buzz
https://news.mit.edu/2016/user-friendly-language-programming-efficient-simulations-0810
https://www.argos-sim.info/