Tesix

  • Uploaded by: Damiano
  • 0
  • 0
  • April 2020
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Tesix as PDF for free.

More details

  • Words: 9,113
  • Pages: 54
UNIVERSITÀ DEGLI STUDI DI TRIESTE FACOLTÀ DI INGEGNERIA Dipartimento di Elettrotecnica, Elettronica ed Informatica

Tesi di Laurea in PROGRAMMAZIONE DEI CALCOLATORI

Sviluppo di un Driver per il Controllo di un Robot Mobile in Ambiente Multipiattaforma

Laureando:

Relatore:

Damiano VITTOR

Dott. Ing. Massimiliano NOLICH

____________________________________

Anno Accademico 2007-2008

In memoria di Remo Pezzetta

INDICE

INDICE ......................................................................................................................... I INTRODUZIONE..............................................................................................................1 Il materiale ................................................................................................................................ 2 L’ambiente di sviluppo .............................................................................................................. 3 Fasi dello sviluppo ..................................................................................................................... 3

IL SISTEMA EMBEDDED ....................................................................................................5 Il Sistema Operativo .................................................................................................................. 5 La preparazione ......................................................................................................................... 6 Deployment del sistema operativo ......................................................................................... 11

IL PROGETTO............................................................................................................... 13 Lo sviluppo di controlli per Robot Mobili ................................................................................ 13 L’architettura generale............................................................................................................ 14 I task RTAI ................................................................................................................................ 15 Le FIFO e la Comunicazione Interprocesso ............................................................................. 17 Player, un framework Robotico .............................................................................................. 18 Il collegamento elettrico delle varie parti del robot ............................................................... 19

I TASK REALTIME ......................................................................................................... 21 Il modulo RTAI per la gestione del sensore ad ultrasuoni....................................................... 21 Il modulo RTAI per la gestione dell’infrarosso ........................................................................ 22 Il modulo RTAI per la gestione dei MOTORI............................................................................ 24 Il modulo RTAI per la gestione dei sensori ODOMETRICI........................................................ 26

I DRIVER PLAYER ......................................................................................................... 29 I driver Player .......................................................................................................................... 29 Srf005driver............................................................................................................................. 30

Indice 2d120xdriver ........................................................................................................................... 32 Driver MotoriDriver ................................................................................................................. 35 Lo script di configurazione ...................................................................................................... 35

CONCLUSIONI ............................................................................................................. 37 Risultati raggiunti .................................................................................................................... 37 Prospettive di sviluppo ............................................................................................................ 37

APPENDICI ................................................................................................................. 39 Redboot ................................................................................................................................... 39 Setup e configurazione di un server NFS ................................................................................. 41 Yaffs File-System...................................................................................................................... 42

RINGRAZIAMENTI ........................................................................................................ 45 BIBLIOGRAFIA ............................................................................................................. 47

ii

INTRODUZIONE

Motivazione della tesi La tesi si inquadra in un progetto che prevede lo sviluppo di robot di servizio, che siano capaci di muoversi su di un piano in modo autonomo, evitando, nei limiti della loro percezione sensoriale, gli ostacoli sul loro percorso. Grazie a queste proprietà si desidera renderli capaci di funzioni più complesse che possono variare di situazione in situazione. Per ottenere questo risultato si vogliono utilizzare più livelli di astrazione che permettano almeno di separare la logica di alto livello da quella di livello più basso che gestisce sensori e attuatori. In questo modo si possono ottenere vantaggi notevoli dal punto di vista della riutilizzazione del codice e nella facilità del porting verso altre piattaforme robotiche con caratteristiche hardware differenti.

Gli obiettivi della tesi L’obiettivo del lavoro di tesi proposto è stato realizzare un pacchetto di driver per una piattaforma robotica preesistente che si integri in un framework chiamato Player. Si è realizzato, a tal proposito, del software che si interpone tra dei dispositivi hardware e l’utilizzatore (il framework) in grado di pilotarne le funzionalità. Si desidera, in questo modo, che tale software esponga un’interfaccia standard che ne celi la complessità intrinseca. I driver sviluppati si occupano della gestione dei sensori e degli attuatori montati sul robot. In particolare, sono stati utilizzati sensori a ultrasuoni, ad infrarosso e odometrici, oltre che un circuito di comando motori. Grazie a questo pacchetto di driver si vuole anche rendere facilmente interoperabile il robot con tutto il repertorio di software di alto livello già realizzato all’interno del progetto Player come il “wavefront” e il “vhf” (rispettivamente per il path-finding e la collision-avoidance) ed inoltre si vuole permettere lo sviluppo di una logica indipendente dall’hardware.

1

Introduzione

I Vincoli Il lavoro è stato sviluppato nel laboratorio Smartlab del Dipartimento di Elettrotecnica Elettronica e Informatica della Facoltà di Ingegneria presso l’Università degli Studi di Trieste. Il materiale necessario al progetto era già stato acquistato dal laboratorio per altre attività e quindi è stato utilizzato anche in funzione di questo lavoro. Ciò è stato vincolante sia nella scelta dell’ambiente di sviluppo sia in quella del sistema operativo. Infatti in base ai sistemi operativi supportati dalla ditta produttrice dell’hardware, al loro costo economico e alla possibilità di essere impiegati con processi real-time la scelta è dovuta ricadere più o meno obbligatoriamente su un sistema GNU/Linux.

Il materiale • • • • • •

Sistema embedded Ts-7250 della Technologic Systems Sensori ultrasuoni Devantech SRF005 Sensori infrarosso Sharp 2D120X Sensori Odometrici HEDS-5505 della Agilent Technologies Driver Motori #203 della Wirz Electronics Motori m455m63 della Globe Motors

Technologic System TS-7250 Il TS-7250 è un sistema embedded basato su un chip Cirrus Logic con core ARM9: l’EP9302. Questo chip a basso consumo include nel suo package un processore ARM920T funzionante a 200Mhz e una serie di periferiche standard come quelle USB o Ethernet e linee di digital I/O. La caratteristica che rende appetibile questo sistema per la robotica è il basso consumo (circa 2 – 3 W) e la disponibilità di una moltitudine di periferiche onboard.

Devantech SRF005 Il sensore SRF005 è un sensore distanziometrico a ultrasuoni che integra già un microcontrollore che gestisce la generazione degli impulsi e la loro rilevazione. E’ controllabile tramite delle porte di Digital I/O (DIO). La sua portata è di circa 4 metri con una precisione dell’ordine del centimetro.

2

Introduzione

Sharp GP2D120X Il sensore Sharp GP2D120X è un sensore distanziometrico a infrarosso e funziona come un normale fotodiodo. Va collegato direttamente ad un analog-digital converter (ADC) per la lettura della caduta di tensione. La sua portata è di circa 0,3 metri con una precisione superiore al centrimetro.

Wirz Electronics #203 Low Current Motor Driver E’ un circuito amplificatore che serve per modulare la tensione fornita ai motori allo scopo di poter regolare la velocità di rotazione degli stessi. Questo circuito dispone di due controlli motori indipendenti che vengono pilotati tramite due coppie di porte di digital I/O.

Sensori odometrici HEDS-5505 I sensori odometrici sono atti a rilevare il verso e la velocità di rotazione dell’asse di un motore. Questo modello in particolare usa una tecnologia ottica a quadratura. Ogni sensore si collega direttamente a due porte di digital I/O sulle quali vengono trasmessi due segnali sfasati di 90°. Grazie a questi segnali si può determinare il movimento del motore.

L’ambiente di sviluppo La cross-compilazione dei moduli rtai, del kernel e il servizio nfs sono stati eseguiti su di un sistema Gnu/Linux Kubuntu 8.04 eseguito come macchina virtuale su un host Windows VISTA. Per lo sviluppo dei driver si è scelto di utilizzare KDevelop come IDE e make come build-tool. Il gestore di macchine virtuali utilizzato è VirtualBox prodotto dalla SUN Microsystems. VirtualBox, Kubuntu, KDevelop e make sono software scaricabili ed utilizzabili gratuitamente.

Fasi dello sviluppo Il lavoro è stato organizzato nel modo seguente: 1. Scelta della GNU cross-platform toolchain. 2. Patch dei sorgenti del kernel linux con le estensione realtime. 3. Cross-compilazione del kernel e dei moduli necessari per il funzionamento dell’hardware.

