atc_radar

TP2-ARCH-05 : Décoder le ciel#

Objectifs pédagogiques#

  • comprendre ce qu’est un protocole on demand ou broadcast

  • déduire l’architecture du système de surveillance du traffic aérien

  • Afficher les différents aéronefs équipés ADS-B autour du gymnase en temps réel

  • Compter les avions passant au-dessus du gymnase et mettre en évidence les enjeux sociaux

Instruments et capteurs physiques d’un aéronef#

Un aéronef (un avion, un hélicoptère, un dirigeable, etc..) est équipé d’un grand nombre de capteurs (ou sondes) :

Instrument

Fonction

Horizon artificiel (gyroscope)

Indique l’attitude de l’avion (inclinaison en roulis et en tangage) par rapport à l’horizon.

Altimètre

Mesure l’altitude par rapport au niveau de la mer à l’aide de la pression atmosphérique.

Anémomètre (indicateur de vitesse)

Mesure la vitesse de l’avion par rapport à l’air ambiant (vitesse indiquée ou IAS).

Variomètre (ou VSI - Vertical Speed Indicator)

Indique la vitesse ascensionnelle ou de descente de l’avion (en pieds/minute).

Compas magnétique

Indique le cap magnétique suivi par l’avion.

Indicateur de cap (ou gyroscope directionnel)

Permet un cap stable sans perturbations magnétiques.

Turn coordinator

Montre la vitesse de virage et la coordination entre le roulis et le lacet.

GPS (Global Positioning System)

Fournit la position précise (latitude, longitude, altitude), la vitesse sol et le cap réel.

VOR/DME

Radio-navigation utilisant des balises au sol pour le guidage sur routes aériennes.

ADF (Automatic Direction Finder)

Oriente l’avion vers une balise NDB (radio à basse fréquence).

ILS (Instrument Landing System)

Aide à l’atterrissage de précision (guidage vertical et horizontal).

sondes

A ces instruments, on ajoute (pour les aéronefs récents), des systèmes électroniques :

Système

Fonction

ADS-B (Automatic Dependent Surveillance - Broadcast)

Émet et reçoit des données de position, vitesse et altitude via GPS (utilisé par les contrôleurs et autres avions).

Inertial Measurement Unit (IMU)

Utilise accéléromètres et gyroscopes pour estimer les mouvements (souvent couplé avec GPS).

FMS (Flight Management System)

Gère les routes de vol, consommation de carburant, calculs de performance.

TCAS (Traffic Collision Avoidance System)

Avertit le pilote d’un risque de collision avec un autre aéronef.

Radar météorologique embarqué

Permet de détecter les orages et zones de turbulence à distance.

Chaque capteur ou système se trouve affiché dans le cockpit des aéronefs (modernes) :

cockpit

Tous les paramètres sont enregistrés à intervalles réguliers notamment dans l’une des deux boîtes noires de l’appareil. Certaines de ces informations sont en outre transmises chaque seconde environ en mode broadcast, c’est-à-dire diffusion.

Le protocole ADS-B#

Certaines des données de l’avionique sont transmise en utilisant le protocole ADS-B qui est ouvert.

ADSB

Les données contenues dans un message ADS-B (transmis chaque seconde) sont :

Donnée dans le message ADS-B

Source à bord

Position (lat, long)

GPS ou GNSS (couplé parfois à une IMU)

Altitude barométrique

Altimètre (via pression statique)

Altitude GNSS

GPS

Vitesse sol (ground speed)

GPS ou FMS

Cap (track angle)

Compas gyro ou GPS

Vertical rate (taux de montée/descente)

Variomètre / capteurs barométriques

Identifiant de l’aéronef

Transpondeur Mode S / avionique

Code transpondeur (squawk)

Transpondeur (piloté par ATC ou pilote)

Statut système

Avionique (statut du transpondeur, TCAS actif, etc.)

Le protocole ADS-B (pour Automatic dependent surveillance-broadcast) permet de contrôler l’espace aérien. C’est l’un des outils (parmi plusieurs autres) utilisés pour la sécurité du traffic aérien.

Les stations au sol peuvent ensuite capter ces messages et reconstruire la trajectoire d’un aéronef donné.

dump1090

Structure d’un message ADS-B#

Un message ADS-B a la forme suivante :

Élément transmis

Exemple

Explication

Adresse ICAO

A9C3F2

Numéro unique de l’avion (comme une plaque)

Type de message

3

Définit les données transmises par l’aéronef

Appel radio (Callsign)

AFR007

Le nom du vol (Air France 007)

Altitude

37000 ft

Hauteur à laquelle vole l’avion

Position

48.85, 2.35

Latitude et longitude (GPS)

Vitesse sol

480 kt

Vitesse réelle de déplacement

Cap (track)

270°

Direction de l’avion

Taux de montée/descente

-512 ft/min

Montée ou descente

Un message brut sera transmis de la façon suivante :

8DA9C3F2201A0A3F8B096527B6F0

