kopia lustrzana https://github.com/cyoung/stratux
Decode US civil Mode S codes to N numbers
rodzic
a062241c7a
commit
efaaa8777d
114
main/traffic.go
114
main/traffic.go
|
@ -13,6 +13,7 @@ import (
|
|||
"bufio"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"net"
|
||||
|
@ -75,7 +76,8 @@ const (
|
|||
|
||||
type TrafficInfo struct {
|
||||
Icao_addr uint32
|
||||
Tail string
|
||||
Reg string // Registration. Calculated from Icao_addr for civil aircraft of US registry.
|
||||
Tail string // Callsign. Transmitted by aircraft.
|
||||
Emitter_category uint8 // Formatted using GDL90 standard, e.g. in a Mode ES report, A7 becomes 0x07, B0 becomes 0x08, etc.
|
||||
OnGround bool // Air-ground status. On-ground is "true".
|
||||
Addr_type uint8 // UAT address qualifier. Used by GDL90 format, so translations for ES TIS-B/ADS-R are needed.
|
||||
|
@ -349,6 +351,12 @@ func parseDownlinkReport(s string, signalLevel int) {
|
|||
ti.Last_seen = stratuxClock.Time // need to initialize to current stratuxClock so it doesn't get cut before we have a chance to populate a position message
|
||||
ti.Icao_addr = icao_addr
|
||||
ti.ExtrapolatedPosition = false
|
||||
|
||||
thisReg, validReg := icao2faa(icao_addr)
|
||||
if validReg {
|
||||
ti.Reg = thisReg
|
||||
ti.Tail = thisReg
|
||||
}
|
||||
}
|
||||
|
||||
ti.Addr_type = addr_type
|
||||
|
@ -650,6 +658,12 @@ func esListen() {
|
|||
ti.Icao_addr = icao
|
||||
ti.ExtrapolatedPosition = false
|
||||
ti.Last_source = TRAFFIC_SOURCE_1090ES
|
||||
|
||||
thisReg, validReg := icao2faa(icao)
|
||||
if validReg {
|
||||
ti.Reg = thisReg
|
||||
ti.Tail = thisReg
|
||||
}
|
||||
}
|
||||
|
||||
ti.SignalLevel = 10 * math.Log10(newTi.SignalLevel)
|
||||
|
@ -1000,6 +1014,104 @@ func updateDemoTraffic(icao uint32, tail string, relAlt float32, gs float64, off
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
icao2faa() : Converts 24-bit Mode S addresses to N-numbers.
|
||||
|
||||
Input: uint32 representing the Mode S address. Valid range for
|
||||
translation is 0xA00001 - 0xADF7C7, inclusive.
|
||||
|
||||
Values outside the range A000001-AFFFFFF are flagged as non-US.
|
||||
Values between ADF7C8 - AFFFFF are allocated to the United States,
|
||||
but are not used for aicraft on the civil registry. These could be
|
||||
military, other public aircraft, or (future use) temporary
|
||||
anonymous addresses.
|
||||
|
||||
Output:
|
||||
string: String containing the decoded tail number (if decoding succeeded),
|
||||
"NON-US" (for non-US allocation), and "MIL" for non-civil US allocation.
|
||||
|
||||
bool: True if the Mode S address successfully translated to an
|
||||
N number. False for all other conditions.
|
||||
*/
|
||||
|
||||
func icao2faa(icao_addr uint32) (string, bool) {
|
||||
// Initialize local variables
|
||||
base34alphabet := string("ABCDEFGHJKLMNPQRSTUVWXYZ0123456789")
|
||||
faaOffset := uint32(0xA00001)
|
||||
tail := ""
|
||||
|
||||
// Discard non-US ICAO codes
|
||||
if (icao_addr < 0xA00001) || (icao_addr > 0xAFFFFF) {
|
||||
//fmt.Printf("%X is a non-US address.\n", icao_addr)
|
||||
return "NON-US", false
|
||||
}
|
||||
|
||||
// Discard addresses that are not assigned to aircraft on the civil registry (public aircraft: USAF, USN, USMC, USCG, ANG, FBI, etc.)
|
||||
if icao_addr > 0xADF7C7 {
|
||||
//fmt.Printf("%X is a US aircraft, but not on the civil registry.\n", icao_addr)
|
||||
return "MIL", false
|
||||
}
|
||||
|
||||
serial := int32(icao_addr - faaOffset)
|
||||
// First digit
|
||||
a := (serial / 101711) + 1
|
||||
|
||||
// Second digit
|
||||
a_remainder := serial % 101711
|
||||
b := ((a_remainder + 9510) / 10111) - 1
|
||||
|
||||
// Third digit
|
||||
b_remainder := (a_remainder + 9510) % 10111
|
||||
c := ((b_remainder + 350) / 951) - 1
|
||||
|
||||
// This next bit is more convoluted. First, figure out if we're using the "short" method of
|
||||
// decoding the last two digits (two letters, one letter and one blank, or two blanks).
|
||||
// This will be the case if digit "B" or "C" are calculated as negative, or if c_remainder
|
||||
// is less than 601.
|
||||
|
||||
c_remainder := (b_remainder + 350) % 951
|
||||
var d, e int32
|
||||
|
||||
if (b >= 0) && (c >= 0) && (c_remainder > 600) { // alphanumeric decoding method
|
||||
d = 24 + (c_remainder-601)/35
|
||||
e = (c_remainder - 601) % 35
|
||||
|
||||
} else { // two-letter decoding method
|
||||
if (b < 0) || (c < 0) {
|
||||
c_remainder -= 350 // otherwise " " == 350, "A " == 351, "AA" == 352, etc.
|
||||
}
|
||||
|
||||
d = (c_remainder - 1) / 25
|
||||
e = (c_remainder - 1) % 25
|
||||
|
||||
if e < 0 {
|
||||
d -= 1
|
||||
e += 25
|
||||
}
|
||||
}
|
||||
|
||||
a_char := fmt.Sprintf("%d", a)
|
||||
var b_char, c_char, d_char, e_char string
|
||||
|
||||
if b >= 0 {
|
||||
b_char = fmt.Sprintf("%d", b)
|
||||
}
|
||||
|
||||
if b >= 0 && c >= 0 {
|
||||
c_char = fmt.Sprintf("%d", c)
|
||||
}
|
||||
|
||||
if d > -1 {
|
||||
d_char = string(base34alphabet[d])
|
||||
if e > 0 {
|
||||
e_char = string(base34alphabet[e-1])
|
||||
}
|
||||
}
|
||||
|
||||
tail = "N" + a_char + b_char + c_char + d_char + e_char
|
||||
return tail, true
|
||||
}
|
||||
|
||||
func initTraffic() {
|
||||
traffic = make(map[uint32]TrafficInfo)
|
||||
seenTraffic = make(map[uint32]bool)
|
||||
|
|
|
@ -59,6 +59,7 @@ function TrafficCtrl($rootScope, $scope, $state, $http, $interval) {
|
|||
}
|
||||
new_traffic.icao = obj.Icao_addr.toString(16).toUpperCase();
|
||||
new_traffic.tail = obj.Tail;
|
||||
new_traffic.reg = obj.Reg;
|
||||
if (obj.Squawk == 0) {
|
||||
new_traffic.squawk = "----";
|
||||
} else {
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
<div class="panel-body traffic-page">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<span class="col-xs-3"><strong>Callsign</strong></span>
|
||||
<span class="col-xs-3" ng-hide="showReg"><strong>Callsign</strong></span>
|
||||
<span class="col-xs-3" ng-show="showReg"><strong>Tail Num</strong></span>
|
||||
<span class="col-xs-2" ng-hide="showSquawk"><strong>Code</strong></span>
|
||||
<span class="col-xs-2" ng-show="showSquawk"><strong>Squawk</strong></span>
|
||||
<span class="col-xs-5 text-right" ng-hide="GPS_connected && RelDist"><strong>Location</strong></span>
|
||||
|
@ -29,11 +30,15 @@
|
|||
<div class="row" ng-repeat="aircraft in data_list | orderBy: 'dist'">
|
||||
<div class="separator"></div>
|
||||
<div class="col-sm-6">
|
||||
<span class="col-xs-3">
|
||||
<span class="col-xs-3" ng-hide="showReg">
|
||||
<span ng-show="aircraft.tail" ng-class="'label traffic-style'+aircraft.src+aircraft.targettype">{{aircraft.addr_symb}}<strong> {{aircraft.tail}}</strong></span>
|
||||
<span ng-hide="aircraft.tail" ng-class="'label traffic-style'+aircraft.src+aircraft.targettype">{{aircraft.addr_symb}}<strong> [--N/A--]</strong></span>
|
||||
</span>
|
||||
<span class="col-xs-3" ng-show="showReg">
|
||||
<span ng-show="aircraft.reg" ng-class="'label traffic-style'+aircraft.src+aircraft.targettype">{{aircraft.addr_symb}}<strong> {{aircraft.reg}}</strong></span>
|
||||
<span ng-hide="aircraft.reg" ng-class="'label traffic-style'+aircraft.src+aircraft.targettype">{{aircraft.addr_symb}}<strong> [--N/A--]</strong></span>
|
||||
</span>
|
||||
|
||||
|
||||
<span class="col-xs-2">
|
||||
<span style="font-size:80%" ng-hide="showSquawk">{{aircraft.icao}}<span style="font-size:50%">{{aircraft.addr_type == 3 ? " (TFID)" : ""}}</span></span>
|
||||
<span ng-show="showSquawk"><span ng-show="aircraft.squawk < 1000">0</span><span ng-show="aircraft.squawk < 100">0</span><span ng-show="aircraft.squawk < 10">0</span>{{aircraft.squawk}}</span>
|
||||
|
@ -60,19 +65,26 @@
|
|||
<div class="panel-body traffic-footer">
|
||||
<div class="separator"></div>
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
<label class="control-label col-xs-6">Show Tail Number</label>
|
||||
<span class="col-xs-3"><ui-switch ng-model='showReg' settings-change></ui-switch></span>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<label class="control-label col-xs-6">Show Squawk</label>
|
||||
<span class="col-xs-3"><ui-switch ng-model='showSquawk' settings-change></ui-switch></span>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<label class="control-label col-xs-6">Show Distance</label>
|
||||
<label class="control-label col-xs-6" ng-show="GPS_connected">Show Distance</label>
|
||||
<label class="control-label text-muted col-xs-6" ng-hide="GPS_connected">Show Distance N/A</label>
|
||||
<span class="col-xs-3"><ui-switch ng-model='RelDist' settings-change></ui-switch></span>
|
||||
</div>
|
||||
<!--
|
||||
<div class="col-sm-4">
|
||||
<label class="control-label col-xs-6">GPS Status</label>
|
||||
<span ng-show="GPS_connected" class="label label-success col-xs-3" style="font-size:100%; display:block; height: 34px; line-height: 34px">Valid</span>
|
||||
<span ng-hide="GPS_connected" class="label label-danger col-xs-3" style="font-size:100%; display:block; height: 34px; line-height: 34px">No Fix</span>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -85,7 +97,8 @@
|
|||
<div class="panel-body traffic-page">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<span class="col-xs-4"><strong>Callsign</strong></span>
|
||||
<span class="col-xs-4" ng-hide="showReg"><strong>Callsign</strong></span>
|
||||
<span class="col-xs-4" ng-show="showReg"><strong>Tail Num</strong></span>
|
||||
<span class="col-xs-3"><strong>Code</strong></span>
|
||||
<span class="col-xs-3"><strong>Squawk</strong></span>
|
||||
</div>
|
||||
|
@ -102,9 +115,13 @@
|
|||
<div class="row" ng-repeat="aircraft in data_list_invalid | orderBy: 'icao'">
|
||||
<div class="separator"></div>
|
||||
<div class="col-sm-6">
|
||||
<span class="col-xs-4">
|
||||
<span class="col-xs-4" ng-hide="showReg">
|
||||
<span ng-show="aircraft.tail" ng-class="'label traffic-style'+aircraft.src+aircraft.targettype">{{aircraft.addr_symb}}<strong> {{aircraft.tail}}</strong></span>
|
||||
<span ng-hide="aircraft.tail" ng-class="'label traffic-style'+aircraft.src+aircraft.targettype">{{aircraft.addr_symb}}<strong> [--N/A--]</strong></span>
|
||||
</span>
|
||||
<span class="col-xs-4" ng-show="showReg">
|
||||
<span ng-show="aircraft.reg" ng-class="'label traffic-style'+aircraft.src+aircraft.targettype">{{aircraft.addr_symb}}<strong> {{aircraft.reg}}</strong></span>
|
||||
<span ng-hide="aircraft.reg" ng-class="'label traffic-style'+aircraft.src+aircraft.targettype">{{aircraft.addr_symb}}<strong> [--N/A--]</strong></span>
|
||||
</span>
|
||||
<span class="col-xs-3" style="font-size:80%">{{aircraft.icao}}<span style="font-size:50%">{{aircraft.addr_type == 3 ? " (TFID)" : ""}}</span></span>
|
||||
<span class="col-xs-3"><span ng-show="aircraft.squawk < 1000">0</span><span ng-show="aircraft.squawk < 100">0</span><span ng-show="aircraft.squawk < 10">0</span>{{aircraft.squawk}}</span>
|
||||
|
|
Ładowanie…
Reference in New Issue