sabato 31 dicembre 2011

Correva l'anno 0x07DC

Eccolo che arriva ...è già passato per la Nuova Zelanda, l'Australia, il Giappone, la Cina, la Russia ...eccolo sta arrivando anche qui, di corsa come tutti gli anni.
Di corsa vengono e di corsa se ne vanno. Viaggiano a 15°/ora lungo i Meridiani, sono i nostri anni, qui, sul Pianeta Terra! Sul Pianeta Marte sarebbe tutto diverso, infatti per i marziani oggi è un giorno come un altro! Non ci saranno mica dei marziani tra Noi?


L'anno 0x07DB (2011 in notazione decimale) volge al termine. Ma come lo abbiamo utilizzato? Quale eredità lascerà all'anno 2012 che sta arrivando? Questa è davvero una domanda difficile...

Ed il Blog Libera Elettronica quale modesto contributo ha dato per questa Civiltà (!?) del Pianeta Terra? Nel video che segue ho riassunto alcuni temi che trovate nei precedenti articoli. Guardiamolo insieme...


Certamente, si poteva fare di più e meglio, ma considerate che per fare tutto ciò ci sono volute centinaia di ore di lavoro. Tutto è stato realizzato "from scratch" ...nessun copia-incolla.

Tutto è stato fatto per Voi che siete i miei stimatissimi lettori.
Tutto è stato fatto per la libera circolazione della conoscenza, delle idee, delle iniziative ...ecco perché Vi trovate nella Libera-Elettronica. Non ho mai chiesto contributi economici, mai li chiederò e mai li rifiuterò ;) ma esistono molti modi per contribuire all'attività del blog, spesso basati sul libero scambio :)

Infine, per coloro che stanno seguendo il Mini tutorial C...

/* Happy New Year */
#include <stdio.h>
int main()
{
    short year = 0x07DC;
    printf("\nBuon %d!\n", year);
    return 0;
}

Non mi resta che augurarvi un sereno Anno 2012 ...pardon, volevo dire Anno 0x07DC.

Qui Pianeta Terra, a presto con tantissime novità! Ciro.

venerdì 30 dicembre 2011

Mini Tutorial C - Lesson 5

Benvenuti nell'ultima parte del Mini Tutorial C, per l'anno 2011 che ormai volge al termine. Questo post è dedicato alla Free Software Foundation e, quindi, come non inserire Richard Matthew Stallman tra le foto che ho allegato ad ogni lezione.

e co-autore del Compilatore GNU GCC ...il compilatore!)

Oggi esploreremo un altro frammento di codice ANSI C, cercando di introdurre nuovi elementi sintattici. Uno per tutti #ifdef ovvero come istruire il preprocessore nella compilazione condizionale.

Andiamo subito a vedere il codice odierno:

/* Mini Tutorial C - Lesson 5 */

#include <stdio.h>
#include <string.h>

/* another preprocessor directive */
#define DEBUG

/* global variable */
char g_string[80];

/* String Reverse function */
void str_reverse(int len, char* str)
{
    /* define local variable */
    int i;
   
    /* string walk */
    for (i=0; i<len; i++) {
        /* copy the input variable into global string */
        g_string[i] = str[len - i - 1];
        g_string[len+1] = '\0'; //ASCIIZ string terminator
    }

    return;
}

/* entry point */
int main()
{
    /* define a string buffer */
    char str_buf[80];

    /* other variable */
    int input_len = 0;

    /* output a question */
    printf("Write Your name and press ENTER\n");
   
    /* read response */   
    scanf("%s", str_buf);

#ifdef DEBUG //preprocessor in action
    printf("Your Input == %s\n", str_buf);
#endif

    input_len = strlen(str_buf);
   
#ifdef DEBUG //preprocessor in action
    printf("String Len == %d\n", input_len);
#endif

    /* reverse char order */
    str_reverse(input_len, str_buf);

    /* print result */
    printf("The reverse of Your name is: %s\n", g_string);
   
    /* terminate program */
    return 0;
} 

Compiliamo con il comando:
gcc lesson5.c -o lesson5

Eseguiamo... e cerchiamo di scoprire i limiti di questo programma.
Come sempre sta a voi modificare il codice e vedere come cambia il risultato.
E' il miglior modo per imparare!