qui est une suite de bits codés ici en hexadécimal

Type de message (typecode)#

Le type de message, ou typecode, dans un message ADS-B est un nombre compris entre 0 et 31. Il indique ce que contient le message, c’est-à-dire quel type d’information est transmis par l’avion à ce moment-là : parfois le nom du vol, parfois la position, parfois la vitesse, etc..

Typecode (TC)

Signification du message

Donnée transmise

1 à 4

Identification de l’avion

Callsign (ex : AFR007)

5 à 8

Non utilisé ou réservé

9 à 18

Position (surface ou en vol)

Altitude, CPR (latitude/longitude)

19

Vitesse et cap

Vitesse sol, cap, taux de montée/descente

20 à 22

Données supplémentaires de vitesse

Moins utilisées

23 à 31

Réservés ou non-ADS-B

Souvent non pertinents pour usage civil

Exercice 1 : Décodage d’un message ADS-B#

Il suffit de conaître la structure de la suite de bits codée en hexadécimal. Il est possible de le faire à la main mais nous préférerons utiliser une bibliothèque de fonctions (un module externe) qui le fait tout seul : pyModeS

En vous aidant d’une IA artificielle, complètez le code suivant pour afficher les éléments du message ADS-B reçu (typcode, callsign, etc..)

import pyModeS as pms

# 🔢 Exemple de message ADS-B hexadécimal
message = "8DA9C3F2201A0A3F8B096527B6F0"  # à remplacer par un message réel
print("Message ADS-B reçu :", message)

# 1️⃣ Adresse ICAO de l’avion (code unique de 24 bits)
icao = pms.common.icao(message)
print("Adresse ICAO :", icao, "→ identifiant unique de l'avion")
Message ADS-B reçu : 8DA9C3F2201A0A3F8B096527B6F0
Adresse ICAO : A9C3F2 → identifiant unique de l'avion

Exercice 2 : Afficher les avions#

Tous les avions se trouvant au-dessus du Gymnase de Beaulieu sont stockés dans un fichier de type JSON : c’est un format de description et de transmission de données.

Ce fichier se trouve à l’adresse http://adresseIP_donnee_par_l'enseignant/adsb/avions.json

En voici un exemple :

[
    {
        "flight": "AFR1234",
        "lat": 48.8571,
        "lon": 2.3542,
        "altitude": 10200,
        "speed": 850,
        "timestamp": "2025-05-22T14:00:00"
    },
    {
        "flight": "BAW2020",
        "lat": 48.8530,
        "lon": 2.3600,
        "altitude": 10400,
        "speed": 890,
        "timestamp": "2025-05-22T14:01:00"
    }
]

En vous aidant d’une IA générative, construisez une page en HTML permettant d’afficher les avions qui se trouvent au-dessus du gymnase de Beaulieu. Vous pouvez vous inspirer du fichier suivant :

Vous devez télécharger le fichier avions.json et le placer au même niveau que votre fichier HTML local.

Exercice 3 : Mise à jour automatique#

Modifiez votre fichier HTML pour qu’il se mette à joue automatiquement (le fichier JSON sur le serveur se met à jour automatiquement).

Exercice 4 : Compter les avions#

Ecrivez un programme Python qui :

  1. télécharge le fichier JSON (avions.json) depuis le serveur en local sur votre ordinateur

  2. lis le fichier local

  3. compte les avions qui se trouvent dans un périmètre donné autour du gymase

    • la position du gymnase (latitude et longitude) se trouvent via google maps (prenez la position exacte de la salle 310)

    • la position des avions est stockée dans le fichier JSON

    • il faut calculer en degrés, minutes, secondes de latitude et longitude

Exercice 5 (pour aller plus loin) : Affichage en temps réel#

