Integrazione Thymio Raspberry PI

Comportamento del robot programmato sul Raspberry PI con python

L'esempio seguente mostra come controllare Thymio II da un software che è in esecuzione sul Raspberry PI. Il software acquisisce i valori dei sensori di prossimità del Thymio II, processa questo valore in modo che Thymio II segua un oggetto che si muove di fronte ad esso.

Per questo esempio, abbiamo attrezzato un Thymio II, con un Raspberry PI, una batteria portatile USB (Golf power bank 5200mAh) e una connessione Wi-fi Edimax EW-7811Un.

Ecco alcune immagini che mostrano il robot:

Vista laterale
2014-01-31%2013.46.45.jpgVista posteriore
2014-01-31%2013.47.04.jpgVista dal davanti
2014-01-31%2013.47.15.jpg

Il Thymio può essere controllato direttamente da un software in esecuzione sul Raspberry PI. A questo scopo si usa asebamedulla invece di asebaswitch, al fine di utilizzare la libreria DBus, integrato in asebamedulla, per la comunicazione tra il software e il Thymio II.

Per eseguire asebamedulla sul vostro Raspberry PI, si usa quasi lo stesso comando che si usa per asebaswitch

asebamedulla "ser:device=/dev/ttyACM0"

supponendo ancora una volta che il vostro Thymio II sia il dispositivo /dev/ttyACM0.

Ora che il vostro Raspberry PI è collegato al Thymio, è possibile scrivere un piccolo software in grado di inviare e ricevere comandi utilizzando la libreria DBus. Scegliamo linguaggio Python per scrivere il software, ma può anche essere scritta in C, C++…

Il programma che stiamo andando presente si interfaccia con ASEBA utilizzando D-Bus. Utilizza anche GObject e OptionParser biblioteche. È necessario installare la libreria GObject sul vostro Raspberry PI con il comando:

sudo apt-get install python-gobject

Se sei un principiante con Python, un buon tutorial per imparare la lingua Python può essere trovato qui
http://docs.python.org/2/tutorial/

Ecco lo script python che stiamo utilizzando:

import dbus
import dbus.mainloop.glib
import gobject
from optparse import OptionParser
 
proxSensorsVal=[0,0,0,0,0]
 
def Braitenberg():
    #get the values of the sensors
    network.GetVariable("thymio-II", "prox.horizontal",reply_handler=get_variables_reply,error_handler=get_variables_error)
 
    #print the proximity sensors value in the terminal
    print proxSensorsVal[0],proxSensorsVal[1],proxSensorsVal[2],proxSensorsVal[3],proxSensorsVal[4]
 
    #Parameters of the Braitenberg, to give weight to each wheels
    leftWheel=[-0.01,-0.005,-0.0001,0.006,0.015]
    rightWheel=[0.012,+0.007,-0.0002,-0.0055,-0.011]
 
    #Braitenberg algorithm
    totalLeft=0
    totalRight=0
    for i in range(5):
         totalLeft=totalLeft+(proxSensorsVal[i]*leftWheel[i])
         totalRight=totalRight+(proxSensorsVal[i]*rightWheel[i])
 
    #add a constant speed to each wheels so the robot moves always forward
    totalRight=totalRight+50
    totalLeft=totalLeft+50
 
    #print in terminal the values that is sent to each motor
    print "totalLeft"
    print totalLeft
    print "totalRight"
    print totalRight
 
    #send motor value to the robot
    network.SetVariable("thymio-II", "motor.left.target", [totalLeft])
    network.SetVariable("thymio-II", "motor.right.target", [totalRight])    
 
    return True
 
def get_variables_reply(r):
    global proxSensorsVal
    proxSensorsVal=r
 
def get_variables_error(e):
    print 'error:'
    print str(e)
    loop.quit()
 
if __name__ == '__main__':
    parser = OptionParser()
    parser.add_option("-s", "--system", action="store_true", dest="system", default=False,help="use the system bus instead of the session bus")
 
    (options, args) = parser.parse_args()
 
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
 
    if options.system:
        bus = dbus.SystemBus()
    else:
        bus = dbus.SessionBus()
 
    #Create Aseba network 
    network = dbus.Interface(bus.get_object('ch.epfl.mobots.Aseba', '/'), dbus_interface='ch.epfl.mobots.AsebaNetwork')
 
    #print in the terminal the name of each Aseba NOde
    print network.GetNodesList()
 
    #GObject loop
    print 'starting loop'
    loop = gobject.MainLoop()
    #call the callback of Braitenberg algorithm
    handle = gobject.timeout_add (100, Braitenberg) #every 0.1 sec
    loop.run()

L'algoritmo implementato farà seguire a Thymio II un oggetto che si muove di fronte ad esso, utilizzando i suoi sensori di prossimità e il principio del veicolo Braitenberg. Il principio del veicolo Braitenberg consiste nel collegare direttamente i valori rilevati dai sensori di prossimità con il controllo della velocità del motore all'interno del software attraverso opportune relazioni matematiche, e in base ai valori ottenuti dai cinque sensori anteriori di prossimità di Thymio II, il robot si orienterà verso l'oggetto che si muove.

In questo programma si usa il comando network.SetVariable e network.GetVariable per impostare e leggere i valori delle variabili ASEBA. Per esempio, per fare in modo che la ruota sinistra del robot si muova in avanti con una velocità di 100, usiamo il comando network.SetVariable per modifcare la variabile "motor.left.target" del Nodo ASEBA "thymio-II" con il valore [100]

network.SetVariable("thymio-II", "motor.left.target", [100])

Se vogliamo leggere le variabili, per esempio, i sensori di prossimità, dovremmo usare network.GetVariable con il nome ASEBA Node "thymio-II" e il nome della variabile "prox.horizontal" che è il nome del variabile che contiene un elenco di valori dei 7 sensori di prossimità del Thymio II.

network.GetVariable("thymio-II", "prox.horizontal",reply_handler=get_variables_reply,error_handler=get_variables_error)

Per conoscere il nome del nodo ASEBA del Thymio II, l'istruzione

network = dbus.Interface(bus.get_object('ch.epfl.mobots.Aseba', '/'), dbus_interface='ch.epfl.mobots.AsebaNetwork')
print network.GetNodesList()

stamperà l'elenco dei nodi ASEBA. Per conoscere il nome del nodo, per esempio, nel nostro caso il nome del nodo è stato "thymio-II", si dovrebbe eseguire il codice una volta e leggere nel terminale il nome del nodo, e poi tornare al codice e sostituire il nome del nodo per le istruzioni che inviano e ricevono variabili.

Se si desidera inviare un evento al Thymio II dal Raspberry PI, è possibile chiamare network.SendEvent. Ad esempio, la seguente istruzione invierà Evento 1 con 2 argomenti, con valori rispettivamente 5 e 7.

network.SendEvent(1, [5,7])
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License