Official topic: multicotteri con arduino!

astrobeed:
Premesso che pure a me non piace come è scritto MulitWii, ma per altri motivi, mi spieghi cosa c'entrano le classi col scrivere un programma diviso in più file ?
Guarda che nulla vieta di usare un file per ogni funzione con i relativi file.h, tecnica normalmente usata quando su un programma ci lavora più di una persona.
Lo stesso IDE di Arduino permette di dividere il programma in più file, cosa praticamente obbligatoria da fare quando lo sketch cresce troppo per via delle pesanti limitazioni dell'editor dell'IDE di Arduino, cosa a cui preferisco ovviare utilizzando un vero editor per programmatori esterno.
Per quanto riguarda le #define in buona parte servono per la compilazione condizionale, ovvero permettono di decidere quali parti del programma compilare in funzione dell'hardware utilzzato, pure queste non hanno nulla a che vedere con le classi e sono indispensabili, semmai poteva raggrupparle in un apposito file .h di definizione invece di lasciarle dentro il programma rendendolo ostico da leggere.

io uso una classe per gestire i motori, contenuta nella classe del pid, poi una classe "stabilizzazione" che esegue l'algoritmo che contiene una classe IMU che legge i sensori, ed infine una classe che si occupa di leggere la radio tramite interrupt. ogni sensore/algoritmo di stabilizzazione/settaggio dei motori è (virtualmente, visto che per ora ce né solo una) una classe a parte. Il codice rimane molto più pulito e intercambiabile, e comunque un ciclo di aggiornamento dura meno di 2ms..

scusami ma quà non sono d'accordo. Il vantaggio delle classi, è che oltre a contenere funzioni possono contenere anche valori. In pratica sono una struct che oltre a contenere variabili, contiene anche funzioni (cosa possibilissima da fare in C usando puntatori a funzioni, credo che siano stati fatti proprio così i linguaggi ad oggetti...)

in oltre esiste una cosa chiamata ereditarietà ed overloading dei metodi. Per esempio, la mia classe astratta dei sensori non può essere usata (è astratta), ma può essere estesa. nell'estensione puoi scrivere tutto il codice che vuoi, ma sei costretto a fornire i metodi della classe astratta, ovviamente seguendo le linee guida contenute in essa. Quindi, nel mio caso, sei costretto a creare un metodo init() che eventualmente inizializza il sensore, un metodo update() che legge i volori dai sensori, e un metodo leggi() che ritorna un array di float dal sensore (come e cosa ci sia nell'array è una linea guida che varia dalla tipologia)
Il mio programma terrà la tua classe in una variabile di tipo superclasse astratta, quindi potrà usare solo i metodi che ti ho esplicitamente costretto a creare, ma questio metodi al loro interno potranno usare tutte le funzioni di classe. Quindi se vuoi cambiare un sensore, non modifichi le define, ma solo l'istanziamento della classe.
Così eviti tutta la storia della compilazione condizionale, anzi, se vuoi modificare un sensore, sai subito dove mettere le mani, anzichè impazzire in un pde chilometrico.

Poi ovvio che puoi usare le librerie, ma io sono un fan della programmazione ad oggetti (anche se un poco rallentano il codice)

astrobeed:

Quando finalmente riuscirò a fare il primo volo(cioè appena sistemo definitivamente il wmp+nunchuck) posterò tutto il codice.

Il mio consiglio è di lasciar perdere il Nunchuk come sensore accelerometrico, troppo bassa la risoluzione per essere realmente utile, con gli stessi soldi acquisti un sensore decisamente migliore e senza tutti i problemi di interfacciamento attraverso il WMP.

già, l'ho notato, ma è quello che ho in casa. E fare un ordine apposta spendo più dispedizione che di sensore. Certo ci fosse qualcosa che trovi al supermarket...

astrobeed:

superlol:
non per fare il pingolo ma le dev sono divise in diversi files ma poi nelle stable sono riuniti in uno per semplificare la vita poi a chi deve fare il quadri che non sempre è un esperto di arduino-elettronica.