3

Introduzione

4. Cross-compilazione dei moduli/task realtime per il kernel. 5. Preparazione file-system. 6. Configurazione del bootloader e installazione del file-system (per il sistema di sviluppo). 7. Cross-compilazione di player. 8. Analisi e sviluppo dei moduli real-time per la lettura dei dati acquisiti dai vari sensori e l’azionamento dei motori. 9. Analisi e sviluppo dei driver per Player. 10. Preparazione degli script di configurazione e di avvio del robot. 11. Installazione di player, dei driver e degli script sul robot. 12. Configurazione del bootloader e installazione del file-system (per il sistema di produzione).

4

IL SISTEMA EMBEDDED

Il Sistema Operativo La Technologic System supporta per la TS-7250 GNU/Linux, WinCE e Netbsd. La scheda viene precaricata dalla fabbrica con una distribuzione debian minimale (TS-Linux), basata su kernel linux 2.4, realizzata dal produttore stesso.

La scelta del sistema operativo Uno dei criteri di scelta del sistema operativo, oltre costo e supporto per il nostro hardware, è stata la possibilità di soddisfare i requisisti imposti dal nostro progetto. Tra questi requisiti vi era per esempio la necessità di rispondere rapidamente ai dati sensoriali che elabora, per esempio, al fine di evitare la collisione con oggetti o persone nell’ambiente in cui si muove. Per questo motivo un sistema operativo real-time è solitamente preferibile per lo sviluppo di sistemi robotici. Nell’ambito dei sistemi operativi real-time utilizzabili che siano supportati e che non siano commerciali, si è deciso di usare una distribuzione GNU/Linux con estensioni real-time.

The Real-time Application Interface (RTAI) RTAI si presenta come una patch per il kernel Linux e una serie di librerie di supporto per lo sviluppo. La patch introduce, tramite le HAL (Hardware Abstraction Layer) del kernel, un nuovo schedulatore che programma i processi in realt-time (task) in maniera precisa e deterministica. Quest’ultimo considera il kernel Linux come un idle task eseguendolo quando il kernel real-time non è attivo. Il task Linux, inoltre, non può mai bloccare gli interrupt o impedire di essere interrotto nella sua esecuzione (being preempted).

5

Il sistema embedded

RTAI è stato sviluppato dal Dipartimento di Ingegneria Aerospaziale del Politecnico di Milano ed è liberamente utilizzabile.

La preparazione Il bootloader Sulla TS-7250 è precaricato un bootloader basato su eCos, un sistema operativo real-time minimale per sistemi embedded. Questo bootloader si chiama RedBoot ed è stato utilizzato nel nostro progetto per il caricamento dell’immagine del kernel, per la sua esecuzione e per scrivere l’immagine stessa sulla memoria flash della scheda. Per questioni di praticità, a tal proposito, sono stati realizzati due script di avvio separati per Redboot: uno utilizzato in fase di sviluppo, ed uno per il sistema finale “dimostrativo”. Per quanto riguarda l’utilizzo di Redboot si è provveduto a riportare nel testo, quando necessario, i comandi utilizzati. Per ulteriori dettagli su Redboot sono stati scritti degli approfondimenti nell’appendice.

Scelta della GNU Cross-Platform Toolchain Per poter compilare un codice valido per la nostra piattaforma robotica si è dovuta utilizzare di una cross-platform toolchain, cioè di un insieme di programmi e librerie necessari per la compilazione e la generazione di eseguibili per una piattaforma diversa da quella su cui essa viene usata. A questo scopo il produttore della scheda fornisce sul suo repository ftp1 già una gamma di toolchain di cui si è scelto di utilizzare, in particolare, la crosstool-linuxgcc-3.3.4-glibc-2.3.2-0.28rc39 .

Preparazione del kernel Una volta recuperati i sorgenti del kernel tskernel-2.4.26-ts11 si è provveduto ad applicare la patch adeos rttskernel-2.4.26-tsX-adeos.patch per l’estensione realtime, disponibile sempre nel ftp della Technologic System. Questa patch consiste in uno script di modifica dei sorgenti del kernel atto ad introdurre le nuove funzionalità necessarie per trasformarlo in un Sistema Operativo real-time.

1

ftp://ftp.embeddedarm.com

6

Il sistema embedded

Prima di poter applicare la suddetta patch, è stato necessario definire al suo interno alcune informazioni, in modo che la stessa venga applicata con successo. In particolare, si sono modificate le righe che specificano la versione di kernel su cui applicare la patch e il prefisso del cross-compilatore che si ha intenzione di utilizzare. Nella fattispecie, sono state aggiunte/rimosse le seguenti righe: -EXTRAVERSION =-ts11 +EXTRAVERSION =-ts11-rt +CROSS_COMPILE = /tools/crosstool/arm-9tdmilinux-gnu/gcc-3.3.4-glibc-2.3.2/bin/arm9tdmi-linux-gnu+DEPMOD= /bin/true

E’ stato, poi, bypassato l’utilizzo del comando depmod sostituendolo con /bin/true in quanto non è in grado di gestire la cross-compilazione. E’ stata quindi applicata la patch con il comando: patch -p1 -b < ./../rt-tskernel-2.4.26-ts11adeos.patch

Si è passati quindi a modificare il Makefile del kernel assicurando che le seguenti variabili fossero correttamente impostate. ARCH := arm CROSS_COMPILE = /tools/crosstool/arm-9tdmilinux-gnu/gcc-3.3.4-glibc-2.3.2/bin/arm9tdmi-linux-gnuDEPMOD = /bin/true

Configurazione del kernel La configurazione del kernel è essenziale per far riconoscere ed utilizzare al sistema operativo le periferiche del sistema. Tale operazione avviene attraverso degli script di configurazione e un menu visuale in cui l’utente può scegliere direttamente l’hardware che vuol fargli supportare. In tal senso la technologic system ha provveduto a fornire, insieme ai sorgenti del suo kernel, più script di configurazione per il loro hardware. Questo avrebbe, in teoria, dovuto rendere questa operazione abbastanza semplice. Tuttavia una modifica nella tipologia di flash montata sulla scheda (una variazione nella dimensione dei blocchi di memoria) ha creato non pochi problemi nella configurazione del kernel stesso. Il driver YAFFS, indicato nella configurazione del sistema che si voleva utilizzare, non supporta il tipo di flash memory con blocchi da 512byte e per questo impediva le operazione di scrittura sulla flash della scheda.

7

Il sistema embedded

Per questo motivo nella configurazione del kernel è di notevole importanza assicurarsi del tipo di flash presente sulla scheda e utilizzare uno dei due seguenti script di configurazione per il suo corretto funzionamento. ts7250_config 512byte ts7250_2k_config 2kbyte

per memoria con blocchi da per memoria con blocchi da

Quindi per una corretta configurazione del kernel per l’hardware utilizzato si deve eseguire i seguenti comandi: make [ts7250_config|ts7250_2k_config]

per configurare le periferiche della scheda make oldconfig

per configurare il supporto RTAI attivando quando richiesto solamente attivando solamente ADEOS e ADEOS DOMAINS ARE THREAD e quindi make dep make menuconfig

A questo punto sarà possibile visualizzare la configurazione finora impostata ed eventualmente integrare il supporto per altre periferiche. Nel nostro caso in specifico i seguenti moduli sono stati attivati/integrati: 1. Loadable module support 1.1.

Kernel module loader

2. System Type 2.1.

EP9301 Options

2.1.1. EP9301 Internal DMA Support 3. Plug and Play configuration 3.1.

Plug and Play support

3.1.1. ISA Plug and Play support 4. Sound 4.1.

Sound support

4.1.1. OSS sound modules 4.1.2. Verbose initialisation 5. USB support

8

5.1.

USB verbose debug messages

5.2.

USB Audio support

Il sistema embedded

Compilazione del kernel Per compilare il kernel si possono quindi eseguire i comandi make make zImage make modules make modules_install INSTALL_MOD_PATH=

A questo punto si ha a disposizione nella directory ./arch/arm/boot/ l’immagine del kernel da installare nella scheda e (nella cartella specificata dalla variabile INSTALL_MOD_PATH) i moduli del kernel da inserire nel file system della scheda arm.

