Maledette funzioni!!

paolometeo2:
La seriale software è richiesta dallo shield GPS. Ho copiato le istruzioni dallo sketch di esempio di Adafruit. Credo che l'inizializzazione sia dentro la funzione di libreria GPS.begin(9600).

Giusto, non pensavo a questo.

Ecco il programma completo in Attach. E' possibile definire 3 punti, che possono essere selezionati tramite i 3 pulsanti posti su LCD color. Il programma calcola la distanza con il punto selezionato e la direzione in cui si trova.

GPS_parsing_LSM303_LCD.ino (13 KB)

Paolo, perché non cambi il titolo alla discussione e alleghi il file nel primo topic con una spiegazione?
Il titolo lo devi cambiare sempre nel primo topic. :grin:

concordo con la modifica del titolo, e se alleghi uno schema elettrico sarebbe un ottimo topic da inserire in Megatopic.

Questo progetto e' importante, oppure e' sbagliato :slight_smile:
perche' dico questo ? perche' ci e' sempre stato detto che con arduiino non si potessero raggiungere precisioni al metro.

Come stanno le cose ?

x il discorso delle funzioni perche' dici che non puoi ragionare piu' con subroutine ?
Io ancora non uso funzioni con passaggi di parametri oppure return di valori, quindi appunto faccio tutto con funzioni Void e gestione dei dati via variabili globali. Non e' obbligatorio usare funzioni non void e con argomenti.
Domande:
ci sono casi in cui e' obbligatorio usare argomenti e return di valori?
usare funzioni "complete" e' questione di stile, di risparmio memoria, o entrambi ?
grazie

  1. non so se il progetto ha tutti i requisiti per andare in Megatopic (mancherebbe la questione del "grosso interesse")
  2. la questione dell'usare o meno funzioni con argomenti e/o con restituzione di valori (per favore, NON usate "ritornare": è un inglesismo schifoso, viene da "return", che suona stridente quanto "voltaggio" suona alle orecchie di un elettronico) non è una questione di gusti ma di necessità. Nel senso che le usi se ti servono. Se fai una funzione che applica un certo algoritmo ai parametri che riceve e poi restituisce il risultato in una var globale e questa funzione la chiami da più punti del programma, devi stare attento a non fare confusione nel codice perché potresti sovrascriverla.

Testato:
perche' dico questo ? perche' ci e' sempre stato detto che con arduiino non si potessero raggiungere precisioni al metro.
Come stanno le cose ?

Arduino non ha i double quindi i calcoli col GPS non si possono fare con risoluzione metrica, solo kilometrica, cosa ampiamente discussa nel topic dei quadricotteri.
Basta farsi un paio di calcoli di prova per capirlo, il gps fornisce valori fino a tre cifre intere e sei cifre decimali, i modelli migliori (=$$$) anche sette-otto, i float 32 bit al massimo rappresentano sette cifre tra parte intera e decimale.
In Italia la latidudine media è ~40°, la longitudine media è ~12° (andando molto a Nord scende sotto il valore di 10), ovvero valori con due cifre per la parte intera il che vuol dire perdere l'ultima cifra decimale fornita dal gps, poi mettiamoci gli errori di arrotondamento, molto pesanti per via della complessità del calcolo, ed ecco che la risoluzione minima reale diventa da molte decine di metri a diverse centinaia, la precisione reale è kilometrica.

leo72:
Se fai una funzione che applica un certo algoritmo ai parametri che riceve e poi restituisce il risultato in una var globale e questa funzione la chiami da più punti del programma, devi stare attento a non fare confusione nel codice perché potresti sovrascriverla.

Pero' se faccio attenzione a non sovrascriverla funziona tutto ? possiamo dire quindi che e' soggettivo usare argomenti+restituzioni rispetto a manipolazioni di var globali ?
Sotto l'aspetto dell'occupazione di memoria, oppure di velocita', ci sono differenza tra i due metodi ?

E' vero che ogni volta che crei una funzione che accetta dei parametri devi mettere questi dati nello stack, ma se usi una var globale e poi se devi parcheggiare la variabile globale in altre variabili, alla fine occupi lo stesso della memoria per le variabili tampone.

E comunque non è elegante :wink:

astrobeed:
ed ecco che la risoluzione minima reale diventa da molte decine di metri a diverse centinaia, la precisione reale è kilometrica.

quindi questo progetto ha un qualche errore di valutazione da qualche parte, visto che dichiara

Adesso, dopo queste prove, sono abbastanza sicuro che i float di Arduino sono abbastanza precisi da garantirmi qualche metro, che è la stessa precisione di un buon GPS.

leo72:
E' vero che ogni volta che crei una funzione che accetta dei parametri devi mettere questi dati nello stack, ma se usi una var globale e poi se devi parcheggiare la variabile globale in altre variabili, alla fine occupi lo stesso della memoria per le variabili tampone.
E comunque non è elegante :wink:

Grazie, sono metallaro :wink:
Diciamo che al punto dove sono ora, non essendo un programmatore, mi accontento di non essere elegante, l'importante e' che mentalmente mi risulta piu' facile ragionare sui codici che scrivo usando solo var globali. Logicamente resta cmq importante saper leggere una funzione con argomenti e return di valori, altrimenti non si capisce il codice che si vuole copiare scrivere :slight_smile:

Per "eleganza" intendo anche ottimizzato e leggibile. Anche per te stesso :wink:
Mi fai questo con una funzione che non restituisce niente e non accetta nessun valore? ]:smiley: ]:smiley:

int e = media(media(a, b), media(c, d));

int media(int temp1, int temp2) {
  return ((temp1 + temp2) / 2);
}

ci lavoro :slight_smile:

Assomiglia un sacco al mio, a Bassano non l'avevi visto Paolo ? :slight_smile:
Non uso una bussola digitale però salvo su SD, ho integrato una batteria al Litio ed un carica batterie tramite mini-usb, lo schermo è il classico nokia 5100 :slight_smile:
se vuoi ti posto il codice pure del mio se ti interessa :slight_smile:

Testato:

astrobeed:
ed ecco che la risoluzione minima reale diventa da molte decine di metri a diverse centinaia, la precisione reale è kilometrica.

quindi questo progetto ha un qualche errore di valutazione da qualche parte, visto che dichiara

Adesso, dopo queste prove, sono abbastanza sicuro che i float di Arduino sono abbastanza precisi da garantirmi qualche metro, che è la stessa precisione di un buon GPS.

Qui mi chiedo come sia possibile, il mio è abbastanza preciso ma tempo addietro feci delle prove nel calcolare la distanza ed in effetti l'errore era decisamente alto, ora non ho letto tutto il topic per mancanza di tempo però vorrei capire come sia possibile che l'errore su a me su cento metri ne segnava 180 e a te ? :slight_smile:
ciaooo

Testato:

leo72:
E' vero che ogni volta che crei una funzione che accetta dei parametri devi mettere questi dati nello stack, ma se usi una var globale e poi se devi parcheggiare la variabile globale in altre variabili, alla fine occupi lo stesso della memoria per le variabili tampone.
E comunque non è elegante :wink:

Grazie, sono metallaro :wink:
Diciamo che al punto dove sono ora, non essendo un programmatore, mi accontento di non essere elegante, l'importante e' che mentalmente mi risulta piu' facile ragionare sui codici che scrivo usando solo var globali. Logicamente resta cmq importante saper leggere una funzione con argomenti e return di valori, altrimenti non si capisce il codice che si vuole copiare scrivere :slight_smile:

l'uso di funzioni è migliore per evitare di ricopiare il codice in più punti e per dividere il codice in blocchi indipendenti.
il salto di funzione impiega tempo per scrivere i dati nello stack, oltre che lo stato attuale dei registri, e poi ricaricare il tutto al momento del ritorno. Però è anche vero che il compilatore può decidere di rendere delle funzioni "inline", ovvero al momento della pre-compilazione decidere che l'uso di una funzione è inefficiente e copiare il codice contenuto nella funzione al posto della chiamata: puoi anche specificare al compilatore di comportarsi così (o meglio suggerirlo, visto che può ignorare la cosa) con la keyword "inline".

Qui mi chiedo come sia possibile, il mio è abbastanza preciso ma tempo addietro feci delle prove nel calcolare la distanza ed in effetti l'errore era decisamente alto

infatti, sarebbe da fpreparare un bell'elenco di coordinate GPS con risultati attesi calcolati con una buona precisione, e magari scelte con un criterio tra le più balorde, così d'ora in poi abbiamo tutti un buon punto di riferimento per -dimostrare- che il codice funziona.

Si usa dire "pics or it didn't happen", per il nostro caso lo cambierei in "TEST or it didn't happen" XD

Arduino non ha i double quindi i calcoli col GPS non si possono fare con risoluzione metrica, solo kilometrica, cosa ampiamente discussa nel topic dei quadricotteri.
Basta farsi un paio di calcoli di prova per capirlo, il gps fornisce valori fino a tre cifre intere e sei cifre decimali, i modelli migliori (=$$$) anche sette-otto, i float 32 bit al massimo rappresentano sette cifre tra parte intera e decimale.
In Italia la latidudine media è ~40°, la longitudine media è ~12° (andando molto a Nord scende sotto il valore di 10), ovvero valori con due cifre per la parte intera il che vuol dire perdere l'ultima cifra decimale fornita dal gps, poi mettiamoci gli errori di arrotondamento, molto pesanti per via della complessità del calcolo, ed ecco che la risoluzione minima reale diventa da molte decine di metri a diverse centinaia, la precisione reale è kilometrica.