Vediamo per passi cosa rappresenta questo programma:
  • lo scopo principale è quello di invertire il contenuto di una stringa, fornita in ingresso mediante il canale stdin (standard input). Es. Pippo => oppiP.
  • il programma è suddiviso in due funzioni: main() e str_reverse()
  • main() rappresenta il punto di entrata e uscita dal programma, è una funzione standard, mentre str_reverse() è una funzione custom, cioè il nome, i parametri di ingresso-uscita e il comportamento, li scegliete Voi che siete i programmatori.
  • nei precedenti post del Mini Tutorial, che trovate qui, abbiamo utilizzato la libreria stdio, mentre oggi includiamo anche una funzione dalla libreria string, pertanto, troverete la relativa direttiva di include.
  • la funzione della libreria string che andremo a utilizzare è la strlen() che ci dirà di quanti caratteri è costituita la nostra string ASCIIZ. Cosa significa ASCIIZ? Una stringa terminata con il carattere 0x00 ovvero '\0'. Zero, null'altro che Zero ...è un token che serve a delimitare la stringa.
  • tra le direttive del preprocessore, oggi, abbiamo utilizzato quella per la compilazione condizionale #ifdef, in pratica se la costante simbolica DEBUG è definita, quella porzione di codice verrà compilato e aggiunto al nostro programma, altrimenti no!

Qui Pianeta Terra, a presto!


giovedì 29 dicembre 2011

Mini Tutorial C - Lesson 4

Proseguiamo con il nostro Mini Tutorial,
come avrete capito dai precedenti articoli che trovate qui, qui e qui, il corso non lo scrivo Io, ma lo fate Voi, che siete i miei stimatissimi lettori, modificando il codice proposto, per vedere come cambia il risultato finale.

 (Dennis Ritchie, padre fondatore del Linguaggio C,
scomparso purtroppo in questo anno 2011
...mi piacerebbe potergli dire ancora una volta Grazie!
Ognuno di noi può leggere la sua biografia qui 
su Wikipedia, la nostra Enciclopedia preferita!)

Tornando con i piedi sul nostro Pianeta Terra ...senza di voi parlerei al vento, ma dalle statistiche del blog vedo che siete sempre più numerosi e appassionati (NdC, Nota di Ciro: mi accorgo che molte visite provengono da paesi esteri ...questo blog è in Lingua Italiana, quella derivata dagli Antichi Romani, pertanto, mi scuso con i miei lettori se devono fare un passo in più con traslator.google.com. Cerco di commentare il codice in Lingua Inglese, considerandola come una lingua franca!).

Guardiamo subito il codice di oggi:

/* Mini Tutorial C - Lesson 4 */

#include <stdio.h>

/* global variable */
char g_string[] = {"Global!"};

/* C custom function declaration and definition */
void my_function(char* str)
{
    printf("%s\n",str); /* what is this? */
    return;
}

/* the entry point */
int main()
{
    /* define and initialize a local constant string */
    char l_string[] = {"Local!"};
   
    /* call a custum function passing a poiter */
    my_function(g_string);

    /* modify a global variable ...and recall the funtion */
    g_string[6] = '?'; //this is a char
    my_function(g_string);
   
    /* same as the previous, but passing an address */   
    my_function(&g_string[0]);

    /* same as the previous, but passing a local string */   
    my_function(l_string);

    return 0;
}

Cosa fa questo programma?
Semplice! Introduce il concetto di Funzione, di Variabile Globale e di Puntatore alla Variabile.

Compiliamo il codice con il comando:
gcc lesson4.c -o lesson4

Eseguiamo con il comando:
./lesson4

L'output sarà:
Global!
Global?
Global?
Local!

Se ci sono domande Vi aspetto nei commenti. Oggi non c'è nessun trabocchetto!!!
Qui Pianeta Terra, a presto! Ciro.

lunedì 26 dicembre 2011

Mini Tutorial C - Lesson 3

Ecco subito la terza parte, non Vi lascio in attesa!
Le due precedenti lezioni le trovate qui e qui.


Augusta Ada Byron, meglio nota come Ada Lovelace, è stata una matematica inglese, nota soprattutto per il suo lavoro alla macchina analitica ideata da Charles Babbage.
I suoi appunti sulla macchina includono quello che è conosciuto come il primo algoritmo inteso per essere elaborato da una macchina, tanto che ella è spesso ricordata come la prima programmatrice di computer al mondo

Guardiamo, immediatamente, il codice ANSI C:

/* Mini Tutorial C - Lesson 3 */

#include <stdio.h>