Modifiez votre programme pour :

  1. qu’il télécharge le fichier à intervalle régulier (par exemple 5 secondes le fichier depuis le serveur

  2. compte le nombre d’avions dans le périmètre donné durant ce même intervalle

Jack Sweeney : tracking des célébrités#

Né en 2002, Jack Sweeney, alors étudiant à l’Université de Floride, a développé un bot publiant sur X (anciennement Twitter) les données en temps réel des avions privés de célébrités. Parmi elles, Elon Musk, Jeff Bezos, Mark Zuckerberg, Bill Gates, Donald Trump, Drake, Taylor Swift.

Son système utilise les données librement accessibles provenant des messages ADS-B.

Il a été poursuivi en justice par certaines célébrités, notamment Elon Musk, pour ses activités.

Privacy ICAO Aircraft Address program#

En 2025, la FAA (Federal Aviation Administration) étasunienne a lancé le programme Privacy ICAO Aircraft Address qui permet, sous certaines conditions, à un avion d’utiliser un identifiant ICAO qui n’est pas relié à un opérateur. Cette procédure rend donc le tracking des avions qui en sont équipés, plus difficile. Ce programme fonctionne uniquement au-dessus du territoire des USA.

Sources#

ANNEXES : Mise en place#

Le matériel à disposition est le suivant :

  1. un serveur permettant d’enregistrer les messages ADS-B

  2. une antenne permettant d’opérer sur la fréquence 1090 MHz (60 cm) munie d’un amplificateur et d’un câble coaxial

  3. une clé RTL-SDR vers USB pour relier l’antenne au serveur

Au niveau logiciel, nous utiliserons :

  1. le logiciel dump1090-mutability qui permet de traduire les signaux provenant de la clef RTL-SDR en chaînes lisibles par le reste du stack software.

  2. le serveur web apache qui permet d’afficher les données sous la forme d’un site web installé sur le serveur.

Démarrage des services de capture#

Apache2#

L’installation du serveur apache se fait très simplement (sous un système Linux à base de Debian) :

sudo apt-get install apache2

Il suffit de créer un répertoire accessible à tout le monde (pour plus de sécurité, il faut inclure l’utilisateur du service dump1090-mutability au groupe apache2 en écriture):

mkdir /var/www/htnl/adsb
chmod 777 /var/lib/htnl/adsb

dump1090-mutability#

Installer le logiciel :

sudo apt-get install dump1090-mutability

modifier la latitude et la longitude actuelle dans le fichier

/etc/default/dump1090-mutability

Puis lancer :

sudo dump1090-mutability --interactive --net --write-json /run/dump1090-mutability

Les données peuvent ensuite être visionnées en temps réel sous :

http://localhost/adsb/aircraft.json

Export des données chaque 2 secondes#

Pour exporter les données stockées dans /run/dump1090-mutability vers le dossier du serveur apache2 /var/www/html/adsb dans un fichier avions.json, exécuter le script suivant :

import urllib.request
import json
import time
from datetime import datetime

# Zone du gymnase (attention : mettre les bonnes latitude et longitude !!)

# LAT_MIN = 46.52
# LAT_MAX = 46.54
# LON_MIN = 6.62
# LON_MAX = 6.64

LAT_MIN = 0
LAT_MAX = 100
LON_MIN = 0
LON_MAX = 100

URL = "localfile/avions.json"

def est_dans_zone(lat, lon):
    return LAT_MIN <= lat <= LAT_MAX and LON_MIN <= lon <= LON_MAX

def collecter():
    try:
        with urllib.request.urlopen(URL) as response:
            data = json.loads(response.read())
        avions = data.get("aircraft", [])

        avions_filtrés = []
        for avion in avions:
            lat = avion.get("lat")
            lon = avion.get("lon")
            if lat is not None and lon is not None and est_dans_zone(lat, lon):
                vitessekm = avion.get("speed",0)
                vitessekm = int(vitessekm*1.609344)
                altitudem = avion.get("altitude",0)
                altitudem = int(altitudem*0.3048)
                avions_filtrés.append({
                    "flight": avion.get("flight", "").strip(),
                    "lat": lat,
                    "lon": lon,
                    "altitude": altitudem,
                    "speed": vitessekm,
                    "timestamp": datetime.now().isoformat()
                })

        # Sauvegarde dans un fichier JSON
        with open("/var/www/html/adsb/avions.json", "w") as f:
            json.dump(avions_filtrés, f, indent=4)

        print(f"{len(avions_filtrés)} avions sauvegardés.")
    except Exception as e:
        print("Erreur :", e)

if __name__ == "__main__":
    # Décommenter la ligne suivante 
#    while True:
        collecter()
        time.sleep(2)  # Répéter toutes les 2 secondes
Erreur : unknown url type: 'localfile/avions.json'

Exercice 1 (compter le nombre d’avions dans une zone définie)#

import urllib.request
import json
import time

# Coordonnées du gymnase (rectangle géographique à ajuster selon votre position réelle)
# Gymnase de Beaulieu : LAT = 46.527936727497014, LON = 6.621917339000671
LAT_MIN = 46.32
LAT_MAX = 46.72
LON_MIN = 6.42
LON_MAX = 6.82

URL = "http://localhost/adsb/avions.json"

def est_dans_zone(lat, lon):
    return LAT_MIN <= lat <= LAT_MAX and LON_MIN <= lon <= LON_MAX

# Décommenter la ligne suivante:
# while True:
    try:
        # Récupère les données JSON
        with urllib.request.urlopen(URL) as response:
            avions = json.loads(response.read())

        count = 0
        for avion in avions:
            lat = avion.get("lat")
            lon = avion.get("lon")
            flight = avion.get("flight", "").strip()
            alt = avion.get("altitude")
            speed = avion.get("speed")

            if lat is not None and lon is not None and est_dans_zone(lat, lon):
                count += 1
                print(f"Vol {flight} | Altitude : {alt} m | Vitesse : {speed} km/h")

        print(f"Nombre d'avions au-dessus du gymnase: ", count)
        
        time.sleep(5)  # Attend 10 secondes avant la prochaine lecture

    except Exception as e:
        print("Erreur lors de la récupération :", e)
        time.sleep(5)