Cursor on Target to najmniejszy schemat, który wykonuje najwięcej pracy we współczesnym oprogramowaniu taktycznym. Pojedynczy dokument XML — kilkaset bajtów — niesie pozycję, tożsamość, pewność i czas życia, a ten dokument wystarcza, by umieścić znacznik na każdej mapie w sieci mesh. Powstał jako inicjatywa MITRE, by umożliwić operatorowi przekazanie celu z jednego systemu do drugiego dosłownym gestem kursora, i stał się lingua franca ekosystemu TAK. To analiza pole po polu formatu Cursor on Target: model event, taksonomia typów, geometria point, kontener detail oraz realia poprawnego generowania i walidowania.

1. model event w CoT

Każda wiadomość CoT to pojedynczy element <event>. Nie ma koperty, nagłówka ani osobnego rejestru typów wiadomości — element główny jest wiadomością. To celowa decyzja projektowa, dzięki której CoT jest tani: jeden rekurencyjny schemat przenosi przyjaznego żołnierza, wrogi pojazd, geofence, wiadomość czatu, sygnał ratunkowy i ślad sensora, bez osobnej ścieżki kodu dla każdego typu wiadomości na łączu.

Event zawiera dokładnie jedno dziecko <point> (gdzie dana rzecz się znajduje) oraz opcjonalne dziecko <detail> (wszystko inne na jej temat). Semantyka eventu jest w pełni określona przez jego atrybuty oraz otwartą treść <detail>. Parser, który rozumie cztery podstawowe atrybuty i point, potrafi narysować dowolną wiadomość CoT na mapie, nie rozumiejąc ani jednego rozszerzenia detail — ta właściwość płynnej degradacji sprawia, że CoT skaluje się między dostawcami, którzy nigdy się nie konsultowali.

Warto zatrzymać się nad tym, czego w modelu nie ma. Na poziomie schematu nie istnieje rozróżnienie między jednostką, znacznikiem, wiadomością czatu a śladem sensora — to wszystko są eventy, odróżniane jedynie przez ich type oraz dzieci detail, które niosą. Nie ma potwierdzeń, nie ma numerów sekwencyjnych ani sesji. CoT działa na zasadzie fire-and-forget; niezawodność, kolejność i dostarczanie są przesunięte w dół do transportu (TCP, TLS lub multicast UDP) i do aplikacji powyżej. Ten minimalizm jest definiującą cechą schematu: robi jedną rzecz — mówi, gdzie coś jest i czym jest, przez ograniczony czas — i nie chce rozrastać się we własny stos protokołów.

2. atrybuty eventu

Element <event> niesie stały zestaw atrybutów. version to wersja schematu, niemal zawsze 2.0. uid to globalnie unikatowy identyfikator opisywanej rzeczy — nie wiadomości, lecz rzeczy. Ponowne wysłanie zaktualizowanej pozycji dla tej samej encji wykorzystuje to samo uid; tak odbiorca wie, że ma przesunąć istniejący znacznik, a nie utworzyć nowy. UID-y to dowolne ciągi znaków, ale klienty TAK konwencjonalnie używają stabilnego identyfikatora per-urządzenie (np. ANDROID-serial) do raportów własnej pozycji.

type to ciąg typu MITRE (sekcja 3). how opisuje pochodzenie danych — sposób, w jaki pozycja została uzyskana. Częste wartości to h-g-i-g-o (człowiek, z GPS, wprowadzone ręcznie) oraz m-g (maszyna, GPS). Pole how pozwala silnikowi fuzji inaczej ważyć ręcznie wprowadzony raport spot niż żywy strumień GPS.

Triada cyklu życia to time, start i stale — wszystkie znaczniki czasu w UTC w formacie ISO 8601. time to moment wytworzenia wiadomości. start to moment, od którego informacja staje się ważna. stale to moment jej wygaśnięcia. Okno między start a stale to czas ważności eventu: po upływie stale zgodny odbiorca musi potraktować event jako wygasły i usunąć lub wyszarzyć znacznik. Raport własnej pozycji z poruszającej się jednostki może ustawić stale na time + 75 sekund; statyczny punkt pomiarowy może ustawić go na wiele godzin do przodu. Poprawne ustawienie tej triady to najczęstsze źródło „znaczników-duchów" — ustaw stale zbyt daleko w przyszłości, a martwe ślady będą zalegać; ustaw je zbyt krótko, a żywe ślady będą migotać.

Kluczowy wniosek: CoT nie ma jawnej wiadomości usunięcia. Ślad wycofuje się, pozwalając mu wygasnąć, albo wysyłając ostatnią aktualizację, której czas stale jest już w przeszłości. Zarządzanie stanem w sieci CoT jest zatem problemem przekroczenia czasu, a nie problemem transakcji — każdy odbiorca niezależnie wykonuje garbage collection według własnego zegara, dlatego rozsynchronizowanie zegarów między węzłami jest zagrożeniem operacyjnym, a nie kosmetycznym.

