Informatique · Seconde · 5 min de lecture
Lire une position GPS dans une trame NMEA
Un récepteur GPS fournit sa position sous forme de trames texte normalisées NMEA 0183, champs séparés par des virgules ; dans une trame GGA, la latitude est écrite ddmm.mmm (deux chiffres de degrés, puis les minutes avec leur partie décimale) suivie de N ou S, la longitude dddmm.mmm (trois chiffres de degrés) suivie de E ou W ; un dernier champ, après « * », est une somme de contrôle ; conversion en degrés décimaux : degrés + minutes / 60, avec un signe négatif au sud et à l'ouest.
Chapitre du programme : Sciences numériques et technologie
Bloc 1 sur 7 · Comprendre
Comprendre : une ligne de texte, des champs
Un récepteur GPS transmet sa position sous forme de trames de texte normalisées par le protocole NMEA 0183. Chaque trame commence par le caractère « dollar » (omis dans les affichages de cette leçon), suivi d'un identifiant, puis de champs séparés par des virgules. Elle se termine par « * » et une somme de contrôle de deux caractères.
Voici une trame de type GGA (position) :
GPGGA,123519,4851.200,N,00221.000,E,1,08,0.9,35.0,M,46.9,M,,*78| Champ | Valeur | Signification |
|---|---|---|
| 1 | 123519 | heure : 12 h 35 min 19 s, en temps universel (UTC) |
| 2 | 4851.200 | latitude, format ddmm.mmm |
| 3 | N | nord (S : sud) |
| 4 | 00221.000 | longitude, format dddmm.mmm |
| 5 | E | est (W : ouest) |
| 6 et suivants | 1, 08, 0.9, 35.0, M… | qualité, nombre de satellites, précision, altitude en mètres… |
La latitude 4851.200 se lit : les deux premiers chiffres sont les degrés (48), la suite est un nombre de minutes (51,200). La longitude 00221.000 a trois chiffres de degrés (002) puis les minutes (21,000).
Bloc 2 sur 7 · Approfondir
Approfondir : degrés décimaux et somme de contrôle
Conversion en degrés décimaux. Un degré vaut 60 minutes : valeur = degrés + minutes / 60. Au sud et à l'ouest, la valeur est négative.
Pour la trame ci-dessus : 48 + 51,2 / 60 ≈ 48,8533 et 2 + 21 / 60 = 2,35.
Vérification par programme (facultative). Dans l'extrait ci-dessous, trame.split(",") découpe la trame à chaque virgule et donne la liste des champs (champs[0] est GPGGA, champs[2] la latitude) ; champs[2][:2] désigne les deux premiers caractères du champ et champs[2][2:] tous les suivants ; int et float transforment ces textes en nombre entier et en nombre à virgule ; round(lat, 4) arrondit au dix-millième.
trame = "GPGGA,123519,4851.200,N,00221.000,E,1,08,0.9,35.0,M,46.9,M,,*78"
champs = trame.split(",")
print(champs[1], champs[2], champs[3], champs[4], champs[5])
lat = int(champs[2][:2]) + float(champs[2][2:]) / 60
lon = int(champs[4][:3]) + float(champs[4][3:]) / 60
print(round(lat, 4), round(lon, 4))123519 4851.200 N 00221.000 E
48.8533 2.35Somme de contrôle. Elle permet au destinataire de détecter une trame abîmée pendant la transmission. On combine par ou exclusif les codes de tous les caractères situés entre le « dollar » et « * », et on écrit le résultat en hexadécimal sur deux chiffres. Dans l'extrait (facultatif), ord(c) donne le code du caractère c, ^ est l'opérateur ou exclusif de Python, et format(x, "02X") écrit x en hexadécimal sur deux chiffres. Si le calcul ne redonne pas les deux caractères reçus, la trame a été altérée : on ne s'y fie pas.
corps = "GPGGA,123519,4851.200,N,00221.000,E,1,08,0.9,35.0,M,46.9,M,,"
x = 0
for c in corps:
x = x ^ ord(c)
print(format(x, "02X"))78On retrouve bien le 78 écrit après « * ».
Bloc 3 sur 7 · Exemple
Exemple guidé : une position au sud et à l'ouest
Énoncé. Un récepteur envoie la trame suivante. Donner la latitude et la longitude en degrés décimaux, arrondies au dix-millième.
GPGGA,081530,3352.128,S,07400.360,W,1,07,1.1,12.0,M,30.2,M,,*7DMéthode.
- Latitude : champ 3352.128, suivi de S. Degrés : 33 ; minutes : 52,128. 33 + 52,128 / 60 = 33,8688. Au sud : −33,8688.
- Longitude : champ 07400.360, suivi de W. Degrés : 074 (trois chiffres) ; minutes : 00,360. 74 + 0,36 / 60 = 74,0060. À l'ouest : −74,0060.
trame = "GPGGA,081530,3352.128,S,07400.360,W,1,07,1.1,12.0,M,30.2,M,,*7D"
champs = trame.split(",")
lat = int(champs[2][:2]) + float(champs[2][2:]) / 60
lon = int(champs[4][:3]) + float(champs[4][3:]) / 60
if champs[3] == "S":
lat = -lat
if champs[5] == "W":
lon = -lon
print(round(lat, 4), round(lon, 4))-33.8688 -74.006Dans ce programme, if champs[3] == "S": change le signe de la latitude au sud, et de même pour W. Python n'affiche pas le zéro final : −74,006 et −74,0060 sont la même valeur.
Bloc 4 sur 7 · Visualiser
Voir : découper les champs de position
| Champ | Découpage | Degrés | Minutes | Calcul | Lettre | Degrés décimaux |
|---|---|---|---|---|---|---|
| 4851.200 | dd + mm.mmm | 48 | 51,200 | 48 + 51,2 / 60 | N | 48,8533 |
| 00221.000 | ddd + mm.mmm | 2 | 21,000 | 2 + 21 / 60 | E | 2,3500 |
| 3352.128 | dd + mm.mmm | 33 | 52,128 | 33 + 52,128 / 60 | S | −33,8688 |
| 07400.360 | ddd + mm.mmm | 74 | 0,360 | 74 + 0,36 / 60 | W | −74,0060 |
Continuez sur votre lancée
Vous avez découvert l’essentiel et un exemple. Retrouvez la suite du cours et les points à retenir, puis passez à l’entraînement guidé dans votre compte.
- Les formules et les repères à retenir
- Les erreurs fréquentes expliquées
- Un exercice avec des aides et sa correction
L’accès gratuit comprend les cours et exercices de votre niveau choisi.
Sources
- BO spécial n°1 du 22 janvier 2019 — programme de sciences numériques et technologie de seconde générale et technologique, annexe (https://cache.media.education.gouv.fr/file/SP1-MEN-22-1-2019/08/5/spe641_annexe_1063085.pdf) — thème « Localisation, cartographie et mobilité », protocole NMEA 0183
- NMEA 0183, Standard for Interfacing Marine Electronic Devices, National Marine Electronics Association — phrase GGA, somme de contrôle
Vous pensez avoir trouvé une erreur dans cette leçon ? Signalez-la par e-mail.