Compilazione dei moduli rtai Si è usata la versione di RTAI 3.2 (magma) che è quella ufficialmente supportata dalla Technologic System. Prima della compilazione può essere necessario modificare il codice sorgente per evitare l’insorgere di problemi durante la configurazione. Nel file rtai-3.2/base/config/kconfig/mconf.c alla riga 91 bisogna togliere l’attributo statico alla variabile current_menu Fatto ciò si è preseguiti nella compilazione con i seguenti comandi: make ARCH=arm CROSS_COMPILE=/tools/crosstool/arm-9tdmi-linuxgnu/gcc-3.3.4-glibc-2.3.2/bin/arm-9tdmilinux-gnumake install

Nel menu di configurazione bisogna prestare attenzione a selezionare il giusto path ai sorgenti del kernel che si è compilato precedentemente. E inoltre conveniente specificare il percorso tipo /usr/realtime dove verrà effettuata la build da spostare nella board. NOTA IMPORTANTE: E’ necessario ricompilare rtai ogni qualvolta sia STATO ricompilato il kernel

9

Il sistema embedded

Compilazione di player Per compilare una versione minimale di player bisogna disporre delle seguenti librerie oltre quelle già presenti nel file-system base della TS-7250. Queste ovviamente devono essere compilate per la piattaforma arm: libpthread libsdtc++ libtools

Le prime due erano disponibili sul file-system esteso chiamato debian-sarge1.14.tar reperibile sul ftp della technology system. La terza è stata ricompilata in quanto non era disponibile un binario già pronto. In particolare è stata usata la versione libtool-1.5.26 per la compilazione della libreria. La procedura usata è stata quella riportata nel file INSTALL della root dei sorgenti. E’ importante ricordarsi di fare l’export dei path per i binari del cross compilatore e assicurarsi che lo stesso venga utilizzato. Per quanto riguarda player bisogna quindi impostare le seguenti variabile d’ambiente: export CC=gcc export PATH= export CCFLAGS = -I -l export LDFLAGS = -L libs

Dove ai blocchi comprendenti le parentesi angolari vanno sostituiti i relativi percorsi assoluti necessari. Quindi si può procedere con la configurazione del pacchetto con il comando: ./configure --prefix=/home/damiano/PlayerStage/build/ --build=x86-linux --host=arm9tdmi-linux-gnu --disable-alldrivers -disable-debug --disable-tests --disableexamples

E alla compilazione con make install

Il risultato della compilazione sarà posto nella directory specificata dal parametro PREFIX del configure e cioè nel nostro caso in /home/damiano/PlayerStage/build/. In ogni caso è sconsigliabile tentare di compilare player direttamente sulla scheda arm, in quanto non è una strada facilmente percorribile.

10

Il sistema embedded

Preparazione del file-system Per la prepazione del file-system del nostro sistema embedded si è partiti dal filesystem originale, precaricato nella flash, al quale si sono aggiunti i moduli e le librerie necessarie per il funzionamento di Player e RTAI. In particolare: • • • •

I moduli del kernel vanno copiati nella directory /lib/modules del root filesystem di destinazione. I moduli RTAI vanno copiati preferibilmente dentro /usr/realtime. Il contenuto della build di player è stata copiata integralmente dentro /usr/local/ Le librerie richieste da player (libpthread, libsdtc++ e libtools) sono state copiate nella directory /usr/lib/

Tutti i percorsi qui menzionati sono relativi alla root del file system della scheda arm.

Deployment del sistema operativo Per poter utilizzare il file-system da noi preparato è necessario passare il device che lo contiene come parametro all’esecuzione del kernel. Questo si può effettuare modificando lo script di avvio del sistema operativo, nel bootloader. Durante lo sviluppo di questo progetto, come già menzionato nell’introduzione, sono stati utilizzati due modi per caricare il file-system.

Il sistema di sviluppo Il primo modo “di sviluppo” prevede la condivisione del root file-system tramite una seconda macchina di sviluppo. Grazie a ciò, non è stato necessario aggiornare di continuo il file-system presente sulla flash della scheda ad ogni modifica delle librerie o dei moduli sviluppata. Inoltre, tale approccio ciò non ci ha vincolato alla dimensioni della flash. Questo è stato realizzato utilizzando una condivisione nfs contentente il filesystem che è stato creato (maggiori dettagli a questo proposito vengono forniti in appendice) e provvedendo a modificare i parametri del comando exec dello script di caricamento del kernel nel bootloader. In particolare è stato rimosso il parametro root ed è stato aggiunto il parametro nfsroot come segue: exec –c”ttyAM0,115200 ip= nfsroot=:<nome condivisione>”

11

Il sistema embedded

dove • •

è l’ip del server che fa da host al servizio nfs <nome condivisione> è il nome della condivisione nfs contenente il root file system da usare

Il sistema di Produzione Il sistema di produzione è indipendente da altre macchine. Anzi, non è previsto sia collegato in rete ad alcuna altra macchina. Deve quindi caricare il file-system dalla memoria flash integrata nella scheda. Per caricare il file-system sulla scheda è necessario seguire la procedura per il ripristino del file-system specificata nell’appendice. C’è da considerare, inoltre, un problema riguardante le dimensione del file-system stesso. La scheda a nostra disposizione monta una memoria flash troppo piccola (32MB) rispetto la dimensione necessaria a ospitare tutte le librerie di cui ha bisogno Player per funzionare. Si è deciso quindi di dividere il file-system spostando il contenuto di /usr su una memoria flash esterna da collegare alla scheda tramite porta USB. Per fare ciò si è partizionata e formattata quest’ultima con un file-system ext3 (con il comando mkfs). A questo punto non è rimasto che copiare al suo interno la cartella /usr e fare il mount della stessa sul sistema con i seguenti comandi. /usr/bin/loadUSBModules.sh

Per caricare i moduli di gestione dell’USB. mount -t auto /dev/scsi/host0/bus0/target0/lun0/part1 /usr

Per fare il mount della prima partizione della chiavetta USB. E’ tuttavia consigliabile salvare il primo script in /etc/init.d e richiamarlo con un link simbolico in /etc/rc.d/rc3.d/ e aggiungere nel file /etc/fstab la seguente riga: /dev/scsi/host0/bus0/target0/lun0/part1 ext3 /usr

Infine sarà necessario modificare la linea di avvio del kernel nello script di avvio del bootloader nel seguente modo: exec –c”ttyAM0,115200 ip= root=/dev/mtdblock/1”

12

IL PROGETTO

Lo sviluppo di controlli per Robot Mobili Come citato nell’introduzione, una delle motivazioni fondamentali di questo lavoro, è stata creare un piattaforma robotica che abbia una serie di caratteristiche utili allo sviluppo di logiche robotiche. In particolare: • • • • •

Semplifichi la portabilità. Permetta la simulazione. Permetta lo sviluppo in maniera indipendente dall’hardware a disposizione. Permetta l’elaborazione distribuita. Sia di facile utilizzo.

A tal scopo, ci si è proposti di utilizzare una piattaforma già esistente e collaudata chiamata “Player”. Player, come verrà descritto più avanti, tenta di introdurre questi vantaggi tramite una serie di interfacce e di livelli di astrazione. Tratteremo ora di come è realizzato un sistema che presenti la funzionalità del proprio hardware all’interno di Player attraverso la preparazione della piattaforma robotica e lo sviluppo di driver specifici. Questo lavoro prevede • • •

la preparazione del sistema operativo che il robot utilizza, come abbiamo già illustrato. lo sviluppo dei driver hardware necessari al funzionamento dei sensori e degli attuatori. lo sviluppo dei driver per player.

13

Il progetto

L’architettura generale Sono stati realizzati da me quattro task real-time atti a leggere le informazioni dai sensori e al comando dei motori. Sul lato opposto, tre driver per il framework player (sempre sviluppati da me) si occupano della gestione dei task real-time e dell’interpretazione dei dati letti. Lo scambio delle informazioni tra il processo del server player e dei task real-time avviene tramite FIFO di sistema. I driver di player si occupano di rendere le informazioni tratte dei sensori disponibili tramite delle interfacce standard ad altri driver Player o ai client stessi. Tale architettura viene illustrata nel seguente diagramma:

Le parti sviluppate da me sono state evidenziate in giallo.

14

Il progetto

