Jump to content
GianCann

Pybricks: MicroPython per Powered UP

Recommended Posts

Sono passati oramai 3 mesi da quando vi parlai, per la prima volta, di Pybricks. A quei tempi c'era veramente ben poco ,oltre al sito...

È ora arrivato il momento di aprire in topic specifico visto che, nel frattempo, il lavoro è andati avanti e una prima beta-release pubblica sta per essere rilasciata.

Faccio un brevissimo riassunto per chi non avesse seguito il topic dedicato al Powered UP.

PyBricks è un firmware (software per  microcontollori) alternativo a quello originale LEGO che, una volta installato su uno degli smart hub Powered Up (Move/Smart/Technic Hub) consentirà di programmarlo con il linguaggio MicroPython per far eseguire il nostro programma senza necessità di uno smartphone/tablet.

Sostanzialmente, una volta programmato, basterà accendere l' Hub e immediatemente inizierà ad eseguire la sequenza di comandi secondo la logica da noi stabilità.

Oltre al vantaggio di non richiedere un device esterno (smartphone o tablet che sia), ci saranno tempi di esecuzione del codice molto più veloci perché lo stesso sarà in esecuzione direttamente nel micro, e non nello smartphone con tutto il passaggio di informazioni tramite Bluetooth che ne consegue.

I ragazzi che stanno sviluppando questo firmware (la prima beta sarà rilasciata solo per il Move Hub) ha da poco aggiornato il sito e, soprattutto, hanno iniziato a rendere pubblica la documentazione (seppur non definitiva)

https://docs.pybricks.com/en/latest/

Aggiornerò questo topic esplorando PyBricks illustrando come impiegarlo nei nostri diorami/MOC 😉

Edited by GianCann

Share this post


Link to post
Share on other sites

Beh... funziona 😄😄😄

 

Ovviamente stiamo parlando di una versione Alpha e quindi non tutto fila sempre liscio... 

Al momento siamo in 3 a "giocarci": io, un francese (Philo Hurbain) e un portoghese (Jorge Pereira).

Ho fatto varie prove, dal classico "Hello Word" per microcontrollori (il blink di un LED) fino a provare varie combinazioni di motori e, non di meno, l'uso del sensore di colore come trasmettitore IR 

Insomma, ci sono belle prospettive...

Nel prossimo post entrerò più nel dettaglio, anche perché devo ancora approfondire alcuni aspetti.

Share this post


Link to post
Share on other sites
1 ora fa, Pix ha scritto:

Spero che passino anche all'HUB "normale"

Si, è questione di tempo.
Benché l'architettura sia simile tra i vari HUB, ci sono lievi differenze sia hardware che software.

Sono partiti con il Boot Move Hub perché è il primo che è stato rilasciato e quindi ci studiano da più tempo (hanno fatto tutto in reverse engineering).

Share this post


Link to post
Share on other sites

Sin da quando uscì il sistema Powered Up mi chiesi se, un giorno, sarebbe stato possibile implementare sensori personalizzati...

Quel giorno è arrivato 😉

Nel firmware PyBricks c'è la classe LUMPDevice (LUMP è l'acronimo di LEGO UART Messaging Protocol, introdotto anni fa con l'NXT) che consente di scambiare dati tramite comunicazione seriale.

Oggi ho provato questa classe, usando un Micro:Bit come sensore.

Sul Micro:Bit gira un codice MicroPython che legge i dati dell'accelerometro/giroscopio, li "normalizza" leggermente, e poi li trasmette via seriale. Il cavetto USB rosso che si vede nel video è usato solo per alimentare il microcontrollore.

Sul Move Hub, invece, gira un semplice loop che legge continuamente i dati in ingresso tramite la classe LUMPDevice.