@astro, non capisco perché insisti sul discorso precisione. Ho fatto parecchi confronti tra distanze calcolate da Arduino, tra due punti di coordinate date dal GPS, e le stesse calcolate con un programma Fortran in doppia precisione (real*otto), oltre a calcolarle con una HP di buona memoria. Se le coordinate si riferiscono ad aree italiane con distanze dell'ordine di qualche chilometro, i calcoli danno precisioni di qualche metro. Ho fatto prove anche sul campo.
@PaoloP, se interessa posto cambiare titolo al topic, mi rimetto però al parere del moderatore. Convengo anch'io che qui si sono mischiati due topic. Uno di tipo software sulle funzioni e l'altro sul GPS.
Scusate tutti se rispondo tardi, ma sono in vacanza e non trovo spesso connessioni veloci. Comunque le discussioni innescate mi interessano.
paolo

paolometeo2:
[@astro, non capisco perché insisti sul discorso precisione. Ho fatto parecchi confronti tra distanze calcolate da Arduino, tra due punti di coordinate date dal GPS, e le stesse calcolate con un programma Fortran in doppia precisione (real*otto),

Perché quanto affermi è impossibile, nel topic su i quadricotteri la cosa era stata sviscerata nei minimi dettagli, con tanto di calcoli e software di esempio per Arduino.
La matematica è una scienza esatta, non puoi calcolare con precisione metrica la distanza tra due coordinate gps con solo sei cinque, se non solo quattro (dipende dalla parte intera) cifre decimali significative, per giunta con dei calcoli trigonometrici di mezzo, servono almeno 10 cifre significative dopo la virgola, cosa per la quale sono indispensabili i double.

Perché quanto affermi è impossibile, nel topic su i quadricotteri la cosa era stata sviscerata nei minimi dettagli, con tanto di calcoli e software di esempio per Arduino.
La matematica è una scienza esatta, non puoi calcolare con precisione metrica la distanza tra due coordinate gps con solo sei cinque, se non solo quattro (dipende dalla parte intera) cifre decimali significative, per giunta con dei calcoli trigonometrici di mezzo, servono almeno 10 cifre significative dopo la virgola, cosa per la quale sono indispensabili i double.

Il mio ragionamento è semplice. Un grado in latitudine corrisponde a circa 110 km, questo vuol dire che 1 m è circa 1/100000 gradi. Cioè siamo sulla quinta cifra decimale della latitudine. Per la longitudine, alle nostre latitudini, la distanza è circa 70 km, quindi siamo lì. La distanza è calcolata come se lat e long fossero coordinate cartesiane su piano e questo è vero per distanze dell'ordine di pochi chilometri. La conversione tra differenze in gradi e metri è fatta moltiplicando per un fattore pari a R*pi/180 dove R è il raggio terrestre medio e pi = pi greco. L'unico calcolo trigonometrico è il coseno della latitudine quando si calcola la distanza tra due longitudini.
Ho fatto una prova su una distanza dell'ordine di un centinaio di metri, misurando con una bindella, e le cose tornano a meno di qualche metro.

paolometeo2:
Il mio ragionamento è semplice. Un grado in latitudine corrisponde a circa 110 km, questo vuol dire che 1 m è circa 1/100000 gradi.

Se ti "inventi" dei calcoli che sono validi solo in un ristretto range di lat. e long, per giunta approssimati su un piano, è un altro paio di maniche, però un sistema che calcola il vettore tra due coordinate gps non può essere limitato a solo una certa zona e per spazi di pochi km, magari risolve il tuo problema però non va bene per un uso generico.
Io ho perso molto tempo per trovare una semplificazione per questo calcolo, rispetto a quello canonico che tiene conto del modello geodetico, con una approssimazione valida per tutto il globo, salvo le zone polari, con buoni risultati a patto di introdurre un fattore correttivo per ogni 250 metri di dislivello s.l.m., però puoi scordarti di fare questi conti con solo i float.

Concordo con te che una formula generale per tutto il globo non funzionerebbe a 32 bit, però ti assicuro che le approssimazioni che faccio, possono essere estese ad un'area abbastanza ampia, sicuramente tutta l'Italia e oltre. A meno che un quadricottero non faccia la traversata dell'Atlantico :D, si può sempre trovare una buona approssimazione. Tieni anche conto che un normale GPS non consente precisioni maggiori di qualche metro.

quindi si insiste sulla questione, e questo e' bello. :slight_smile:

ricapitolando paolo tu stai dicendo che con arduino uno, 328P, potresti impostare le coordinate di arrivo di un modellino in partenza da roma (ti vengo in contro :)) verso il duomo di milano, e che questo, avendo tutto cio' di cui occorre (benzina, batterie, fortuna, aiuto del signore) e leggendo in realtime le coordinate di un gps a bordo, riuscirebbe ad atterrare nella piazza del duomo ?