int main()
{
    /* list of declarations */
    char idx = 0;
   
    /* cycle */
    do {
        printf("I'm on cycle, step: %d\n", idx);

        /* multiple conditions */
        switch (idx) {
            case 0:
                printf("   idx value: %d\n", idx);
                break;
            case 1:
                printf("   idx value: %d\n", idx);
                break;
            case 2:
                printf("   idx value: %d\n", idx);
                break;
            default:
                printf("   idx value: %d\n", idx);
                break;
        }

    } while (++idx <= 5);

    /* endless loop */ 
    while (1) printf("Break me with CTRL-C, ");

    return 0;
}

Copiamo e incolliamo il codice nel nostro editor preferito (GEDIT), salviamo con nome "lesson3.c" e compiliamo con il comando:

gcc -Wall lesson3.c -o lesson3

...eseguiamo con il comando:

./lesson3

Ecco fatto! Con qualche piccolo trabocchetto, iniziamo a prendere confidenza con i Cicli, le Condizioni Multiple e i Loop. Modificate il codice per vedere come cambiano i risultati ...è il miglior modo per imparare!

Qui Pianeta Terra, ...avete mai sentito parlare di ADA-95? A presto, Ciro.

venerdì 23 dicembre 2011

Mini Tutorial C - Lesson 2

Bentrovati!
Questa è la seconda lezione del Mini Tutorial C, la prima la trovate qui.