Guarda che il problema del MultiWii non è come è suddiviso in file, è una questione secondaria, il vero problema è che ci sono molte cose che sono scritte alla come capita capita e/o di puro copia incolla preso dal web, p.e. il pid non è vero pid, il kalman è molto generico e poco efficace, e tante altre cosette.
Intendiamoci non intendo denigrare il lavoro dell'autore, anzi tutt'altro, però ci sono grossi margini di miglioramento per le prestazioni, zero margini per aggiungere nuove funzionalità perché siamo al limite della CPU.

una cosa che non ho ancora capito è perchè hanno riscritto il protocollo i2c usando direttamente i registri...che gli costava usare la wire.h?

Stamattina sono buono, ricordati che le coordinate GPS sono referenziate ad un determinato modello geodetico, quindi per poterle utilizzare devi tenere conto anche del modello su cui lavorano.
Se pensi che determinare la distanza tra due coordinate GPS, anche di punti vicini, sia una cosa semplice e che esiste una formuletta semplice per farlo allora non sai in guaio ti stai cacciando smiley-grin

pensavo ad un atmega solo per il GPS... però devo ammettere che ancora non ho iniziato nemmeno a spulciare il protocollo e la sua "traduzione". Quando sarà tempo (ovvero il quad vola, con magnetometro e barometro che ancora devo comprare e implementare) sicuramente ci sbatterò la testa, e se ardino dovesse fallire (e le finanze lo permetteranno :P) mi prenderò volentieri qualcosa di superiore come il dsPIC33 o (non vedo l'ora) un'ARM.

lesto:
scusami ma quà non sono d'accordo. Il vantaggio delle classi, è che oltre a contenere funzioni possono contenere anche valori

Voglio sperare che non stai cercando di spiegare a me cosa sono e a cosa servono le classi ? :slight_smile:

Così eviti tutta la storia della compilazione condizionale, anzi, se vuoi modificare un sensore, sai subito dove mettere le mani, anzichè impazzire in un pde chilometrico.

Ecco qui ti sfugge completamente il senso della compilazione condizionale, che tra parentesi si usa anche in C++.

ma io sono un fan della programmazione ad oggetti (anche se un poco rallentano il codice)

Un poco ?
Il peso, in termini di memoria usata, sia flash che ram, e di rallentamento velocità d'esecuzione è molto alto, sopratutto su una piccola MCU a 8 bit, e questo è uno dei motivi della lentezza di Wiring.
Per lavorare in modo efficiente, parliamo di software di sistema e controllo di processo, su una piccola MCU, ma anche su un super micro, il solo ed unico linguaggio, a parte l'assembly, è, e almeno per il momento rimane, il C ANSI, tutto il resto è fuffa :slight_smile:

già, l'ho notato, ma è quello che ho in casa. E fare un ordine apposta spendo più dispedizione che di sensore. Certo ci fosse qualcosa che trovi al supermarket...

Ovvio che non ha senso spendere 10 Euro di corriere per 15-20 Euro di merce, però alla prima occasione metti in conto la sostituzione del Nunchuk con un normale accelerometro.

una cosa che non ho ancora capito è perchè hanno riscritto il protocollo i2c usando direttamente i registri...che gli costava usare la wire.h?

Non ho ancora approfondito il discorso I2C del MultiWii, ma credo abbia riscritto le routine per renderle più efficienti ed evitare alcune condizioni di blocco che ci sono nelle wire.h

pensavo ad un atmega solo per il GPS... però devo ammettere che ancora non ho iniziato nemmeno a spulciare il protocollo e la sua "traduzione".

Il problema non è interpretare le sentenze NMEA, sono solo delle stringhe ASCII con un certo formato e i dati sono scritti in chiaro, ecco un esempio:

$GPRMC,151036.999,A,4536.81050,N,00857.63140,E,0.09,27.90,260308,,,A*5F

$GPRMC è l'identificatore della sentenza, ne esistono molti tipi diversi perché si usano anche per altra tipologia di strumenti.
151036.999 ora UTC (hhmmss.sss)
A stato: A = Active, valido; V = Void, nullo
4536.81050 latitudine (ddmm.mmmmm)
N N = nord; S = sud
00857.63140 Longitudine (dddmm.mmmmm)
E E = est; W = ovest
0.09 Velocità in nodi
27.90 Direzione di movimento in gradi reali
260308 Data (ddmmyy)
Variazione / Declinazione Magnetica in gradi ()
Versi della variazione / declinazione (
)
A Tipo di rilevazione: A = Autonomous
*5F Checksum

Alcuni campi possono non essere presenti, sono quelli vuoti tra le virgole, dipendono dalle caratteristiche tecniche del GPS, in pratica basta un parser per estrapolare in un vettore i dati reali che ci interessano.
Il vero problema è tutta la parte matematica necessaria per calcolare la distanza tra due coordinate GPS e che, per via della risoluzione richiesta, è obbligatorio l'uso della matematica a 64 bit.

la compilazione condizionale rimane, ma anzichè essere sparsa per tutto il codice rimane solo all'inizializzazione delle classi. molto più comodo no?

per quanto riguarda la lentezza, sinceramente per ora uso circa 7 o 8 classi, ma non ho assolutamente problemi di lentezza del codice, quindi non vedo perchè preoccuparsi (per ora). Pensavo di diminuire di 2 classi, semplicemente evitando di usare una classe per sensore (una per i giro, una per gli accelerometri, etc..) e usarne una "globale" detta IMU (già presente che raccoglie le classi sensori). Ma comunque per ora devo far andare i sensori :slight_smile:

per l'i2c ho notato che la wire è bloccante, e l'unico modo per non essere "bloccati" è usando gli interrupt (fornisce già le funzioni da "overridare")

per il GPS sarebbe da aprire un post a parte perchè bisognerebbe prima di tutto capire quale matematica serve, creare il tipo di dato adatto, e mettere assieme tutti i pezzi.. non facile

Per il gps io ci sono, ho anche un gps da 40e che ancora non ho avuto tempo di interfacciare ad arduino...
Invece per la questione di ampliamento delle funzionalita', non si potrebbe pensare di usare 2 o piu' atmega?

lesto:
....

per il GPS sarebbe da aprire un post a parte perchè bisognerebbe prima di tutto capire quale matematica serve, creare il tipo di dato adatto, e mettere assieme tutti i pezzi.. non facile

http://arduino.cc/playground/Multiwii/GPS

ragazzi io posso darvi una mano per l' algoritmo del gps, ma solo in modo teorico, perchè nono ho ancora messo l emani ne su arduino ne su un gps, e quindi sono un po con le mani legate...

beh comunque come ha detto astro bisogna ripiegare su un altro processore, però credo sia fattibile poi si potrebbe senza fare troppe modifiche al codice multiwii attaccare i giroscopi ecc a questa MCU che legge anche i dati e ricrea dei "falsi" dati come venissero dalla IMU in modo da ridirigere nel punto giusto il quadri :roll_eyes: insomma un lavoro disumano ]:smiley:

