Costruzione e Sviluppo in ambiente STNucleo di un Quadricottero con Stabilizzazione dell’Assetto

80
Università degli Studi di Trieste Dipartimento di Ingegneria e Architettura Corso di Studi in Ingegneria dell’Informazione Costruzione e Sviluppo in ambiente STNucleo di un Quadricottero con Stabilizzazione dell’Assetto Tesi di Laurea Triennale Candidato: Simone Fini Relatore: Prof. Ing. Stefano Marsi Correlatore: Prof. Ing. Sergio Carrato Anno Accademico 2015-2016

Transcript of Costruzione e Sviluppo in ambiente STNucleo di un Quadricottero con Stabilizzazione dell’Assetto

Università degli Studi di Trieste Dipartimento di Ingegneria e Architettura

Corso di Studi in Ingegneria dell’Informazione

Costruzione e Sviluppo in

ambiente STNucleo di un

Quadricottero con Stabilizzazione

dell’Assetto

Tesi di Laurea Triennale

Candidato:

Simone Fini

Relatore:

Prof. Ing. Stefano Marsi

Correlatore:

Prof. Ing. Sergio Carrato

Anno Accademico 2015-2016

Desidero ringraziare il mio relatore,

il Professor Stefano Marsi,

per la pazienza, la fiducia,

l’esempio di professionalità

e di amore verso la professione

che mi ha dato.

Desidero inoltre ringraziare il mio correlatore,

il Professor Sergio Carrato,

sempre disponibile e pronto a dare una mano

a chiunque ne abbia bisogno.

Indice

L’Hardware ............................................................................................................ 3

1.1 La Scheda Programmabile ..................................................................... 3

1.1.1 Caratteristiche Generali ............................................................. 3

1.1.2 L’Ambiente di Sviluppo “mbed” .................................................. 8

1.2 I Motori Brushless ................................................................................ 11

1.3 Gli E.S.C. .............................................................................................. 15

1.3.1 Introduzione al dispositivo ....................................................... 15

1.3.2 Programmazione degli E.S.C. in Dotazione ............................. 17

1.3.3 Codice Utilizzato per la Programmazione degli E.S.C. ........... 19

1.3.4 Determinazione delle Caratteristiche Fisiche dei Motori ....... 20

1.4 Il Ricevitore ad Infrarossi (IR) ............................................................. 24

1.4.1 Funzionamento della Trasmissione ......................................... 24

1.4.2 Il Protocollo NEC ...................................................................... 26

1.5 MPU6050 .............................................................................................. 29

1.5.1 Il Sensore ................................................................................... 29

1.5.2 La FIFO ..................................................................................... 31

1.5.3 Giroscopio ed Accelerometro ..................................................... 31

1.5.4 Digital Motion Processor........................................................... 33

1.5.5 Il Clocking ................................................................................. 34

I Filtri Software ................................................................................................... 35

2.1 Il DMP ed i Quaternioni ....................................................................... 37

2.2 Il Filtro Complementare ...................................................................... 39

2.2.1 Implementazione Software del Filtro Complementare ........... 40

2.3 Il Filtro di Kalman ............................................................................... 43

2.3.1 Trattazione Matematica del Filtro ........................................... 43

2.3.2 Implementazione Software del Filtro di Kalman: la Libreria

“kalman” ............................................................................................. 45

2.4 Confronto Sperimentale tra i Due Filtri .............................................. 49

2.4.1 Simulazione 0°-90°-0° ............................................................... 49

2.4.2 Simulazione con Piattaforma e Microcontrollore Arduino ...... 51

L’Applicazione Android “Drone” .......................................................................... 54

3.1 Caratteristiche Generali di un’App Android ....................................... 55

3.2 Android Manifest .................................................................................. 56

3.3 Implementazione della Grafica tramite Linguaggio XML .................. 58

3.3.1 Layout “Intro” ............................................................................ 59

3.3.2 Layout “Main” ........................................................................... 62

3.4 Implementazione del Codice Esecutivo Java ...................................... 65

3.4.1 Activity “Intro” .......................................................................... 66

3.4.2 Activity “MainActivity” ............................................................. 68

Sitografia e Bibliografia ....................................................................................... 71

1

Introduzione

Con questo documento si vuole descrivere l’intero processo di assemblaggio,

programmazione ed interfacciamento con l’esterno di un quadricottero, oggetto

di studio del candidato. Si vuol rendere noto che l’intero lavoro consta di due

parti distinte, che quindi dovrebbero essere lette assieme per una comprensione

globale del progetto.

Dapprima verrà descritta la componente hardware del sistema, con particolare

attenzione al funzionamento degli elementi fondamentali del drone (scheda

programmabile, electronic speed controls, motori, sensore infrarosso, giroscopio

ed accelerometro).

In secondo luogo verrà posta attenzione alla parte software, con la descrizione

dettagliata del codice C++/Java di programmazione.

Siccome però “elettronica” ed “informatica” non sono più due settori tecnologici

nettamente separati, ma parte di quell’unica realtà delle tecnologie IC, in questo

elaborato non sarà presente una chiara distinzione tra le due parti, ma esse

formeranno una sola traccia espositiva, agganciandosi e completandosi a

vicenda.

Figura 1: il drone

2

3

Capitolo 1

L’Hardware

1.1 La Scheda Programmabile

Un microcontrollore è un sistema elettronico programmabile in grado di

acquisire e gestire opportunamente dati provenienti da sorgenti hardware

esterne.

È un sistema d’elaborazione completo, che può essere suddiviso in varie

componenti, ognuna delle quali ha un compito ben preciso per il funzionamento

dell’apparato nel suo complesso:

CPU o microprocessore, ovvero il “cervello” che gestisce tutti i processi

eseguiti;

ROM, memoria in cui viene salvato il programma creato;

RAM, memoria che viene utilizzata per la gestione delle variabili

temporanee;

Timer, circuito oscillatore che definisce il clock ed i vari intervalli

temporali;

Porte I/O, che permettono la comunicazione con altri dispositivi [1].

1.1.1 Caratteristiche Generali

Le schede STM32 appartengono alla famiglia dei microcontrollori di

STMicroelectronics, azienda franco-italiana con sede a Ginevra, leader nel

settore di produzione di componenti elettronici a semiconduttore. Sono

particolarmente indicate per applicazioni/progetti sia a scopo d’insegnamento,

sia in ambito industriale, data la enorme offerta in termini di prestazioni e

prezzi.

4

In particolare il modello montato sul drone è una STM32L053R8, le cui

caratteristiche principali sono riportate in seguito:

CPU ARM 32-bit Cortex-M0+;

32 MHz di frequenza massima della CPU;

Bassa tensione di funzionamento (dagli 1.8V fino ai 3.6V);

64 KB di memoria Flash;

8 KB di memoria RAM [2].

Figura 2: schema a blocchi di STM32L053R8

Come visibile dall’immagine riportata sopra, la scheda può essere comodamente

divisa in due parti: quella contenente il microprocessore, che ovviamente dovrà

sempre essere presente sull’applicativo, e quella relativa all’ST-Link (un

semplice programmatore/debugger). In questo modo, da un lato si è in grado di

ridurre l’ingombro, dall’altro si rende il codice di programmazione protetto ed

immodificabile.

Dal punto di vista della connettività, la STM32L053R8 è un dispositivo che offre

la maggior parte delle funzionalità richieste normalmente; su di essa infatti si

trovano:

1 porta USB 2.0 ad alta velocità, utilizzabile sia come seriale che come

5

entrata per l’alimentazione esterna;

1 LED tricolore (LD1) che fornisce informazioni sullo stato di

comunicazione dell’ST-Link:

o lampeggia lentamente di rosso prima che l’USB sia inizializzata,

rimane acceso il rosso dopo;

o lampeggia rosso e verde durante la comunicazione PC-scheda;

o rimane acceso il verde quando la comunicazione è avvenuta con

successo;

o rimane acceso l’arancione se la comunicazione fallisce;

1 LED (LD2) utilizzabile dall’utente;

1 LED (LD3) utilizzato per la verifica dello stato dell’alimentazione;

1 pulsante di reset ed 1 utilizzabile dall’utente (USER_BUTTON);

2 tipologie di pin: quelli compatibili con Arduino (utilizzati nel caso

particolare dell’interfacciamento della scheda con i vari sensori) ed i

cosiddetti pin Morpho, grazie ai quali si ha diretto accesso agli I/O del

microprocessore.

Figura 3: pin Morpho

6

Figura 4: pin Arduino compatibili

Di seguito è riportata una veloce spiegazione delle funzionalità dei pin Arduino

compatibili:

+3v3: fornisce una tensione di 3.3V;

+5v: fornisce una tensione di 5V;

GND: ground (riferimento);

VIN: pin di alimentazione esterna della scheda. E’ possibile applicare una

tensione compresa tra i 7V ed i 12V ad una corrente massima di 800mA;

An: pin per ingressi analogici;

Dn: pin per ingressi digitali; in particolare…

o D3,D4,D5,D6,D9,D11,D12,D13 possono essere usati come PWM;

o D14 e D15 (o D10 o D6) possono essere utilizzati per implementare

il protocollo di comunicazione I2C;

o D0 e D1 sono utilizzati solamente come pin per la comunicazione

seriale in alternativa o parallelamente alla porta USB;

7

Infine qualche parola va spesa per le modalità di alimentazione; come già

riportato in precedenza, la scheda può essere alimentata sia tramite USB sia

tramite pin. Per impostare una delle due modalità e per fare in modo che la

board non subisca danni (a volte critici) dovuti ad eventuali sovratensionamenti,

si deve modificare leggermente l’architettura della circuiteria, mediante dei

jumpers. Questi sono dei semplici ponticelli metallici mobili, utilizzati per

cortocircuitare dei contatti in modo da attivare o disattivare funzioni diverse del

circuito [3].

L’alimentazione di default è quella via USB, ma se il PC non è in grado di

erogare una corrente di 300mA il microprocessore non potrà funzionare; allora

è possibile, con il jumper JP1 chiuso, richiedere allo stesso calcolatore una

corrente di 100mA.

Se in alternativa si vuole alimentare la scheda tramite pin VIN è necessario

spostare il jumper JP5 in posizione E5V, lasciando aperto JP1 e connettendo

l’USB solo dopo l’accensione del micro per poter eseguire la programmazione [4].

Fonte Ingresso Tensione Corrente

Massima

JP1 JP5 ST-LINK

PC con USB

che può erogare

300mA

USB 5V 300mA Aperto U5V Non

rimosso

PC con USB

che non può

erogare 300mA

USB 5V 100mA Chiuso U5V Non

rimosso

Carica batterie USB 5V Non

specificato

Chiuso U5V Non

rimosso

Alimentazione

esterna

VIN 7÷12V 800mA Aperto E5V Possibile

rimuoverlo

Alimentazione

esterna

E5V 5V 500mA Aperto E5V Possibile

rimuoverlo

Alimentazione

esterna

+3V3 3.3V Non

specificato

Indifferente Indifferente Rimosso

Tabella 1: configurazione dei jumpers in base alla sorgente di alimentazione

8

1.1.2 L’Ambiente di Sviluppo “mbed”

Mbed1 è una piattaforma online nata per semplificare la vita ai programmatori:

infatti questo ambiente di sviluppo permette di scrivere codice di

programmazione (per le schede programmabili che supportano questo servizio)

e salvarlo all’interno di un cloud dedicato, in modo tale da poter lavorare in

qualsiasi momento, su qualsiasi calcolatore ed in qualsiasi luogo, a patto

ovviamente di essere in possesso di una connessione Internet.

La forza di questo ambiente di sviluppo però è la libreria “mbed.h”, creata dagli

sviluppatori ufficiali e contenente le classi principali e, in linea di massima, più