Con l’infrastruttura di player è possibile collegare l’output di questi driver ad altri driver, che espongono interfacce a più alto livello di astrazione. Questo può essere fatto tramite degli script di configurazione di player. Il risultato della elaborazione successiva (così come i dati ad ogni stadio di processo) sarà disponibile al programma che ne voglia gestire la logica tramite le librerie di player.

I task RTAI I task RTAI sono, in pratica, dei moduli del kernel linux che fanno uso di caratteristiche speciali tipiche dei sistemi operativi real-time introdotte da RTAI.

I moduli del kernel linux Un modulo del kernel linux è una porzione di codice che può essere aggiunta al kernel linux durante la sua esecuzione. Uno dei vantaggi principali di questa caratteristica è che non è necessario ricompilare l’intero kernel del sistema operativo ogniqualvolta si voglia far supportare al sistema operativo un nuovo dispositivo hardware o implementarne una nuova funzionalità. Il gestore che permette il caricamento di moduli in run-time si chiama Loadable Kernel Module (LKM) e introduce diverse categorie di moduli (o meglio di servizi) caricabili: • • • • •

Driver per periferiche. Driver per file-system. Driver di rete. Moduli per definire nuove chiamate a sistema o per ridefinirne quelle esistenti. Nuovi interpreti per eseguibili.

E’ importante sapere che i moduli del kernel, essendo eseguiti in kernel-space, NON possono: • •

Usare funzioni della libreria standard C. Usare aritmetiche floating-point.

L’aggiunta e la rimozione di un modulo del kernel linux può venire eseguita tramite i comandi di sistema insmod e rmmod.

La struttura di un modulo del kernel linux. L’interfaccia di un modulo del kernel linux è costituita fondamentalmente da due metodi che vengono chiamati rispettivamente all’inserimento e alla rimozione del modulo stesso. Li riportiamo qui:

15

Il progetto

int init_module(void) void cleanup_module(void)

Per sviluppare un modulo valido per il kernel è sufficiente implementare tali moduli.

Sviluppo di un task real-time. Come spiegato, un task real-time si presenta come un modulo del kernel linux. Le due chiamate sopra citate dovranno quindi essere presenti nel codice del modulo. Inoltre nell’inizializzazione avremo una serie di chiamate a funzione necessarie per la creazione del task real-time e il suo schedulamento. In particolare saranno presenti le seguenti chiamate a funzione: rt_task_init; rt_task_make_periodic_relative_ns start_rt_timer

La prima istruzione crea un nuovo task real-time, la seconda imposta la periodicità del task e infine la terza avvia il timer. Nella funzione di clean-up del modulo, invece, si troveranno le rispettive funzioni per fermare il timer e distruggere il task: stop_rt_timer(); rt_task_delete();

Le principali funzioni RTAI RT_TASK* rt_task_init ( int max_msg_size )

int

name, int

priority, int

stack_size,

Crea un nuovo task real-time. “name” è l’identificatore unico con il quale è possible referenziare il task. “priority” è la priorità del task. int rtf_create (

unsigned int

minor, int

size )

Crea una FIFO real-time della dimensioni iniziale “size” e identificatore “minor” int rt_task_make_periodic_relative_ns ( RTIME start_delay, RTIME period )

RT_TASK *

task,

Imposta il task “task” in modalità periodica con periodo “period”. “start_delay” definisce il ritardo di prima esecuzione. void rt_task_wait_period ( void )

16

Il progetto

Attende fino al sopraggiungere del prossimo periodo. E’ usato nei task periodici. Permette l’esecuzione di altri task durante questo intervallo di tempo. start_rt_timer ( int )

Avvia un timer real-time. stop_rt_timer

Ferma il timer real-time.

Le FIFO e la Comunicazione Interprocesso Uno dei punti cruciali del progetto è creare un sistema di comunicazione che permetta di trasferire le informazione tra i task in real-time e il processo in userspace (Player). Per fare ciò, purtroppo, non è possibile utilizzare gli strumenti classici dell’ambiente linux per l’IPC (Inter Process Communication). RTAI però mette a disposizione strumenti simili che sopperiscono a questa mancanza. Questi strumenti sono: L E F IFO R EAL - TIME RTAI fornisce una versione specializzata delle FIFO per l’ambiente realtime. Sono dei buffer unidirezionali non bloccanti che permettono il trasferimento di dati in modalità asincrona. Ad ogni FIFO corrisponde un file del tipo /dev/rtf/ dove e il numero identificatore della FIFO. La creazione e l’accesso deve avvenire dal task real-time tramite le API fornite, mentre i processi in user-space possono accedervi tramite le primitive classiche che linux mette a disposizione per l’accesso ai file. S HARED MEMORY Viene allocato un blocco di memoria che può essere letto e scritto da tutti i processi attivi nella macchina. Si accede a questa memoria direttamente con un puntatore. Per questo motivo bisogna garantire l’accesso in mutua esclusione per il corretto funzionamento. Ciò può avvenire tramite dei semafori. E’ possibile accedere alla memoria condivisa tramite un file di sistema. (/dev/rtai_shm)

17

Il progetto

M ESSAGE Q UEUE E RPC E’ un meccanismo di scambio di messaggi dove mittente e destinatario devono conoscersi. Le code di messaggi vengono ordinate per priorità e le chiamate sono bloccanti fintantoché il destinatario non riceve il messaggio o nel caso delle RPC fino alla risposta del destinatario. M AILBOX In questo caso la mailbox fa da centro di smistamento dei messaggi. Più produttori e consumatori possono registrarsi contemporaneamente alla stessa mailbox e mandare e ricevere messaggi. Nel nostro caso è stato scelto di utilizzare delle FIFO per le IPC in quanto l’uso che ne dobbiamo fare è limitato e il loro utilizzo è molto semplice. Per utilizzare una FIFO in un task real-time è sufficiente utilizzare i seguenti comandi:

int rtf_create(unsigned int fifo, int size)

Crea la FIFO real-time con identificativo “fifo” e dimensione iniziale “size”. int rtf_put(unsigned int fifo, char * buf, int count)

Scrive nella FIFO “fifo”, un array di byte “buf” della dimensione “count”.

rtf_destroy ( int fifo )

Distrugge la FIFO real-time precedentemente creata con identificatore “fifo”.

Player, un framework Robotico Player è un HAL (Hardware Abstraction Layer) per dispositivi robotici. In pratica definisce, tramite delle interfacce, sia una serie di caratteristiche e comportamenti comuni dei dispositivi solitamente presenti sui robot, sia le azioni standard con cui si può interagire con questi dispositivi. In questo modo chi sviluppa la logica di comando del robot non deve preoccuparsi dei dettagli hardware del robot e il codice che farà utilizzo di queste interfacce sarà facilmente portabile anche tra robot con un diverso hardware.

18

Il progetto

Player mette a disposizione, oltre che queste librerie di driver e interfacce, anche numerosi tool di utilità per chi sviluppa applicazioni per la robotica. Tra questi tool alcuni sono di notevole interessere ed in particolare il programma “player” che è in pratica un server di rete per il controllo robotico e permette quindi anche la realizzazione di una piattaforma robotica distribuita.

Il collegamento elettrico delle varie parti del robot Il sensore ultrasuoni è stato collegato al connettore LCD della scheda TS-7250. In particolare la coppia di porte LCD_1 LCD_0 della TS-7250, corrispondenti ai pin 7 ed 8 è stata collegata ai piedini rispettivamente di trigger e di echo. L’alimentazione del sensore invece è stata prelevata dai pin 1 e 2 del connettore LCD che sono rispettivamente 5v e GND. Il lettore infrarosso invece è stato collegato all’ADC e, in particolare, il canale 0 del ADC converter corrispondente al pin 1 del connettore A/D è stato collegato all’uscita Vc del sensore infrarosso. La sua alimentazione è stata invece presa dai pin 16 e 2 del connettore DIO corrispondenti a 3.3v e GND. Il controllo motore gestito dal circuito Wirz (e dal suo circuito di opto-isolazione) è stato collegato sulle coppie di porte DIO LCD_2 LCD_3 e LCD_4 LCD_5 corrispondenti ai pin 10, 9 e 12, 11 del connettore LCD. LCD_2 e LCD_4 regolano la velocità, mentre LCD_3 e LCD_5 la direzione. I sensori odometrici sono invece collegati alla porta DIO della TS-7250 e, precisamente, alle coppie di porte DIO0, DIO1 e DIO2, DIO3 corrispondenti ai pin 1, 3 e 5, 7. Di queste, DIO0 e DIO1 saranno rispettivamente i canali A e B di un odometro, e DIO2 e DIO3 quelli dell’altro.