3. hierarchia typów MITRE

Atrybut type koduje to, czym jest dana rzecz, używając kropkowo-myślnikowej taksonomii MITRE. Najważniejszą rodziną jest typ atomowy, z prefiksem a-. Typ atomowy czyta się jako sekwencję tokenów rozdzielonych myślnikami: a-f-G-U-C.

Pierwszy token po a to przynależność: f sojusznik, h wróg, n neutralny, u nieznany, p oczekujący, plus warianty assumed/suspect. Kolejny token to wymiar walki: G ląd, A powietrze, S nawodny (morze), U podwodny, P kosmos, F SOF. Pozostałe tokeny schodzą w głąb hierarchii symboli MIL-STD-2525 — a-f-G-U-C to przyjazna jednostka lądowa, bojowa, i tak dalej. Symbol wieloznaczny a-f-G-* oznacza „przyjazną rzecz lądową, bliżej nieokreśloną", a renderery wracają do najbliższego zdefiniowanego symbolu. Rodziny inne niż atomowe używają innych prefiksów: b- dla bitów (dane sensora/geometrii, np. b-m-p-s-p-i dla punktu zainteresowania sensora), t- dla zadań i y- dla odpowiedzi. Geniusz kropkowej taksonomii polega na tym, że jest dekodowalna po prefiksie: klient, który zna tylko a-f-G, wciąż może umieścić ogólną ikonę przyjaznej jednostki lądowej i płynnie zdegradować na końcówce, której nie rozpoznaje.

4. element point

Element <point> jest obowiązkowy i niesie pięć atrybutów, wszystkie wymagane. lat i lon to stopnie dziesiętne WGS-84. hae to wysokość nad elipsoidą w metrach — uwaga „nad elipsoidą", a nie nad średnim poziomem morza; mieszanie HAE z wysokością ortometryczną (przesunięcie geoidy może przekraczać 30 m) to klasyczny błąd błędu pionowego, gdy CoT spotyka system oczekujący MSL.

ce to błąd kołowy — promień poziomej niepewności 1-sigma w metrach. le to błąd liniowy — niepewność pionowa w metrach. Razem pozwalają odbiorcy narysować pierścień dokładności zamiast zwodniczo precyzyjnego punktu. Wartość wartownicza 9999999 (często zapisywana jako 9999999.0) oznacza „nieznane" — to nie jest realny pomiar, to schematowy null. Punkt umieszczony ręcznie bez zmierzonej dokładności niesie ce="9999999" le="9999999", a logika fuzji musi traktować tę wartość jako przypadek szczególny, a nie jako błąd rzędu dziesięciu tysięcy kilometrów.

Ponieważ każdy atrybut jest wymagany, nie istnieje coś takiego jak point bez wysokości czy bez oszacowania błędu — schemat zmusza producenta do złożenia deklaracji, nawet jeśli tą deklaracją jest „nieznane". To cicho dobra decyzja projektowa: odbiorca nigdy nie musi zgadywać, czy brakujące pole oznacza zero, nieznane czy domyślne. Albo ma realną liczbę, albo ma wartość wartowniczą, a te dwie są jednoznaczne. Kosztem jest to, że leniwe kodery zaszywają na sztywno hae="0.0" dla wszystkiego, co jest gorsze niż wartość wartownicza, bo wygląda jak realny pomiar na poziomie morza. Jeśli nie znasz wysokości, powiedz to za pomocą 9999999; nie deklaruj zera.

5. element detail

Element <detail> to otwarty kontener rozszerzeń i to w nim faktycznie żyje ekosystem CoT. Schemat nie nakłada żadnego ograniczenia na jego dzieci — dowolny poprawny składniowo XML jest legalny — co pozwoliło TAK nadbudować bogaty protokół aplikacyjny na ogólnym formacie SA bez jego rozgałęzienia.

Konwencjonalne podelementy są szeroko respektowane. <contact> niesie czytelny dla człowieka callsign oraz, w przypadku TAK, adresowanie punktu końcowego do bezpośredniego przesyłania wiadomości. <track> niesie course i speed dla poruszających się encji, zamieniając statyczny punkt w wektor. <remarks> to swobodny tekst. <status> raportuje rzeczy takie jak poziom baterii. <__group> (podwójny podkreślnik) przypisuje jednostce kolor i rolę zespołu TAK — Cyan, Team Member — sterując kolorem ikony na ekranie każdego członka zespołu. <takv> raportuje wersję klienta TAK, urządzenie i platformę. Ponieważ detail jest otwarty, odbiorca po prostu pomija dzieci, których nie rozpoznaje, co stanowi całą podstawę interoperacyjności CoT i TAK między heterogenicznymi klientami.

6. CoT a Link 16 i VMF

CoT zajmuje tę samą przestrzeń koncepcyjną co serie J i VMF, lecz z przeciwnymi priorytetami projektowymi. Wiadomości J Link 16 to słowa o stałym formacie, upakowane bitowo, dopasowane do slotu TDMA; VMF (MIL-STD-6017) to zmienny, lecz ściśle zorientowany bitowo format dla nośników o niskiej przepustowości. CoT to rozwlekły XML zbudowany dla sieci IP, gdzie bajty są tanie, a czas programisty nie.

Mapowanie CoT na wiadomość J jest stratne w obie strony. Przynależność i wymiar walki w CoT mapują się czysto na pola śladu J3.x oraz na pola tożsamości VMF, a lat/lon/hae tłumaczą się bezpośrednio. Niedopasowanie impedancji tkwi w precyzji i semantyce: jakość śladu w serii J to dyskretna wartość wyliczeniowa, podczas gdy ce/le w CoT to ciągłe metry; otwarty <detail> w CoT nie ma odpowiednika o stałym formacie i jest hurtowo odrzucany na bramie. I odwrotnie — pola serii J, takie jak konkretne tryby IFF czy udział w sieci pochodzący z PPLI, nie mają natywnego slotu w CoT i muszą być przemycane do niestandardowych rozszerzeń detail. Bramy łączące CoT i taktyczne łącza danych niosą zatem stanowczą, ręcznie utrzymywaną mapę pól — ten sam problem tłumacza-z-poglądami, który pojawia się wszędzie w NATO-wskim C2.

7. strumieniowanie a TAK

W produkcji CoT jest strumieniem, nie dokumentem. TAK Server multipleksuje eventy CoT między klientami: raport własnej pozycji jednostki płynie w górę po trwałym połączeniu TCP (często TLS) z konfigurowalną częstotliwością — zwykle co 1 do 10 sekund w zależności od ruchu i ustawienia „dynamic reporting" — a serwer rozsyła go do subskrybentów, opcjonalnie filtrowanych według misji, grupy lub geofence. Mesh SA, tryb bezserwerowy, rozsyła te same eventy multicastem przez UDP w sieci lokalnej, dzięki czemu drużyna działa bez infrastruktury.

Częstotliwości wiadomości napędzają inżynierię. Ćwiczenie z 200 węzłami, gdzie każdy raportuje co 2 sekundy, to 100 eventów/sekundę samej własnej pozycji, jeszcze przed śladami sensorów. Serwer nie utrzymuje protokołu usuwania dla niczego z tego; zamiast tego każdy klient niezależnie wykonuje garbage collection na podstawie znaczników stale, które widział. Garbage collection sterowany przez stale jest elegancki — bez lidera, bez konsensusu — ale oznacza, że klient, który straci łączność, będzie obserwować, jak cały jego obraz starzeje się i znika zgodnie z harmonogramem, co zwykle jest poprawnym zachowaniem, a czasami przykrą niespodzianką podczas blackoutu łączności.

8. walidowanie i generowanie CoT

Format na łączu jest pobłażliwy, co ułatwia wyemitowanie subtelnie wadliwego CoT. Waliduj względem opublikowanego schematu Event.xsd podczas rozwoju, ale znaj jego granice: XSD sprawdza, że point istnieje oraz że atrybuty cyklu życia są obecne i poprawnie typowane, lecz nie powie ci, że twoje stale jest przed twoim start, że twój token type jest bezsensowny, ani że twoje hae jest wysokością geoidalną udającą wysokość elipsoidalną.

Powracające błędy zniekształconych wiadomości są przewidywalne. Znaczniki czasu bez końcowego Z lub z przesunięciami strefy lokalnej — czas CoT to UTC, kropka, a brakujące Z wysyła znaczniki w przeszłość lub przyszłość. Odwrócone czasy życia, gdzie stale poprzedza start, tworzące eventy martwe już przy dostarczeniu. Ponowne użycie jednego uid dla odrębnych encji, co sprawia, że dwa realne ślady zlewają się w jeden migoczący znacznik. Emitowanie realnie wyglądającego ce zamiast wartownika 9999999 dla niezmierzonego punktu, co zwodzi fuzję do zaufania śmieciom. Gdy budujesz koder CoT, uczyń triadę cyklu życia typem pierwszoklasowym, który wymusza start ≤ stale i renderuje UTC z Z, generuj UID-y ze stabilnego klucza encji, a nie z licznika per-wiadomość, oraz emituj wartownika nieznanej wartości jawnie. Ustaw te cztery niezmienniki poprawnie, a twój CoT będzie współpracować z klientami, których nigdy nie widziałeś — co jest całym sensem tego formatu.