utilizzate dai consumatori (qui di seguito non vengono riportate tutte le

categorie di oggetti con i relativi metodi, ma soltanto quelle utilizzate per la

programmazione del drone):

AnalogIn, per la gestione dei segnali analogici che arrivano ai pin della

scheda

o AnalogIn (PinName pin), il costruttore che ha come parametro

un pin;

o float read(), funzione per leggere una tensione in ingresso e lo

rappresentarla attraverso un valore di tipo float compreso tra 0.0

e 1.0.

AnalogOut, per i segnali analogici inviati dalla scheda

o AnalogOut (PinName pin), analogo al costruttore di AnalogIn;

o void write(float value), setta una tensione in uscita fornita

come parametro.

DigitalIn, per gestire i segnali digitali in ingresso

o DigitalIn (PinName pin), costruttore;

o int read(), funzione che legge una tensione in ingresso;

quest’ultima viene rappresentata da uno 0 o da un 1.

DigitalOut, per gestire i segnali digitali in uscita

1 https://www.mbed.com/en/

9

o DigitalOut (PinName pin), costruttore;

o void write(int value), funzione atta ad impostare l’uscita a 0 o

1.

InterruptIn, per la gestione di un interrupt, ovvero un evento che

consente l’interruzione di un processo qualora si verifichi un determinato

evento definito dall’utente

o InterruptIn (PinName pin), costruttore;

o void rise(Callback <void()> function), metodo che richiama

una funzione durante il fronte di salita di un determinato segnale

in ingresso, ad esempio quando un interruttore, inserito in un

circuito con resistenza di pull-down, viene chiuso e la tensione

conseguentemente si alza;

o void fall(Callback <void> function), simile al precedente, ma

che chiama la funzione durante il fronte di discesa, ad esempio

quando un interruttore, collegato con una resistenza di pull-down,

viene aperto e la tensione si abbassa.

PwmOut, per inviare da un pin digitale un segnale PWM

o PwmOut (PinName pin), costruttore;

o void period_us(int us), imposta il periodo in microsecondi

dell’onda mantenendo inalterata la larghezza dell’impulso. Sono

presenti anche le versioni atte a fornire il parametro

rispettivamente in secondi e millisecondi;

o void pulsewidth_us(int us), setta la larghezza dell’impulso in

microsecondi mantenendo inalterato il periodo. Come per il metodo

precedente esistono le versioni in secondi e millisecondi.

Serial, grazie alla quale si riesce a configurare la scheda programmabile

per la comunicazione seriale di tipo RS232 con altri dispositivi

o Serial (PinName tx, PinName rx, int baud), costruttore che

crea una porta seriale connessa ai pin specifici di trasmissione e

ricezione, con un determinato baud, ovvero il numero di dati che

viene trasmesso in un secondo.

10

Timer, che inizializza un semplice conteggio temporale

o void start(), fa partire il timer;

o void stop(), lo ferma;

o void reset(), resetta il conteggio;

o int read_us(), ritorna il periodo di tempo passato in

microsecondi.

I2C, libreria che permette di implementare l’omonimo protocollo. Questa

verrà presentata nella seconda parte della tesi, con un maggior grado di

dettaglio e precisione.

11

1.2 I Motori Brushless

Figura 5: motori usati per il drone con relative eliche

I motori utilizzati per sostenere il drone durante la fase di volo richiedono

particolari caratteristiche; devono infatti:

essere poco ingombranti, ma allo stesso tempo erogare molta potenza;

lavorare con un rendimento molto alto, per fare in modo di massimizzare

il periodo di utilizzo del sistema;

essere controllabili con un grado di precisione elevata sia in velocità che

in accelerazione.

Per soddisfare tali requisiti si può far ricorso ai motori sincroni di tipo brushless.

Una macchina sincrona, identificata la maggior parte delle volte attraverso

l’acronimo MS, è una macchina elettrica rotante, funzionante in corrente

alternata.

Il funzionamento della maggior parte di queste macchine si basa sul principio

del campo magnetico rotante: per ottenerlo, occorre soddisfare le seguenti due

condizioni:

tre avvolgimenti (bobine) fissi nello spazio uguali tra loro, con lo stesso

numero di spire N e disposti con gli assi a 120° l’uno dall’altro;

12

all’interno di questi tre avvolgimenti devono circolare tre correnti AC

isofrequenziali, con lo stesso valore massimo IM e sfasate tra loro di 120°.