19

Il progetto

20

I TASK REALTIME

Il modulo RTAI per la gestione del sensore ad ultrasuoni Il sensore ad ultrasuoni si interfaccia alla scheda TS-7250 tramite due porte di digital I/O. Lo schema di funzionamento è abbastanza semplice: alzando il livello del segnale di una delle due porte di digital I/O è possibile inviare un segnale “trigger” che produce il segnale acustico. Sull’altra linea, invece, sarà possibile osservare il tempo di percorrenza dell’eco del segnale: dalla partenza all’arrivo. Si veda dunque il seguente grafico illustrativo:

21

I Task RealTime

Il codice Invio il trigger: outb_p(DIO_OUTPUT_PIN_MASK,DIO_LCD_DATA); rt_sleep(nano2count(15000LL)); outb_p(0x00,DIO_LCD_DATA);

Attendo che il segnale si alzi sulla seconda linea DIO e salvo un timestamp: while ((inb_p(DIO_LCD_DATA) & DIO_INPUT_PIN_MASK) == 0x00){ … } start_eco_pulse = rt_get_cpu_time_ns();

Attendo che il segnale si abbassi e calcolo da differenza: while ((inb_p(DIO_LCD_DATA) & DIO_INPUT_PIN_MASK) != 0x00){ … } distance = rt_get_cpu_time_ns()-start_eco_pulse;

Il modulo RTAI per la gestione dell’infrarosso

Il sensore infrarosso si interfaccia con la scheda tramite un canale dell’ADC integrato sulla scheda. Il segnale restituito dal sensore è un segnale analogico in tensione che varia principalmente in funzione della distanza.

L’Adc integrato nel EP9302 L’adc integrato nell’ep9302 è un ADC con 5 canali a 12 bit che può misurare tensioni da 0 a 3,3 volt. Per poter utilizzare l’ADC bisogna prima seguire un procedura particolare atta ad abilitarlo, alimentarlo e attivare il canale per la lettura. Tutto ciò avviene impostando determinati registri in maniera opportuna.

22

I Task RealTime

In particolare i passi da seguire sono i seguenti: 1. 2. 3. 4. 5. 6.

Impostare il SYSSWLOCK per sbloccare il registro SYS Impostare il bit TSEN per attivare il clock dell’ADC Impostare il bit TIN per disabilitare la modalità touchscreen Resettare il bit ADCPD per alimentare il device Impostare il ADCSWLOCK per sbloccare il registro ADC Impostare ADCSWITCH_OFFSET per selezionare il canale di lettura

A questo punto è possibile effettuare le misure iterando la lettura del registro ADCRESULT_OFFSET e controllando se il bit SDR è settato. Qualora non lo fosse, significa che la lettura è stata già letta e va scartata. Quindi: 7. Leggo il flag SDR da ADCRESULT_OFFSET 8. Leggo i dati da ADCRESULT_OFFSET

Il codice L’inizializzazione /* set SYSSWLOCK PUNTO 1 */ outl_p(UNLOCK_VAL, SYSCON_PAGE + SYSSWLOCK); //unlock the software lock /* set TSEN bit PUNTO 2 */ val = inl_p(SYSCON_PAGE + KEYTCHCLKDIV); outl_p(TSEN_MASK | val, SYSCON_PAGE + KEYTCHCLKDIV); //attivo il clock del adc /* set TIN bit PUNTO 3 */ val = inl_p(SYSCON_PAGE + DEVICECFG); outl_p(val | ADCEN_MASK, SYSCON_PAGE + DEVICECFG); //disabilito il touchscreen /* clear ADCPD bit PUNTO 4*/ val = inl_p(SYSCON_PAGE + DEVICECFG); outl_p(val & ~ADCPD_MASK, SYSCON_PAGE + DEVICECFG); //power up del clock e del adc /* set ADCSWLOCK PUNTO 5*/ outl_p(UNLOCK_VAL, ADC_PAGE + ADCSWLOCK_OFFSET); //unlock the soft lock /* set adc channel PUNTO 6*/ outl_p(ADC_CH0, ADC_PAGE + ADCSWITCH_OFFSET);

e quindi poi per le letture si itera:

23

I Task RealTime

/* wait sdr set PUNTO 7*/ while(is_ADC_busy()); /* read data PUNTO 8*/ //read result from data register val = inl_p(ADC_PAGE + DATA_OFFSET); //scarto i bit 16bitt alti val = val & DATA_MASK; dove ADC_busy() è il controllo se il dato è nuovo val = inl_p(ADC_PAGE + ADCRESULT_OFFSET); if((val & SDR_MASK) == SDR_MASK) return TRUE; return FALSE;

Il modulo RTAI per la gestione dei MOTORI Il modulo RTAI per la gestione dei MOTORI colloquia attraverso quattro porte di digital I/O (due per motore) con il circuito Wirz per il controllo motori. Il circuito ha bisogno di due segnali distinti in ingresso per ogni motore, rappresentanti la direzione del moto e la velocità. Per quanto riguarda la selezione della direzione sarà necessario alternare il livello del segnale sulla porta di digital I/O per invertire la direzione. Si noti che però occorre eseguire l’operazione a motori fermi per non danneggiare il circuito. Per quanto riguarda invece la modifica di velocità di rotazione dei motori, questa avviene tramite la generazione di un’onda quadra a frequenza fissa (tra i 100Hz e i 20kHz) e variando il “duty cycle”, ovverosia il tempo in cui il livello di tensione è alto nel periodo. E’ stato creato quindi un task con il compito di generare il segnale per i due motori in base ai dati letti dalla FIFO di input con la procedura rappresentata nel seguente diagramma.

24

I Task RealTime

V e lo c it à M o to re A

V e lo c it à M o to re B

Vel A > 0

Si

A ccendi A

No Si Vel B > 0 A s p e t ta la p r o s s im a s c h e d u la z io n e

Vel A > 0 e Vel B > 0

A ccendi B

Si No

No No Vel B > A Si Vel B > 0

Si

A tte n d i il “ D u ty T im e ” di B

No

Vel A > 0

Si

A tte n d i il “ D u ty T im e ” di A

No Spegni B

A tt e n d i il “ D u ty T im e ” d i A

Spegni A

A tte n d i il “ D u ty T im e ” di A - B

Spegni A

A tt e n d i il “ D u ty T im e ” d i B

A tte n d i il “ D u ty T im e ” di B - A

Spegni B

