Cursor on Target (CoT) est un format de message basé sur XML développé par l'Air Force Research Laboratory américain au début des années 2000 pour résoudre un problème spécifique : comment partager la position, l'identité et le statut d'une cible ou d'une unité entre des systèmes militaires hétérogènes qui n'ont pas été conçus pour l'interopérabilité ? La réponse fut un schéma XML minimal et extensible que tout système peut produire et consommer.
Deux décennies plus tard, CoT est devenu le standard de facto pour les rapports de position et le partage d'événements dans l'écosystème tactique de bord. ATAK (Android Team Awareness Kit), WinTAK, iTAK, TAK Server et des centaines de plugins parlent CoT. Dans le contexte des programmes DGA (Direction générale de l'armement) comme SICS-G et SITAWARE, CoT constitue le format d'intégration pour les données de position tactiques provenant de systèmes partenaires.
Structure XML : éléments event, point et detail
Un message CoT est un document XML avec un seul élément racine : <event>. Chaque message CoT est un événement, qu'il décrive une mise à jour de position, un rapport de capteur, un message de chat ou une tâche de mission.
Un rapport de position CoT minimal :
<event version="2.0"
uid="BRAVO-1-FR"
type="a-f-G-U-C"
how="m-g"
time="2026-05-11T08:30:00.000Z"
start="2026-05-11T08:30:00.000Z"
stale="2026-05-11T08:31:00.000Z">
<point lat="48.8566"
lon="2.3522"
hae="35.0"
ce="10.0"
le="5.0"/>
<detail>
<contact callsign="BRAVO-1-FR"/>
<group name="Blue" role="Team Leader"/>
<track speed="0.0" course="90.0"/>
</detail>
</event>
uid : Identifiant globalement unique de l'entité. Maintenu à travers tous les rapports pour la même entité.
type : Chaîne hiérarchique encodant la classification de l'entité. a-f-G-U-C = atome, ami, sol, unité, combat. a-h-A = atome, hostile, air.
stale : Heure après laquelle le rapport doit être considéré comme périmé. Définir à environ 2× l'intervalle de mise à jour attendu.
point : Position de l'entité en coordonnées WGS84. hae est l'altitude au-dessus de l'ellipsoïde WGS84 en mètres (pas MSL). ce et le sont les erreurs circulaires et linéaires en mètres.
Types CoT : hiérarchie de classification
a-f-G (Force terrestre amie) : Affiché avec un rectangle bleu selon MIL-STD-2525.
a-h-G (Force terrestre hostile) : Affiché avec un losange rouge.
a-u-G (Contact terrestre inconnu) : Affiché avec un point d'interrogation jaune. Pour les contacts radar non identifiés.
a-f-A (Aéronef ami) : UAV, hélicoptères et aéronefs à voilure fixe alliés. Particulièrement pertinent pour l'intégration des systèmes de drones dans les programmes DGA.
b-m-p-s-m (Repère de carte) : Événements statiques comme les obstacles, les points de passage et les zones de rassemblement. Type le plus courant pour les annotations de la COP.
t-x-m-c (Tâche de mission) : Messages de coordination de mission transmis entre systèmes de commandement. Utilisé dans les intégrations SITAWARE pour distribuer les ordres aux éléments subordonnés.
TAK Server : routage, filtrage et fédération
TAK Server est le composant côté serveur de l'écosystème TAK. Il reçoit les messages CoT des clients connectés et les achemine vers d'autres clients en fonction de règles configurables.
Les groupes limitent quels clients peuvent voir quels événements. Un groupe nommé "BRAVO" ne recevra que les événements CoT associés à ce groupe — les événements des autres groupes sont filtrés au niveau du serveur. La fédération connecte plusieurs instances TAK Server, permettant aux événements CoT de circuler entre instances de serveurs à différents emplacements — le mécanisme par lequel les positions de niveau inférieur deviennent visibles dans les systèmes COP de niveau supérieur sans connexions directes des clients. Dans les programmes EMA (État-major des armées), la fédération permet l'intégration des serveurs TAK de niveau compagnie avec les systèmes C2 de niveau brigade sans exposer les connexions réseau directes.
Les flux de données entrants permettent à TAK Server d'accepter des connexions depuis des sources de données externes — capteurs, radars, systèmes d'identification ami-ennemi — et de les traduire en événements CoT distribués aux clients connectés. Ce mécanisme est utilisé pour intégrer les données radar de surveillance aérienne dans les COP tactiques des forces terrestres.
Implémentation en Python : parser et générer des CoT
La bibliothèque pytak fournit une implémentation complète de la génération d'événements CoT. Pour le parsing, le module standard xml.etree.ElementTree de Python suffit. La connexion à TAK Server via TCP nécessite d'établir une connexion TCP au port 8087 (ou TLS sur 8089) et d'écrire la chaîne XML suivie d'un octet terminateur null. La bibliothèque pytak abstrait cela et supporte également l'UDP multicast pour les déploiements en réseau local.
Exemple de génération d'un événement CoT position en Python :
import xml.etree.ElementTree as ET
from datetime import datetime, timedelta, timezone
def build_cot_position(uid, lat, lon, hae, callsign):
now = datetime.now(timezone.utc)
stale = now + timedelta(seconds=60)
fmt = "%Y-%m-%dT%H:%M:%S.000Z"
event = ET.Element("event", {
"version": "2.0",
"uid": uid,
"type": "a-f-G-U-C",
"how": "m-g",
"time": now.strftime(fmt),
"start": now.strftime(fmt),
"stale": stale.strftime(fmt)
})
ET.SubElement(event, "point", {
"lat": str(lat),
"lon": str(lon),
"hae": str(hae),
"ce": "10.0",
"le": "5.0"
})
detail = ET.SubElement(event, "detail")
ET.SubElement(detail, "contact", {"callsign": callsign})
ET.SubElement(detail, "group", {"name": "Blue", "role": "Team Member"})
ET.SubElement(detail, "track", {"speed": "0.0", "course": "0.0"})
return ET.tostring(event, encoding="unicode")
Pour envoyer ce message à TAK Server via TCP :
import socket
def send_cot_tcp(host, port, cot_xml):
with socket.create_connection((host, port), timeout=5) as sock:
payload = cot_xml.encode("utf-8") + b"\x00"
sock.sendall(payload)
Pour parser un message CoT entrant depuis une source de données terrain :
def parse_cot_position(xml_str):
root = ET.fromstring(xml_str)
uid = root.get("uid")
event_type = root.get("type")
stale = root.get("stale")
point = root.find("point")
lat = float(point.get("lat"))
lon = float(point.get("lon"))
hae = float(point.get("hae"))
detail = root.find("detail")
callsign = None
if detail is not None:
contact = detail.find("contact")
if contact is not None:
callsign = contact.get("callsign")
return {"uid": uid, "type": event_type, "lat": lat,
"lon": lon, "hae": hae, "callsign": callsign,
"stale": stale}
Intégration avec les pipelines de fusion multi-sources
Dans les systèmes C2 de défense modernes, CoT est rarement la seule source de données de position. Les systèmes SICS-G et SITAWARE ingèrent simultanément des données CoT depuis les éléments équipés ATAK, des données Link 16 depuis les aéronefs et les systèmes navals, et des données NFFI (NATO Friendly Force Information) depuis les systèmes de commandement partenaires. Un pipeline de fusion doit normaliser ces sources en un modèle de données commun tout en préservant la provenance de chaque piste.
L'approche standard consiste à traduire chaque format source en CoT en interne — en attribuant des UIDs stables dérivés du format source (par exemple, un ID de piste Link 16 mappé vers un UID CoT déterministe), puis à distribuer les pistes fusionnées via TAK Server fédéré aux clients de visualisation. Cela permet aux clients ATAK standard d'afficher des données de position issues de sources non-CoT sans modification.
Guide pour le temps stale : Définir le temps stale à environ 2× l'intervalle de mise à jour attendu pour le type d'entité. Pour un soldat à pied se mettant à jour toutes les 30 secondes, stale doit être de 60 secondes. Un stale trop long provoque la persistance de pistes fantômes dans la COP après qu'une entité est passée hors ligne.