{

𝑖𝑎 = 𝐼𝑀𝑐𝑜𝑠(𝜔𝑡)

𝑖𝑏 = 𝐼𝑀𝑐𝑜𝑠 (𝜔𝑡 +2𝜋

3)

𝑖𝑐 = 𝐼𝑀𝑐𝑜𝑠 (𝜔𝑡 +4𝜋

3)

Ogni avvolgimento percorso da corrente quindi sostiene una forza

elettromotrice, sinusoidale e con lo stesso valore massimo, diretta secondo l’asse

dell’avvolgimento stesso. Utilizzando quindi la regola del parallelogramma per

la somma di vettori, si determina che la forza elettromotrice risultante ha, in

ogni istante, lo stesso valore, pari ad 1.5 volte quello massimo della f.e.m. di una

singola fase, e ruota nello spazio con velocità angolare costante.

La legge di Hopkinson stabilisce che “una forza elettromotrice produce un flusso

di induzione magnetica Φ, che è proporzionale alla f.e.m. stessa”, ed è

esprimibile attraverso la seguente relazione:

Φ = |𝑓. 𝑒.𝑚. |

𝑟𝑖𝑙𝑢𝑡𝑡𝑎𝑛𝑧𝑎

Il campo magnetico B, infine, supponendolo omogeneo e perpendicolare alla

superficie, è definito come il rapporto tra il flusso di induzione magnetica e la

superficie stessa:

Φ = 𝐵 ∙ 𝑆 = 𝐵𝑆𝑐𝑜𝑠𝛼

Pertanto i tre avvolgimenti producono un campo magnetico rotante, equivalente

a quello prodotto da un magnete posto in rotazione da un sistema meccanico.

La MS è denominata sincrona poiché la sua velocità di rotazione è la stessa del

campo rotante al suo interno, ovvero

𝑣0 =120𝑓

𝑝

con p=numero delle polarità magnetiche della macchina, f=frequenza della

13

corrente AC [5] [6].

È costituita da due strutture magnetiche differenti:

una, il rotore, su cui sono presenti diversi poli magnetici di polarità

alterna;

l’altra, chiamata statore, alloggia un avvolgimento, percorso da correnti,

in cui vengono indotte le forze elettromotrici.

Nel caso dei motori brushless, i poli sono generati attraverso la disposizione di

magneti permanenti sul rotore (o internamente o esternamente ad esso); in

questo modo quindi, il rotore andrà ad interagire direttamente con il campo

magnetico rotante, creando quindi una coppia motrice:

𝑇 = 𝛷𝑆𝛷𝑅 sin 𝜃

dove ΦS è l’intensità del flusso magnetico dello statore, ΦR è l’intensità del flusso

magnetico del rotore, θ l’angolo compreso tra i due vettori che li rappresentano.

Figura 6: posizione relativa dei campi magnetici

La coppia massima si ha quando i due flussi sono ortogonali, mentre quando essi

14

sono paralleli è nulla e non avviene alcun tipo di rotazione; risulta quindi

evidente come il corretto funzionamento di un motore di questo tipo è

strettamente legato alla conoscenza esatta della posizione del flusso del rotore

[7].

Per questo motivo, esistono due diverse tipologie di motori brushless:

i sensored, ovvero dotati di tre speciali sensori ad effetto Hall, incorporati

nello statore, che generano un segnale nel momento in cui i poli magnetici

del rotore li oltrepassano. Questo segnale può essere alto (per un polo

positivo) o basso (per un polo negativo); ad ogni bobina del motore è

collegata una coppia di sensori, ed in base alla combinazione della

tensione prodotta da questi il controllore (il cui funzionamento viene

descritto nel capitolo successivo) determina la posizione esatta dei poli

magnetici del rotore e distribuisce le correnti statoriche in modo che il

flusso del campo magnetico rotante sia da subito in anticipo, rispetto a

quello del campo magnetico rotorico, di un angolo tale da permettere alla

coppia motrice di attivare la rotazione. In questo modo si prevengono i

ritardi di risposta del motore [8].

i sensorless (montati2 sul drone), motori privi dei sensori sopra citati, che

non interagiscono in alcun modo con i dispositivi di controllo. Per questo

motivo, il campo magnetico rotante potrebbe trovarsi inizialmente in

posizione tale da produrre una coppia motrice molto bassa, o addirittura

nulla, che non permette la rotazione istantanea del rotore.

2 http://www.rhydolabz.com/documents/26/BLDC_A2212_13T.pdf

15

1.3 Gli E.S.C.

Figura 7: gli e.s.c interfacciati con la scheda

1.3.1 Introduzione al dispositivo

Gli e.s.c., acronimo di Electronic Speed Control, sono dei complicati dispositivi

elettronici che hanno il compito di regolare la velocità di rotazione di un motore

di tipo brushless, collegato attraverso i tre morsetti (in questo caso blu) per la

corrente trifase; sono in grado quindi, attraverso l’utilizzo di un microprocessore

interno, di convertire un segnale di tipo PWM in ingresso in un una corrente

trifase (il cui amperaggio massimo è indicato sulla guaina che riveste il circuito)

proporzionale al duty cycle d’entrata, che andrà a variare il numero di giri al

minuto del motore brushless.

La parte fondamentale per quanto riguarda gli e.s.c. risiede però nella loro

implementazione; ogni tipologia, marca o modello è programmabile. Per inciso

esistono tre diverse modalità di programmazione: i più costosi vengono spesso

forniti insieme ad un programma Windows/OS compatibile, e i parametri

possono essere impostati direttamente da computer. Ci sono poi gli e.s.c. dotati

16

di una particolare tastiera ed infine, i più semplici ma anche i più diffusi

(utilizzati anche per la costruzione del drone), che presentano una particolare

sequenza di programmazione che si interfaccia verso il mondo esterno

attraverso una serie di suoni emessi dai motori collegati.

Di seguito sono riportate le diverse funzioni che presentano gli e.s.c. in

dotazione:

modalità break: imposta la possibilità del motore di effettuare brusche

interruzioni della rotazione, ovvero il motore può fermare

immediatamente la sua corsa quando lo si porta a velocità zero, oppure

esso può proseguire per inerzia fino a raggiungere asintoticamente la

velocità richiesta, qualsiasi essa sia. I possibili valori sono Enabled o

Disabled;

tipo di batteria: determina che tipo di batteria è collegata ai morsetti di

alimentazione, se Li-xx (al litio) o Ni-xx (al nichel);

modalità di protezione alla bassa tensione (low voltage protection mode):

definisce se, allo spegnimento, ridurre gradualmente (Soft Cut-Off) o

immediatamente (Cut-off) la potenza erogata;

modalità di protezione all’abbassamento della tensione della batteria (low

voltage protection threshold): determina la tensione di soglia per il

funzionamento dei motori. I valori impostabili sono Low, Medium e High

o se la batteria è al litio i valori di tensione low/medium/hard sono

rispettivamente 2.6V/2.85V/3.1V moltiplicato per il numero delle

celle, che viene calcolato automaticamente;

o se la batteria è al nichel, i valori sono invece 0%/45%/60% del

voltaggio iniziale.

modalità di startup: imposta la rapidità con cui i motori, da fermi,

raggiungono il numero di giri impostato. Il valore Normal è preferito per

i droni o tutti gli aerei ad ala fissa, mentre Soft e Super-Soft sono scelti

per gli elicotteri;

timing: determina l’allungo del motore (ovvero la velocità massima che

esso riesce a raggiungere). Di default il parametro è Low, ma può essere

17

impostato anche su Medium o High, a discapito però di un eccessivo

surriscaldamento del sistema [9].

1.3.2 Programmazione degli E.S.C. in Dotazione3

Come si fa a programmare questi dispositivi ascoltando soltanto degli effetti

acustici?

In realtà, ad ogni sequenza di suoni corrisponde una diversa funzione; perciò

innanzitutto si deve entrare in modalità programmazione, impostando il

throttle del segnale PWM al massimo (ovvero un valore del duty cycle che, come

verrà descritto in seguito, è definito dall’utente), accendendo il sistema ed

aspettando, con questa impostazione, all’incirca sette secondi, dopo i quali verrà

emesso un suono speciale.

Successivamente per poter scegliere il parametro che si vuole andare a

modificare il sistema provvederà ad emettere 8 suoni in sequenza:

Suono Modalità

* Modalità break

** Tipo di batteria

*** Modalità di protezione alla bassa tensione

**** Modalità di protezione all’abbassamento della tensione della

batteria

_ Modalità di startup

_* Timing

_** Impostazione di tutti i parametri ai valori di default

__ Uscita dalla modalità di programmazione

Tabella 2: corrispondenza tra suoni e funzioni. Con * si intende suono corto, con _

suono lungo

3 http://www.sarkanyellato.hu/wp-content/uploads/2011/10/RC-Timer-10.18.30.40A-ESC-Instruction.pdf

18

In corrispondenza del suono che interessa si deve settare il throttle al minimo

entro tre secondi dallo stesso, in modo tale da accedere a tutte le varie possibilità

di valore per quella determinata funzione che, anche in questo caso, verranno

identificate attraverso dei suoni:

Modalità * ** ***

Brake Disabled Enabled

Tipo di batteria Li-xx Ni-xx

Modalità di protezione alla bassa tensione Soft Cut-

Off

Cut-Off

Modalità di protezione all’abbassamento

della tensione della batteria

Low Medium High

Modalità di startup Normal Soft Super-

Soft

Timing Low Medium High

Tabella 3: corrispondenza tra suoni e valori possibili per ogni modalità. Con * si

intende suono corto

Per scegliere un determinato valore, si setta il valore del throttle al massimo,

fino a che non viene emesso un tono speciale; in questo modo si ha una conferma

che il valore scelto è stato settato.

A questo punto, mantenendo il throttle così com’è si viene riportati nel menu

principale, e si possono andare a modificare altre modalità; se invece si porta il

throttle a valore minimo, si esce dalla modalità di programmazione e gli e.s.c.

saranno pronti a comandare i motori.

Prima di fare tutto ciò però, siccome il controllo della programmazione avviene

essenzialmente alternando il valore del throttle da massimo a minimo e

viceversa, si devono impostare questi due valori, o per meglio dire, fornire al

microprocessore il full scale range del segnale di comando. Per fare ciò si deve

impostare il throttle al valore che si vuole memorizzare come massimo,

accendere gli e.s.c. ed aspettare circa due secondi, dopo i quali verrà emesso un

doppio suono corto (**), che sarà la conferma dell’avvenuta registrazione. Fatto

ciò si andrà a abbassare il livello d’ingresso, in modo da salvare il valore minimo;

in questo caso però prima verranno emessi una serie di suoni corti (*) in base

19

alla tipologia di batteria che alimenta il sistema, poi un suono lungo (_) che

avverte l’utilizzatore che il range di valori è stato correttamente settato.

1.3.3 Codice Utilizzato per la Programmazione degli E.S.C.

Per comodità quindi si è sviluppato un semplice programma “universale”, in

modo tale da poter sia settare i valori massimi che minimi del throttle e che

consenta inoltre di andare a scorrere tutti i menù degli e.s.c. senza dover

modificare nulla, né all’interno del codice principale di funzionamento del drone

né a livello di hardware.

Come prima cosa si imposta il segnale PWM a livello logico uno, e fino a che il

pin D2 collegato all’e.s.c. non riceve un impulso che implichi l’accensione del

sistema, si aspetta, in modo tale da essere sicuri che il primo segnale che verrà

mandato all’e.s.c. sia alto.

20

A questo punto vi è la presenza di un interrupt, che fa in modo (agganciando il

segnale alla funzione invert) di cambiare il valore della variabile state ogni

qualvolta venga premuto lo user button della scheda. Infine si entra in un ciclo

infinito, in cui in base al valore booleano si imposta il PWM alto o basso.

In questo modo, premendo semplicemente un bottone si è in grado di alternare

i valori del throttle senza passare per stati intermedi, che potrebbero portare a

degli errori nelle impostazioni di configurazione degli e.s.c. senza accorgersene.

1.3.4 Determinazione delle Caratteristiche Fisiche dei

Motori

Una volta accertato il corretto comportamento dei dispositivi di controllo si sono

determinate le varie proprietà dei motori, come la spinta ed il consumo elettrico,

per ogni valore del throttle compreso tra 0.1 e 0.9, in modo da utilizzarli nella

maniera più corretta possibile (se per esempio si andasse a fornire un

amperaggio troppo basso rispetto alla richiesta, non ci sarebbe sufficiente

numero di giri e quindi propulsione).

Figura 8: misurazione della spinta del motore

21

Per questo test sono stati utilizzati degli strumenti molto semplici, quali:

una bilancia da cucina con risoluzione pari ad 1g (non elevata in un contesto

assoluto, ma più che sufficiente per la misurazione in questione);

tre generatori di tensione/corrente da 30V/6A ciascuno;

un unico motore montato al centro del drone per eliminare, in maniera

semplice, gli errori dovuti al disequilibrio del sistema, nel caso in cui fosse

stato appoggiato al bilancino soltanto un braccio.

Pwm Ampere

0.0 0.0

0.1 0.43

0.2 0.97

0.3 1.63

0.4 2.6

0.5 3.72

0.6 4.88

0.7 6.37

0.8 9.1

0.9 10.8

Tabella 4: ampere assorbiti dal motore

Grafico 1: grafico degli ampere assorbiti da un singolo motore

0

2

4

6

8

10

12

0,0 0,1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9

PWM values

Ampere absorbed by a single Motor

Ampere

22

Come è visibile dal grafico sopra riportato, l’andamento della curva di

amperaggio non è lineare, ma piuttosto esponenziale; per tale motivo, se tutti e

quattro i motori fossero fatti funzionare ad una velocità moderata (supponendo

throttle pari a 0.3), basterebbe una batteria in grado di erogare 8A, mentre se

gli stessi si volessero utilizzare ad un numero di giri massimale non

basterebbero 40A.

Pwm Test1 Test2 Test3 Test4 Test5 Avg Peak Var

0.0 0.0g 0.0g 0.0g 0.0g 0.0g 0.0g 0.0g 0.0

0.1 20g 23g 22g 19g 21g 21g 26g 2.5

0.2 60g 65g 60g 56g 58g 60g 65g 11.2

0.3 100g 106g 103g 95g 101g 101g 106g 16.5

0.4 150g 156g 150g 140g 150g 149g 154g 33.2

0.5 200g 202g 200g 190g 200g 198g 203g 22.8

0.6 230g 250g 247g 230g 247g 241g 251g 98.7

0.7 270g 280g 290g 280g 283g 281g 291g 51.8

0.8 320g 320g 330g 325g 327g 324g 334g 19.3

0.9 350g 345g 350g 350g 350g 349g 359g 5.0

Tabella 5: spinte del motore, valore medio e relativa varianza, picco medio

Grafico 2: grafico della media di spinta e del picco

0

50

100

150

200

250

300

350

400

0,0 0,1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9

PWM values

Thurst and Peak of a Single Motor

Peak Thurst

23

Per quanto riguarda invece la spinta si sono fatte cinque differenti misurazioni

per ogni valore del PWM e ne è stata poi calcolata la media.

Si è notato che il comportamento del singolo motore in questo caso ha uno

sviluppo pressoché lineare, tranne che per un periodo di tempo poco significativo

e poco influente rispetto al funzionamento complessivo del sistema, ma

comunque apprezzabile, per cui è presente un valore di picco.

24

1.4 Il Ricevitore ad Infrarossi (IR)

1.4.1 Funzionamento della Trasmissione

La comunicazione infrarossa tra due dispositivi elettronici è una tra le più

semplici ed economiche alternative per l’utilizzo della trasmissione wireless di

dati digitali (binari). Bastano infatti soltanto due componenti:

un trasmettitore, ovvero un led che funziona come un normale diodo ad

emissione luminosa, tranne per il fatto che l’onda emanata è invisibile

all’occhio umano;

un ricevitore, ovvero un foto-sensore che invia l’informazione estrapolata

dalla sequenza luminosa al dispositivo a cui è collegato [10].

Ad ogni diversa funzionalità del dispositivo di comando (selezionabile

solitamente attraverso la pressione di un tasto, fisico o virtuale) è associato un

diverso segnale, il quale viene fatto passare attraverso un codificatore che lo

trasforma in una sequenza di impulsi elettrici. Questa è prima modulata, in

modo tale da aumentare il suo rapporto segnale-rumore, e successivamente

inviata al led, che emette quindi un segnale luminoso quando in ingresso è

presente una tensione alta, mentre invece rimane spento se il segnale è basso.

Più precisamente si parla di due diversi stati:

space, durante il quale non c’è emissione luminosa (nessun impulso);

mark, ovvero la condizione per la quale il led lampeggia con una

determinata frequenza compresa tra i 30kHz ed i 60kHz [11].

Ci possono essere tre diverse codifiche utilizzate da un trasmettitore:

la codifica “Manchester”, attraverso la quale vengono identificati i bit 1 o

0 in base alla posizione del mark all’interno di vari slot temporali;

25

Figura 9: codifica Manchester o Bifase

la codifica “Pulse Distance”, con la quale i valori dei bit vengono

differenziati in base al periodo temporale che intercorre tra due marks;

Figura 10: codifica Pulse Distance

la codifica “Pulse Length”, per la quale i valori dei bit vengono

differenziati in base alla differente durata dai marks.

Figura 11: codifica Pulse Length

26

A questo punto, il segnale luminoso viene catturato dal ricevitore, che lo traduce

in tensione, e viene demodulato, in modo tale da avere in uscita un segnale logico

da cui ricavare le informazioni trasmesse [12].

Ovviamente, per fare in modo che i due dispositivi “si capiscano” e che quindi la

trasmissione avvenga in maniera corretta, serve implementare un protocollo;

solitamente ogni azienda produttrice utilizza il proprio (Sony, Samsung,

Siemens, NEC, Panasonic, ecc...), ed ognuno si differenzia rispetto agli altri in

base alla frequenza di modulazione ed alla durata di ogni slot temporale che

identifica ogni singolo bit.

1.4.2 Il Protocollo NEC

La trasmissione dei dati, in realtà, non è limitata al solo comando selezionato;

infatti, ogni pacchetto è formato da:

una sequenza di “start”, che indica l’inizio della comunicazione;

l’indirizzo del dispositivo ricevente;

il comando da eseguire;

una sequenza di “stop”, grazie alla quale il ricevitore riconosce la fine del

messaggio.

Figura 12: specifiche della codifica Pulse Distance per il protocollo NEC

In particolare, il protocollo di comunicazione infrarossa NEC (utilizzato per il

comando del drone attraverso l’applicazione Android) si basa sulla tipologia di

27

codifica Pulse Distance, e struttura le componenti riportate precedentemente

nel seguente modo:

un mark della durata di 9ms (ovvero sedici volte il mark utilizzato per la

distinzione dei bit), seguito da uno space di 4.5ms. Questa successione

designa l’inizio del trasferimento dell’informazione;

8 bit d’indirizzo;

8 bit negati d’indirizzo;

8 bit di comando;

8 bit negati di comando;

un mark di durata di 562.5us, che indica la fine della comunicazione [13]

[14].

Tutti i bit vengono trasmessi partendo dal LSB; inoltre i campi negati sono

utilizzati sia come prevenzione verso gli errori sia per rendere costante la durata

di un messaggio.

Figura 13: esempio di pacchetto NEC; ogni rettangolo rappresenta un mark

28

L’intero funzionamento del protocollo quindi può essere sintetizzato attraverso

la seguente tabella:

Componente Mark Space

Header di inizio

trasmissione 9000us 4500us

Bit “0” 562.5us 562.5us

Bit “1” 562.5us 1.6875ms

Header di fine

trasmissione 562.5us Non presente o lungo

Tabella 6: sintesi del funzionamento del protocollo NEC

La maggior parte delle volte però, la durata effettiva degli stati non è mai

perfettamente coerente con lo standard: sono frequenti infatti differenze tra i

valori effettivi e quelli teorici dell’ordine di grandezza di alcuni microsecondi

(per esempio, 9156vs9000 o 4548vs4500).

La ragione di tale incoerenza è attribuibile al fatto che i dispositivi remoti sono

“low-cost”, e montano quindi oscillatori interni, solitamente di tipo RC, che non

forniscono un periodo preciso ed accurato.

29

1.5 MPU6050

Si vuole introdurre l’argomento con una definizione: “un sistema di navigazione

inerziale è un ausilio alla navigazione di un mezzo, è composto da computer e

sensori con il fine di stimare la posizione, la velocità e l’orientamento della

vettura senza la necessità di riferimenti esterni” [15]. Il principale componente

di tale sistema è l’IMU (i.e. Inertial Measurement Unit), un dispositivo

elettronico in grado di misurare l’accelerazione inerziale e la velocità angolare

di una massa. A seconda dei casi, può anche essere capace di calcolare il campo

magnetico in cui il corpo è immerso e la sua altitudine.

I sensori IMU sono diventati ai giorni d’oggi uno dei congegni più impiegati in

ogni sorta di sistema elettronico: dagli smartphones, agli APR (Aeromobili a

Pilotaggio Remoto, o UAVs ) e ai robot autostabilizzanti.

Per effettuare tutte queste misure, un IMU è composto da più parti:

uno o più accelerometri;

uno o più giroscopi;

un magnetometro (o bussola);

un altimetro

Si veda ora più nel dettaglio il funzionamento di un accelerometro e di un

giroscopio, che sono i sensori che poi si andranno ad utilizzare nel corso del

progetto.

1.5.1 Il Sensore

Il dispositivo utilizzato in questa tesi è l’InvenSense MPU-6050 [16] che

contiene, riuniti in un singolo circuito integrato, un accelerometro e un

giroscopio, entrambi a tre assi. È infatti un sensore a sei assi, o con sei gradi di

libertà, che quindi fornisce sei valori come output. Impiega il protocollo I2C per

la comunicazione con l’esterno. Si tratta di un IMU economico ma piuttosto

affidabile e preciso, è tra i più diffusi

30

per progetti di questo tipo. In questa tesi viene utilizzato con il modulo GY-521,

così da avere l’MPU-6050 già pronto per l’interfacciamento con la scheda

programmabile. Inoltre nel modulo è presente un regolatore di tensione, che gli

permette di essere alimentato con una tensione compresa tra 3.3V e 5V. Oltre

ad accelerometro e giroscopio, l’MPU contiene anche un Digital Motion

Processor (DMP), di cui si parlerà in seguito, oltre ad una FIFO. È infine

presente un sensore di temperatura che può risultare utile per effettuare

opportune compensazioni dei dati di movimento. Tutte le informazioni qui

riportate sono state recuperate dal datasheet disponibile presso il sito della

InvenSense4.

Tramite I2C è possibile configurare molte impostazioni dell’MPU, scrivendo sui

suoi registri. Molti di questi però non sono ben documentati e quindi non è

assolutamente scontato capire il loro utilizzo. La mappa dei registri con le

relative descrizioni è disponibile presso il sito della InvenSense5. Va segnalato

tuttavia che l’utilizzo dei registri non è assolutamente banale, per questo è stata

costruita una libreria ad hoc che implementi le funzionalità più importanti, che

verrà esposta successivamente.

4 https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Datasheet1.pdf 5 https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf

Figura 14: componenti dell'MPU6050

31

1.5.2 La FIFO

È possibile impostare l’MPU affinché scriva i dati dell’accelerometro e del

giroscopio nella FIFO, oppure eventualmente nei registri dedicati, perdendo

però la sicurezza di leggere tutti i dati generati dal sensore nel caso in cui la

lettura degli stessi avvenga ad una frequenza inferiore rispetto alla

memorizzazione. È tuttavia possibile impostare un interrupt (uscita INT) che

segnali la disponibilità di nuovi dati nei registri, in modo tale da andare a

leggerli prima che questi vengano sovrascritti.

La FIFO ha una dimensione di 1024 bytes ed è accessibile, ovviamente, tramite

interfaccia seriale. I registri di configurazione della FIFO determinano i dati che

vengono scritti al suo interno (giroscopio, accelerometro, temperatura, DMP).

Una comodità derivante dall’utilizzo della FIFO, oltre che, come già detto, la

certezza di non perdere dati, è il burst read. Questa funzione permette di leggere

tutti i dati della coda in un breve lasso di tempo, fino a svuotarla, per poi

aspettare che si torni a riempire. Così facendo è possibile lasciare il processore

della scheda logica in low-power mode mentre l’MPU riempie la FIFO.

1.5.3 Giroscopio ed Accelerometro

I campioni forniti da giroscopio ed accelerometro sono raw, grezzi, e per questo

vanno elaborati dopo essere stati prelevati (dai registri o dalla FIFO) per

ottenere le velocità angolari e le accelerazioni. Un ulteriore calcolo di fusione va

eseguito per arrivare agli angoli di Eulero (come verrà spiegato nell’introduzione

del capitolo riguardante i filtri).

Sull’MPU sono presenti sei convertitori AD da 16 bit, che permettono il

campionamento simultaneo dell’accelerometro e del giroscopio su ogni asse.

Avendo i campioni un peso di due byte l’uno, per sei assi si raggiunge un peso

totale di 12 bytes.

Il giroscopio ha una frequenza di campionamento configurabile da 4Hz a 8kHz

32

(standard 8kHz) e un filtro passa-basso programmabile da 5Hz a 256Hz.

L’accelerometro ha una frequenza di campionamento configurabile da 4Hz a

1kHz (standard 1kHz), con un filtro passa-basso da 5Hz a 260Hz. I filtri low

pass non sono stati trattati nella libreria utilizzata per il progetto.

L’interfaccia I2C è configurabile in fast-mode per lavorare a 400kHz oppure in

standard-mode a 100kHz. Considerando che ogni byte trasmesso richiede 9

clocks (8 bits più l’acknowledge), alla frequenza standard di 100kHz si

trasmettono i 12 bytes di campioni con una frequenza di circa 900Hz

(considerando che si prelevino sia i dati dell’accelerometro che quelli del

giroscopio, senza però la temperatura). Questo è un limite teorico che non viene

mai raggiunto, in quanto in ogni trasmissione I2C va considerato anche l’invio

dell’indirizzo dello slave con cui comunicare e del registro da cui leggere/scrivere

(ulteriori due bytes).

Sia il giroscopio che l’accelerometro sono configurabili su diversi livelli di

sensibilità, come riportato nella tabella sottostante. Ovviamente a seconda della

sensibilità impostata ogni LSB assume un peso diverso.

Gyro Full

Scare Range

(°/sec)

Gyro Sensibility

(LSB/°/sec)

Accel Full

Scale Range (g)

Accel

Sensibility

(LSB/g)

±250 131 ±2 16384

±500 65.5 ±4 8192

±1000 32.8 ±8 4096

±2000 16.4 ±16 2048

Tabella 7: Full Scale Range di accelerometro e giroscopio

Con queste informazioni è possibile trasformare i dati raw forniti dai sensori in

velocità angolari e accelerazioni. Ad esempio un valore raw di 2048 rappresenta

1g con la sensibilità minima (±16g), 1/2 g con la sensibilità ±8g, 1/4 g con ±4g e

infine 1/8 g con la sensibilità massima (±2g).

L’ulteriore passaggio per arrivare agli angoli di Eulero ha richiesto tuttavia un

33

ulteriore studio, che per la sua complessità ha richiesto un capitolo interamente

dedicato.

1.5.4 Digital Motion Processor

Il DMP (Digital Motion Processor), processore integrato nell’MPU, è in grado di

elaborare tramite avanzati algoritmi di fusione i dati grezzi a sei assi forniti dai

sensori. La sua implementazione è però tenuta segreta dalla InvenSense e,

sebbene per Arduino si trovino in abbondanza sul web librerie che lo trattino,

per ST-Nucleo la situazione è più complicata.

Nel corso del progetto si è provato a fare un porting della libreria più famosa

disponibile in ambiente Arduino: MPU6050 e I2Cdev di Jeff Rowberg,

disponibile su GitHub6. Purtroppo, sebbene funzioni piuttosto bene sotto gran

parte degli aspetti, non si può dire lo stesso per la parte di implementazione del

DMP. Sul web sono disponibili molti esempi di bug rilevati nella libreria quando

si utilizza il DMP, e non ci sono modi per capire come questo processore operi e

quindi correggerli. Per questo motivo, utilizzarlo per droni e altre applicazioni

di questo genere non è consigliato. In caso di freeze e crash inaspettati potrebbe

diventare veramente pericoloso.7

Nel corso del progetto si è cercato di utilizzare il DMP, configurato per dirottare

l’output nella FIFO. Si è avuto modo di notare l’incredibile precisione degli

algoritmi di fusione, gli angoli di Eulero ottenuti risultavano molto più precisi

di tutti i filtri fino ad allora utilizzati. Interessante notare che il DMP è in grado

di calcolare anche la rotazione sull’asse z (yaw o imbardata), cosa impossibile da

fare con i filtri.

Purtroppo dopo pochi test è subito emerso un problema: l’MPU dopo qualche

minuto andava in freeze, senza apparente motivo. Si è cercato di capire se

potesse essere un problema di overflow della FIFO, senza risultato. Si è cercato

6 https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050 7 https://github.com/jrowberg/i2cdevlib/issues/252

34

allora di calcolare e inserire manualmente gli offsets per il DMP, ritendendo

decisamente lunga l’attesa di 10 secondi ad ogni riavvio della scheda. Purtroppo

non è affatto chiaro come funzionino gli offsets del DMP (e sembrano non essere

gli stessi offsets presenti per il giroscopio e l’accelerometro): la documentazione

relativa è molto approssimativa se non inesistente. Potrebbe essere interessante

un approfondimento a riguardo, dirottando l’output del DMP sui registri

dedicati invece che sulla FIFO: si semplificherebbe così in maniera consistente

l’operazione di lettura dei dati (che altrimenti richiederebbe anche la gestione

dell’interrupt) e forse si risolverebbe il problema del freeze. In ogni caso,

premettendo che bisognerebbe verificare l’affidabilità dell’MPU con DMP attivo

(anche dopo aver risolto i problemi di freeze riscontrati), diversi utenti su

internet hanno segnalato una sostanziale indifferenza nel comportamento dei

loro velivoli con l’utilizzo del DMP o dei filtri [17]. Per questo motivo in questo

progetto si è scelto di abbandonare il processore integrato e proseguire

utilizzando i filtri.

1.5.5 Il Clocking

L’MPU 6050 permette di usare diverse sorgenti di clock, esterne o interne:

un oscillatore interno da 8MHz

uno degli oscillatori MEMS del giroscopio (asse x, y o z)

una sorgente esterna da 32,768kHz (onda quadra)

una sorgente esterna da 19,2MHz (onda quadra)

All’accensione il dispositivo usa l’oscillatore interno per operare, finché non

viene programmato diversamente. Selezionare il giroscopio come fonte di clock

fornisce maggiore stabilità e quindi è fortemente consigliato. Tuttavia in casi in

cui ad esempio il consumo di energia è il parametro principale, è possibile

disattivare i giroscopi e utilizzare l’oscillatore interno come riferimento.

35

Capitolo 2

I Filtri Software

L’MPU6050, come è stato descritto nel capitolo precedente, salva all’interno dei

propri registri dedicati sei dati (ciascuno della dimensione di due byte) per ogni

lettura:

i primi tre corrispondono alle componenti della velocità angolare del

sistema rispetto gli assi x, y, e z di un riferimento ortogonale il cui centro

coincide con il centro di massa della struttura;

gli ultimi tre corrispondono invece alle componenti rispetto agli stessi

assi del vettore accelerazione, che nel caso in cui il sistema sia fermo,

corrisponde all’accelerazione di gravità.

Ci sono però due problemi fondamentali, infatti:

se per la determinazione della posizione angolare dell’oggetto nello spazio

si utilizzassero soltanto i dati grezzi del giroscopio (definendo quindi

l’angolo come 𝜃 = ∫ 𝜔𝑑𝑡𝑡

0, ricordando che la velocità angolare è definita

come 𝜔 =𝑑𝜃

𝑑𝑡) ne risulterebbe tipicamente una misura accurata e non

suscettibile ad agenti esterni, ma che presenterebbe un effetto di deriva

a lungo termine dovuto all’errore che si accumula durante l’operazione di

integrazione;

se invece si usufruisse soltanto dei dati grezzi dell’accelerometro si

otterrebbe una misura angolare che in linea di principio non necessita di

integrazione, in quanto la direzione dell’accelerazione di gravità può

fornire direttamente gli angoli di Eulero del dispositivo, ma per contro la

misura dell’accelerazione risulta evidentemente sensibile a tutte le forze

di disturbo sul sistema. Per questo motivo, l’accelerometro fornirebbe

una buona lettura soltanto nel caso in cui il dispositivo si muovesse con

un moto rettilineo uniforme. Peraltro anche le eventuali vibrazioni dei

motori vengono ad aggravare ulteriormente il problema, introducendo un

36

significativo rumore [18].

Si tratta quindi di “fondere” opportunamente i campioni forniti da entrambi i

sensori, per ottenere una corretta rappresentazione degli Angoli di Eulero:

roll, corrispondente alla rotazione attorno all’asse x;

pitch, corrispondente alla rotazione attorno all’asse y;

yaw, corrispondente alla rotazione attorno all’asse z.

37

2.1 Il DMP ed i Quaternioni

Un metodo tipicamente usato per elaborare i dati sopra citati consiste nel

configurare opportunamente il DMP in modo tale da minimizzare gli errori,

propri del giroscopio e dell’accelerometro, per ottenere un calcolo preciso degli

angoli spaziali.

Uno dei dati che il DMP è in grado di fornire sono i cosiddetti quaternioni: questi

sono delle estensioni dei numeri complessi appartenenti allo spazio lineare 𝐻(𝑅)

a quattro dimensioni con base {1, i, j, k}. Ogni quaternione quindi è definito come

la combinazione lineare della suddetta base di forma 𝑞 = 𝑎 + 𝑖𝑏 + 𝑗𝑐 + 𝑘𝑑, dove

i, j, k sono le varie unità immaginarie.

Attraverso queste entità matematiche è possibile rappresentare orientamento e

rotazione di un oggetto nello spazio tridimensionale: infatti, dato un generico

quaternione unitario (ovvero la cui norma, definita come ‖𝑞‖ = √∑ 𝑞𝑖23𝑖=0 , vale

uno)

𝑞𝑢 = 𝑎𝑢 + 𝑖𝑏𝑢 + 𝑗𝑐𝑢 + 𝑘𝑑𝑢 = (𝑎𝑢, 𝒖) = cos 𝜃 + 𝒖 sin 𝜃,

esso rappresenta la rotazione di un angolo pari a 2θ attorno all’asse descritto

dal versore

𝒖 = (𝑏𝑢, 𝑐𝑢, 𝑑𝑢)𝑇.

Viceversa, data una rotazione di angolo θ attorno all’asse individuato dal versore

𝑢, il quaternione unitario che la descrive può essere ottenuto come 𝒒𝒖 =

(cos𝜃

2, 𝑏𝑢sin

𝜃

2, 𝑐𝑢sin

𝜃

2, 𝑑𝑢 sin

𝜃

2). In particolare, le rotazioni attorno ai tre assi di

un sistema di riferimento cartesiano corrispondono ai seguenti quaternioni

elementari [19]:

𝑅(𝑖, 𝛼) → 𝒒𝒙 = (cos𝛼

2, sin

𝛼

2, 0, 0)

𝑅(𝑗, 𝛽) → 𝒒𝒚 = (cos𝛽

2, 0, sin

𝛽

2, 0)

𝑅(𝑘, 𝛾) → 𝒒𝒛 = (cos𝛾

2, 0, 0, sin

𝛼

2)

L’utilizzo di queste entità quindi è particolarmente indicato per risolvere il

38

cosiddetto problema di “Gimbal Lock” o di “Blocco Cardanico”, ovvero la perdita

di un grado di libertà in un sistema tridimensionale descritto attraverso gli

angoli di Eulero quando avviene una rotazione dell’oggetto tale da far coincidere

due assi spaziali [20].

Si supponga per esempio che un aereo passi dall’avere un’inclinazione di 0°

rispetto all’asse y ad averne una di 90°; l’asse delle x e quello delle z quindi

vengono a coincidere, facendo sì che non si possa più discriminare quale sia

l’angolo di roll e quale quello di yaw.

Purtroppo però Invensense, azienda costruttrice del giroscopio montato sul

drone, non fornisce l’algoritmo da essi impiegato né per il computo dei

quaternioni né per il calcolo degli angoli spaziali, rendendo “open-source”

solamente una libreria per Arduino; per questo motivo è compito del

programmatore della scheda, in assenza della configurazione del DMP,

implementare i filtri software attraverso i quali i dati raw vengono elaborati,

per ottenere così valori degli angoli di roll e pitch il più possibile accurati e

precisi. Per quanto riguarda invece l’angolo di yaw è possibile determinarlo solo

attraverso l’elaborazione dei dati provenienti dal giroscopio, in quanto qualsiasi

variazione dell’angolo di imbardata risulterebbe del tutto ininfluente rispetto

alla variazione del vettore gravitazionale.

39

2.2 Il Filtro Complementare

L’idea alla base del filtro complementare consiste nel far passare il dato

proveniente dall’accelerometro attraverso un filtro passa basso, in modo da

mantenere la stabilità della misura a lungo termine ed eliminare le

accelerazioni istantanee (per estrapolare soltanto il vettore di gravità). Al

contempo il dato proveniente dal giroscopio viene filtrato attraverso un filtro

passa alto, per rimuovere l’effetto di deriva nel tempo. Le due uscite filtrate

vengono quindi sommate per creare una stima dell’angolo spaziale del sistema

che combina le parti più significative dei dati letti da entrambi i sensori [21].

Figura 15: schematizzazione del funzionamento di un filtro complementare

L’input dei due filtri però non può essere semplicemente la lettura grezza

proveniente dai registri dell’MPU, poiché il dato finale deve rappresentare un

angolo, si vuole che entrambi i sensori riportino tale dato; per questo motivo, da

una parte i dati del giroscopio, come visto in precedenza, vengono integrati nel

tempo, dall’altra i valori dell’accelerometro vengono elaborati attraverso

l’utilizzo della funzione:

40

𝑎𝑡𝑎𝑛2(𝑦, 𝑥) =

{

atan (

𝑦

𝑥), 𝑠𝑒 𝑥 > 0

atan (𝑦

𝑥) + 𝜋, 𝑠𝑒 𝑥 < 0 ˄ 𝑦 ≥ 0

atan (𝑦

𝑥) − 𝜋, 𝑠𝑒 𝑥 < 0 ˄ 𝑦 < 0

+𝜋

2, 𝑠𝑒 𝑥 = 0 ˄ 𝑦 > 0

−𝜋

2, 𝑠𝑒 𝑥 = 0 ˄ 𝑦 < 0

𝑛𝑜𝑛 𝑑𝑒𝑓𝑖𝑛𝑖𝑡𝑎, 𝑠𝑒 𝑥 = 0 ˄ 𝑦 = 0

Questa, a partire da due valori (che sono rispettivamente la componente z del

vettore accelerazione e una tra le due componenti x o y, in base all’angolo che si

vuole determinare), fornisce l’angolo in radianti tra il semiasse positivo delle x

di un piano cartesiano ed un punto di coordinate (x, y), restituendo un valore

compreso nell’intervallo (-𝜋, 𝜋).

2.2.1 Implementazione Software del Filtro Complementare

I filtri complementari possono essere evidentemente di ordini diversi: si parte

dai filtri cosiddetti “di primo ordine”, grazie ai quali si riesce ad ottenere una

buona stima dei vari angoli spaziali, proseguendo poi con i filtri “di secondo

ordine” o “di terzo ordine”; questi ultimi sono molto più complessi da realizzare

a livello software, senza che però vi sia un guadagno in precisione di

approssimazione angolare significativo da rendere giustificato l’aumento della

complessità dell’algoritmo [22]. Per questo motivo per il progetto drone si è scelto

di sviluppare un semplice filtro complementare di ordine uno, il cui codice è

riportato di seguito:

41

Attraverso questa prima parte di codice vengono creati i due array che

serviranno per memorizzare temporaneamente i dati raw provenienti dalla

lettura dei due sensori; inoltre sono create le variabili corrispondenti agli angoli

da calcolare.

A questo punto viene richiamata la funzione getMotion6, grazie alla quale gli

array creati in precedenza vengono riempiti. Successivamente vengono integrati

i dati provenienti dal giroscopio: in questo caso, siccome tutte le azioni vengono

effettuate dal microprocessore a tempo discreto, questa operazione consiste nel

sommare agli angoli calcolati durante i cicli passati i dati raw dell’ultima

lettura, moltiplicati per il fattore 61.1e-6, corrispondente al periodo di tempo che

intercorre tra due rilevazioni successive. Questo valore viene determinato dal

reciproco del prodotto tra 131 (il valore del LSB rispetto al Full Scale Range

scelto, ovvero ±250 deg/s) e 250Hz (la frequenza del loop).

Per mezzo di questa porzione di codice viene calcolato dapprima il vettore

accelerazione totale, e successivamente, facendo riferimento alla geometria

spaziale e alla trigonometria, vengono determinati gli angoli di roll e pitch dai

dati dell’accelerometro. Il valore 57.296 è determinato dal rapporto tra 180 e 𝜋

e viene utilizzato per convertire il risultato della funzione asin da radianti a

42

gradi.

Infine, quando l’elaborazione viene effettuata per la prima volta dall’accensione

del sistema, gli angoli calcolati attraverso i dati del giroscopio vengono

eguagliati a quelli calcolati attraverso l’accelerometro, per avere una precisione

iniziale maggiore (supponendo che all’avvio del sensore la struttura sia ferma, e

che quindi non agiscano forze esterne di disturbo), e l’array globale contenente

gli angoli finali viene inizializzato a zero; successivamente invece viene

implementato il filtro, in cui il giroscopio ha peso 99.96% rispetto al calcolo

totale, mentre l’accelerometro lo 0.04%.

Per migliorare maggiormente la precisione di approssimazione e per avere

variazioni meno brusche, viene applicato un filtro anche nella fase di

aggiornamento dei valori dell’array globale.

43

2.3 Il Filtro di Kalman

Il filtro di Kalman è una procedura matematica ricorsiva che permette di

descrivere e prevedere l’evoluzione futura dello stato di un sistema dinamico

perturbato da fonti di rumore esterne, sulla base di misure linearmente

dipendenti dallo stato stesso.

Questo processo consiste nell’utilizzare la stima iniziale di una grandezza (che

nel caso del progetto corrisponde all’angolo calcolato attraverso i dati raw del

giroscopio), l’errore stimato iniziale ed i campioni misurati sperimentalmente

(ovvero gli angoli derivanti dai campioni del giroscopio) per calcolare un nuovo

valore stimato, che dipende sia dalla stima iniziale sia dalla grandezza misurata

[23], come viene spiegato in maniera più dettagliata successivamente.

Procedendo con l’iterazione e utilizzando volta per volta nuove misurazioni,

l’errore diventa sempre più piccolo e la stima dello stato attuale sempre più

vicina al valore reale.

2.3.1 Trattazione Matematica del Filtro

Si consideri un generico sistema lineare a tempo discreto del tipo

{𝒙𝒌 = 𝚽𝒌−𝟏𝒙𝒌−𝟏 + 𝚪𝒌−𝟏𝒖𝒌−𝟏 +𝒘𝒌−𝟏

𝒛𝒌 = 𝑯𝒌𝒙𝒌 + 𝒗𝒌 (a)

in cui:

𝒙𝒌 rappresenta la grandezza da stimare;

Φ è chiamata “matrice di transizione dello stato”, ed i suoi valori

rappresentano la relazione tra il k-esimo stato ed il (k-1)-esimo;

Γ è la matrice che lega l’input allo stato del sistema;

𝒖𝒌 è l’ingresso del sistema;

𝒘𝒌 rappresenta il rumore di processo;

𝒛𝒌 rappresenta la misurazione effettuata;

H è detta “matrice di sensitività di misurazione”, ed i suoi valori

44

rappresentano la sensitività dell’i-esima misurazione rispetto al j-esimo

stato;

𝒗𝒌 rappresenta il rumore di misurazione.

Le variabili aleatorie 𝒘𝒌 e 𝒗𝒌 sono assunte come indipendenti, con distribuzione

di probabilità Gaussiana 𝑝(𝑥) =1

𝜎√2𝜋𝑒−(𝑥−𝜇)2

2𝜎2 a valor medio nullo e varianza pari

rispettivamente a 𝑸𝒌 e 𝑹𝒌.

Si vuole far notare che tutti gli elementi sopracitati, nel caso di un sistema n-

dimensionale, sono grandezze vettoriali; se però lo studio del filtro di viene

semplificato ad un caso monodimensionale, tutti gli elementi diventano degli

scalari.

L’iterazione del filtro di Kalman consiste di due stadi:

il calcolo della stima a priori dello stato attuale;

l’aggiornamento e la correzione dei valori da utilizzare per il ciclo

successivo e quindi la stima a posteriori dello stato del sistema.

Come primo passaggio viene calcolata a priori la stima della grandezza in

esame:

�̂�𝒌− = 𝚽𝒌−𝟏𝒙𝒌−𝟏 + 𝚪𝒌−𝟏𝒖𝒌−𝟏 (b)

e, successivamente, il valore della matrice di covarianza (che fornisce

l’indicazione della tendenza di due variabili aleatorie a muoversi assieme [24])

dell’errore rispetto la stima appena determinata:

𝑷𝒌− = 𝑬[𝒆𝒌

−𝒆𝒌−𝑇] = 𝚽𝒌−𝟏𝑷𝒌−𝟏𝚽𝒌−𝟏

𝑇 + 𝑸𝒌, con 𝒆𝒌− = 𝒙𝒌 − �̂�𝒌

− (c)

Durante la seconda fase invece viene calcolata la stima dello stato a posteriori

(d) cercando di minimizzare l’effetto di disturbo introdotto dalla componente

rumore sulla misurazione; per fare ciò vengono utilizzati sia la stima a priori

calcolata precedentemente (b) sia la differenza (chiamata “innovation” o

“residuo”) tra la misura della grandezza attuale ed una previsione di essa [25],

45

utilizzando l’equazione della misurazione effettuata (a):

�̂�𝒌 = �̂�𝒌− +𝑲𝒌(𝒛𝒌 −𝑯𝒌𝒙𝒌) (d)

Lo stato calcolato varia quindi in base alla matrice 𝑲𝒌 ,chiamata “guadagno di

Kalman”, che, se determinata attraverso la formula seguente, minimizza la

covarianza a posteriori:

𝑲𝒌 = 𝑷𝒌−𝑯𝒌

𝑇(𝑯𝒌𝑷𝒌−𝑯𝒌

𝑇 + 𝑹𝒌)−𝟏 (e)

ed i cui elementi hanno valori compresi tra [0,1] che dipendono sia dall’errore

sulla stima sia da quello sulla misura. Utilizzando questo valore, la stima a

posteriori della matrice di covarianza diviene:

𝑷𝒌 = 𝑬[𝒆𝒌𝒆𝒌𝑇] = (𝐼 − 𝑲𝒌𝑯𝒌) 𝑷𝒌

−, con 𝒆𝒌 = 𝒙𝒌 − �̂�𝒌 (f)

In questo modo quindi, mano a mano che il programma viene eseguito in

maniera ricorsiva, lo stato (d) verrà stimato con un errore sempre minore, e

siccome la matrice di guadagno (e) verrà aggiornata ad ogni ciclo, permettendo

quindi di ridurre sempre più il valore della covarianza a posteriori (f),

approssimerà in maniera sempre più precisa lo stato reale [26].

2.3.2 Implementazione Software del Filtro di Kalman: la

Libreria “kalman”

Di seguito viene riportata l’intera libreria utilizzata per l’implementazione del

filtro di Kalman. Per ogni metodo viene proposta una descrizione che si collega

al sottocapitolo precedente 4.3.1, in modo da rendere più chiara l’applicazione

della teoria matematica alla pratica di calcolo.

46

Il primo metodo viene utilizzato per inizializzare tutte le componenti del filtro:

come prima cosa vengono poste a zero la deriva del giroscopio (x_bias), la stima

dell’angolo (x_rate) e l’angolo calcolato (x_angle). Successivamente vengono

settati i valori delle matrici di covarianza dell’errore di misurazione (R_angle) e

dell’errore di processo (Q_gyro e Q_angle). Infine vengono posti a zero tutti gli

elementi della matrice P della covarianza rispetto alla stima dello stato del

sistema.

47

Il metodo kalman_predict permette di realizzare la prima delle due fasi

ricorsive del filtro citate precedentemente: come prima cosa viene eliminata la

componente di deriva del giroscopio dalla misura effettuata dallo stesso

(dot_angle); quindi il dato “pulito” viene moltiplicato per il periodo di loop (dt),

realizzando, come visto durante il capitolo riguardante il filtro complementare,

l’operazione di integrazione a tempo discreto, attraverso la quale viene fornita

una stima a priori dell’angolo. Successivamente la matrice di covarianza viene

aggiornata, applicando il risultato finale della relazione (c) sopra indicata.

Il metodo kalman_update invece realizza la seconda fase ricorsiva del filtro,

fornendo la stima a posteriori dell’angolo. Innanzitutto viene determinato il

“residuo” (y) e successivamente, attraverso l’applicazione dell’equazione (e),

viene calcolata la matrice riga 𝑲𝒌 (i cui elementi in questo caso sono identificati

da K_0 e K_1): in questo caso viene fatto il rapporto tra la covarianza calcolata a

priori e la somma della stessa con la covarianza dell’errore di misurazione.

Infine viene aggiornata la matrice di covarianza, determinando quindi il suo

48

valore a posteriori (f), e viene fornita la stima a posteriori dell’angolo, come

descritto da (e).

49

2.4 Confronto Sperimentale tra i Due Filtri

Nei capitoli precedenti è stato illustrato, sia dal punto di vista teorico che da

quello pratico, il funzionamento dei filtri adottati per il progetto drone; non sono

stati presi in considerazione però i criteri attraverso i quali scegliere quale delle

due soluzioni adottare.

Per questo motivo sono state ideate ed eseguite due simulazioni sperimentali

per confrontare i comportamenti di entrambi i filtri:

una, meno rigorosa e precisa, effettuata soltanto mediante l’utilizzo del

movimento di una mano;

l’altra, realizzata attraverso una piattaforma basculante ed una scheda

Arduino.

2.4.1 Simulazione 0°-90°-0°

Il primo test realizzato è stato effettuato in maniera molto semplice, utilizzando

soltanto un supporto perpendicolare al banco da lavoro ed un timer:

per tre secondi il sensore è stato lasciato inerte in posizione orizzontale

(0°);

al terzo secondo è stata effettuata una transizione, della durata di un

secondo, verso la posizione verticale (90°);

al decimo secondo è stata effettuata la seconda ed ultima modifica

d’inclinazione, anch’essa della durata di un secondo, durante il quale

l’MPU6050 è stato riportato in posizione orizzontale (0°).

Ovviamente la perfetta simultaneità tra timer e movimento manuale non è

garantita; tuttavia grazie ai dati raccolti, riportati di seguito, viene fornita

un’idea generale di come i due filtri si comportano sia durante una fase

transitoria, corrispondente alla traslazione angolare del sensore, sia durante

una fase di regime.

Come è possibile notare dal grafico seguente, il filtro di Kalman approssima in

50

maniera quasi perfetta l’inclinazione reale del sensore; il filtro complementare

invece produce una misurazione meno accurata ed è soggetto a lunghi periodi di

assestamento prima dell’avvicinamento ad un valore di equilibrio; questo effetto

è conseguenza del maggior peso che è stato fornito ai dati provenienti dal

giroscopio.

Grafico 3: confronto tra filtro complementare e filtro di Kalman

-200

-150

-100

-50

0

50

100

0,0 1,2 2,4 3,6 4,8 6,0 7,1 8,3 9,5 10,7 11,9 13,1 14,3 15,5 16,7 17,9 19,0

First Kalman vs Complementary Filters Simulation

Acc_raw Gyro_raw Complementary Kalman Real value

51

2.4.2 Simulazione con Piattaforma e Microcontrollore

Arduino

Figura 16: esecuzione della simulazione

Il secondo test effettuato è quello di maggior rilievo dal punto di vista

sperimentale, poiché simula con un ottimo grado di approssimazione la fase

reale di volo del drone, tranne per il fatto che in questo caso la struttura possiede

un unico grado di libertà di movimento.

Per la simulazione sono stati utilizzati:

una piattaforma montata su di un blocco cardanico;

un servomotore;

una scheda Arduino.

Attraverso un semplice codice è stato programmato il microprocessore in modo

da controllare il servo. Quest’ultimo, grazie al movimento rotatorio di 180° del

perno, permette l’oscillazione della piattaforma, che per motivi di costruzione

raggiunge l’inclinazione massima di circa 6° (sia positivamente che

negativamente rispetto al piano orizzontale).

I dati, riportati nella tabella sottostante, sono stati presi in considerazione

durante un periodo di dieci oscillazioni complete della struttura, in modo da

ottenere una lettura sul lungo periodo, e non su di un’unica perturbazione.

52

Grafico 4: comportamento del filtro di Kalman durante 10 oscillazioni

Grafico 5: comportamento del filtro complementare durante 10 oscillazioni

Anche in questo caso Kalman risponde meglio alle perturbazioni, sebbene la

differenza tra i due filtri si sia assottigliata: le variazioni di posizione infatti

sono più rapide e meno ampie, non permettendo quindi al sistema di avere

-2000

-1500

-1000

-500

0

500

1000

1500

2000

2500

3000

-300

-250

-200

-150

-100

-50

0

50

100

150

200

250

1 5 9 13 17 21 25 29 33 37 41 45 49 53 57 61 65 69 73 77 81 85 89 93 97 101105

Kalman Filter Behavior

Accelerometer Kalman Gyro

-2000

-1500

-1000

-500

0

500

1000

1500

2000

2500

3000

-300

-250

-200

-150

-100

-50

0

50

100

150

200

250

1 5 9 13 17 21 25 29 33 37 41 45 49 53 57 61 65 69 73 77 81 85 89 93 97 101105

Complementary Filter Behavior

Accelerometer Complementary Gyro

53

periodi di stazionarietà e grandi variazioni angolari (che amplificano l’effetto

derivativo del filtro complementare). Tuttavia, come mostrato attraverso la

tabella seguente, il numero dei dati ricavati attraverso l’utilizzo del filtro di

Kalman i cui valori sono compresi all’interno dell’intervallo [-6°, +6°] è molto

maggiore rispetto a quello dei dati prodotti attraverso l’implementazione del

filtro complementare.

Grafico 6: rapporto tra dati interni all'intervallo +-6° e quelli esterni

In conclusione, qualora non si fosse in possesso di un codice da utilizzare per

l’implementazione del filtro di Kalman, l’utilizzo del filtro complementare

sarebbe un’ottima alternativa, in quanto si presuppone che il drone sia soggetto

a piccole turbolenze durante la fase stazionaria, e che l’inclinazione massima

durante il suo movimento non sia mai superiore ai 30/35° [27].

Al contrario invece, se si fosse in grado di utilizzare il filtro di Kalman per

predire la posizione spaziale di un oggetto generico, questa sarebbe sicuramente

la soluzione ideale, esso fornisce un’approssimazione di certo più precisa; per

contro esso comporta un incremento dei tempi computazionali causato dalla

maggior complessità algoritmica.

68

99

40

9

0

20

40

60

80

100

120

1 2

Confronto Complementare vs Kalman

Valori compresi tra +-6° Valori non compresi tra +-6°

54

Capitolo 3

L’Applicazione Android “Drone”

Come descritto nel capitolo d’introduzione alle componenti hardware, il drone è

stato dotato di un ricevitore infrarossi per riuscire a controllarne il

comportamento a distanza. Per inciso, l’utilizzo di trasmissione infrarossa è

stato preferito ad altre tipologie di comunicazione elettronica wireless (quali per

esempio Wi-Fi, Bluetooth o ZigBee) per il semplice motivo che essa soddisfa in

maniera ottima i requisiti minimi richiesti:

controllo remoto da distanza inferiore ai 2/3m;

bassa probabilità d’errore dovuto ad interferenze nella comunicazione.

Si è pensato quindi di sviluppare un’applicazione [28] destinata all’installazione

su dispositivi mobili montanti sistema operativo Android e dotati di un

emettitore di luce infrarossa, per rendere più “smart” ed in un futuro espandibile

il controllo del sistema.

In alternativa è possibile comunque utilizzare un dispositivo “classico”, come un

telecomando, in quanto i pacchetti di dati inviati al ricevitore corrispondono a

sequenze standard del protocollo NEC (in particolare, a quelle di FF, Pause e

Play di un videoregistratore8).

8 http://irdb.tk/find/

55

3.1 Caratteristiche Generali di un’App Android

Una generica applicazione Android è il risultato della combinazione di una serie

di file contenenti sia il linguaggio di programmazione (Java e XML) sia tutte le

risorse utilizzate. In particolare:

AndroidManifest.xml, ovvero il file attraverso il quale vengono fornite

al sistema operativo le informazioni necessarie per l’avvio del processo,

come il nome, l’icona, le componenti dell’applicazione ed i permessi

necessari;

NameActivity.java, all’interno del quale si ritrova il codice d’esecuzione

in linguaggio Java;

Layout.xml, ossia il file attraverso il quale viene implementata la grafica

dell’applicazione;

Colors.xml, Strings.xml, Style.xml, contenenti rispettivamente i

colori, le stringhe e gli stili utilizzati durante l’esecuzione dell’app;

Drawable, MipMap, ovvero due cartelle all’interno delle quali vengono

salvate le immagini impiegate rispettivamente come sfondi e come logo

[29].

Il concetto fondamentale che però è alla base di ogni applicativo Android è

l’activity, ovvero una finestra contenente l’interfaccia utente dell’applicazione,

attraverso la quale viene permessa l’iterazione uomo-macchina. Ogni app può

avere zero o più activity, ma solitamente ne è presente almeno una; in

particolare, nel caso in esame, le activities sono due: “Intro” e “MainActivity”

(i cui funzionamenti vengono riportati in seguito).

Ad ognuna di queste è stata assegnata una specifica azione da eseguire, quindi

per il corretto funzionamento dell’intera applicazione è necessario che riescano

a comunicare tra loro: tale operazione è resa possibile grazie all’uso dell’Intent,

ovvero “una descrizione astratta di un’operazione che deve essere eseguita

dall’applicazione” [30].

56

3.2 Android Manifest

Il codice sopra riportato costituisce la sezione di applicazione denominata

“Manifest”.

Siccome nel caso del progetto drone non viene utilizzata alcuna funzione del

dispositivo esterna all’app stessa (come ad esempio l’accesso ai contatti, la

navigazione in internet, l’utilizzo della geolocalizzazione attraverso GPS, la

modifica dell’agenda, ecc…), non è necessaria la presenza dei permessi; il file in

questione perciò contiene soltanto l’elenco delle componenti dell’applicazione

(i.e. le activities).

Come prima cosa quindi vengono impostati l’icona (android:icon), salvata

all’interno della cartella MipMap, ed il nome (android:label) che verranno

visualizzati sul display del dispositivo e che identificheranno in maniera univoca

l’applicazione; successivamente viene definito il tema (android:theme),

contenuto all’interno del file style.xml.

57

Infine vengono dichiarate tutte le activities che partecipano all’esecuzione

dell’applicazione; in particolare, attraverso il comando <intent-filter> viene

scelta quale tra tutte dev’essere visualizzata all’avvio.

58

3.3 Implementazione della Grafica tramite

Linguaggio XML

Ogni activity ha bisogno di una propria struttura grafica, che prende il nome di

Layout: nel caso particolare di Android, viene creata utilizzando un particolare

metalinguaggio di programmazione denominato XML (eXtensible Markup

Language). Questo è un linguaggio dichiarativo, che non richiede cioè la

scrittura di un codice, ma che si basa su delle semplici strutture chiamate tags.

Esistono svariate tipologie di layout; tuttavia la maggior parte delle applicazioni

ne utilizzano soltanto due:

LinearLayout, che consiste in una disposizione ordinata e sequenziale

degli elementi grafici (può essere sia orizzontale sia verticale);

RelativeLayout, ovvero una disposizione delle componenti totalmente

impostabile dal programmatore, senza quindi una struttura di base

ordinata.

Questi layouts vengono suddivisi in diverse aree, ognuna delle quali occupa una

precisa posizione dello schermo, attraverso le quali viene rappresentato un

effetto grafico e gestito un evento riguardante l’interazione tra utente e

dispositivo mobile [31]: le View, tutte derivanti dalla superclasse

android.view.View.

Di seguito vengono riportate le strutture utilizzate per il progetto drone:

TextView, ovvero una porzione di schermo all’interno della quale possono

essere inserite varie stringhe di testo;

ImageView, simile alla TextView, contenente però un’immagine;

Button, ovvero un bottone virtuale attraverso il quale l’utente può

interagire con il funzionamento dell’applicazione.

Ognuna di queste View ha molti parametri di personalizzazione, denominati

“attributi”; il più importante tra tutti è sicuramente l’attributo id, attraverso

cui viene identificata ogni View in modo univoco: soltanto grazie ad esso infatti

è possibile fare riferimento ad una struttura grafica (con il comando

59

@id/nome_assegnato) o richiamarla all’interno del codice di programmazione

(attraverso R.id.nome_assegnato).

3.3.1 Layout “Intro”

60

Attraverso i tags sopra riportati viene implementato l’aspetto grafico

dell’activity “Intro”.

Come prima cosa viene impostato un layout lineare con orientamento verticale

a pieno schermo (si noti inoltre che all’interno del file “manifest”, utilizzando il

comando android:screenOrientation, è stata bloccata la rotazione

orizzontale).

Successivamente vengono create tre View, le cui descrizioni vengono riportate di

seguito:

la prima struttura è un bottone, la cui larghezza

(android:layout_width) è uguale alla struttura parente, ovvero il

layout lineare, ma i cui margini (android:layout_margin) sono di 16dp

per ogni lato. Per inciso, l’unità di misura della dimensione in Android è

il dp, ovvero il density pixel; questo per fare in modo che la

rappresentazione grafica di una struttura in diversi display con diverse

densità di pixel sia la medesima. Il bottone viene inoltre reso cliccabile

(andorid:clickable) e viene impostata la raffigurazione della stringa

denominata “button_in” e salvata all’interno del file string.xml.

la seconda struttura è un altro bottone invisibile (android:visibility)

e non cliccabile, molto più grande del precedente; la sua funzione è

soltanto quella di fornire una divisione in proporzione fissa dello

schermo;

l’ultima struttura è invece una TextView, contenente una semplice

stringa di “firma” dell’applicazione.

Il risultato grafico del sopracitato layout “Intro” è il seguente (l’immagine sotto

riportata rappresenta il vero display di uno smartphone LG G39):

9 http://www.lg.com/it/telefoni-cellulari/lg-G3-D855

61

Figura 7: grafica del layout "Intro"

62

3.3.2 Layout “Main”

63

Il metalinguaggio XML sopra riportato implementa il design della seconda ed

ultima activity “MainActivity”.

Il layout scelto è lineare orientato verticalmente rispetto al display del

dispositivo, in questo caso però contiene una View in più rispetto al precedente:

i primi tre elementi grafici sono dei bottoni uguali per dimensioni, forma

e stile, tutti cliccabili e visibili, contenenti però tre diverse stringhe di

testo (rispettivamente button1, button2 e button3). Come verrà

descritto nel capitolo successivo, ad ognuno di questi bottoni è assegnata

una diversa sequenza di dati da inviare al ricevitore infrarosso del drone;

l’ultimo elemento è invece una TextView, di dimensione inferiore rispetto

ai bottoni precedenti, che contiene (android:src) un’immagine

denominata logo salvata all’interno della cartella Drawable; le dimensioni

della figura, ovvero il logo dell’Università degli Studi di Trieste, vengono

64

adattate alla grandezza della View che la contiene (android:scaleType).

Figura 8: grafica del layout “Main”

65

3.4 Implementazione del Codice Esecutivo Java

L’ultimo passo per la creazione di un’applicazione Android funzionante consiste

nella compilazione del codice Java, attraverso il quale vengono definite le azioni

che devono essere eseguite in corrispondenza di un determinato evento, ovvero

la pressione di un bottone. Nel caso del progetto drone l’unica attività

implementata è l’invio di un pacchetto dati, tramite comunicazione infrarossa,

al ricevitore.

Si noti però che, a differenza di tutte le altre case di dispositivi mobile quali ad

esempio Samsung, HTC, Huawei e Sony, l’azienda koreana LG (costruttrice del

G3 utilizzato) non si è basata sulla classe ConsumerIrManager10, sviluppata da

Google, ma ha preferito implementare una propria libreria, denominata “LG

QRemote11”. Per lo sviluppo del codice quindi sono state utilizzate le linee guida

fornite direttamente dalla casa madre del dispositivo mobile, importando di

volta in volta i vari elementi dei packages necessari.

10 https://developer.android.com/reference/android/hardware/ConsumerIrManager.html 11 http://mobile.developer.lge.com/develop/sdks/lg-qremote-sdk/

66

3.4.1 Activity “Intro”

Per fare in modo che gli oggetti utilizzati all’interno del codice Java vengano

riconosciuti dall’ambiente di sviluppo, vengono importate le varie classi dai

rispettivi packages; in particolare, le classi Intent, AppCompatActivity,

Bundle, Log, View, Button appartengono alle librerie standard Android, mentre

invece IRBlaster ed IRBlasterCallback sono entrambe classi create

appositamente da LG, come descritto precedentemente.

Come prima cosa quindi viene definita la classe base “Intro”, derivante da

AppCompatActivity, e vengono ereditati di fatto tutti gli attributi di

quest’ultima attraverso il costrutto super.onCreate (quindi tutte le variabili e

67

i metodi propri di un’activity Android) [32]. Viene definito quindi un metodo

onCreate, utilizzato per inizializzare l’activity e richiedente come parametro un

oggetto di tipo Bundle, che contiene lo stato dell’attività in esecuzione;

all’interno del suddetto metodo perciò viene inserito tutto il codice riguardante

l’activity stessa.

Successivamente vengono creati due oggetti:

cellBlaster, grazie al quale vengono gestiti tutti gli eventi IR;

cell, che si occupa di controllare il LED IR fisico del dispositivo [33].

A questo punto, viene invocato il metodo setContentView, attraverso il quale

viene rappresentata l’interfaccia grafica, che deve essere passata come

parametro; in questo caso si fa riferimento al layout “Intro” attraverso l’utilizzo

di R.layout.activity_intro: ciò vuol dire che il file XML è memorizzato

all’interno della sottocartella layout di Res.

Infine viene fatto riferimento al bottone denominato start, attraverso l’utilizzo

del metodo fondamentale findViewById, facendo in modo che alla pressione

(ovviamente virtuale) dello stesso venga inviato il pacchetto di dati x986730CF

(il cui contenuto verrà spiegato successivamente) con una frequenza portante di

38kHz (sendIRPattern); questo per fare in modo che venga avviato il metodo

catch del setup del drone per il controllo del corretto funzionamento dei singoli

motori. Una volta che il pacchetto d’informazioni viene inviato, viene creato un

oggetto di tipo Intent, attraverso il quale è possibile passare dall’activity

corrente “Intro” a “MainActivity”.

68

3.4.2 Activity “MainActivity”

Come descritto precedentemente, come prima cosa vengono importate le classi

utilizzate (le stesse dell’activity “Intro”), viene definita la classe base

“MainActivity”, il metodo onCreate e creati i due oggetti cellBlaster e cell;

69

la parte fondamentale di questo codice tuttavia risiede all’interno dei tre metodi

onClick.

Ogni qualvolta infatti venga premuto uno dei tre bottoni presenti

nell’interfaccia, viene azionato il LED IR, che invia, con una frequenza di

modulazione pari a 38kHz, un pacchetto diverso in base all’elemento grafico su

cui è stata fatta pressione. Si noti che le cifre all’interno dell’array corrispondono

agli intervalli di durata rispettivamente dei marks e degli spaces, ed i loro valori

sono conformi al protocollo standard NEC descritto nel capitolo dedicato

all’hardware di sistema. Per fare più chiarezza tuttavia, vengono riportate delle

tabelle di “conversione”, grazie alle quali è possibile comprendere meglio il

contenuto della trasmissione:

1°Sequenza 2°Sequenza 3°Sequenza 4°Sequenza 5°Sequenza 6°Sequenza

Corrispondenza Header inizio

trasmissione Indirizzo

Indirizzo

negato Comando

Comando

negato

Header fine

trasmissione

Binario - 1001000 01100111 00110000 11001111 -

Decimale - 25 230 12 243 -

Tabella 8: conversione pacchetto corrispondente al bottone "up"

Alla pressione del bottone up quindi viene inviato al ricevitore IR, il cui indirizzo

è 25 [34], il comando 12 (analogo ad “FF” di un videoregistratore), che è stato

fatto corrispondere all’aumento del throttle del segnale PWM in uscita dal pin

del microcontrollore di un fattore pari a 50e-2.

1°Sequenza 2°Sequenza 3°Sequenza 4°Sequenza 5°Sequenza 6°Sequenza

Corrispondenza Header inizio

trasmissione Indirizzo

Indirizzo

negato Comando

Comando

negato

Header fine

trasmissione

Binario - 1001000 01100111 01110000 10001111 -

Decimale - 25 230 14 241 -

Tabella 9: conversione pacchetto carrispondente al bottone "down"

Alla pressione invece del bottone down viene inviato il comando 14, associato

alla funzione “Pause”, corrispondente al decremento del throttle del PWM di un

fattore pari a -50e-2.

70

1°Sequenza 2°Sequenza 3°Sequenza 4°Sequenza 5°Sequenza 6°Sequenza

Corrispondenza Header inizio

trasmissione Indirizzo

Indirizzo

negato Comando

Comando

negato

Header fine

trasmissione

Binario - 1001000 01100111 10100000 01011111 -

Decimale - 25 230 5 250 -

Tabella 8: conversione pacchetto corrispondente al bottone "reset"

Infine, premendo il bottone reset viene inviato il comando 5 (funzione “Play”),

utilizzato come sistema di sicurezza, attraverso il quale viene fermata la corsa

dei motori, indipendentemente dalla loro velocità di rotazione, ed il drone viene

resettato. Successivamente viene creato un oggetto di tipo Intent, che permette

di ritornare all’activity “Intro”, per poter far ripartire il drone senza dover

riavviare l’applicazione.

Sitografia e Bibliografia

[1] D. Beninato, «Introduzione ai microcontrollori PIC,» [Online]. Available:

http://www.dei.unipd.it/~ieeesb/PIC/PresentazionePIC_01.pdf.

[2] «STM32 Nucleo-64 development board with STM32L053R8 MCU,

supports Arduino and ST morpho connectivity,» [Online]. Available:

http://www.st.com/content/st_com/en/products/evaluation-tools/product-

evaluation-tools/mcu-eval-tools/stm32-mcu-eval-tools/stm32-mcu-

nucleo/nucleo-l053r8.html.

[3] «Jumper,» [Online]. Available:

https://www.techopedia.com/definition/5299/jumper.

[4] L. Tanganelli, «Alla scoperta delle schede di sviluppo STM32 Nucleo,»

[Online]. Available: http://www.settorezero.com/wordpress/alla-scoperta-

delle-schede-di-sviluppo-stm32-nucleo/.

[5] L. Frosini, «Ripasso sul campo magnetico rotante,» [Online]. Available:

http://www-3.unipv.it/dmae/materiale_didattico/Costruzioni_13.pdf.

[6] A. d. Gerlando, «Macchina sincrona,» [Online]. Available:

http://docenti.etec.polimi.it/IND32/Didattica/ME_professionalizzante/mat

eriale_didattico/dispense/5_MS.pdf.

[7] L. Frosini, «Il motore brushless (1° parte): principi di funzionamento,»

[Online]. Available: http://www-

3.unipv.it/dmae/materiale_didattico/Costruzioni_22.pdf.

[8] S. Keeping, «Introduzione al controllo dei motori c.c. brushless,» [Online].

Available: https://www.digikey.it/it/articles/techzone/2013/mar/an-

introduction-to-brushless-dc-motor-control.

[9] RC Timer, «Manual of RC Timer ESC 30A Brushless Motor Speed

Controller,» [Online]. Available: http://www.sarkanyellato.hu/wp-

content/uploads/2011/10/RC-Timer-10.18.30.40A-ESC-Instruction.pdf.

[10] FutureElectronics, «What is an Infrared Receiver?,» [Online]. Available:

http://www.futureelectronics.com/en/optoelectronics/infrared-

receivers.aspx.

[11] SBProject, «IR Remote Control Theory,» [Online]. Available:

http://www.sbprojects.com/knowledge/ir/index.php.

[12] D. Tan, «Infrared Remote Control Protocols: Part 1,» [Online]. Available:

http://irq5.io/2012/07/27/infrared-remote-control-protocols-part-1/.

[13] G. Singh, «NEC Protocol IR (Infrared) Remote Control With a

Microcontroller,» [Online]. Available:

http://www.circuitvalley.com/2013/09/nec-protocol-ir-infrared-remote-

control.html.

[14] Vishay Semiconductors, «Data Formats for IR Remote Control,» [Online].

Available: http://www.vishay.com/docs/80071/dataform.pdf.

[15] Tampere University of Technology, «Basic Principles of Inertial

Navigation,» [Online]. Available:

http://aerostudents.com/files/avionics/InertialNavigationSystems.pdf.

[16] InvenSense, «MPU-6050 Six-Axis (Gyro + Accelerometer) MEMS

MotionTracking™ Devices,» [Online]. Available:

https://www.invensense.com/products/motion-tracking/6-axis/mpu-6050.

[17] GeekMomProjects, «MPU-6050 Redux: DMP Data Fusion vs.

Complementary Filter,» [Online]. Available:

http://www.geekmomprojects.com/mpu-6050-redux-dmp-data-fusion-vs-

complementary-filter/.

[18] G. Wetzstein, «Quaternions & IMU Sensor Fusion with Complementary

Filtering,» [Online]. Available:

https://stanford.edu/class/ee267/lectures/lecture10.pdf.

[19] B. Bona, «Quaternioni,» [Online]. Available:

http://www.ladispe.polito.it/corsi/meccatronica/01GTG/2008-

09/Slides/Quaternioni.pdf.

[20] GeekMomProjects, «MPU-6050: DMP Data from i2cdevlib,» [Online].

Available: http://www.geekmomprojects.com/mpu-6050-dmp-data-from-

i2cdevlib/.

[21] Instructables, «IMU Part 2: Complementary Filter,» [Online]. Available:

http://www.instructables.com/id/PCB-Quadrotor-Brushless/step15/IMU-

Part-2-Complementary-Filter/.

[22] Robottini, «Kalman filter vs Complementary filter,» [Online]. Available:

http://robottini.altervista.org/kalman-filter-vs-complementary-

filter?doing_wp_cron=1381307547.0642869472503662109375.

[23] M. Agozzino, «Tracciamento di particelle con Filtro di Kalman,» [Online].

Available:

http://amslaurea.unibo.it/12064/1/Tracciamento%20di%20particelle%20c

on%20filtro%20di%20Kalman.pdf.

[24] «Alcuni concetti di statistica: medie, varianze, covarianze e regressioni.,»

[Online]. Available: http://www.apogeonline.com/2002/libri/88-7303-864-

6/ebook/pdf/864_appendice1.pdf.

[25] P. Medici, «Filtro di Kalman,» [Online]. Available:

http://www.ce.unipr.it/people/medici/geometry/node52.html.

[26] A. P. A. Mohinder S. Grewal, Kalman Filtering-Theory and Practice

Using MATLAB, A John Wiley & Sons, Inc., Publication, 2008.

[27] DroneBase, «Droni per fotogrammetria e rilievo,» [Online]. Available:

http://www.dronebase.it/prodotto/drone-per-fotogrammetria-x-cam-700/.

[28] W.-M. Lee, Android 4 Application Development, John Wiley & Sons, Inc.,

2012.

[29] Google, «Android Developers,» [Online]. Available:

https://developer.android.com/index.html.

[30] Google, «Intent,» [Online]. Available:

https://developer.android.com/reference/android/content/Intent.html.

[31] G. Maggi, «View: le basi dell’interfaccia grafica,» [Online]. Available:

http://www.html.it/pag/48742/view/.

[32] M. Petrioli, «Analizziamo il nostro progetto (1a parte),» [Online].

Available: http://www.mrwebmaster.it/android/analizziamo-nostro-

progetto-1a-parte_10602.html.

[33] LG Electronics, «LG QRemote SDK,» [Online]. Available:

http://mobile.developer.lge.com/develop/sdks/lg-qremote-sdk/.

[34] irdb, «Known IR protocols for NEC devices,» [Online]. Available:

http://irdb.tk/db/.