Il codice N.B. Il funzionamento del seguente codice non è stato verificato sul robot if (pwm_duty_cycle_A != 0 && pwm_duty_cycle_B != 0) { if (pwm_duty_cycle_A > 0) outb_p(inb_p(DIO_MOTOR_DATA)| 0x01,DIO_MOTOR_DATA); if (pwm_duty_cycle_B > 0) outb_p(inb_p(DIO_MOTOR_DATA)| 0x04,DIO_MOTOR_DATA); //decido chi devo spegnere per primo time = TASK_PWM_PERIOD; if (pwm_duty_cycle_A < pwm_duty_cycle_B) { //aspetto e spengo A per primo if (pwm_duty_cycle_A > 0) { time = TASK_PWM_PERIOD*pwm_duty_cycle_A/0x100; rt_sleep(nano2count(time)); outb_p(inb_p(DIO_MOTOR_DATA)& 0xFE,DIO_MOTOR_DATA); } //quidni spengo B rt_sleep(nano2count(TASK_PWM_PERIOD - time));

25

I Task RealTime

outb_p(inb_p(DIO_MOTOR_DATA)& 0xFB,DIO_MOTOR_DATA); } else { //aspetto e spengo B per primo if (pwm_duty_cycle_B > 0) { time = TASK_PWM_PERIOD*pwm_duty_cycle_B/0x100; rt_sleep(nano2count(time)); outb_p(inb_p(DIO_MOTOR_DATA)& 0xFB,DIO_MOTOR_DATA); } //quindi spengo A rt_sleep(nano2count(TASK_PWM_PERIOD - time)); outb_p(inb_p(DIO_MOTOR_DATA)& 0xFE,DIO_MOTOR_DATA); } } rt_task_wait_period();

Il modulo RTAI per la gestione dei sensori ODOMETRICI Il modulo RTAI per la gestione dei sensori odometrici colloquia con i sensori attraverso due coppie di porte di digital I/O. Infatti il sensore genera sulle due digital I/O due segnali periodici uguale sfasati di 90°.

26

I Task RealTime

Questo consente di determinare il verso e la velocità di rotazione del motore. Il verso infatti si determina dallo sfasamento dei due canali. La velocità di rotazione, invece, dipende dalla durata del periodo. In questo modulo verranno creati due task separati: uno per leggere i dati e uno per riempire la FIFO. Si è scelto questo approccio in quanto è necessario campionare lo stato delle due porte abbastanza velocemente da non perdere l’ordine in cui i fronti d’onda salgono o scendono ma sarebbe inutile immettere dati nella FIFO con questa cadenza. Si è quindi preferito inserire le informazioni nella FIFO in un task separato con una periodicità diversa. Il task per la lettura eseguirà quindi le seguente operazioni periodicamente: 1. Lettura dello stato delle due linee di ogni motore 2. Confronto con lo stato precedente di ogni motore 3. In caso di variazione di stato, incremento o decremento del contatore motore

Il codice // PUNTO 1 state=inb_p(PORTB); nowa=state & DIO_ODOMETRY1_MASK; nowb=state & DIO_ODOMETRY2_MASK; // PUNTO 2 tempa = step_odo(&olda,nowa,DIO_ODOMETRY1_MASK); tempb = step_odo(&oldb,nowb,DIO_ODOMETRY2_MASK); // PUNTO 3 counta+=(signed int)tempa; countb-=(signed int)tempb;

dove step_odo() assume come argomenti lo stato passato, lo stato attuale del segnale e la maschera da usare per poi determinare il verso di rotazione. Questa operazione viene eseguita secondo il grafico riportato all’inizio del capitoletto.

27

I DRIVER PLAYER

I driver Player Player può caricare dinamicamente delle estensioni chiamate “driver” dagli sviluppatori di player. Questi driver permettono sia di integrare i vari disposivi del robot all’interno del framework player, sia di associare tra loro altri driver per esporre interfacce di livello più alto. L’interfaccia di un driver presenta tre metodi principali: • • •

Setup Shutdown ProcessMessage

In particolare, i primi due vengono chiamati quando il modulo viene attivato o disattivato. Il terzo, invece, viene eseguito ogniqualvolta il driver è pronto per ricevere i messaggi dagli altri driver a cui è collegato e ci sono dei messaggi in attesa di essere elaborati. Il lavoro del driver verrà eseguito quindi all’interno di un thread dove verrà gestito il flusso di informazioni come mostrato nell’immagine in alto. virtual int Setup(); virtual int Shutdown(); virtual int ProcessMessage(QueuePointer &resp_queue, player_msghdr * hdr, void * data);

29

I Driver Player

Per generare il thread è possibile utilizzare una serie di metodi della della classe Driver che deve essere ereditata per pe poter scrivere un driver. In n particolare, StartThread() e StopThread() generano e terminano un thread che andrà a eseguire la funziona Main(),, già dichiarata dentro la classe Driver, di cui sarà necessario fare l’override. virtual void Main();

All’interno del main si chiamerà la funzione di driver ProcessMessages().. In questo sto modo, il nostro driver potrà rendersi disponibile a ricevere messaggi tramite la ProcessMessage(…). ProcessMessage(…) Si userà anche la funzione Publish(…) per spedire messaggi contenenti informazioni informazi relative all’hardware. Se si vuole inoltre realizzare delle librerie caricate dinamicamente da player, player bisognerà includere dei blocchi di codice statici che si occupino di: • •

registrare il driver stesso all’interno del registro dei driver di player istruire player su come generare una propria instanza.

Per far cio è necessario ecessario implementare il seguente metodo come “esterno”: int player_driver_init(DriverTable* table)

ed usare il metodo DriverTable::AddDriver(char *name, DriverInitFn DriverTable:: initfunc initfunc)

per informare player su che he metodo usare per instanziare un driver.

Srf005driver er Questo driver è dedicato a leggere i dati del sensore a ultrasuoni dalla FIFO e metterli a disposizione della piattaforma player attraverso l’interfaccia “sonar”.. Oltre a ciò il driver si occupa di installare e rimuovere il modulo realreal time della gestione del sensore quando richiesto.. In questo modo è possibile sia risparmiare capacità di calcolo sia allungare l’autonomia del robot. L’interfaccia “sonar” che questo driver espone gestisce schiere di sensori ad ultrasuoni. u Essa prevede che il driver:

30

I Driver Player

• •

sia interrogato riguardo alla disposizione di ogni sensore nella schiera gli sia richiesta l’attivazione e la disattivazione dei sensori per risparmiare capacità delle batterie (funzione che non è supportata dall’hardware a nostra disposizione).

Riepilogando lo scopo del nostro driver sarà quello di: • • •

Leggere i dati dalla FIFO e trasformali in misure di distanza Rispondere alle richieste sulla disposizione dei sensori ad ultrasuoni Trasmettere le letture fatte

Eleaborazione delle distanze Le letture vengono prese dal modulo RTAI per la gestione del sensore ad ultrasuoni tramite le FIFO. Si ricordi che la FIFO è riempita con dei long int rappresentanti il tempo tra il lancio dell’impulso sonoro e la ricezione dell’eco espresso in nanosecondi. Prima di strutturare e inoltrare il messaggio con questo dato si dovrà calcolare la distanza percorsa dall’impulso e dividerlo per due al fine di calcolare la distanza dall’ostacolo presente dinanzi al sensore. Il calcolo da fare è banale, considerata la velocità del suono nell’aria a temperatura ambiente è di circa 343m/s. ܵ[݉] = ‫ ∗ ]ݏ݊[ݐ ≅ ݐ ∗ ݒ‬5800000

Geometrie dei sensore ad ultrasuoni L’interfaccia “sonar” di player prevede che per ogni sensore ad ultrasuoni sia possibile richiederne la posizione in cui è montato e la direzione in cui è puntato rispetto al robot. Questa richiesta verrà formulata con un messaggio del tipo PLAYER_MSGTYPE_REQ e sottotipo PLAYER_SONAR_REQ_GET_GEOM. A tale richiesta bisogna rispondere con un messaggio di tipo PLAYER_MSGTYPE_RESP_ACK e sottotipo PLAYER_SONAR_REQ_GET_GEOM. A questo messaggio è stata allegata una struttura dati di tipo player_sonar_geom_t contenente le geometrie di tutti i sensori ad ultrasuoni disponibili (posizione e direzione). Si utilizza, infine, la funzione Publish() della classe Driver per pubblicare il messaggio.

Trasmissione delle letture Per le letture sarà necessario preparare un messaggio del tipo PLAYER_MSGTYPE_DATA e sottotipo PLAYER_SONAR_DATA_RANGES con allegata una struttura dati di tipo player_sonar_data_t.

31

I Driver Player

Questa struttura dati deve contentere tutte le ultime letture dei sensori ultrasuoni compresi nell’arrayy rappresentato dal driver. Nel nostro caso ci sarà un’unicaa rilevazione.

Setup e Shutdown del driver Il modulo si occupa, come detto, detto anche del inserimento del modulo real-time time e della sua rimozione tramite delle semplice chiamate shell ai comandi insmod e rmmod. system("insmod rt_sonar.o"); system("rmmod rt_sonar.o");

2d120xdriver Questo driver è dedicato alla lla lettura della FIFO contenente i dati acquisiti dal d sensore infrarosso e all’inserimento mento degli stessi all’interno del sistema di eventi di Player. L’interfaccia Player layer per gli array di sensori infrarosso è molto simile a quella per i sensori ad ultrasuoni. ultrasuoni In questo caso, però, è necessario fare qualche elaborazione in più per interpretare i dati letti dai sensori. In particolare, la funzione che fa corrispondere alla distanza di un oggetto posto dinanzi al sensore una tensione non è invertibile e quindi sarà necessario adottare degli accorgimenti per poter ottenere delle letture significative. Questo driver si occuperà come il precedente driver per il sensore ad ultrasuoni delle seguenti operazioni: • • •

Leggere i dati dalla FIFO e trasformali in misure di distanza Rispondere alle richieste sulla disposizione dei sensori infrarosso Trasmettere ttere le letture di tensione e di distanza fatte

Elaborazione delle distanze Anche qui le letture verranno prese dalla FIFO riempita dal modulo RTAI per la gestione del sensore infrarosso. Queste letture di tipo intero rappresentano i livelli di quantizzazione del segnale di ingresso all’ADC. Le letture devono essere correlate ate con i due punti di riferimento misurati dal produttore per ogni canale

32

I Driver Player

dell’hardware e registrate nella EEPROM della stessa scheda tra l’indirizzo l 0x07EB e l’indirizzo 0x07FE come valori da 16bit. In particolare in questa zona di memoria si trova un array bidimensionale dalla seguente struttura che definisce i valori delle d tensioni riferimento a 0 e 2.5V [channel number][0V ref. point, 2.5V ref. Point]

Calcolato il valore di tensione ensione presente in ingresso all’ADC a è possibile calcolare calcol la distanza dell’oggetto posto davanti al sensore. Per fare ciò, però, prima bisogna rendere rendere la funzione di trasformazione del sensore invertibile.

33

I Driver Player

Questo è realizzabile semplicemente restringendo il dominio della funzione nel intervallo [3cm - 40cm] e installando fisicamente il sensore in modo tale che questa distanza minima sia sempre rispettata. A questo punto la funzione è stata divisa in tante spezzate in cui può essere considerata lineare. Si ottiene così la seguente tabella, in cui nella prima riga abbiamo biamo i valori di tensione e nella seconda riga i relativi valori di distanza (assoluta): 0.31

0.37

0.43

0.52

0.65

0.73

0.81

0.93

1.05

1.26

1.4

1.55

1.76

2.1

2.34

2.73

2.98

3.3

40

35

30

25

20

18

16

14

12

10

9

8

7

6

5

4

3.5

3

Nel costruttore del driver vengono calcolati i coefficienti angolari delle spezzate. Una volta determinata la spezzata di appartenenza del punto, questo dato verrà poi utilizzato per calcolare la distanza effettiva nel seguente modo: distance = uppermapping[1][c-1] uppermapp + m[c]*(irdaValue - uppermapping[0][c-1]);

dove uppermapping è l’array ’array rappresentante la tabella qua sopra, sopra m è l’array dei coefficienti angolari delle spezzate relative ai punti noti e irdavalue è il valore della tensione rilevata.

Geometria dei sensori infrarosso L’interfaccia “ir” di Player layer prevede che per ogni sensore a infrarosso sia possibile richiederne la posizione one in cui è montato e la direzione in cui è puntato rispetto al robot. Questa richiesta verrà formulata con un messaggio del tipo PLAYER_MSGTYPE_REQ e sottotipo PLAYER_IR_REQ_POSE.. A tale richiesta bisogna rispondere con un messaggio di tipo PLAYER_MSGTYPE_RESP_ACK LAYER_MSGTYPE_RESP_ACK. A questo messaggio è stata allegata una struttura dati di tipo player_ir_pose_t contenente le geometrie di tutti i sensori ad infrarosso disponibili (posizione, e direzione). direzione) Per fare ciò è stata utilizzata la funzione Publish() della classe Driver.