I dati ricevuti, vengono mostrati sulla console di output di MU (il software usato per programmare l'Hub) e sono ricevuti tramite Bluetooth.

Questa cosa, naturalmente, apre scenari interessanti 😉

Edited by GianCann

Share this post


Link to post
Share on other sites

Nel weekend ho proseguito con i test su Pybricks.
Specifico che la prima versione del firmware che ci è stata messa a disposizione (che è non è ancora beta) non consente ancora di salvare in modo permanente un nostro script MicroPython nella memoria flash del micro.
Non perché il firmware non è sia ancora in grado di farlo ma perché, in questa fase di test del runtime MicroPython, sarebbero numerose le scritture sulla flash e gli sviluppatori preferiscono non 'eccedere'.

Chi ha avuto, o ha a che fare con i microcontrollori sa che le memorie flash hanno un numero di scritture limitato (comunque elevato, da non dover preoccupare: andiamo sull'ordine delle decine di migliaia di volte).
Però, quanto meno in questa fase, i ragazzi del team Pybricks vanno molto cauti su questo aspetto e stanno persino valutando per il futuro una modalità "deep sleep" dove l'Hub possa mantenere nella memoria "ram" il codice dello script anche in caso di cambio delle batterie (grazie al generoso condensatore presente sulla scheda elettronica) così come avveniva ai tempi dell'RCX.

Ovviamente, sia io che gli altri beta tester abbiamo sottolineato che il punto di vista di forza di Pybricks deve essere quello di poter programmare a piacimento lo Smart Hub e di poterlo usare, anche a distanza di mesi, senza preoccuparsi di nulla (ovvero di dover ricaricare il programma, nel caso le batterie si fossero nel frattempo esaurite).
Quindi, di poter salvare il modo *permamenente* il nostro script sulla memoria flash.

Come funziona Pybrycks?

Come penso sia ormai chiaro, Pybricks è un firmware (ovvero un software che viene memorizzato nella memoria permanente di un microcontrollore) e quindi, innanzitutto, è necessario procedere alla sostituzione di quello originale LEGO.

E' un'operazione che è possibile effettuare grazie alla modalità "Bootloader" che LEGO ha implementato sui suoi smart hub proprio per aggiornare/sostituire il proprio firmware via via che aggiungo le funzionalità e/o risolvono i bug (nel mondo reale, non ci sono software che non soffrono di bug).

Per poter quindi caricare un nuovo firmware è necessario forzare lo smart hub ad entrare in modalita "Bootloader":
Da Hub spento, è necessario tener premuto il pulsante di accensione finché il LED non diventa di colore viola.
A questo punto, lo smart hub è pronto a ricevere il nuovo firmware (trasferito come un flusso di byte, via Bluetooth)
A trasferimento dati completato, lo smart Hub si riavvia ed entra in modalità Pybricks (LED accesso sul colore blue).
Il team di sviluppo ha integrato il meccanismo di "flashing" del firmware direttamente all'interno dell'editor MU.

MU è un semplice editor opensource pensato per scrivere programmi in Python/MicroPython.
E' pensato per essere semplice e, nondimeno, per programmare i microcontrollori che supportano MicroPython (incluso Micro:bit, ESP, ed altre board simili).

Cos'è esattamente Pybrikcs?

Sostanzialmente è un interprete di codice MicroPython in grado di eseguire script con estensione *.mpy
MicroPython è un linguaggio di programmazione derivato dal fratello maggiore Python, ed è pensato appositamente per poter funzionare sui microcontrollori.

Con Pybricks, questi script (abbastanza semplici da scrivere) possono essere trasferiti via Bluetooth sulla memoria Ram del micro dove per poi essere realmente interpretati/eseguiti.

Questa è la grossa (e non unica, tra l'altro) differenza con il firmware originale LEGO:
Il programma è interpretato ed eseguito direttamente nel micro, a differenza dell'App LEGO dove il codice viene eseguito sullo smartphone che, in un continuo passaggio di dati con lo Smart Hub (via Bluetooth), invia i comandi verso i motori e/o legge i dati dai sensori.

La differenza di eseguire il codice direttamente sul microcontrollore comporta una serie di vantaggi, a partire dalla velocità di esecuzione dello stesso: parliamo di fattori di moltiplicazione che vanno da 10 a 100 volte più veloci e che consentono quindi di realizzare cose impossibili con l'App (pensate, ad esempio, ad un line follower molto preciso e veloce oppure ad un robot self-balanced, così come un treno che può interpretare molto velocemente e precisamente i checkpoint colorati lungo il percorso).

Il firmware Pybricks, inoltre, estende le funzionalità dello Smart Hub implementando già ora il protocollo LEGO UART Messaging Protocol e, in futuro, una più generale classe UART per la comunicazione via seriale con dispositivi/sensori custom.

A regime, il programma *.mpy potrà essere salvato sulla memoria del micro ed essere eseguito all'accensione (probabilmente, con una sequenza di 2-3 click sul pulsante verde). Ne stiamo discutendo proprio stamani, sul sistema più idoneo su come gestire questa modalità.

Ieri sera, dopo uno primo scambio di idee con gli sviluppatori, ci hanno rilasciato una nuova versione del firmware dove c'è una preview di questa possibilità.

Comunque, rispetto al firmware originale LEGO, qui siamo su un altro pianeta... 
Certamente Pybricks non sarà per tutti, ma per molti.

Giusto per farvi capire, ecco uno script di esempio.

#definisco le variabili che rappresenta l'Hub e il motore connesso alla porta A
hub = MoveHub()
leftMotor = Motor(Port.A)

#eseguo il ciclo per 10 volte
for i in range(10):
    #scrivo una stringa sullo stdout (via seriale BLE)
    print("Blink!", i)
    #accendo il LED dell'Hub sul colore arancione
    hub.light.on(Color.ORANGE)
    #aspetto 100 millisecondi
    wait(100)
    #accendo il LED dell'Hub sul colore verde
    hub.light.on(Color.GREEN)
    #faccio fare un giro completo (360°) al motore, ad una velocità di 500°/s
    leftMotor.run_angle(500, 360)
Edited by GianCann

Share this post


Link to post
Share on other sites

Giusto per fare un esempio pratico del vantaggio di Pybricks, rispetto l'App ufficiale LEGO.
Prendiamo questo modulo GBC dell'ingegnoso Akiyuki. Quando lo ha realizzato ancora non c'era il supporta per il multi-hub e quindi doveva utilizzare uno smartphone per ogni carrello e per la stazione di caricamento.

Oggi, se gli va bene, con un solo smartphone forse riuscirrebbe a far funzionare 2-3 carrelli, e la stazione di caricamento.

Con PyBricks, non ci sarà bisogno di alcuno smartphone/tablet e i carrelli potranno essere anche 10! Ognuno con la sua intelligenza autonoma...

 

Edited by GianCann

Share this post


Link to post
Share on other sites

Ecco un micro-esempio, della modalità che abbiamo denominato (per ora) PRM: Permanent Running Mode.

Questo è il mio Move Hub... lo accendo, e poi premendo sul pulsate, ottengo un movimento di 90° in senso orario del motore interno "A". Notate il led dell'Hub... non lampeggia (come farebbe l'hub appena accesso con il firmware originale, per indicare che è in attesa di un dispositivo 'master') ma diventa immediatamente blue, ad indicare che è pronto per ricevere uno script tramite seriale.
Siccome uno script è già stato memorizzato al suo interno, è sufficiente premere sul pulsante per eseguirlo. Lo script "precaricato" è banalmente:

leftMotor = Motor(Port.A)
leftMotor.run_angle(500,90)

 

Share this post


Link to post
Share on other sites

Ho a disposizione uno Spike Prime e quindi non potevo non provare i sensori su Pybricks. Vi faccio notare che, ad oggi, questi sensori non sono supportati dall'App LEGO.

Sono test molto semplici il cui scopo è stato solo quello di verificare che funzionassero. Molto interessante il sensore di tocco che, a differenza dei suoi predecessori per RCX/NXT/EV3, fornisce (anche) un valore di pressione in una scala da 1 a 100.

Sensore di tocco:

Sensore a ultrasuoni;

Sensore di colore: in realtà, non ho usato il sensore come tale, ma come led animato (al suo interno sono presenti 3 led, controllabili indipendentemente).

 

Share this post


Link to post
Share on other sites

Esplorando i metodi delle varie classi finora implementate in Pybricks, ieri sera ho fatto qualche test con run_until_stalled della classe Motor.

Questo metodo permette di avviare un motore (di tipo tachimetrico) specificando la velocità di rotazione in gradi al secondo.
Il metodo è sincrono e restituisce l'angolo di rotazione nel momento in cui l'albero motore va in stallo ovvero incontra un ostacolo.

leftMotor = Motor(Port.A)
pos = leftMotor.run_until_stalled(100,Stop.COAST,30)

100 = velocità di rotazione espressa in gradi al secondo
Stop.COAST = la tipologia di stop che deve effettuare il motore, nel momento di stallo
30 = rappresenta il duty_limit, ovvero la forza di torzione (utile per non sforzare meccanismi con rapporti elevati)

Quando il motore avrà raggiunto il punto di stallo, in pos avrò l'angolo di rotazione percorso dal motore rispetto al punto 0.

I motori tachimetrici supportati dal sistema Powered Up sono questi:
pupmotors

(nella foto non è mostrato il Move Hub, i cui due motori interni sono comunque tachimetrici)

Conoscere il range di azione di un motore è fondamentale quando si deve inizializzare un meccanismo che agisce in un raggio di azione limitato meccanicamente (ad esempio: lo sterzo di un veicolo, il controllo di uno scambio ferroviario, un GBC).

Quando avviamo il nostro meccanismo/programma, non è assodato che la posizione dell'albero motore sia nota o predefinita.

Grazie a run_until_stalled, quindi, all'avvio del programma possiamo eseguire la seguente procedura:

1) Azionare (con run_until_stalled) il motore in senso antiorario finché non arrivi al punto di stallo
2) Impostare il primo punto di stallo come "Posizione 0" temporanea, usando il metodo reset_angle della classe Motor.
3) Azionare il motore in senso orario finché non arrivi al nuovo punto di stallo, usando nuovamente run_until_stalled.
4) Rilevare l'angolo di rotazione effettuato dal motore a partire dal punto '0' temporaneo impostato al punto 2) (ammettiamo di ottenre il valore 180)
5) Dividere per due il valore ottenuto (risultato: 90) ottenendo l'angolo di riferimento di metà range di azione. Questo valore sarà memorizzato in una variabile, per uso successivo.
6) Ruotare in senso antiorario l'albero motore sulla base di del valore ottenuto al punto 5). Per fare questo, si userà il metodo run_angle della classe Motor. Questo metodo posiziona l'albero motore sull'angolo passato come parametro, facendo riferimento allo zero assoluto impostato al passo 2). Invocando run_angle(360,90), quindi, l'albero motore ruoterà in senso antiorario (ricordate: il motore era fermo alla posizione 180°, e  deve ruotare in senso antiorario per arrivare alla posizione 90°). Il valore 360 rappresenta la velocità di rotazione, ovvero 360° al secondo.
7) Impostare nuovamente la posizione 0 (con reset_angle) che, questa volta, sarà la posizione centrale definitiva.