(Alan Touring ...uno dei pre-fondatori dell'era informatica)

Oggi parliamo (...in linguaggio C) di Liste, Cicli e Condizioni.
Come sempre lo faremo per esempi ed in forma pratica, con codice liberamente scaricabile (...copia e incolla nel tuo editor preferito) e compilabile con GCC, il mio "compilatore" open-source preferito!

Vi riporto subito il codice della seconda lezione.
Nota: stiamo lavorando ancora con una sola, semplice funzione, quella chiamata main(), che rappresentra l'entry point, cioè il punto di ingresso, di ogni programma C:

/* Mini Tutorial C - Lesson 2 */

#include <stdio.h>
#define SPACE 0x20

int main()
{
    /* list of declarations */
    char c = '!';
    short s = 32767;
    int i;
    float f = 0.1f;
    double d = 0.01f;
   
    /* cycle */
    for (i=0; i<10; i++) {
        printf("Short Integer Number: %d\n", s);
        s++;
        printf("Floating Point 32bit Number: %1.6f\n", f);
        f = f + 0.1f;
        printf("Floating Point 64bit Number: %1.12f\n", d);
        d = d + 0.1f;
    }

    /* condition */
    if (c == SPACE) {
        printf("char c = SPACE\n", c);
    } else {
        printf("char c = %c\n", c);   
    }

    /* another list */
    printf("\nEnd of The C Tutorial - Lesson 2\n");

    return 0;
}

Compileremo questo codice con il consueto comando:

gcc lesson2.c -o lesson2

L'output sarà il seguente:

Short Integer Number: 32767
Floating Point 32bit Number: 0.100000
Floating Point 64bit Number: 0.009999999776
Short Integer Number: -32768
Floating Point 32bit Number: 0.200000
Floating Point 64bit Number: 0.110000001267
Short Integer Number: -32767
Floating Point 32bit Number: 0.300000
Floating Point 64bit Number: 0.210000002757
Short Integer Number: -32766
Floating Point 32bit Number: 0.400000
Floating Point 64bit Number: 0.310000004247
Short Integer Number: -32765
Floating Point 32bit Number: 0.500000
Floating Point 64bit Number: 0.410000005737
Short Integer Number: -32764
Floating Point 32bit Number: 0.600000
Floating Point 64bit Number: 0.510000007227
Short Integer Number: -32763
Floating Point 32bit Number: 0.700000
Floating Point 64bit Number: 0.610000008717
Short Integer Number: -32762
Floating Point 32bit Number: 0.800000
Floating Point 64bit Number: 0.710000010207
Short Integer Number: -32761
Floating Point 32bit Number: 0.900000
Floating Point 64bit Number: 0.810000011697
Short Integer Number: -32760
Floating Point 32bit Number: 1.000000
Floating Point 64bit Number: 0.910000013188
char c = !

End of The C Tutorial - Lesson 2

Fatto?  Notate quache cosa che non vi convince?
Parliamone, se volete! Io noterei qualcosa di strano...

Comunque, le cose importanti sono queste:
  • Nella prima parte della funzione main() abbiamo definito delle variabili e le abbiamo identificate con dei tipi predefiniti (es. char, short, int, float, ecc.)
  • Poi abbiamo effettuato ciclicamente alcune semplici operazioni matematiche (...somme)
  • Infine, abbiamo valutato una "condizione", scegliendo tra due differenti possibilità
Modificate il codice per vedere come l'output cambia ...è il miglior modo per imparare!

Esercizio: come faccio a far visualizzare char c = SPACE?

Qui Paneta Terra, vi aspetto nei commenti! Ciro.

sabato 17 dicembre 2011

Mini Tutorial C - Lesson 1

Benvenuti nella prima lezione del corso di programmazione in Linguaggio ANSI C.
Iniziamo con un corso per tutti, partendo dalle basi e, via via, estendendo le nostre lezioni fin dove sapremo, insieme, spingerci.


Prima di iniziare, vorrei dirvi alcune cose sulla programmazione dei computer.
Lo dico a parole mie!!!

  • Il Computer, come la Lavatrice, esegue un Programma
  • Il programma è costituito da una sequenza di passi successivi, detti Istruzioni
  • Le Istruzioni sono specifiche per ogni macchina (Computer, Lavatrice, Frullatore, ecc.)
  • Ogni Macchina può eseguire le proprie istruzioni, ma non le istruzioni di altre macchine
  • Ogni Linguaggio di programmazione è basato sul paradigma delle Liste, dei Cicli e delle Condizioni
  • La Programmazione è una Scienza antica quanto l'umanità
  • Programmare non è difficile ...è complesso!!!

Ciò detto, iniziamo subito a programmare ...ma prima dobbiamo "creare" l'ambiente di programmazione.
Poiché studieremo avendo in mente l'approccio Open-Source, cominciamo con l'installare una Macchina Linux. Vi consiglio di installare Ubuntu, una distribuzione Linux per Personal Computer che Vi consentirà di Programmare, Navigare e ...Divertirvi.

Per installare Ubuntu, andate sul sito http://www.ubuntu.com/ e fate Click sul menù Download ...seguite le istruzioni. E' semplicissimo, basta attenersi a ciò che vi verrà richiesto di fare.

Bene! Sono passate 48 ore a imprecare contro le Pen Drive i CD ROM, ecc?
E' il normale lavoro del Programmatore! Non scoraggiatevi ...è una vita che lo faccio. Tutto si supera.

Adesso, aprite il programma Gnome Terminal e digitate il seguente comando:

sudo apt-get install build-essential

Avete appena installato il Compilatore GCC e l'utility Make.
Iniziamo con un semplice programma per verificare che tutto sia Ok.
Aprite l'editor di testi GEDIT e inserite il seguente testo ...pardon, programma:

#include <stdio.h>

int main()
{
    printf("C Tutorial - Lesson 1\n");

    return 0;
}

Compiliamo il programma con il seguente comando:

gcc lesson1.c -o lesson1

Eseguiamo il programma, digitando:

./lesson1

L'output dovrà essere...

C Tutorial - Lesson 1

Tutto bene? Se avete problemi, scrivetemi nei commenti e cercherò di aiutarvi.

Qui Pianeta Terra, a presto per la seconda lezione.

P.S.: Per coloro che hanno fretta, consiglio di leggere il seguente libro: The C Programming Language ...lo trovate su Amazon.com (qui).

venerdì 16 dicembre 2011

Navighiamo in 3D - Parte 2

Nella prima parte dell'articolo, che trovate qui, ho introdotto l'argomento delle mappe altimetriche georeferenziate. Il data base SRTM (Shuttle Radar Topography Mission) è stato realizzato e pubblicato, per offrire una copertura pressoché globale della superficie del nostro Pianeta Terra.

(Modello 3D realizzato con Blender)

Oggi voglio mostrarvi un video, che ho realizzato per Voi, per dimostrare come l'utilizzo di tali mappe rappresenti un metodo estremamente efficace per implementare un'applicazione di Realtà Aumentata (Agumented Reality), detta anche di Computer Mediated Reality, utile nelle applicazioni di geo-localizzazione 3D di veicoli.

Ora, guardiamo insieme il video...


Visto? I territori rappresentati sono quelli del basso Lazio e della Campania. Essi vengono fedelmente rappresentati con una risoluzione di 3 Secondi d'Arco (circa 90m alle nostre latitudini). Ho cercato di far corrispondere alcune viste aeree, con la stessa prospettiva geografica  realizzabile con  l'ombreggiatore (...virare a 45° di bank è una sensazione ...non descrivibile nel blog!!!).
Per la realizzazione dei video 3D, consiglio di utilizzare Blender, un CAD 3D Open-Source, liberamente scaricabile dal sito http://www.blender.org/ e di seguire il tutorial che trovate qui, grazie a John Flower.
Direi che non mi resta che ricevere i Vostri video di realtà virtuale. Li pubblico volentieri!

Qui Pianeta Terra, ...in 3D, a presto.


martedì 22 novembre 2011

Human Machine Interface, quando le macchine parlano e sentono

Nel post di oggi vorrei mostrarvi un progetto sperimentale di Interfaccia Utente, realizzato alcuni anni fa (nel 2004 ...come passa in fretta il tempo!). Tuttavia il progetto resta ancora attuale, salvo qualche aggiornamento nei singoli componenti che, troppo spesso, hanno un ciclo di vita piuttosto breve.

(click sull'immagine, per ingrandire)

Il tema fondamentale è ancora quello di come realizzare delle macchine che possano interagire in maniera efficace con l'utente e di come realizzare interfacce intuitive ed efficienti, ...in poche parole di come dosare le "palline" dello zucchero quando prendiamo il caffè alla "macchinetta" aziendale (operazione che in effetti richiede ...un minimo di esercizio! Vero?). Prima di scendere nei dettagli, guardiamo insieme il video che ho realizzato per Voi:


State ancora ballando al ritmo Techno di NeXus? Noooo? Nell'elettronica un pò di musica non guasta! Ok, i file MP3 li scarico prevalentemente da jamendo.com, attenendomi, strettamente, al tipo di licenza con cui l'Autore distribuisce i contenuti qui sul Pianeta Terra. A proposito, la licenza di questo blog è Creative Commons - BY - NC - SA, stesso discorso per i video sul canale YouTube "liberaelettronica".


Nel video abbiamo visto delle card colorate che vengono posizionate in prossimità di un avvolgimento. Si tratta di TAG RFID (Radio Frequency IDentification) il cui funzionamento è ben illustrato nella pagina Wikipedia che trovate qui. Display LCD e Tastiera 4x4, meritano forse minore attenzione, ma restano pur sempre un elemento fondamentale nell'interazione con la Macchina. L'applicazione prevedeva anche ingressi analogici a 12bit, ingressi digitali optoisolati e uscite digitali a transistor e relè.
Da notare che, nel circuito che vi propongo nella seguente figura, le macchine possono comunicare anche tra loro e, pertanto, utilizzare canali di comunicazione quali Reti GSM (telefoni cellulari) e Reti Intranet/Internet. Dovremo quindi provvedere a realizzare le dovute interfacce (nel nostro caso una porta seriale RS232 per il modem GSM e un Core Module XPORT per le connessioni Ethernet e TCP/IP).


Pubblicare tutto il codice ANSI C di questa applicazione risulterebbe eccessivamente pesante per il blog, ma è disponibile per coloro che me lo richiederanno via email.
Vi anticipo solo un frammento di codice per leggere dalla tastiera 4x4:

/* key pad 16 layout
    1   2   3   F
    4   5   6   E
    7   8   9   D
    A   0   B   C
*/

unsigned char keypad16_read(void) {

    unsigned char scan, tmp_scan, col, col_drive, ret_code;

    /* init column driver */
    col_drive = 0x0E;

    /* scan row by col (low=key pressed) */
    for (col=0; col<4; col++) {   

        /* set column (PG0,1,,3) */
        P2_reg &= 0xF0;
        P2_reg = P2_reg | (col_drive & 0x0F);
        P2 = P2_reg;

        /* read row (EXP0,1,,3) */
        scan = P3 & 0x3F;
        scan >>= 2;

        /* if key pressed and hold */
        if ((scan & 0x0F) < 0x0F){

            delay_ms(10);
            tmp_scan = P3 & 0x3F;
            tmp_scan >>=2;

            if (tmp_scan == scan) {
                /* compose scan code */
                scan = scan | (col_drive << 4);

                /* ASCII conversion */
                switch (~scan) {

                    case 0x88 : ret_code = '1'; break;
                    case 0x84 : ret_code = '2'; break;
                    case 0x82 : ret_code = '3'; break;
                    case 0x81 : ret_code = 'F'; break;
                    case 0x48 : ret_code = '4'; break;
                    case 0x44 : ret_code = '5'; break;
                    case 0x42 : ret_code = '6'; break;
                    case 0x41 : ret_code = 'E'; break;
                    case 0x28 : ret_code = '7'; break;
                    case 0x24 : ret_code = '8'; break;
                    case 0x22 : ret_code = '9'; break;
                    case 0x21 : ret_code = 'D'; break;
                    case 0x18 : ret_code = 'A'; break;
                    case 0x14 : ret_code = '0'; break;
                    case 0x12 : ret_code = 'B'; break;
                    case 0x11 : ret_code = 'C'; break;

                    default : ret_code = 0;
                }

                break; /* terminate for cicle */

            } else {
                /* key spike */
                ret_code = 0;
            }
        } else {
            /* no key pressed */
            ret_code = 0;
        }

        /* set column driver for the next column */
        col_drive <<= 1;
        col_drive |= 0x01;
    }

    return ret_code;
} 

Qui Pianeta Terra ...ove le macchine hanno un ruolo sempre crescente, a presto.

giovedì 17 novembre 2011

L'Elettronica Open Source

Oggi una novità per i lettori di Libera Elettronica!
Siamo, insieme, presenti su una delle comunità italiane più ampie dell'open source ...soprattutto per ciò che riguarda l'elettronica.


Non è merito mio, è merito Vostro!
Nel seguente link (http://it.emcelettronica.com/portuxg20-embedded-linux-getting-started) potete trovare il nostro primo articolo sull'utilizzo di un computer embedded Linux. Altri articoli seguiranno.



Qui Pianeta Terra, a presto!

venerdì 4 novembre 2011

Un Robot alla guida - Parte 3

Aggiungiamo ancora un tassello al nostro Autopilota/Navigatore; oggi parliamo del GPS (Global Positioning System), che è ormai abbastanza noto ai più anche grazie alle diffuse applicazioni in campo "consumer", prevalentemente nel settore automobilistico ...ma non solo.

(moderno ricevitore GPS con Antenna integrata ...un francobollo!)

Più in generale, dobbiamo immaginare il GPS (sistema estremamente complesso se esaminato dal punto di vista tecnico e nelle sue varie componenti o segmenti) come uno degli elementi principali di quelle applicazioni che prendono il nome di GNSS (Global Navigation Satellite System). Vorrei rimandare, per coloro che sono interessati ad un approfondimento tecnico, la descrizione di tutti i dettagli a documenti specializzati sull'argomento. Ne esistono tanti e alla fine dell'articolo vi riporterò la mia personale bibliografia ...può esservi utile.

(mappa 3D georeferenziata del basso Lazio)

Tra i vari componenti dei sistemi GNSS, di cui il GPS fa parte, è importante ricordare che dal 1 Ottobre 2009 è attivo in Europa il servizio EGNOS (European Geostationary Navigation Overlay Service). Tale servizio consente, mediante una complessa rete di Stazioni Terrestri e Ripetitori Satellitari Geosincroni, di implementare la cosiddetta "correzione differenziale" su scala geografica (...continentale appunto!).
In breve, possiamo riepilogare così, per punti, la recente storia del servzio di geolocalizzazione satellitare:
  • Il sistema GPS fu progettato agli inizi degli anni '70 dal US-DoD (Department of Defense, Stati Uniti) e divenne pienamente operativo, anche per uso civile, nel 1994. Il grado di accuratezza, in quegli anni, era un CEP (Circle of Equiprobalility) di circa 100 metri. Contemporaneamente e per gli stessi scopi bellici, l'URSS, realizzava il sistema GLONASS, concettualmente equivalente al GPS made in USA.
  • In data 1 Maggio 2000, il presidente degli Stati Uniti - Bill Clinton - decretò l'abolizione del SA (Selective Availability), un sottosistema che limitava la precisione del GPS per gli usi civili e, pertanto, il CEP passò da 100 m a 10-15 m.
  • In data 1 Ottobre 2009, l'Agenzia Spaziale Europea (ESA) iniziò la diffusione pubblica dell'Overlay EGNOS, portando il CEP a circa 2 m. (Nota: EGNOS è l'equivalente del sistema WASS operativo in Nord America).

(confronto tra mappa Google e mappa 3D
di un percorso GPS, andata e ritorno,
da/al Porto Turistico di San Felice Circeo)

Poche righe non possono certo condensare quaranta anni di evoluzione tecnologica, ma è interessante osservare come il servizio GNSS, costituito da GPS + EGNOS + GLONASS + (futuro GALILEO), condurrà l'accuratezza della localizzazione 3D, sul nostro caro Pianeta Terra, dalla grandezza del Metro a quella del Decimetro.
In questo scenario nuovi servizi potranno essere migliorati o, talvolta, inventati from scratch. Pensiamo, ad esempio, alla possibilità di tracciare la nostra posizione o quella di un Robot, su di una mappa e con la risoluzione del Centimetro!
Incredibile ...fino a pochi anni fa!!!

Ma come possiamo utilizzare un ricevitore GPS nelle nostre applicazioni "embedded"?
Semplice! Un moderno ricevitore (es. Garmin GPS 18x OEM), mediante una interfaccia UART (Universal Asyncronous Receiver Transmitter), ci invierà dei messaggi periodici nei quali è contenuta la nostra posizione sul geoide Terra, secondo il modello WGS-84.
Tali messaggi, definiti Sentenze, saranno codificate in accordo allo standard NMEA 0183 oppure in formato proprietario. I formati proprietari, ovviamente, variano da costruttore a costruttore (...sono in tanti ormai) e dovranno essere interpretati "manuali tecnici alla mano", mentre i formati standard risultano tutti normalizzati.
Nel seguente esempio Vi riporto la Sentenza GPRMC (Minimum Required - Type C) che rappresenta un comune denominatore per molti ricevitori OEM:

Sentenza RMC - 12 campi + Header $GPRMC + Trailer XX Hex Chk

$GPRMC,      Carattere di sincronismo '$' e denominazione GPRMC
171429,      Orario Fix [hhmmss]
A,           A=Fix valido, V=Warning (msg. non valido)
4113.5304,   Latitudine 41° 13.5304 secondi d'arco decimali
N,           N=Emisfero Nord, S=Emisfero Sud
01305.7166,  Longitudine 013° 05.7166 secondi d'arco decimali
E,           E=Quadrante Est, W=Quadrante Ovest
000.0,       Velocità in Nodi (Ground Speed!!!)
000.0,       Direzione Geografica (...non magnetica!!!)
200509,      Data Fix [ggmmhh]
001.8,       Deviazione magnetica rispetto a dir. geografica
E            Quadrante di deviazione magnetica
*7D          Checksum per verifica integrità messaggio

Questo messaggio, ad esempio, potrà essere ricevuto dal nostro microcomputer embedded, mediante una interfaccia RS232, RS422 o RS485, e consentirci, così, di elaborare la posizione del veicolo (automobile, aereo, imbarcazione, ...pedone, animale, robot!) in coordinate ECEF (Earth Fixed Earth Centered) o altro sistema di coordinate, se richieste.

(fare click per ingrandire)

Vediamo, ora, alcuni testi consigliati per approfondire l'argomento. Vi ricordo che per migliorare il grado di 'accuracy' nella determinazione della posizione è opportuno correlare l'output del sensore GPS con l'output del sensore inerziale-geomagnetico. Tale combinazione ci porterà alla realizzazione di un sensore GPS-INS (GPS-Inertial Navigation System) ...come è appunto il nostro Progetto Open di "Robot alla Guida".

Ecco i titoli:
  1. The Global Positioning System & Inertial Navigation - Farrel & Bath
  2. Strapdown Inertial Navigation Technology, Second Edition (Progress in Astronautics and Aeronautics) - Titterton & Weston
  3. Applied Mathematics in Integrated Navigation Systems, Third Edition - Rogers
  4. Quaternions and Rotation Sequences: A Primer with Applications to Orbits, Aerospace and Virtual Reality - Kuipers
Qui Pianeta Terra, un mondo reale ed un modello matematico, in cui orientarsi e navigare!

venerdì 28 ottobre 2011

Navighiamo in 3D

Cari Amici del blog, oggi desidero parlarvi delle Mappe Georeferenziate SRTM (Shuttle Radar Topography Mission). Il progetto SRTM è da considerare uno sforzo colossale, organizzato dalla NASA e da altre Agenzie spaziali (ASI compresa), finalizzato alla realizzazione di un Data Base in 3D dell'intera superficie del nostro Pianeta Terra.

 


Nella precedente immagine vedete graficamente in cosa consiste l'output del progetto SRTM: una miriade di file altimetrici, detti TILE, perfettamente georeferenziati, che riportano in formato numerico l'altezza sul livello del mare (S.l.m.) di ogni rilievo, collina, montagna (isole e isolette, comprese), sparse per il nostro globo terraqueo ...una vera e propria manna per chi è interessato alla realizzazione di un autopilota/navigatore che, scherzosamente, nei precedenti post ho definito come "Un Robot alla Guida".

Come possiamo utilizzare i file HGT del progetto SRTM3?
Procediamo per passi ...e guardiamo insieme le relative immagini!

1) Aggiungiamo il Mare

2) Aggiungiamo il Sole

3) Aggiungiamo una Foto Satellitare dell'area di interesse

4) Elaboriamo l'immagine con un Ombreggiatore 3D ...e il gioco è fatto!!!
(Click per ingrandire - Golfo di Napoli, Penisola sorrentina, Capri)