Fino a domani tarda mattinata sono incasinato con un lavoro che devo assolutamente finire, dopo vi passo la matematica di base necessaria per calcolare il vettore 3D, quindi modulo e due angoli, tra due coordinate GPS non sulla stessa quota, così finalmente vi rendete conto della quantità di calcoli e della loro complessità.

p.s.
Anche volendo semplificare la cosa ragionando solo in 2D non è che cambia molto la complessità del tutto, per passare dal 2D al 3D finale basta applicare Pitagora.

superlol:
beh comunque come ha detto astro bisogna ripiegare su un altro processore, però credo sia fattibile poi si potrebbe senza fare troppe modifiche al codice multiwii attaccare i giroscopi ecc a questa MCU che legge anche i dati e ricrea dei "falsi" dati come venissero dalla IMU in modo da ridirigere nel punto giusto il quadri :roll_eyes: insomma un lavoro disumano ]:smiley:

Si e che MCU???
voglio dire se comincia a diventare un ARM magari in package strani da 200 pin diventa complicato l'uso per utenti normali e non super accessoriati... e per di più non è più arduino :grin:

ratto93:
Si e che MCU???

Da decidere.

voglio dire se comincia a diventare un ARM magari in package strani da 200 pin diventa complicato l'uso per utenti normali e non super accessoriati... e per di più non è più arduino :grin:

