split out fancontrol and gen_gdl90 into different modules, and a common module that shares code between the two

pull/827/merge^2
Adrian Batzill 2021-03-27 12:11:34 +00:00
rodzic f09ae859d1
commit ee97b68b67
12 zmienionych plików z 129 dodań i 123 usunięć

Wyświetl plik

@ -13,8 +13,8 @@
// Use this to make it possible to hide the gen_gdl90 vs fancontrol redeclaration errors.. // Use this to make it possible to hide the gen_gdl90 vs fancontrol redeclaration errors..
//"files.exclude": { "files.exclude": {
// "**/.git": true, "**/.git": true,
// "main/fancontrol.go": true "main/fancontrol.go": true
//} }
} }

Wyświetl plik

@ -24,18 +24,15 @@ else
OGN_RX_BINARY=ogn/ogn-rx-eu_arm OGN_RX_BINARY=ogn/ogn-rx-eu_arm
endif endif
STRATUX_SRC=main/gen_gdl90.go main/traffic.go main/gps.go main/network.go main/managementinterface.go main/sdr.go main/ping.go main/uibroadcast.go main/monotonic.go main/datalog.go main/equations.go main/sensors.go main/cputemp.go main/lowpower_uat.go main/ogn.go main/flarm-nmea.go main/networksettings.go main/xplane.go
FANCONTROL_SRC=main/fancontrol.go main/equations.go main/cputemp.go
all: all:
make xdump978 xdump1090 gen_gdl90 $(PLATFORMDEPENDENT) make xdump978 xdump1090 gen_gdl90 $(PLATFORMDEPENDENT)
gen_gdl90: $(STRATUX_SRC) gen_gdl90: main/*.go common/*.go
export CGO_CFLAGS_ALLOW="-L/root/stratux" && go build $(BUILDINFO) -o gen_gdl90 -p 4 $(STRATUX_SRC) export CGO_CFLAGS_ALLOW="-L/root/stratux" && go build $(BUILDINFO) -o gen_gdl90 -p 4 ./main/
fancontrol: $(FANCONTROL_SRC) fancontrol: fancontrol_main/*.go common/*.go
go build $(BUILDINFO) -o fancontrol -p 4 $(FANCONTROL_SRC) go build $(BUILDINFO) -o fancontrol -p 4 ./fancontrol_main/
xdump1090: xdump1090:
git submodule update --init git submodule update --init

Wyświetl plik

@ -15,11 +15,9 @@ FANCONTROL_SRC=main/fancontrol.go main/equations.go main/cputemp.go
all: xdump978 xdump1090 gen_gdl90 $(PLATFORMDEPENDENT) all: xdump978 xdump1090 gen_gdl90 $(PLATFORMDEPENDENT)
gen_gdl90: $(STRATUX_SRC) gen_gdl90: main/*.go common/*.go
CGO_CFLAGS_ALLOW="-L$(CURDIR)" go build $(BUILDINFO) -gcflags '-N -l' -p 4 $(STRATUX_SRC) CGO_CFLAGS_ALLOW="-L$(CURDIR)" go build $(BUILDINFO) -gcflags '-N -l' -o gen_gdl90 -p 4 ./main/
fancontrol:
go build $(BUILDINFO) -p 4 $(FANCONTROL_SRC)
xdump1090: xdump1090:
git submodule update --init git submodule update --init

Wyświetl plik

@ -1,4 +1,4 @@
package main package common
import ( import (
"io/ioutil" "io/ioutil"
@ -7,7 +7,7 @@ import (
"time" "time"
) )
const invalidCpuTemp = float32(-99.0) const InvalidCpuTemp = float32(-99.0)
type CpuTempUpdateFunc func(cpuTemp float32) type CpuTempUpdateFunc func(cpuTemp float32)
@ -16,13 +16,13 @@ calls a callback. This is broken out into its own function (run as
its own goroutine) because the RPi temperature monitor code is buggy, its own goroutine) because the RPi temperature monitor code is buggy,
and often times reading this file hangs quite some time. */ and often times reading this file hangs quite some time. */
func cpuTempMonitor(updater CpuTempUpdateFunc) { func CpuTempMonitor(updater CpuTempUpdateFunc) {
timer := time.NewTicker(1 * time.Second) timer := time.NewTicker(1 * time.Second)
for { for {
// Update CPUTemp. // Update CPUTemp.
temp, err := ioutil.ReadFile("/sys/class/thermal/thermal_zone0/temp") temp, err := ioutil.ReadFile("/sys/class/thermal/thermal_zone0/temp")
tempStr := strings.Trim(string(temp), "\n") tempStr := strings.Trim(string(temp), "\n")
t := invalidCpuTemp t := InvalidCpuTemp
if err == nil { if err == nil {
tInt, err := strconv.Atoi(tempStr) tInt, err := strconv.Atoi(tempStr)
if err == nil { if err == nil {
@ -33,7 +33,7 @@ func cpuTempMonitor(updater CpuTempUpdateFunc) {
} }
} }
} }
if t >= invalidCpuTemp { // Only update if valid value was obtained. if t >= InvalidCpuTemp { // Only update if valid value was obtained.
updater(t) updater(t)
} }
<-timer.C <-timer.C
@ -41,6 +41,6 @@ func cpuTempMonitor(updater CpuTempUpdateFunc) {
} }
// Check if CPU temperature is valid. Assume <= 0 is invalid. // Check if CPU temperature is valid. Assume <= 0 is invalid.
func isCPUTempValid(cpuTemp float32) bool { func IsCPUTempValid(cpuTemp float32) bool {
return cpuTemp > 0 return cpuTemp > 0
} }

Wyświetl plik

@ -8,7 +8,7 @@
and other fuctions of Stratux package and other fuctions of Stratux package
*/ */
package main package common
import ( import (
"fmt" "fmt"
@ -18,7 +18,7 @@ import (
// linReg calculates slope and intercept for a least squares linear regression of y[] vs x[] // linReg calculates slope and intercept for a least squares linear regression of y[] vs x[]
// Returns error if fewer than two data points in each series, or if series lengths are different // Returns error if fewer than two data points in each series, or if series lengths are different
func linReg(x, y []float64) (slope, intercept float64, valid bool) { func LinReg(x, y []float64) (slope, intercept float64, valid bool) {
n := len(x) n := len(x)
nf := float64(n) nf := float64(n)
@ -60,7 +60,7 @@ func linReg(x, y []float64) (slope, intercept float64, valid bool) {
// Returns error if fewer than two data points in each series, if series lengths are different, // Returns error if fewer than two data points in each series, if series lengths are different,
// if weights sum to zero, or if slope is infinite // if weights sum to zero, or if slope is infinite
func linRegWeighted(x, y, w []float64) (slope, intercept float64, valid bool) { func LinRegWeighted(x, y, w []float64) (slope, intercept float64, valid bool) {
n := len(x) n := len(x)
@ -112,7 +112,7 @@ func linRegWeighted(x, y, w []float64) (slope, intercept float64, valid bool) {
// triCubeWeight returns the value of the tricube weight function // triCubeWeight returns the value of the tricube weight function
// at point x, for the given center and halfwidth. // at point x, for the given center and halfwidth.
func triCubeWeight(center, halfwidth, x float64) float64 { func TriCubeWeight(center, halfwidth, x float64) float64 {
var weight, x_t float64 var weight, x_t float64
x_t = math.Abs((x - center) / halfwidth) x_t = math.Abs((x - center) / halfwidth)
if x_t < 1 { if x_t < 1 {
@ -124,7 +124,7 @@ func triCubeWeight(center, halfwidth, x float64) float64 {
} }
// arrayMin calculates the minimum value in array x // arrayMin calculates the minimum value in array x
func arrayMin(x []float64) (float64, bool) { func ArrayMin(x []float64) (float64, bool) {
if len(x) < 1 { if len(x) < 1 {
fmt.Printf("arrayMin: Length too short\n") fmt.Printf("arrayMin: Length too short\n")
return math.NaN(), false return math.NaN(), false
@ -140,7 +140,7 @@ func arrayMin(x []float64) (float64, bool) {
} }
// arrayMax calculates the maximum value in array x // arrayMax calculates the maximum value in array x
func arrayMax(x []float64) (float64, bool) { func ArrayMax(x []float64) (float64, bool) {
if len(x) < 1 { if len(x) < 1 {
fmt.Printf("arrayMax: Length too short\n") fmt.Printf("arrayMax: Length too short\n")
return math.NaN(), false return math.NaN(), false
@ -156,9 +156,9 @@ func arrayMax(x []float64) (float64, bool) {
} }
// arrayRange calculates the range of values in array x // arrayRange calculates the range of values in array x
func arrayRange(x []float64) (float64, bool) { func ArrayRange(x []float64) (float64, bool) {
max, err1 := arrayMax(x) max, err1 := ArrayMax(x)
min, err2 := arrayMin(x) min, err2 := ArrayMin(x)
if !err1 || !err2 { if !err1 || !err2 {
fmt.Printf("Error calculating range\n") fmt.Printf("Error calculating range\n")
@ -169,7 +169,7 @@ func arrayRange(x []float64) (float64, bool) {
} }
// mean returns the arithmetic mean of array x // mean returns the arithmetic mean of array x
func mean(x []float64) (float64, bool) { func Mean(x []float64) (float64, bool) {
if len(x) < 1 { if len(x) < 1 {
fmt.Printf("mean: Length too short\n") fmt.Printf("mean: Length too short\n")
return math.NaN(), false return math.NaN(), false
@ -186,14 +186,14 @@ func mean(x []float64) (float64, bool) {
} }
// stdev estimates the sample standard deviation of array x // stdev estimates the sample standard deviation of array x
func stdev(x []float64) (float64, bool) { func Stdev(x []float64) (float64, bool) {
if len(x) < 2 { if len(x) < 2 {
fmt.Printf("stdev: Length too short\n") fmt.Printf("stdev: Length too short\n")
return math.NaN(), false return math.NaN(), false
} }
nf := float64(len(x)) nf := float64(len(x))
xbar, xbarValid := mean(x) xbar, xbarValid := Mean(x)
if !xbarValid { if !xbarValid {
fmt.Printf("stdev: Error calculating xbar\n") fmt.Printf("stdev: Error calculating xbar\n")
@ -210,17 +210,17 @@ func stdev(x []float64) (float64, bool) {
} }
// radians converts angle from degrees, and returns its value in radians // radians converts angle from degrees, and returns its value in radians
func radians(angle float64) float64 { func Radians(angle float64) float64 {
return angle * math.Pi / 180.0 return angle * math.Pi / 180.0
} }
// degrees converts angle from radians, and returns its value in degrees // degrees converts angle from radians, and returns its value in degrees
func degrees(angle float64) float64 { func Degrees(angle float64) float64 {
return angle * 180.0 / math.Pi return angle * 180.0 / math.Pi
} }
// radiansRel converts angle from degrees, and returns its value in radians in the range -Pi to + Pi // radiansRel converts angle from degrees, and returns its value in radians in the range -Pi to + Pi
func radiansRel(angle float64) float64 { func RadiansRel(angle float64) float64 {
for angle > 180 { for angle > 180 {
angle -= 360 angle -= 360
} }
@ -231,7 +231,7 @@ func radiansRel(angle float64) float64 {
} }
// degreesRel converts angle from radians, and returns its value in the range of -180 to +180 degrees // degreesRel converts angle from radians, and returns its value in the range of -180 to +180 degrees
func degreesRel(angle float64) float64 { func DegreesRel(angle float64) float64 {
for angle > math.Pi { for angle > math.Pi {
angle -= 2 * math.Pi angle -= 2 * math.Pi
} }
@ -242,7 +242,7 @@ func degreesRel(angle float64) float64 {
} }
// degreesHdg converts angle from radians, and returns its value in the range of 0+ to 360 degrees // degreesHdg converts angle from radians, and returns its value in the range of 0+ to 360 degrees
func degreesHdg(angle float64) float64 { func DegreesHdg(angle float64) float64 {
for angle < 0 { for angle < 0 {
angle += 2 * math.Pi angle += 2 * math.Pi
} }
@ -250,7 +250,7 @@ func degreesHdg(angle float64) float64 {
} }
// roundToInt16 cheaply rounds a float64 to an int16, rather than truncating // roundToInt16 cheaply rounds a float64 to an int16, rather than truncating
func roundToInt16(in float64) (out int16) { func RoundToInt16(in float64) (out int16) {
if in >= 0 { if in >= 0 {
out = int16(in + 0.5) out = int16(in + 0.5)
} else { } else {
@ -270,37 +270,37 @@ suitable for relative distance to nearby traffic
// Outputs are distance in meters and bearing in degrees (0° = north, 90° = east) // Outputs are distance in meters and bearing in degrees (0° = north, 90° = east)
// Secondary outputs are north and east components of distance in meters (north, east positive) // Secondary outputs are north and east components of distance in meters (north, east positive)
func distRect(lat1, lon1, lat2, lon2 float64) (dist, bearing, distN, distE float64) { func DistRect(lat1, lon1, lat2, lon2 float64) (dist, bearing, distN, distE float64) {
radius_earth := 6371008.8 // meters; mean radius radius_earth := 6371008.8 // meters; mean radius
dLat := radiansRel(lat2 - lat1) dLat := RadiansRel(lat2 - lat1)
avgLat := radiansRel((lat2 + lat1) / 2) avgLat := RadiansRel((lat2 + lat1) / 2)
dLon := radiansRel(lon2 - lon1) dLon := RadiansRel(lon2 - lon1)
distN = dLat * radius_earth distN = dLat * radius_earth
distE = dLon * radius_earth * math.Abs(math.Cos(avgLat)) distE = dLon * radius_earth * math.Abs(math.Cos(avgLat))
dist = math.Pow(distN*distN+distE*distE, 0.5) dist = math.Pow(distN*distN+distE*distE, 0.5)
bearing = math.Atan2(distE, distN) bearing = math.Atan2(distE, distN)
bearing = degreesHdg(bearing) bearing = DegreesHdg(bearing)
return return
} }
// distRectNorth returns north-south distance from point 1 to point 2. // distRectNorth returns north-south distance from point 1 to point 2.
// Inputs are lat in decimal degrees. Output is distance in meters (east positive) // Inputs are lat in decimal degrees. Output is distance in meters (east positive)
func distRectNorth(lat1, lat2 float64) float64 { func DistRectNorth(lat1, lat2 float64) float64 {
var dist float64 var dist float64
radius_earth := 6371008.8 // meters; mean radius radius_earth := 6371008.8 // meters; mean radius
dLat := radiansRel(lat2 - lat1) dLat := RadiansRel(lat2 - lat1)
dist = dLat * radius_earth dist = dLat * radius_earth
return dist return dist
} }
// distRectEast returns east-west distance from point 1 to point 2. // distRectEast returns east-west distance from point 1 to point 2.
// Inputs are lat/lon in decimal degrees. Output is distance in meters (north positive) // Inputs are lat/lon in decimal degrees. Output is distance in meters (north positive)
func distRectEast(lat1, lon1, lat2, lon2 float64) float64 { func DistRectEast(lat1, lon1, lat2, lon2 float64) float64 {
var dist float64 var dist float64
radius_earth := 6371008.8 // meters; mean radius radius_earth := 6371008.8 // meters; mean radius
//dLat := radiansRel(lat2 - lat1) // unused //dLat := radiansRel(lat2 - lat1) // unused
avgLat := radiansRel((lat2 + lat1) / 2) avgLat := RadiansRel((lat2 + lat1) / 2)
dLon := radiansRel(lon2 - lon1) dLon := RadiansRel(lon2 - lon1)
dist = dLon * radius_earth * math.Abs(math.Cos(avgLat)) dist = dLon * radius_earth * math.Abs(math.Cos(avgLat))
return dist return dist
} }
@ -313,13 +313,13 @@ More accurate over longer distances
// distance calculates distance between two points using the law of cosines. // distance calculates distance between two points using the law of cosines.
// Inputs are lat / lon of both points in decimal degrees // Inputs are lat / lon of both points in decimal degrees
// Outputs are distance in meters and bearing to the target from origin in degrees (0° = north, 90° = east) // Outputs are distance in meters and bearing to the target from origin in degrees (0° = north, 90° = east)
func distance(lat1, lon1, lat2, lon2 float64) (dist, bearing float64) { func Distance(lat1, lon1, lat2, lon2 float64) (dist, bearing float64) {
radius_earth := 6371008.8 // meters; mean radius radius_earth := 6371008.8 // meters; mean radius
lat1 = radians(lat1) lat1 = Radians(lat1)
lon1 = radians(lon1) lon1 = Radians(lon1)
lat2 = radians(lat2) lat2 = Radians(lat2)
lon2 = radians(lon2) lon2 = Radians(lon2)
dist = math.Acos(math.Sin(lat1)*math.Sin(lat2)+math.Cos(lat1)*math.Cos(lat2)*math.Cos(lon2-lon1)) * radius_earth dist = math.Acos(math.Sin(lat1)*math.Sin(lat2)+math.Cos(lat1)*math.Cos(lat2)*math.Cos(lon2-lon1)) * radius_earth
@ -328,7 +328,7 @@ func distance(lat1, lon1, lat2, lon2 float64) (dist, bearing float64) {
x = math.Cos(lat1)*math.Sin(lat2) - math.Sin(lat1)*math.Cos(lat2)*math.Cos(lon2-lon1) x = math.Cos(lat1)*math.Sin(lat2) - math.Sin(lat1)*math.Cos(lat2)*math.Cos(lon2-lon1)
y = math.Sin(lon2-lon1) * math.Cos(lat2) y = math.Sin(lon2-lon1) * math.Cos(lat2)
bearing = degreesHdg(math.Atan2(y, x)) bearing = DegreesHdg(math.Atan2(y, x))
return return
} }
@ -340,14 +340,14 @@ func CalcAltitude(press float64, altoffset int) (altitude float64) {
} }
// golang only defines min/max for float64. Really. // golang only defines min/max for float64. Really.
func iMin(x, y int) int { func IMin(x, y int) int {
if x < y { if x < y {
return x return x
} }
return y return y
} }
func iMax(x, y int) int { func IMax(x, y int) int {
if x > y { if x > y {
return x return x
} }

Wyświetl plik

@ -4,15 +4,17 @@ import (
"encoding/json" "encoding/json"
"flag" "flag"
"fmt" "fmt"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/takama/daemon"
"log" "log"
"net/http" "net/http"
"os" "os"
"os/signal" "os/signal"
"syscall" "syscall"
"time" "time"
"github.com/b3nn0/stratux/common"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/takama/daemon"
) )
// #include <wiringPi.h> // #include <wiringPi.h>
@ -121,8 +123,8 @@ func fanControl() {
myFanControl.TempCurrent = 0 myFanControl.TempCurrent = 0
go cpuTempMonitor(func(cpuTemp float32) { go common.CpuTempMonitor(func(cpuTemp float32) {
if isCPUTempValid(cpuTemp) { if common.IsCPUTempValid(cpuTemp) {
myFanControl.TempCurrent = cpuTemp myFanControl.TempCurrent = cpuTemp
} }
}) })
@ -139,9 +141,9 @@ func fanControl() {
} }
if myFanControl.TempCurrent > (myFanControl.TempTarget + hysteresis) { if myFanControl.TempCurrent > (myFanControl.TempTarget + hysteresis) {
myFanControl.PWMDutyCurrent = iMax(iMin(myFanControl.PWMDutyMax, myFanControl.PWMDutyCurrent+pwmDutyStep), myFanControl.PWMDutyMin) myFanControl.PWMDutyCurrent = common.IMax(common.IMin(myFanControl.PWMDutyMax, myFanControl.PWMDutyCurrent+pwmDutyStep), myFanControl.PWMDutyMin)
} else if myFanControl.TempCurrent < (myFanControl.TempTarget - hysteresis) { } else if myFanControl.TempCurrent < (myFanControl.TempTarget - hysteresis) {
myFanControl.PWMDutyCurrent = iMax(myFanControl.PWMDutyCurrent-pwmDutyStep, 0) myFanControl.PWMDutyCurrent = common.IMax(myFanControl.PWMDutyCurrent-pwmDutyStep, 0)
if myFanControl.PWMDutyCurrent < myFanControl.PWMDutyMin { if myFanControl.PWMDutyCurrent < myFanControl.PWMDutyMin {
myFanControl.PWMDutyCurrent = myFanControl.PWMDutyMin myFanControl.PWMDutyCurrent = myFanControl.PWMDutyMin
} }

Wyświetl plik

@ -12,17 +12,19 @@
package main package main
import ( import (
"bufio"
"encoding/binary" "encoding/binary"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"bufio"
"io" "io"
"log" "log"
"math" "math"
"net" "net"
"time"
"strconv" "strconv"
"strings" "strings"
"time"
"github.com/b3nn0/stratux/common"
) )
/* /*
@ -59,7 +61,7 @@ func makeFlarmPFLAUString(ti TrafficInfo) (msg string) {
gpsStatus = 2 gpsStatus = 2
} }
dist, bearing, _, _ := distRect(float64(mySituation.GPSLatitude), float64(mySituation.GPSLongitude), float64(ti.Lat), float64(ti.Lng)) dist, bearing, _, _ := common.DistRect(float64(mySituation.GPSLatitude), float64(mySituation.GPSLongitude), float64(ti.Lat), float64(ti.Lng))
relativeVertical := computeRelativeVertical(ti) relativeVertical := computeRelativeVertical(ti)
alarmLevel := computeAlarmLevel(dist, relativeVertical) alarmLevel := computeAlarmLevel(dist, relativeVertical)
@ -213,7 +215,7 @@ func makeFlarmPFLAAString(ti TrafficInfo) (msg string, valid bool, alarmLevel ui
} }
// determine distance and bearing to target // determine distance and bearing to target
dist, bearing, distN, distE := distRect(float64(mySituation.GPSLatitude), float64(mySituation.GPSLongitude), float64(ti.Lat), float64(ti.Lng)) dist, bearing, distN, distE := common.DistRect(float64(mySituation.GPSLatitude), float64(mySituation.GPSLongitude), float64(ti.Lat), float64(ti.Lng))
if !ti.Position_valid { if !ti.Position_valid {
dist = ti.DistanceEstimated dist = ti.DistanceEstimated
distN = ti.DistanceEstimated distN = ti.DistanceEstimated
@ -799,11 +801,11 @@ func parseFlarmPFLAA(message []string) {
// lat dist = 60nm = 111,12km // lat dist = 60nm = 111,12km
ti.Lat = mySituation.GPSLatitude + (relNorth / 111120.0) ti.Lat = mySituation.GPSLatitude + (relNorth / 111120.0)
avgLat := ti.Lat / 2.0 + mySituation.GPSLatitude / 2.0 avgLat := ti.Lat / 2.0 + mySituation.GPSLatitude / 2.0
lngFactor := float32(111120.0 * math.Cos(radians(float64(avgLat)))) lngFactor := float32(111120.0 * math.Cos(common.Radians(float64(avgLat))))
ti.Lng = mySituation.GPSLongitude + (relEast / lngFactor) ti.Lng = mySituation.GPSLongitude + (relEast / lngFactor)
if isGPSValid() { if isGPSValid() {
ti.Distance, ti.Bearing = distance(float64(mySituation.GPSLatitude), float64(mySituation.GPSLongitude), float64(ti.Lat), float64(ti.Lng)) ti.Distance, ti.Bearing = common.Distance(float64(mySituation.GPSLatitude), float64(mySituation.GPSLongitude), float64(ti.Lat), float64(ti.Lng))
ti.BearingDist_valid = true ti.BearingDist_valid = true
} }

Wyświetl plik

@ -32,6 +32,7 @@ import (
"syscall" "syscall"
"time" "time"
"github.com/b3nn0/stratux/common"
"github.com/b3nn0/stratux/uatparse" "github.com/b3nn0/stratux/uatparse"
humanize "github.com/dustin/go-humanize" humanize "github.com/dustin/go-humanize"
"github.com/ricochet2200/go-disk-usage/du" "github.com/ricochet2200/go-disk-usage/du"
@ -552,7 +553,7 @@ func makeStratuxStatus() []byte {
} }
// Valid/Enabled: CPU temperature portion. // Valid/Enabled: CPU temperature portion.
if isCPUTempValid(globalStatus.CPUTemp) { if common.IsCPUTempValid(globalStatus.CPUTemp) {
msg[13] = msg[13] | (1 << 4) msg[13] = msg[13] | (1 << 4)
} }
@ -1726,14 +1727,14 @@ func main() {
go baroAltGuesser() go baroAltGuesser()
// Monitor RPi CPU temp. // Monitor RPi CPU temp.
globalStatus.CPUTempMin = invalidCpuTemp globalStatus.CPUTempMin = common.InvalidCpuTemp
globalStatus.CPUTempMax = invalidCpuTemp globalStatus.CPUTempMax = common.InvalidCpuTemp
go cpuTempMonitor(func(cpuTemp float32) { go common.CpuTempMonitor(func(cpuTemp float32) {
globalStatus.CPUTemp = cpuTemp globalStatus.CPUTemp = cpuTemp
if isCPUTempValid(cpuTemp) && ((cpuTemp < globalStatus.CPUTempMin) || !isCPUTempValid(globalStatus.CPUTempMin)) { if common.IsCPUTempValid(cpuTemp) && ((cpuTemp < globalStatus.CPUTempMin) || !common.IsCPUTempValid(globalStatus.CPUTempMin)) {
globalStatus.CPUTempMin = cpuTemp globalStatus.CPUTempMin = cpuTemp
} }
if isCPUTempValid(cpuTemp) && ((cpuTemp > globalStatus.CPUTempMax) || !isCPUTempValid(globalStatus.CPUTempMax)) { if common.IsCPUTempValid(cpuTemp) && ((cpuTemp > globalStatus.CPUTempMax) || !common.IsCPUTempValid(globalStatus.CPUTempMax)) {
globalStatus.CPUTempMax = cpuTemp globalStatus.CPUTempMax = cpuTemp
} }
}) })

Wyświetl plik

@ -10,10 +10,10 @@
package main package main
import ( import (
"errors"
"fmt" "fmt"
"log" "log"
"math" "math"
"errors"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -25,6 +25,8 @@ import (
"os" "os"
"os/exec" "os/exec"
"github.com/b3nn0/stratux/common"
) )
const ( const (
@ -681,7 +683,7 @@ func calcGPSAttitude() bool {
for i := 0; i < length; i++ { for i := 0; i < length; i++ {
tempTime[i] = float64(myGPSPerfStats[i].nmeaTime) tempTime[i] = float64(myGPSPerfStats[i].nmeaTime)
} }
minTime, _ := arrayMin(tempTime) minTime, _ := common.ArrayMin(tempTime)
if minTime > 86401.0 { if minTime > 86401.0 {
log.Printf("GPS attitude: Rebasing GPS time since midnight to current day.\n") log.Printf("GPS attitude: Rebasing GPS time since midnight to current day.\n")
for i := 0; i < length; i++ { for i := 0; i < length; i++ {
@ -757,7 +759,7 @@ func calcGPSAttitude() bool {
if myGPSPerfStats[i].msgType == "GPRMC" || myGPSPerfStats[i].msgType == "GNRMC" { if myGPSPerfStats[i].msgType == "GPRMC" || myGPSPerfStats[i].msgType == "GNRMC" {
tempSpeed = append(tempSpeed, float64(myGPSPerfStats[i].gsf)) tempSpeed = append(tempSpeed, float64(myGPSPerfStats[i].gsf))
tempSpeedTime = append(tempSpeedTime, float64(myGPSPerfStats[i].nmeaTime)) tempSpeedTime = append(tempSpeedTime, float64(myGPSPerfStats[i].nmeaTime))
tempRegWeights = append(tempRegWeights, triCubeWeight(center, halfwidth, float64(myGPSPerfStats[i].nmeaTime))) tempRegWeights = append(tempRegWeights, common.TriCubeWeight(center, halfwidth, float64(myGPSPerfStats[i].nmeaTime)))
} }
} }
lengthSpeed = len(tempSpeed) lengthSpeed = len(tempSpeed)
@ -767,7 +769,7 @@ func calcGPSAttitude() bool {
} else if lengthSpeed == 1 { } else if lengthSpeed == 1 {
v_x = tempSpeed[0] * 1.687810 v_x = tempSpeed[0] * 1.687810
} else { } else {
slope, intercept, valid = linRegWeighted(tempSpeedTime, tempSpeed, tempRegWeights) slope, intercept, valid = common.LinRegWeighted(tempSpeedTime, tempSpeed, tempRegWeights)
if !valid { if !valid {
log.Printf("GPS attitude: Error calculating speed regression from NMEA RMC position messages") log.Printf("GPS attitude: Error calculating speed regression from NMEA RMC position messages")
return false return false
@ -786,7 +788,7 @@ func calcGPSAttitude() bool {
if myGPSPerfStats[i].msgType == "GPGGA" || myGPSPerfStats[i].msgType == "GNGGA" { if myGPSPerfStats[i].msgType == "GPGGA" || myGPSPerfStats[i].msgType == "GNGGA" {
tempVV = append(tempVV, float64(myGPSPerfStats[i].alt)) tempVV = append(tempVV, float64(myGPSPerfStats[i].alt))
tempSpeedTime = append(tempSpeedTime, float64(myGPSPerfStats[i].nmeaTime)) tempSpeedTime = append(tempSpeedTime, float64(myGPSPerfStats[i].nmeaTime))
tempRegWeights = append(tempRegWeights, triCubeWeight(center, halfwidth, float64(myGPSPerfStats[i].nmeaTime))) tempRegWeights = append(tempRegWeights, common.TriCubeWeight(center, halfwidth, float64(myGPSPerfStats[i].nmeaTime)))
} }
} }
lengthSpeed = len(tempVV) lengthSpeed = len(tempVV)
@ -794,7 +796,7 @@ func calcGPSAttitude() bool {
log.Printf("GPS Attitude: Not enough points to calculate vertical speed from NMEA GGA messages\n") log.Printf("GPS Attitude: Not enough points to calculate vertical speed from NMEA GGA messages\n")
return false return false
} else { } else {
slope, _, valid = linRegWeighted(tempSpeedTime, tempVV, tempRegWeights) slope, _, valid = common.LinRegWeighted(tempSpeedTime, tempVV, tempRegWeights)
if !valid { if !valid {
log.Printf("GPS attitude: Error calculating vertical speed regression from NMEA GGA messages") log.Printf("GPS attitude: Error calculating vertical speed regression from NMEA GGA messages")
return false return false
@ -846,9 +848,9 @@ func calcGPSAttitude() bool {
if lengthHeading > 1 { if lengthHeading > 1 {
tempHdgUnwrapped[0] = tempHdg[0] tempHdgUnwrapped[0] = tempHdg[0]
tempRegWeights[0] = triCubeWeight(center, halfwidth, tempHdgTime[0]) tempRegWeights[0] = common.TriCubeWeight(center, halfwidth, tempHdgTime[0])
for i := 1; i < lengthHeading; i++ { for i := 1; i < lengthHeading; i++ {
tempRegWeights[i] = triCubeWeight(center, halfwidth, tempHdgTime[i]) tempRegWeights[i] = common.TriCubeWeight(center, halfwidth, tempHdgTime[i])
if math.Abs(tempHdg[i]-tempHdg[i-1]) < 180 { // case 1: if angle change is less than 180 degrees, use the same reference system if math.Abs(tempHdg[i]-tempHdg[i-1]) < 180 { // case 1: if angle change is less than 180 degrees, use the same reference system
tempHdgUnwrapped[i] = tempHdgUnwrapped[i-1] + tempHdg[i] - tempHdg[i-1] tempHdgUnwrapped[i] = tempHdgUnwrapped[i-1] + tempHdg[i] - tempHdg[i-1]
} else if tempHdg[i] > tempHdg[i-1] { // case 2: heading has wrapped around from NE to NW. Subtract 360 to keep consistent with previous data. } else if tempHdg[i] > tempHdg[i-1] { // case 2: heading has wrapped around from NE to NW. Subtract 360 to keep consistent with previous data.
@ -865,7 +867,7 @@ func calcGPSAttitude() bool {
} }
// Finally, calculate turn rate as the slope of the weighted linear regression of unwrapped heading. // Finally, calculate turn rate as the slope of the weighted linear regression of unwrapped heading.
slope, intercept, valid = linRegWeighted(tempHdgTime, tempHdgUnwrapped, tempRegWeights) slope, intercept, valid = common.LinRegWeighted(tempHdgTime, tempHdgUnwrapped, tempRegWeights)
if !valid { if !valid {
log.Printf("GPS attitude: Regression error calculating turn rate") log.Printf("GPS attitude: Regression error calculating turn rate")
@ -918,7 +920,7 @@ func calcGPSAttitude() bool {
*/ */
g := 32.174 // ft/(s^2) g := 32.174 // ft/(s^2)
omega = radians(myGPSPerfStats[index].gpsTurnRate) // need radians/sec omega = common.Radians(myGPSPerfStats[index].gpsTurnRate) // need radians/sec
a_c = v_x * omega a_c = v_x * omega
myGPSPerfStats[index].gpsRoll = math.Atan2(a_c, g) * 180 / math.Pi // output is degrees myGPSPerfStats[index].gpsRoll = math.Atan2(a_c, g) * 180 / math.Pi // output is degrees
myGPSPerfStats[index].gpsLoadFactor = math.Sqrt(a_c*a_c+g*g) / g myGPSPerfStats[index].gpsLoadFactor = math.Sqrt(a_c*a_c+g*g) / g
@ -980,7 +982,7 @@ func calculateNavRate() float64 {
} }
var halfwidth float64 var halfwidth float64
dt_avg, valid := mean(tempSpeedTime) dt_avg, valid := common.Mean(tempSpeedTime)
if valid && dt_avg > 0 { if valid && dt_avg > 0 {
if globalSettings.DEBUG { if globalSettings.DEBUG {
log.Printf("GPS attitude: Average delta time is %.2f s (%.1f Hz)\n", dt_avg, 1/dt_avg) log.Printf("GPS attitude: Average delta time is %.2f s (%.1f Hz)\n", dt_avg, 1/dt_avg)
@ -1755,7 +1757,7 @@ func baroAltGuesser() {
alts = append(alts, float64(k*100)) alts = append(alts, float64(k*100))
diffs = append(diffs, float64(v)) diffs = append(diffs, float64(v))
} }
slope, intercept, valid := linReg(alts, diffs) slope, intercept, valid := common.LinReg(alts, diffs)
//fmt.Printf("General: %f * x + %f \n", slope, intercept) //fmt.Printf("General: %f * x + %f \n", slope, intercept)
trafficMutex.Lock() trafficMutex.Lock()
@ -1819,7 +1821,7 @@ func baroAltGuesser() {
// X-axis is altitude, Y axis is reported GnssBaroDiff // X-axis is altitude, Y axis is reported GnssBaroDiff
} }
if len(gnssBaroAltDiffs) >= 2 { if len(gnssBaroAltDiffs) >= 2 {
slope, intercept, valid := linRegWeighted(alts, diffs, weights) slope, intercept, valid := common.LinRegWeighted(alts, diffs, weights)
if valid { if valid {
gnssBaroDiff := float64(myAlt) * slope + intercept gnssBaroDiff := float64(myAlt) * slope + intercept
mySituation.muBaro.Lock() mySituation.muBaro.Lock()
@ -1897,10 +1899,10 @@ func makeFFAHRSMessage() {
if isAHRSValid() { if isAHRSValid() {
if !isAHRSInvalidValue(mySituation.AHRSPitch) { if !isAHRSInvalidValue(mySituation.AHRSPitch) {
pitch = roundToInt16(mySituation.AHRSPitch * 10) pitch = common.RoundToInt16(mySituation.AHRSPitch * 10)
} }
if !isAHRSInvalidValue(mySituation.AHRSRoll) { if !isAHRSInvalidValue(mySituation.AHRSRoll) {
roll = roundToInt16(mySituation.AHRSRoll * 10) roll = common.RoundToInt16(mySituation.AHRSRoll * 10)
} }
} }
@ -1959,27 +1961,27 @@ func makeAHRSGDL90Report() {
vs := int16(0x7FFF) vs := int16(0x7FFF)
if isAHRSValid() { if isAHRSValid() {
if !isAHRSInvalidValue(mySituation.AHRSPitch) { if !isAHRSInvalidValue(mySituation.AHRSPitch) {
pitch = roundToInt16(mySituation.AHRSPitch * 10) pitch = common.RoundToInt16(mySituation.AHRSPitch * 10)
} }
if !isAHRSInvalidValue(mySituation.AHRSRoll) { if !isAHRSInvalidValue(mySituation.AHRSRoll) {
roll = roundToInt16(mySituation.AHRSRoll * 10) roll = common.RoundToInt16(mySituation.AHRSRoll * 10)
} }
if !isAHRSInvalidValue(mySituation.AHRSGyroHeading) { if !isAHRSInvalidValue(mySituation.AHRSGyroHeading) {
hdg = roundToInt16(mySituation.AHRSGyroHeading * 10) hdg = common.RoundToInt16(mySituation.AHRSGyroHeading * 10)
} }
if !isAHRSInvalidValue(mySituation.AHRSSlipSkid) { if !isAHRSInvalidValue(mySituation.AHRSSlipSkid) {
slip_skid = roundToInt16(-mySituation.AHRSSlipSkid * 10) slip_skid = common.RoundToInt16(-mySituation.AHRSSlipSkid * 10)
} }
if !isAHRSInvalidValue(mySituation.AHRSTurnRate) { if !isAHRSInvalidValue(mySituation.AHRSTurnRate) {
yaw_rate = roundToInt16(mySituation.AHRSTurnRate * 10) yaw_rate = common.RoundToInt16(mySituation.AHRSTurnRate * 10)
} }
if !isAHRSInvalidValue(mySituation.AHRSGLoad) { if !isAHRSInvalidValue(mySituation.AHRSGLoad) {
g = roundToInt16(mySituation.AHRSGLoad * 10) g = common.RoundToInt16(mySituation.AHRSGLoad * 10)
} }
} }
if isTempPressValid() { if isTempPressValid() {
palt = uint16(mySituation.BaroPressureAltitude + 5000.5) palt = uint16(mySituation.BaroPressureAltitude + 5000.5)
vs = roundToInt16(float64(mySituation.BaroVerticalSpeed)) vs = common.RoundToInt16(float64(mySituation.BaroVerticalSpeed))
} }
// Roll. // Roll.

Wyświetl plik

@ -1,4 +1,3 @@
/* /*
Copyright (c) 2020 Adrian Batzill Copyright (c) 2020 Adrian Batzill
Distributable under the terms of The "BSD New" License Distributable under the terms of The "BSD New" License
@ -11,16 +10,18 @@
package main package main
import ( import (
"encoding/json"
"encoding/hex"
"encoding/binary"
"net"
"bufio" "bufio"
"encoding/binary"
"encoding/hex"
"encoding/json"
"io/ioutil"
"log"
"net"
"strconv" "strconv"
"strings" "strings"
"time" "time"
"log"
"io/ioutil" "github.com/b3nn0/stratux/common"
) )
// {"sys":"OGN","addr":"395F39","addr_type":3,"acft_type":"1","lat_deg":51.7657533,"lon_deg":-1.1918533,"alt_msl_m":124,"alt_std_m":63,"track_deg":0.0,"speed_mps":0.3,"climb_mps":-0.5,"turn_dps":0.0,"DOP":1.5} // {"sys":"OGN","addr":"395F39","addr_type":3,"acft_type":"1","lat_deg":51.7657533,"lon_deg":-1.1918533,"alt_msl_m":124,"alt_std_m":63,"track_deg":0.0,"speed_mps":0.3,"climb_mps":-0.5,"turn_dps":0.0,"DOP":1.5}
@ -211,7 +212,7 @@ func importOgnTrafficMessage(msg OgnMessage, data string) {
} }
// Basic plausibility check: // Basic plausibility check:
dist, _, _, _ := distRect(float64(mySituation.GPSLatitude), float64(mySituation.GPSLongitude), float64(msg.Lat_deg), float64(msg.Lon_deg)) dist, _, _, _ := common.DistRect(float64(mySituation.GPSLatitude), float64(mySituation.GPSLongitude), float64(msg.Lat_deg), float64(msg.Lon_deg))
if (isGPSValid() && dist >= 50000) || (msg.Lat_deg == 0 && msg.Lon_deg == 0) { if (isGPSValid() && dist >= 50000) || (msg.Lat_deg == 0 && msg.Lon_deg == 0) {
// more than 50km away? Ignore. Most likely invalid data // more than 50km away? Ignore. Most likely invalid data
return return
@ -282,7 +283,7 @@ func importOgnTrafficMessage(msg OgnMessage, data string) {
ti.SignalLevel = msg.SNR_dB ti.SignalLevel = msg.SNR_dB
if isGPSValid() { if isGPSValid() {
ti.Distance, ti.Bearing = distance(float64(mySituation.GPSLatitude), float64(mySituation.GPSLongitude), float64(ti.Lat), float64(ti.Lng)) ti.Distance, ti.Bearing = common.Distance(float64(mySituation.GPSLatitude), float64(mySituation.GPSLongitude), float64(ti.Lat), float64(ti.Lng))
ti.BearingDist_valid = true ti.BearingDist_valid = true
} }
ti.Position_valid = true ti.Position_valid = true

Wyświetl plik

@ -10,6 +10,7 @@ import (
"github.com/b3nn0/goflying/ahrs" "github.com/b3nn0/goflying/ahrs"
"github.com/b3nn0/goflying/ahrsweb" "github.com/b3nn0/goflying/ahrsweb"
"github.com/b3nn0/stratux/common"
"github.com/b3nn0/stratux/sensors" "github.com/b3nn0/stratux/sensors"
"github.com/kidoman/embd" "github.com/kidoman/embd"
_ "github.com/kidoman/embd/host/all" _ "github.com/kidoman/embd/host/all"
@ -123,7 +124,7 @@ func tempAndPressureSender() {
mySituation.muBaro.Lock() mySituation.muBaro.Lock()
mySituation.BaroLastMeasurementTime = stratuxClock.Time mySituation.BaroLastMeasurementTime = stratuxClock.Time
mySituation.BaroTemperature = float32(temp) mySituation.BaroTemperature = float32(temp)
altitude = CalcAltitude(press, globalSettings.AltitudeOffset) altitude = common.CalcAltitude(press, globalSettings.AltitudeOffset)
mySituation.BaroPressureAltitude = float32(altitude) mySituation.BaroPressureAltitude = float32(altitude)
if altLast < -2000 { if altLast < -2000 {
altLast = altitude // Initialize altLast = altitude // Initialize

Wyświetl plik

@ -21,6 +21,8 @@ import (
"strings" "strings"
"sync" "sync"
"time" "time"
"github.com/b3nn0/stratux/common"
) )
//-0b2b48fe3aef1f88621a0856110a31c01105c4e6c4e6c40a9a820300000000000000;rs=7; //-0b2b48fe3aef1f88621a0856110a31c01105c4e6c4e6c40a9a820300000000000000;rs=7;
@ -86,14 +88,14 @@ type TrafficInfo struct {
SignalLevel float64 // Signal level, dB RSSI. SignalLevel float64 // Signal level, dB RSSI.
Squawk int // Squawk code Squawk int // Squawk code
Position_valid bool //TODO: set when position report received. Unset after n seconds? Position_valid bool //TODO: set when position report received. Unset after n seconds?
Lat float32 // decimal degrees, north positive Lat float32 // decimal common.Degrees, north positive
Lng float32 // decimal degrees, east positive Lng float32 // decimal common.Degrees, east positive
Alt int32 // Pressure altitude, feet Alt int32 // Pressure altitude, feet
GnssDiffFromBaroAlt int32 // GNSS altitude above WGS84 datum. Reported in TC 20-22 messages GnssDiffFromBaroAlt int32 // GNSS altitude above WGS84 datum. Reported in TC 20-22 messages
AltIsGNSS bool // Pressure alt = 0; GNSS alt = 1 AltIsGNSS bool // Pressure alt = 0; GNSS alt = 1
NIC int // Navigation Integrity Category. NIC int // Navigation Integrity Category.
NACp int // Navigation Accuracy Category for Position. NACp int // Navigation Accuracy Category for Position.
Track float32 // degrees true Track float32 // common.Degrees true
TurnRate float32 // Turn rate in deg/sec (negative = turning left, positive = right) TurnRate float32 // Turn rate in deg/sec (negative = turning left, positive = right)
Speed uint16 // knots Speed uint16 // knots
Speed_valid bool // set when speed report received. Speed_valid bool // set when speed report received.
@ -120,7 +122,7 @@ type TrafficInfo struct {
Alt_fix int32 // Last real, non-extrapolated altitude Alt_fix int32 // Last real, non-extrapolated altitude
BearingDist_valid bool // set when bearing and distance information is valid BearingDist_valid bool // set when bearing and distance information is valid
Bearing float64 // Bearing in degrees true to traffic from ownship, if it can be calculated. Units: degrees. Bearing float64 // Bearing in common.Degrees true to traffic from ownship, if it can be calculated. Units: common.Degrees.
Distance float64 // Distance to traffic from ownship, if it can be calculated. Units: meters. Distance float64 // Distance to traffic from ownship, if it can be calculated. Units: meters.
DistanceEstimated float64 // Estimated distance of the target if real distance can't be calculated, Estimated from signal strength with exponential smoothing. DistanceEstimated float64 // Estimated distance of the target if real distance can't be calculated, Estimated from signal strength with exponential smoothing.
DistanceEstimatedLastTs time.Time // Used to compute moving average DistanceEstimatedLastTs time.Time // Used to compute moving average
@ -225,7 +227,7 @@ func isOwnshipTrafficInfo(ti TrafficInfo) (isOwnshipInfo bool, shouldIgnore bool
} }
trafficDist := 0.0 trafficDist := 0.0
if isGPSValid() { if isGPSValid() {
trafficDist, _, _, _ = distRect(float64(mySituation.GPSLatitude), float64(mySituation.GPSLongitude), float64(ti.Lat), float64(ti.Lng)) trafficDist, _, _, _ = common.DistRect(float64(mySituation.GPSLatitude), float64(mySituation.GPSLongitude), float64(ti.Lat), float64(ti.Lng))
} }
altDiff := 99999.0 altDiff := 99999.0
if ti.AltIsGNSS && ti.Alt != 0 { if ti.AltIsGNSS && ti.Alt != 0 {
@ -306,7 +308,7 @@ func sendTrafficUpdates() {
for key, ti := range traffic { // ForeFlight 7.5 chokes at ~1000-2000 messages depending on iDevice RAM. Practical limit likely around ~500 aircraft without filtering. for key, ti := range traffic { // ForeFlight 7.5 chokes at ~1000-2000 messages depending on iDevice RAM. Practical limit likely around ~500 aircraft without filtering.
if isGPSValid() && ti.Position_valid { if isGPSValid() && ti.Position_valid {
// func distRect(lat1, lon1, lat2, lon2 float64) (dist, bearing, distN, distE float64) { // func distRect(lat1, lon1, lat2, lon2 float64) (dist, bearing, distN, distE float64) {
dist, bearing := distance(float64(mySituation.GPSLatitude), float64(mySituation.GPSLongitude), float64(ti.Lat), float64(ti.Lng)) dist, bearing := common.Distance(float64(mySituation.GPSLatitude), float64(mySituation.GPSLongitude), float64(ti.Lat), float64(ti.Lng))
ti.Distance = dist ti.Distance = dist
ti.Bearing = bearing ti.Bearing = bearing
ti.BearingDist_valid = true ti.BearingDist_valid = true
@ -477,17 +479,17 @@ func estimateDistance(ti *TrafficInfo) {
// calculates coordinates of a point defined by a location, a bearing, and a distance, thanks to 0x74-0x62 // calculates coordinates of a point defined by a location, a bearing, and a distance, thanks to 0x74-0x62
func calcLocationForBearingDistance(lat1, lon1, bearingDeg, distanceNm float64) (lat2, lon2 float64) { func calcLocationForBearingDistance(lat1, lon1, bearingDeg, distanceNm float64) (lat2, lon2 float64) {
lat1Rad := radians(lat1) lat1Rad := common.Radians(lat1)
lon1Rad := radians(lon1) lon1Rad := common.Radians(lon1)
bearingRad := radians(bearingDeg) bearingRad := common.Radians(bearingDeg)
distanceRad := distanceNm / (180 * 60 / math.Pi) distanceRad := distanceNm / (180 * 60 / math.Pi)
lat2Rad := math.Asin(math.Sin(lat1Rad)*math.Cos(distanceRad) + math.Cos(lat1Rad)*math.Sin(distanceRad)*math.Cos(bearingRad)) lat2Rad := math.Asin(math.Sin(lat1Rad)*math.Cos(distanceRad) + math.Cos(lat1Rad)*math.Sin(distanceRad)*math.Cos(bearingRad))
distanceLon := -math.Atan2(math.Sin(bearingRad)*math.Sin(distanceRad)*math.Cos(lat1Rad), math.Cos(distanceRad)-math.Sin(lat1Rad)*math.Sin(lat2Rad)) distanceLon := -math.Atan2(math.Sin(bearingRad)*math.Sin(distanceRad)*math.Cos(lat1Rad), math.Cos(distanceRad)-math.Sin(lat1Rad)*math.Sin(lat2Rad))
lon2Rad := math.Mod(lon1Rad-distanceLon+math.Pi, 2.0*math.Pi) - math.Pi lon2Rad := math.Mod(lon1Rad-distanceLon+math.Pi, 2.0*math.Pi) - math.Pi
lat2 = degrees(lat2Rad) lat2 = common.Degrees(lat2Rad)
lon2 = degrees(lon2Rad) lon2 = common.Degrees(lon2Rad)
return return
} }
@ -639,7 +641,7 @@ func makeTrafficReportMsg(ti TrafficInfo) []byte {
msg[16] = byte(vvel & 0x00FF) msg[16] = byte(vvel & 0x00FF)
// Track. // Track.
trk := uint8(ti.Track / TRACK_RESOLUTION) // Resolution is ~1.4 degrees. trk := uint8(ti.Track / TRACK_RESOLUTION) // Resolution is ~1.4 common.Degrees.
msg[17] = byte(trk) msg[17] = byte(trk)
msg[18] = ti.Emitter_category msg[18] = ti.Emitter_category
@ -871,7 +873,7 @@ func parseDownlinkReport(s string, signalLevel int) {
ti.Lat = lat ti.Lat = lat
ti.Lng = lng ti.Lng = lng
if isGPSValid() { if isGPSValid() {
ti.Distance, ti.Bearing = distance(float64(mySituation.GPSLatitude), float64(mySituation.GPSLongitude), float64(ti.Lat), float64(ti.Lng)) ti.Distance, ti.Bearing = common.Distance(float64(mySituation.GPSLatitude), float64(mySituation.GPSLongitude), float64(ti.Lat), float64(ti.Lng))
} }
ti.Last_seen = stratuxClock.Time ti.Last_seen = stratuxClock.Time
ti.ExtrapolatedPosition = false ti.ExtrapolatedPosition = false
@ -1172,7 +1174,7 @@ func esListen() {
ti.Lat = lat ti.Lat = lat
ti.Lng = lng ti.Lng = lng
if isGPSValid() { if isGPSValid() {
ti.Distance, ti.Bearing = distance(float64(mySituation.GPSLatitude), float64(mySituation.GPSLongitude), float64(ti.Lat), float64(ti.Lng)) ti.Distance, ti.Bearing = common.Distance(float64(mySituation.GPSLatitude), float64(mySituation.GPSLongitude), float64(ti.Lat), float64(ti.Lng))
ti.BearingDist_valid = true ti.BearingDist_valid = true
} }
ti.Position_valid = true ti.Position_valid = true
@ -1467,7 +1469,7 @@ func updateDemoTraffic(icao uint32, tail string, relAlt float32, gs float64, off
ti.Lat = float32(lat + traffRelLat) ti.Lat = float32(lat + traffRelLat)
ti.Lng = float32(lng + traffRelLng) ti.Lng = float32(lng + traffRelLng)
ti.Distance, ti.Bearing = distance(float64(lat), float64(lng), float64(ti.Lat), float64(ti.Lng)) ti.Distance, ti.Bearing = common.Distance(float64(lat), float64(lng), float64(ti.Lat), float64(ti.Lng))
ti.BearingDist_valid = true ti.BearingDist_valid = true
ti.Position_valid = true ti.Position_valid = true