Nella precedente foto abbiamo visto il risultato in una delle tante possibili viste prospettiche. Ma andiamo più in dettaglio e vediamo, con la prossima foto, cosa ci offre il Data Base SRTM3 con la sua risoluzione di 3'' Arco per Pixel.

Questa non è un immagine del Paneta Luna, il nostro caro satellite naturale, ma rappresenta una mappa ombreggiata dei Campi Flegrei, ovvero un'area vulcanica che si estende dalla Collina di Posillipo (Napoli) al Golfo di Pozzuoli e che comprende numerosi Comuni, situati in questa meravigliosa area storico-paesaggistica, ricchi di panorami mozzafiato e reperti archeologici.

Nella prossima immagine, estendendo un pò lo sguardo verso Sud, vediamo...


 ...in primo piano i Campi Flegrei, poi, il monte Vesuvio e, poi, un tratto della Penisola sorrentina.
Qui il tutto si vede meglio salendo sugli appennini al confine con la Provincia di Avellino...

...e qui in vista aerea.


Per gli amanti del "codice C", riporto il listato di un semplice programma utilizzabile per convertire un file HGT in formato BMP, meglio "digeribile" dai nostri PC.

/* SRTM Tile to BMP simple program */

#include <stdio.h>
union t_height {
    unsigned char in_chr[2];
    short height;
} t_height;
/* image buffer */
char buffer[1200][1200][3];