Trasmissione delle letture Per le letture sarà necessario allo stesso modo necessario preparare un messaggio con tipo PLAYER_MSGTYPE_DATA e sottotipo

34

I Driver Player

PLAYER_IR_DATA_RANGES player_ir_data_t.

con

allegata

una

struttura

dati

di

tipo

ti deve contenere conten tutte le ultime Questa struttura dati letture dei sensori infrarosso compresi nell’array rappresentato da questo driver. Nel nostro caso ci sarà un unica rilevazione.

Driver MotoriDriver Moto Il driver motori ha lo scopo sia di comandare l’azionamento dei motori sia di leggere le informazioni degli odometri per fornire una stima della posizione del robot. L’interfaccia player che questo driver implementa è la “position2d”. I compiti principali incipali di questo driver saranno di: 1. Leggere i dati odometrici dal modulo RTAI per i motori tramite la FIFO. 2. Fornire una geometria del robot, cioè la sua forma. 3. Regolare tramite la FIFO la velocità dei motori per ottenere velocità assiali as richieste. 4. Fornire la posizione stimata del robot sul piano. Questo uesto driver è stata realizzato solo in parte e quindi non sarà qui discusso.

Lo script di configurazione Per utilizzaree il nostro robot all’interno del programma player sarà necessario creare un script di configurazione che associa associa al robot una serie di driver che ne rappresentano le funzionalità e le relative configurazioni. Nel el nostro caso dovremo definire tre driver: uno per l’array di sensori ad ultrasuoni, uno per l’array di sensori ad infrarosso e, infine, uno per l’odometria e il comando motori.. Il terzo driver, però, purtroppo non è stato completato per mancanza dell’hardware.

35

I Driver Player

#imhotep.cfg driver ( name "2d120xdriver" plugin "lib2d120xdriver" provides ["ir:0"] fifo "/dev/rtf/1" ) driver ( name "srf005driver" plugin "libsrf005driver" provides ["sonar:0"] fifo "/dev/rtf/0" )

36

CONCLUSIONI

Risultati raggiunti Nell’ambito di questo progetto, si è riuscito a ricompilare il kernel del sistema operativo TS-Linux con le estensioni real-time. E’ stato inoltre cross-compilato il framework Player e le librerie richieste. Player, quindi, è ora eseguibile sulla piattaforma ARM. Si son realizzati i moduli per la lettura in real-time dei sensori e per il comando dei motori. Sono stati sviluppati pure i driver Player che fanno uso di questi ultimi per integrare la nostra piattaforma robotica nell’architettura di Player. Unica eccezione per il driver Player per il controllo motori che non è stato terminato per mancanza dell’hardware necessario. Grazie a questi risultati, è ora possibile scrivere una logica di controllo indipendente dalla piattaforma robotica e utilizzabile con questo robot.

Prospettive di sviluppo Lo sviluppo di driver di alto-livello, l’analisi e la progettazione di logiche decisionali, possono considerarsi l’evoluzione naturale di questo lavoro. Tra questi una delle vie più dirette che può essere intrapresa sul robot è l’integrazione dei driver wavefront per aggiungere al robot la capacità di pianificare percorsi a lungo raggio e quindi dargli la capacità di navigazione in un ambiente complesso. In tale ottica, sarà necessario provvedere a fornire al driver un’informazione rispetto alla posizione del robot e una di navigazione locale, che permetta di evitare collisioni e programmare lo spostamento tra punti vicini. Per far ciò sono già disponibili dei driver, e in particolare:

37

Conclusioni

1. Il driver VHF che serve per dare al robot capacità di navigazione locale secondo l’algoritmo Vector Field Histogram Plus di Ulrich e Borenstein. Questo permette al robot di evitare gli ostacoli muovendosi su un percorso programmato (waypoints) 2. Il driver AMCL che è un implementazione dell’algoritmo di localizzazione adattiva monte-carlo e che serve a localizzare la posizione del robot all’interno di una mappa fornita a priori. La localizzazione avviene a partire dai dati dei sensori laser o sonar. Per soddisfare i requisiti dei driver sarebbe sicuramente necessaria l’integrazione di più sensori ad ultrasuoni sulla piattaforma. Un altro cambiamento essenziale è costituito dalla modifica del modulo real-time in modo che provveda alla lettura di più sensori contemporaneamente, senza dover creare un task ed occupare una FIFO per ognuno dei sensori. Inoltre l’implementazione corrente del driver AMCL funziona solamente con scanner laser. Sarebbe consigliabile prendere in esame la possibilità di modificare quest’ultimo in modo che supporti anche le letture di sensori ad ultrasuoni. Questo anche alla luce dei costi elevati che gli scanner laser possono raggiungere.

38

APPENDICI

Redboot Accesso a redboot E’ possibile accedere a redboot tramite l’interruzione dell’esecuzione automatica dello script di avvio tramite terminale seriale inviando una sequenza di escape (CTRL-C) In alternativa, qualora sia noto l’indirizzo IP della scheda ARM, l’accesso può essere effettuato connettendosi alla porta 9000 tramite protocollo telnet via interfaccia ethernet. Il tempo a disposizione per connettersi a RedBoot tramite ethernet è una finestra di pochi istanti che si apre dopo l’accensione del sistema.