A questo punto, azionando il motore con run_angle usando +/- 90° possono muovere il motore in un verso o nell'altro, e tornare sempre alla posizione 0 con run_angle(360,0)

Questo è il codice completo per trovare la posizione centrale, se il motore è limitato nel suo raggio di azione con dei meccanismi di blocco dell'alberlo motore

myMotor = Motor(Port.A)
pos = myMotor.run_until_stalled(-100,Stop.COAST,30)
myMotor.reset_angle(0)
pos = myMotor.run_until_stalled(100,Stop.COAST,30)
pos = pos / 2
myMotor.run_target(360,pos)
myMotor.reset_angle(0)

In questo video, un esempio pratico dell'uso di run_until_stalled: una volta determinato il centro tra le due plate gialle, il motore si muove da un lato all'altro, senza raggiungere i limiti fisici del raggio di azione.
Notare come l'albero del motore, prima dell'avvio del programma, non sia nella posizione centrale che verrà successivamente determinata.

Vi ricordo che la documentazione di Pybricks è disponibile su https://docs.pybricks.com/en/latest/

Edited by GianCann

Share this post


Link to post
Share on other sites

Proseguono i test... una delle cose che  mi sarebbero piaciute da parte di LEGO, per quanto riguarda il sistema Powered Up, era la documentazione del protocollo "wired" cioè quello dei sensori/motori collegati. E la conseguente possibilità di gestire eventuali sensori personalizzati.