Esistono molte board con ARM che costano relativamente poco e sono già dotate di tutto quello che serve per farlo funzionare.
Ho già linkato a titolo d'esempio l'mBed che ha i connettori a passo 2.54 pertanto facilmente utilizzabile, oltretutto ha una filosofia di programmazione molto simile ad Arduino anche se non usa Wiring, ovvero non è necessario sapere esattamente come funzionano le periferiche interne e la miriade di registri macchina per farlo funzionare.
Arduino ha i suoi limiti, la navigazione real time con GPS è uno di questi.

vi scrivo un algoritmo in linguaggio "umano" poi è da implemetare... io farei cosi, è molto rozzo ma dovrebbe funzionare con poca potenza di calcolo:

assumerei la posizione attuale, come posizione 0;0 del piano cartesiano quindi:

x = longTarget - longAttuale
y = latTarget - latAttuale

quindi:
distanza = sqrt(x^2*y^2)

avendo i 2 cateti, posso sapere l' angolo, quindi

a = arctg(x/y)

ora il problema è: come faccio a ruotare il multicottero di a??? (questo vedetelo voi perche non posso fare porve :D)

poi per semplificare sia la parte dell altitudine, sia evitare di troare ostacoli, salirei ad un altezza si 20m, mi ruoterei e poseguirei verdo il target, controllando 2 volte al secondo la direzione e la distanza

quando

distanza < 1m

mi fermo e scendo alla quota target

la distanza iniziale, non sara corretta, ed avrà un errore rilevante, ma ricalcolando la distanza, l' errore diminuisce, e siccome il tragitto effettivo, è maggiore di quello rettilineo calcolato, si arriverà ad un punto in cui il rov, avra effettuato piu metri di quelli calcolato all inizio, ma sara comunque a piu di 1m dal target, e quindi continuerà a muoversi in quella direzione, sarebe utile rallentare quando la distanza dal target è di 10m.... per muoversi, in modo obliquo, direttamente verso il punto target, è un problema sia di calcolo, che di controllo del mezzo, perche muoversi con un angolo da terra di tot gradi puo creare problemi con la gestione della potenza dei motori, visto che sono loro che si occupano di sollevarsi di quota

Ho già linkato a titolo d'esempio l'mBed che ha i connettori a passo 2.54 pertanto facilmente utilizzabile......

Perdono,,, mi era sfuggito....

aggiornato playground multiwii chiedo conferma nelle resistenze di pullup e pin, inoltre ho messo giù le prime idee per il GPS (messo le equazioni di milvusmilvus e la scheda di Astrobeed, ovviamente potete editare quello che vi pare, mi pare ovvio, anzi FATELO!!! XD)

Come leggevo sul forum di baronerosso.it dove multiwii e' usato le informazioni di cui parliamo noi non arrivano all'esterno, quindi e' importante generare il wiki e magari aprire un canale di comunicazione con l'autore di multiwii per correggere il software alla luce delle indicazioni di astrobeed e le prove fatte. Per altro, se il codice di multiwii fa shifo, si potrebbe migliorare, proporlo o alla peggio, forkarlo. Per dire che oltre alla lamentela c'e' tutto un mondo quando si parla di free software :grin:

milvusmilvus:
assumerei la posizione attuale, come posizione 0;0 del piano cartesiano quindi:
x = longTarget - longAttuale
y = latTarget - latAttuale

quindi:
distanza = sqrt(x^2*y^2)

Sei totalmente fuori strada, magari fosse così semplice, prima di tutto longitudine e latitudine non sono ascissa e ordinata del piano cartesiano, sono una posizione angolare su uno sferoide, inoltre la distanza per ogni singolo grado non è una costante.