Caricamento del Kernel tramite I/O Tramite web server: load -v -r -b 0x00218000 -m http -h

Da flash: fis load <nome partizione> -b 0x00218000

Da TFTP load –b 0x00218000 –h 192.168.0.1 vmlinuxNFS

Scrittura/Cancellazione del kernel nella flash Per visualizzare la lista delle partizioni della flash si usa il comando: fis list

Per cancellare una partizione si usa il comando:

39

Appendici

fis delete <nome partizione>

Per creare una nuova partizione (dopo averla caricata in memoria) fis create –b -l <nome partizione>

Esecuzione un kernel linux Dopo aver caricato in memoria un kernel con il comando load o fis load exec –c “parametri del kernel”

Configurazione della scheda, e del script di avvio Per visualizzare la configurazione corrente: fconfig –l

Per modificare la configurazione corrente: fconfig

In particolare per fare il boot da flash si userà il seguente script: fis load exec –c”ttyAM0,115200 ip= root=/dev/mtdblock/1”

per fare il boot da nfs si usarà invece: fis load exec –c”ttyAM0,115200 ip= nfsroot=:<nome condivisione>”

Dove • • •

40

è l’ip che si vuol dare all’interfaccia ethernet della scheda è l’ip del server che fa da host al servizio nfs <nome condivisione> è il nome della condivisione nfs contenente il root file-system da usare

Appendici

Setup e configurazione di un server NFS Per configurare un server NFS su Linux è essenziale editare il file /etc/exports e avviare i servizi portmap e nfs. Il file /etc/exports non è altro che un elenco dove si specifica quali risorse condividere e con quali modalità (ad esempio readonly o read-write), e con quali credenziali i client potranno accedere a tale risorse (ad esempio network mask etc). Per modificare tale file occorre essere utente root. Di seguito è riportato un esempio del file: #La directory /export e tutto il suo contenuto è esportato via NFS in modalità readonly(ro) e ai soli client con un ip #di network uguale a 10.0.0.0/24 /export 10.0.0.0/255.255.255.0(ro) #La directory /home/kernel e tutto il suo contenuto è esportato via NFS in moadalità read-write(rw) e ai soli client #con un ip di network uguale a 10.0.0.0/24 /home/kernel 10.0.0.0/255.255.255.0(rw)

Una volta impostato correttamente il file /etc/exports, si può avviare il servizio avviando i demoni RPC e NFS: /etc/rc.d/init.d/portmap start /etc/rc.d/init.d/nfs start

Nel caso in cui il servizio sia già attivo occorre semplicemente eseguire il seguente comando per fare in modo che il file /etc/exports venga riletto e che si aggiornino le tabelle interne di appoggio al servizio NFS: exportfs –a

Una configurazione ottimale per un file-system può essere: /home/damiano/armroot 192.168.0.0/255.255.255.0(rw,no_root_squas h,insecure_locks)

Si deve poi ricordare di modificare il file /etc/fstab della partizione “ARM” in modo appropriato, aggiungendo : nfs exec,dev,suid 1 1

e commentando:

41

Appendici

/dev/hda1 / ext2 defaults 1 1

Yaffs File-System Il driver Yaffs per la gestione del file-system su flash durante il boot di default troverà 3 partizioni. La prima contenente il bootroom, la seconda il file-system del sistema e la terza contenente il kernel del sistema operativo e il redboot Più o meno il log di avvio del kernel si presenterà così: Searching for NAND flash... NAND device: Manufacturer ID: 0xec, Chip ID: 0x75 (Samsung NAND 32MiB 3,3V 8-bit) Scanning device for bad blocks Using static partition definition Creating 3 MTD partitions on "NAND 32MiB 3,3V 8bit": 0x00000000-0x00004000 : "TS-BOOTROM" 0x00004000-0x01d04000 : "Linux" 0x01d04000-0x02000000 : "RedBoot"

Per visualizzare il log si può usare il comando dmesg

Ripristino del file-system preinstallato Per ripristinare o installare un nuovo file-system, bisogna prima cancellare il vecchio completamente. Per fare ciò è consigliabile eseguire il kernel su un filesystem esterno montato magari con nfs ed eseguire il comando eraseall /dev/mtd/1

oppure mount /dev/mtdblock/1 /mnt cd /mnt rm –fr

NOTA IMPORTANTE: IN QUESTO PARAGRAFO si suppone che la seconda partizione sia quella del file-system. IL NUMERO di “/dev/mtd/1” e “/dev/mtdblock/1” va sostituito con quello opportuno della partizione “linux” (la numerazione parte da 0) A questo punto si può estrarre la nuova immagine montando la partizione flash, qualora non sia già stato fatto.

42

Appendici

mount /dev/mtdblock/1 /mnt (se non è stato già fatto) tar xzvf -C /mnt umount /mnt

Si può quindi riavviare la scheda con il comando shutdown -r now

43

RINGRAZIAMENTI

Vorrei ringraziare, in primis, i miei genitori che mi han accompagnato con una pazienza senza limite fino a questo traguardo. Senza di voi non sarei arrivato fino a qui. Ringrazio il mio relatore, il prof. Massimiliano Nolich, che è stato sempre disponibilissimo nei miei confronti , aiutandomi ogni qualvolta possibile e dandomi la più piena libertà nell’organizzare e sviluppare il progetto. Un grazie anche a tutti i frequentatori della mailing-list del progetto Player-Stage, e in particolare al signor Paul Osmialowski, per l’aiuto e la disponibilità che mi han dato e l’entusiasmo con cui mi han sempre risposto. Ringrazio anche l’amico e collega, Lorenzo Dal Col per il supporto che mi ha dato nella compilazione del kernel RTAI e Roberto Furlani per la l’aiuto nella revisione della tesi.

45

BIBLIOGRAFIA

Articoli e manuali: • • • • • •

La guida completa C++ - Herbert Schildt. – 2nd Edition - McGraw-Hill, 1999 Building Embedded Linux Sistem - Karim Yaghmour - 2nd Edition – O’Reilly, 2008 Getting started with ts-linux – Technologic Systems, 2006 Linux for ARM on TS-7000 User's Guide – Technologic Systems, 2006 TS-7250 Hardware Manual – Technologic Systems, 2006 TS ARM Linux Developer's Manual – Technologic Systems, 2004

Siti internet di riferimento: • • •

Player - Player User Guide http://playerstage.sourceforge.net/ RTAI https://www.rtai.org/ Technologic System http://www.embeddedarm.com/index.php

Documentazione tecnica: • • • • •

SRF05 - Ultra-Sonic Ranger http://www.robot-electronics.co.uk/htm/srf05tech.htm Sharp - GP2D120X http://www.sharpsma.com/Page.aspx/americas/en/part/GP2D120/ Low Current Motor Driver https://www.zagrosrobotics.com/files/wirz203.pdf Agilent Technologies – Optical Encoders http://www.zagrosrobotics.com/files/heds55xx.pdf Cirrus Logic EP9302 http://www.cirrus.com/en/products/pro/detail/P1066.html

47

Appendici



• • •





48

TS-7250 ARM Single Board Computer http://www.embeddedarm.com/products/board-detail.php?product=TS7250 Linux for ARM on TS-7000 Series SBC's http://www.embeddedarm.com/software/software-arm-linux.php Real Time Application Interface for TS-7000 series SBC's http://www.embeddedarm.com/software/arm-linux-24-rtai.php Player Sonar-Array Interface http://playerstage.sourceforge.net/doc/Player2.1.0/player/group__interface__sonar.html Player Infrared-Array Interface http://playerstage.sourceforge.net/doc/Player2.1.0/player/group__interface__ir.html Player Position2d Interface http://playerstage.sourceforge.net/doc/Player2.1.0/player/group__interface__position2d.html

Related Documents

Tesix
April 2020 2
Presentazione Tesix
April 2020 2

More Documents from "Damiano"

Tesix
April 2020 2
Presentazione Tesix
April 2020 2
Activos.docx
October 2019 4
Oroi_domisis_5_10
October 2019 3
Odigies1
October 2019 2