int main() {
    /* file pointer */
    FILE * fdin;
    FILE * fdout;
    /* array index */
    int x,y;
    /* color components */   
    char color_r;
    char color_g;
    char color_b;
    /* other */
    int min = 0;
    int max = 0;

    char bmp_header[] = {
        0x42, 0x4D, 0x36, 0xEB, 0x41, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
        0x00, 0x00, 0xB0, 0x04, 0x00, 0x00, 0xB0, 0x04,
        0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0xEB, 0x41, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00   
    };
   
    /* open SRTM tile file */
    fdin = fopen("N40E014.hgt", "r");
    if(fdin != NULL) {
        printf("Input file opened.\n");
    } else {
        exit(0);
    }   
    /* transcondig loop */   
    for(y=0; y<1200; y++) {
        for(x=0; x<1200; x++) {
            t_height.in_chr[1] = fgetc(fdin);
            t_height.in_chr[0] = fgetc(fdin);

            /* set color pixel */
            if (t_height.height == 0) {
                color_r = 0;
                color_g = 0;
                color_b = 128;
            } else if (t_height.height > 0) {
                color_r = t_height.height / 7;
                color_g = color_r;
                color_b = color_r;
            }
            buffer[x][y][0] = color_r; //red
            buffer[x][y][1] = color_g; //green
            buffer[x][y][2] = color_b; //blu      
            /* update min, max */
            if (t_height.height > max) {
                max = t_height.height;
            }
            if (t_height.height < min) {
                min = t_height.height;
            }                      
        }
        /* discard pixel 1201 */
        t_height.in_chr[1] = fgetc(fdin);
        t_height.in_chr[0] = fgetc(fdin);
    }   
    /* close .hgt files */
    fclose(fdin);
    /* open BMP file */
    fdout = fopen("SRTM.bmp", "w");
    if(fdout) printf("Output file opened.\n");
    /* write BMP 1200x1200 header */
    for(x=0; x<54; x++) {
        fputc(bmp_header[x], fdout);
    }
    /* write image buffer to BMP data area */
    for(y=1199; y>=0; y--) {
        for(x=0; x<1200; x++) {
            fputc(buffer [x][y][2], fdout); //blu
            fputc(buffer [x][y][1], fdout); //green
            fputc(buffer [x][y][0], fdout); //red
        }
    }   
    fclose(fdout);
    /* message */
    printf("Min: %d  Max: %d\n", min, max);
    printf("Conversion complete.\n");
    /* terminate program */
    return 0;
}

Nei prossimi post vedremo come utilizzare le Mappe SRTM nel nostro navigatore fai-da-te e vedremo anche come utilizzare il file-system Linux in abbinamento al Displey TFT a colori.

Qui Pianeta Terra ...in 3D, a presto.