Anche perché ero (erroneamente) convinto che Powered Up implementasse un nuovo protocollo. Invece, grazie a Pybricks, scopro che i sensori (anche quelli dello Spike, ovviamente) usano lo stesso protocollo denominato "LEGO Uart messaging protocol" già "decodificato" da tempo (perché LEGO, sia mai che rilasci documentazione completa ed aggiornata...) ed usato dai tempi dell'EV3 anche se sembrerebbe lo abbiamo evoluto aggiungendo alcune caratteristiche ancora sotto la lente di ingrandimento di chi sta facendo reverse engineering.

Sono quindi partito da questa scarna documentazione, studiando alcuni esempi basati appunto sull'EV3

https://sourceforge.net/p/lejos/wiki/UART Sensor Protocol/

Capita la logica del protocollo e avendo un esempio già funzionante in MicroPython per Micro:bit, ho riadattato il codice in C++ ed ho usato un ESP8266 per simulare un sensore che invia continuamente una serie di dati (fittizzi, al momento).

Ebbene, funziona 😄😄😄

Nota: l'ESP è alimentato direttamente dalli Smart Hub

Ho usato la classe LUMPDevice di Pybricks che funziona egregiamente benché ho suggerito agli sviluppatori alcuni miglioramenti che verranno valutati sulla base della poca memoria disponibile sul Move Hub (sugli altri Hub c'è più possibilità, dato che hanno una memoria più ampia).

Comunque, oltre alla LUMPDevice ci sarà anche una più generica UARTDevice e non sarà necessario adattarsi alla logica del protocollo LUMP rendendo tutto molto più semplice.

Chi volesse dare un'occhiata al codice C++, lo può trovare qui: https://pastebin.com/6TiK6Sr8 tenendo a mente che è uno sketch "nudo e crudo" senza alcuna ottimizzazione.

Questo, invece, il codice usato sul Move Hub, con Pybricks:

mySensor=LUMPDevice(Port.D)
for a in range(1000):
    print(mySensor.read(0))
    wait(200)

Share this post


Link to post
Share on other sites

Laurens mi ha appena comunicato che hanno integrato nel firmware la possibilità di caricare un programma di default nella memoria dell'Hub. Inoltre, anche l'editor di codice è stato ulteriormente migliorato e reso più semplice nella gestione dell'Hub.

Al momento ancora non hanno rilasciato la nuova versione, ma penso sia ormai questione di giorni...

Share this post


Link to post
Share on other sites
11 ore fa, GianCann ha scritto:

dove viene evidenziata la comunicazione tra due Hub

Laurens mi ha "sbugiardato" 😄😄😄

E' tutto basato sul timing: i due hub dispongono di due distinti programmi con tempestiche di esecuzione precise e vengono lanciati nello stesso momento... quindi, in un video che dura 50 secondi, in sincronismo funziona alla perfezione 😉

La comunicazione tra hub sarà una cosa che arriverà parecchio più avanti.

Share this post


Link to post
Share on other sites

Laurens ha pubblicato la RoadMap di PyBricks!

Pybricks 1.0 was all about bringing Pybricks MicroPython to EV3.

This came out early 2019. It's super exciting to see people using this actively.

An epic number of users! According to Visual Studio Code, anyway.

If you're one of those, click 👍 on this post so we know you're here! 👋

Pybricks 2.0 was all about improving the EV3 experience.

To make it absolutely solid, tested, fully-featured, and FLL-ready.

It's ready now (🚀 🎉 ), and should be available in the latest ev3dev build soon.

Hopefully LEGO will update their official derivative version soon too.

Pybricks 3.0 will add support for Powered Up!

  • Newly supported hubs / programmable 🧱
    • LEGO BOOST MoveHub: MoveHub()
    • LEGO Powered Up City Hub: CityHub()
    • LEGO Technic Control+ Hub: CPlusHub()
  • Newly supported motors / sensors:
    • BOOST Color and Distance Sensor
    • BOOST Interactive Motor
    • Technic Control+ Motors (L, XL)
    • SPIKE Prime Motors (M, L)
    • SPIKE Prime Sensors (Color/Ultrasonic/Force)
  • Go fully open source 🤓
  • Pybricks Code: Cross-platform editor for Powered Up. No install required!
    • Lets you install Pybricks MicroPython firmware
    • Lets you run Pybricks MicroPython scripts
    • Windows 🖥️ / Mac 💻 / Linux 🐧 / Android ☎️ / ChromeOS 🔍
  • By default, a script runs from memory:
    • This is super quick and easy 🚀, but you have to be connected to start the program ⚡ .
    • Use this to test & develop your script.
  • Optionally, a script can be included when you update the firmware:
    • This is slow to download 🐌, but your script stays 🎉!
    • Use this when you're happy with your program (or if you have unlimited patience)
    • Start your script with the button. No Bluetooth connection required. Take your hub anywhere!
    • You have to send us footage if you send it into space 🚀

Pybricks 4.0/5.0 will be ... ?

In other words, what might we do one day, in a galaxy far away, but certainly not right now?

This is all super cool too, but it's better to stay focused on making the essentials really good first.

  • Support for internal sensors like accelerometer and IMU.
  • Support for older (NXT) and newer hubs (Mario)
  • Support for LEGO SPIKE Prime
  • Powered Up hub-to-hub communication
  • Powered Up remote handset support
  • Improvements to EV3 Visual Studio Code extension

There are also a few things that are just not possible due to hardware limitations:

  • Support for WeDo 2.0: Unless we missed something, this firmware can't be updated. So you can't install Pybricks.
  • Most of the hubs have sufficient flash and RAM capability for Pybricks. But the BOOST Move Hub has less than half of what the others have. So, not all new features beyond 3.0 will come to the BOOST Move Hub.

Other than that, the sky is the limit!

Share this post


Link to post
Share on other sites

Al momento poche novità dal punto di vista di Pybricks (stanno lavorando internamente ad un nuovo "Code Editor").

Nel frattempo, in attesa di una versione del firmware valida per il Control+, mi sono rifornito su Bricklink:

IMG_20200524_121151.thumb.jpg.1bcb065b5d170e63f0c56527d34312cf.jpg

 

Edited by GianCann

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...