la distanza iniziale, non sara corretta, ed avrà un errore rilevante, ma ricalcolando la distanza, l' errore diminuisce, e siccome il tragitto effettivo, è maggiore di quello rettilineo calcolato, si arriverà ad un punto in cui il rov,

Esiste un principio fisico chiamato "propagazione degli errori" che inficia immediatamente il tuo ragionamento.

A proposito, sempre come idea GPS base, con un gps si potrebbe registrare tutto il viaggio che fa il velivolo e tenere una storia di dove hai volato, come diario di bordo. Che cosa romantica :drooling_face:

Federico:
Per altro, se il codice di multiwii fa shifo,

Mai detto questo, ho detto che ci sono cose da rivedere, altre da modificare e migliorare, devo capire se vale la pena mettersi a correggere/modificare quel software oppure realizzarne uno nuovo, per il momento propendo più per la seconda.

lesto:
per quanto riguarda la lentezza, sinceramente per ora uso circa 7 o 8 classi, ma non ho assolutamente problemi di lentezza del codice, quindi non vedo perchè preoccuparsi (per ora).

La lentezza non dipende da quanti oggetti usi, questi semmai incidono sulla memoria usata, sia flash che ram, dipende da come devono essere gestiti a livello software di sistema, inoltre è wiring stesso ad usare gli oggetti.

per l'i2c ho notato che la wire è bloccante, e l'unico modo per non essere "bloccati" è usando gli interrupt (fornisce già le funzioni da "overridare")

Basta introdurre dei timeout senza scomodare gli interrupt, il blocco avviene perché le librerie usano un polling eterno sui flag della periferica e se c'è un intoppo non ne escono più.

astrobeed:

milvusmilvus:
assumerei la posizione attuale, come posizione 0;0 del piano cartesiano quindi:
x = longTarget - longAttuale
y = latTarget - latAttuale

quindi:
distanza = sqrt(x^2*y^2)

Sei totalmente fuori strada, magari fosse così semplice, prima di tutto longitudine e latitudine non sono ascissa e ordinata del piano cartesiano, sono una posizione angolare su uno sferoide, inoltre la distanza per ogni singolo grado non è una costante.

la distanza iniziale, non sara corretta, ed avrà un errore rilevante, ma ricalcolando la distanza, l' errore diminuisce, e siccome il tragitto effettivo, è maggiore di quello rettilineo calcolato, si arriverà ad un punto in cui il rov,

Esiste un principio fisico chiamato "propagazione degli errori" che inficia immediatamente il tuo ragionamento.

togliete quetse formule dal playground prima che qualcuno le usi e magari si faccia pure male...

secondo me sul playground andrebbero messi progetti ga completati, o per lo meno testati, quello che ho postato io, era un idea, un abbozzo che ho posto alla vostra attenzione

riguardo latitudine e longitudine, non sono ascissa e ordinata, ma il loro funzionamento è simile.

prova ad eseguire in maniera "automatica" quel algoritmo, e vedi che funzionalmente dovresti avere dei risultati forse però conviene che invece di calcolare la distanza per fermarsi, conviene cerificare che latitudine e longitudine rientrino entro un certo range di valori rispetto al target.

mi puoi dire che idea hai tu sul come implementare il sistema, senza avere limiti di potenza di calcolo, vorresti per carso calcolare la curva che unisce il punto di partenza e quello di arrivo, poi come faresti a farla rispettare al rov? controlleresti che ogni punto di rilevamento delle coordinate sia sulla curva? e in caso di errore ricalcoli l' itinerario?? secondo me avresti lo stesso problema che cercare di eseguire una traettoria rettilinea (ed obliqua tra i due punti, dovendo gestire potenza dei motori per lo spostamento in avanti, e per variare la quota)

non so magari il metodo è piu semplice o piu complesso, ma a me per ora sono venute in mente solo queste 2 idee, comunque domani, provero il mio algoritmo, con il gps in mano una calcolatrice ed una bussola.... e vedo se riesco ad arrivare ad un punto prefissato :D, sembrerò un pazzo che cammina in un campo con un gps in mano :smiley: ma fa niente :smiley: