kopia lustrzana https://github.com/cyoung/stratux
Resolve conflicts.
commit
ef56848715
|
@ -35,7 +35,8 @@ import (
|
|||
"github.com/ricochet2200/go-disk-usage/du"
|
||||
)
|
||||
|
||||
// http://www.faa.gov/nextgen/programs/adsb/wsa/media/GDL90_Public_ICD_RevA.PDF
|
||||
// https://www.faa.gov/nextgen/programs/adsb/Archival/
|
||||
// https://www.faa.gov/nextgen/programs/adsb/Archival/media/GDL90_Public_ICD_RevA.PDF
|
||||
|
||||
var debugLogf string // Set according to OS config.
|
||||
var dataLogFilef string // Set according to OS config.
|
||||
|
@ -203,10 +204,18 @@ func makeLatLng(v float32) []byte {
|
|||
return ret
|
||||
}
|
||||
|
||||
func isDetectedOwnshipValid() bool {
|
||||
return stratuxClock.Since(OwnshipTrafficInfo.Last_seen) < 10*time.Second
|
||||
}
|
||||
|
||||
func makeOwnshipReport() bool {
|
||||
if !isGPSValid() {
|
||||
gpsValid := isGPSValid()
|
||||
selfOwnshipValid := isDetectedOwnshipValid()
|
||||
if !gpsValid && !selfOwnshipValid {
|
||||
return false
|
||||
}
|
||||
curOwnship := OwnshipTrafficInfo
|
||||
|
||||
msg := make([]byte, 28)
|
||||
// See p.16.
|
||||
msg[0] = 0x0A // Message type "Ownship".
|
||||
|
@ -225,15 +234,26 @@ func makeOwnshipReport() bool {
|
|||
msg[4] = code[2] // Mode S address.
|
||||
}
|
||||
|
||||
tmp := makeLatLng(mySituation.Lat)
|
||||
msg[5] = tmp[0] // Latitude.
|
||||
msg[6] = tmp[1] // Latitude.
|
||||
msg[7] = tmp[2] // Latitude.
|
||||
|
||||
tmp = makeLatLng(mySituation.Lng)
|
||||
msg[8] = tmp[0] // Longitude.
|
||||
msg[9] = tmp[1] // Longitude.
|
||||
msg[10] = tmp[2] // Longitude.
|
||||
var tmp []byte
|
||||
if selfOwnshipValid {
|
||||
tmp = makeLatLng(curOwnship.Lat)
|
||||
msg[5] = tmp[0] // Latitude.
|
||||
msg[6] = tmp[1] // Latitude.
|
||||
msg[7] = tmp[2] // Latitude.
|
||||
tmp = makeLatLng(curOwnship.Lng)
|
||||
msg[8] = tmp[0] // Longitude.
|
||||
msg[9] = tmp[1] // Longitude.
|
||||
msg[10] = tmp[2] // Longitude.
|
||||
} else {
|
||||
tmp = makeLatLng(mySituation.Lat)
|
||||
msg[5] = tmp[0] // Latitude.
|
||||
msg[6] = tmp[1] // Latitude.
|
||||
msg[7] = tmp[2] // Latitude.
|
||||
tmp = makeLatLng(mySituation.Lng)
|
||||
msg[8] = tmp[0] // Longitude.
|
||||
msg[9] = tmp[1] // Longitude.
|
||||
msg[10] = tmp[2] // Longitude.
|
||||
}
|
||||
|
||||
// This is **PRESSURE ALTITUDE**
|
||||
//FIXME: Temporarily removing "invalid altitude" when pressure altitude not available - using GPS altitude instead.
|
||||
|
@ -242,25 +262,30 @@ func makeOwnshipReport() bool {
|
|||
var alt uint16
|
||||
var altf float64
|
||||
|
||||
if isTempPressValid() {
|
||||
if selfOwnshipValid {
|
||||
altf = float64(curOwnship.Alt)
|
||||
} else if isTempPressValid() {
|
||||
altf = float64(mySituation.Pressure_alt)
|
||||
} else {
|
||||
altf = float64(mySituation.Alt) //FIXME: Pass GPS altitude if PA not available. **WORKAROUND FOR FF**
|
||||
}
|
||||
|
||||
altf = (altf + 1000) / 25
|
||||
|
||||
alt = uint16(altf) & 0xFFF // Should fit in 12 bits.
|
||||
|
||||
msg[11] = byte((alt & 0xFF0) >> 4) // Altitude.
|
||||
msg[12] = byte((alt & 0x00F) << 4)
|
||||
if isGPSGroundTrackValid() {
|
||||
if selfOwnshipValid || isGPSGroundTrackValid() {
|
||||
msg[12] = msg[12] | 0x09 // "Airborne" + "True Track"
|
||||
}
|
||||
|
||||
msg[13] = byte(0x80 | (mySituation.NACp & 0x0F)) //Set NIC = 8 and use NACp from gps.go.
|
||||
|
||||
gdSpeed := uint16(0) // 1kt resolution.
|
||||
if isGPSGroundTrackValid() {
|
||||
if selfOwnshipValid && curOwnship.Speed_valid {
|
||||
gdSpeed = curOwnship.Speed
|
||||
} else if isGPSGroundTrackValid() {
|
||||
gdSpeed = mySituation.GroundSpeed
|
||||
}
|
||||
|
||||
|
@ -276,7 +301,9 @@ func makeOwnshipReport() bool {
|
|||
|
||||
// Track is degrees true, set from GPS true course.
|
||||
groundTrack := float32(0)
|
||||
if isGPSGroundTrackValid() {
|
||||
if selfOwnshipValid {
|
||||
groundTrack = float32(curOwnship.Track)
|
||||
} else if isGPSGroundTrackValid() {
|
||||
groundTrack = mySituation.TrueCourse
|
||||
}
|
||||
|
||||
|
@ -297,6 +324,17 @@ func makeOwnshipReport() bool {
|
|||
|
||||
msg[18] = 0x01 // "Light (ICAO) < 15,500 lbs"
|
||||
|
||||
if selfOwnshipValid {
|
||||
// Limit tail number to 7 characters.
|
||||
tail := curOwnship.Tail
|
||||
if len(tail) > 7 {
|
||||
tail = tail[:7]
|
||||
}
|
||||
// Copy tail number into message.
|
||||
for i := 0; i < len(tail); i++ {
|
||||
msg[19+i] = tail[i]
|
||||
}
|
||||
}
|
||||
// Create callsign "Stratux".
|
||||
msg[19] = 0x53
|
||||
msg[20] = 0x74
|
||||
|
@ -1126,6 +1164,21 @@ func openReplay(fn string, compressed bool) (WriteCloser, error) {
|
|||
return ret, err
|
||||
}
|
||||
|
||||
/*
|
||||
fsWriteTest().
|
||||
Makes a temporary file in 'dir', checks for error. Deletes the file.
|
||||
*/
|
||||
|
||||
func fsWriteTest(dir string) error {
|
||||
fn := dir + "/.write_test"
|
||||
err := ioutil.WriteFile(fn, []byte("test\n"), 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = os.Remove(fn)
|
||||
return err
|
||||
}
|
||||
|
||||
func printStats() {
|
||||
statTimer := time.NewTicker(30 * time.Second)
|
||||
diskUsageWarning := false
|
||||
|
|
|
@ -159,7 +159,6 @@ func handleStatusWS(conn *websocket.Conn) {
|
|||
*/
|
||||
|
||||
// Send status.
|
||||
<-timer.C
|
||||
update, _ := json.Marshal(&globalStatus)
|
||||
_, err := conn.Write(update)
|
||||
|
||||
|
@ -167,19 +166,20 @@ func handleStatusWS(conn *websocket.Conn) {
|
|||
// log.Printf("Web client disconnected.\n")
|
||||
break
|
||||
}
|
||||
<-timer.C
|
||||
}
|
||||
}
|
||||
|
||||
func handleSituationWS(conn *websocket.Conn) {
|
||||
timer := time.NewTicker(100 * time.Millisecond)
|
||||
for {
|
||||
<-timer.C
|
||||
situationJSON, _ := json.Marshal(&mySituation)
|
||||
_, err := conn.Write(situationJSON)
|
||||
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
<-timer.C
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ package main
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/tarm/serial"
|
||||
"golang.org/x/net/icmp"
|
||||
"golang.org/x/net/ipv4"
|
||||
|
@ -71,11 +72,26 @@ const (
|
|||
NETWORK_AHRS_FFSIM = 2
|
||||
NETWORK_AHRS_GDL90 = 4
|
||||
dhcp_lease_file = "/var/lib/dhcp/dhcpd.leases"
|
||||
dhcp_lease_dir = "/var/lib/dhcp"
|
||||
extra_hosts_file = "/etc/stratux-static-hosts.conf"
|
||||
)
|
||||
|
||||
var dhcpLeaseFileWarning bool
|
||||
var dhcpLeaseDirectoryLastTest time.Time // Last time fsWriteTest() was run on the DHCP lease directory.
|
||||
|
||||
// Read the "dhcpd.leases" file and parse out IP/hostname.
|
||||
func getDHCPLeases() (map[string]string, error) {
|
||||
// Do a write test. Even if we are able to read the file, it may be out of date because there's a fs write issue.
|
||||
// Only perform the test once every 5 minutes to minimize writes.
|
||||
if !dhcpLeaseFileWarning && (stratuxClock.Since(dhcpLeaseDirectoryLastTest) >= 5*time.Minute) {
|
||||
err := fsWriteTest(dhcp_lease_dir)
|
||||
if err != nil {
|
||||
err_p := fmt.Errorf("Write error on '%s', your EFB may have issues receiving weather and traffic.", dhcp_lease_dir)
|
||||
addSystemError(err_p)
|
||||
dhcpLeaseFileWarning = true
|
||||
}
|
||||
dhcpLeaseDirectoryLastTest = stratuxClock.Time
|
||||
}
|
||||
dat, err := ioutil.ReadFile(dhcp_lease_file)
|
||||
ret := make(map[string]string)
|
||||
if err != nil {
|
||||
|
|
|
@ -84,7 +84,7 @@ type TrafficInfo struct {
|
|||
TargetType uint8 // types decribed in const above
|
||||
SignalLevel float64 // Signal level, dB RSSI.
|
||||
Squawk int // Squawk code
|
||||
Position_valid bool // set when position report received. Unset after n seconds? (To-do)
|
||||
Position_valid bool //TODO: set when position report received. Unset after n seconds?
|
||||
Lat float32 // decimal degrees, north positive
|
||||
Lng float32 // decimal degrees, east positive
|
||||
Alt int32 // Pressure altitude, feet
|
||||
|
@ -109,7 +109,7 @@ type TrafficInfo struct {
|
|||
Last_GnssDiffAlt int32 // Altitude at last GnssDiffFromBaroAlt update.
|
||||
Last_speed time.Time // Time of last velocity and track update (stratuxClock).
|
||||
Last_source uint8 // Last frequency on which this target was received.
|
||||
ExtrapolatedPosition bool // TO-DO: True if Stratux is "coasting" the target from last known position.
|
||||
ExtrapolatedPosition bool //TODO: True if Stratux is "coasting" the target from last known position.
|
||||
Bearing float64 // Bearing in degrees true to traffic from ownship, if it can be calculated.
|
||||
Distance float64 // Distance to traffic from ownship, if it can be calculated.
|
||||
//FIXME: Some indicator that Bearing and Distance are valid, since they aren't always available.
|
||||
|
@ -184,7 +184,7 @@ func sendTrafficUpdates() {
|
|||
log.Printf("==================================================================\n")
|
||||
}
|
||||
code, _ := strconv.ParseInt(globalSettings.OwnshipModeS, 16, 32)
|
||||
for icao, ti := range traffic { // TO-DO: Limit number of aircraft in traffic message. ForeFlight 7.5 chokes at ~1000-2000 messages depending on iDevice RAM. Practical limit likely around ~500 aircraft without filtering.
|
||||
for icao, ti := range traffic { //TODO: Limit number of aircraft in traffic message. ForeFlight 7.5 chokes at ~1000-2000 messages depending on iDevice RAM. Practical limit likely around ~500 aircraft without filtering.
|
||||
if isGPSValid() {
|
||||
// func distRect(lat1, lon1, lat2, lon2 float64) (dist, bearing, distN, distE float64) {
|
||||
dist, bearing := distance(float64(mySituation.Lat), float64(mySituation.Lng), float64(ti.Lat), float64(ti.Lng))
|
||||
|
@ -209,11 +209,14 @@ func sendTrafficUpdates() {
|
|||
if ti.Age > 2 { // if nothing polls an inactive ti, it won't push to the webUI, and its Age won't update.
|
||||
trafficUpdate.SendJSON(ti)
|
||||
}
|
||||
if ti.Position_valid && ti.Age < 6 { // ... but don't pass stale data to the EFB. TO-DO: Coast old traffic? Need to determine how FF, WingX, etc deal with stale targets.
|
||||
if ti.Position_valid && ti.Age < 6 { // ... but don't pass stale data to the EFB.
|
||||
//TODO: Coast old traffic? Need to determine how FF, WingX, etc deal with stale targets.
|
||||
logTraffic(ti) // only add to the SQLite log if it's not stale
|
||||
|
||||
if ti.Icao_addr == uint32(code) { //
|
||||
log.Printf("Ownship target detected for code %X\n", code) // DEBUG - REMOVE
|
||||
if ti.Icao_addr == uint32(code) {
|
||||
if globalSettings.DEBUG {
|
||||
log.Printf("Ownship target detected for code %X\n", code)
|
||||
}
|
||||
OwnshipTrafficInfo = ti
|
||||
} else {
|
||||
msg = append(msg, makeTrafficReportMsg(ti)...)
|
||||
|
@ -688,7 +691,7 @@ func esListen() {
|
|||
}
|
||||
|
||||
// generate human readable summary of message types for debug
|
||||
// TO-DO: Use for ES message statistics?
|
||||
//TODO: Use for ES message statistics?
|
||||
/*
|
||||
var s1 string
|
||||
if newTi.DF == 17 {
|
||||
|
@ -1072,7 +1075,7 @@ func icao2reg(icao_addr uint32) (string, bool) {
|
|||
} else if (icao_addr >= 0xC00001) && (icao_addr <= 0xC3FFFF) {
|
||||
nation = "CA"
|
||||
} else {
|
||||
// future national decoding is TO-DO
|
||||
//TODO: future national decoding.
|
||||
return "NON-NA", false
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ func icao2reg(icao_addr uint32) (string, bool) {
|
|||
} else if (icao_addr >= 0xC00001) && (icao_addr <= 0xC3FFFF) {
|
||||
nation = "CA"
|
||||
} else {
|
||||
// future national decoding is TO-DO
|
||||
//TODO: future national decoding.
|
||||
return "NON-NA", false
|
||||
}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue