Programmation Python
Découvrez le protocole NMEA qui est utilisé dans le système de positionnement GPS.
Cette activité s'inscrit dans la thématique Localisation, cartographie et mobilité du programme de SNT.
Elle est proposée par Luc Vincent, actuellement professeur de Physique-Chimie et d'ISN/ICN au lycée des Graves à Bordeaux.
Capacités attendues
Décoder une trame NMEA pour trouver des coordonnées géographiques.
Les différents composants d'un appareil électronique (ex : un téléphone mobile) communiquent par des protocoles normalisés. Ainsi, les puces GPS qui effectuent les calculs de positionnement envoient leurs résultats présentés suivant une trame normalisée : la trame NMEA 0183. Le développeur d'un dispositif souhaitant interroger un GPS sait qu'il pourra exploiter cette trame pour obtenir des informations de date et de position.
La norme NMEA est le protocole de transmission des données GPS. Ces données sont transmises sous la forme de trames. Chaque trame commence par le caractère $ et se compose de plusieurs éléments séparés par des virgules. Voici un exemple de trame :
$GPGGA, 064036.289, 4836.5375, N, 00740. 9373, E, 1, 04, 3.2, 200.2, M, , , , 0000*0E
Les deux premiers caractères correspondent à l'identifiant du récepteur : ici GP pour Global Positioning System. Les trois lettres suivantes correspondent à l'identifiant de la trame : GGA pour GPS Fix et Date. C'est la trame la plus courante.
Décomposons maintenant cette trame selon les premiers éléments qui la composent :
GPGGA : type de la trame
064036.289 : heure d'envoi de la trame, ici 06h 40min 36,289s (UTC)
4836.5375, N : latitude Nord, ici 48°36,5375' (en DM, degrés minutes)
00740.9373, E : longitude Est, ici 7°40,9373' (en DM également)
1 : type de positionnement (1 pour le positionnement GPS)
04 : nombre de satellites utilisés
3.2 : précision horizontale
200.2, M : altitude, ici 200 mètres
Généralement, on exprime les coordonnées géographiques dans le système sexagésimal, noté DMS pour degrés, minutes, secondes. Par exemple 49°30'30'' pour 49 degrés, 30 minutes et 30 secondes. Une minute d'angle vaut 1/60 degrés tandis qu'une seconde d'angle vaut 1/3600 degrés.
Il est également possible d'utiliser les unités DM (Degré Minute) ou DD (Degré décimal) :
En DMS : 49°30'30''
En DM : 49°30,5'
En DD : 49,5083° (généralement avec quatre décimales)
Vérifier par un calcul que la latitude 48°36.5375' (DM) de la trame NMEA donnée en exemple en début d'activité correspond à 48°36'32.25" (DMS).
Sachant que alors .
Voici une vue des résultats de quelques instructions Python obtenues depuis la console :
>>> ligne="nom,prenom,age,17" >>> element=ligne.split(",") >>> element ['nom','prenom','age','17'] >>> type(element) <class 'list'> >>> element[1] 'prenom' >>> prenom=element[1] >>> prenom[2:4] 'en' >>> type(element[3]) <class 'str'> >>> int(element[3]) 17 >>> float(element[3]) 17.0 >>>
D'après ces résultats, quelle instruction en python permet d'obtenir une liste nommée attribut
à partir d'une chaîne de caractères nommée trame
?
trame = "$GPGGA, 064036.289, 4836.5375, N, 00740. 9373, E, 1, 04, 3.2, 200.2, M, , , , 0000*0E"
Il faut saisir l'instruction : attribut=trame.split(",")
.
Ecrire la fonction tramePrefixes(trame)
qui reçoit une trame complète et renvoie l'identifiant du récepteur, c'est-à-dire les deux premières lettres du type de la trame (premier élément après le caractère $. Sur la trame d'exemple, la fonction doit renvoyer "GP".
On teste ensuite la fonction avec la trame d'exemple.
def tramePrefixes(trame): talkerId=trame[1:3] return talkerId
Modifier cette fonction pour qu'elle renvoie le nom de l'équipement qui a émis la trame. On utilisera les correspondances suivantes :
BD ou GB : Beidou
GA : Galileo
GP : GPS
GL : GLONASS
On teste alors la fonction.
def tramePrefixes(trame): talkerId=trame[1:3] if talkerId=="GD" or talkerId=="GB": tramePrefixesValue="Beidou" elif talkerId=="GA": tramePrefixesValue="Galileo" elif talkerId=="GP": tramePrefixesValue="GPS" elif talkerId=="GL": tramePrefixesValue="GLONASS" return tramePrefixesValue
Ecrire une fonction ggaUtc(trame)
qui reçoit une trame complexe et renvoie l'heure en h, min, s.
def ggaUtc(trame): #on transforme la trame en liste attribut=trame.split(',') #on sélectionne l'élément qui correspond à l'heure time=attribut[1] utc=time[:2]+" h "+time[2:4]+" min "+time[4:]+" s" return utc
Ecrire une fonction ggaLat(trame)
qui reçoit une trame complète et renvoie la latitude convertie en DMS.
def ggaLat(trame): attribut=trame.split(',') lat=attribut[2] lat_deg=lat[:2] lat_min=lat[2:4] lat_sec=str(float(lat[4:])*60) latDMS=lat_deg+" D "+lat_min+" M "+lat_sec+" S " return latDMS
Pour définir sa position sur la Terre, on utilise le plus souvent les coordonnées géographiques : la latitude, la longitude et l'altitude. Pour la latitude et la longitude on rencontre trois notations :
Degré Minute Seconde (DMS)
Degré Minute (DM)
Degré décimal (DD)
Les récepteurs "GPS" fournissent la localisation sous une forme normalisée facilement décodable, par exemple selon le protocole NMEA 0183 (National Marine Electronics Association).