Add new GPS status messages

pull/169/head
AvSquirrel 2015-12-27 08:47:37 +00:00
rodzic 555f9ccb8c
commit 681e05f3a3
6 zmienionych plików z 94 dodań i 30 usunięć

Wyświetl plik

@ -459,8 +459,8 @@ func makeSXHeartbeat() []byte {
// Number of GPS satellites locked.
msg[16] = byte(globalStatus.GPS_satellites_locked)
//FIXME: Number of satellites connected. ??
msg[17] = 0xFF
// Number of satellites tracked
msg[17] = byte(globalStatus.GPS_satellites_tracked)
// Summarize number of UAT and 1090ES traffic targets for reports that follow.
var uat_traffic_targets uint16
@ -703,10 +703,13 @@ func cpuTempMonitor() {
func updateStatus() {
if isGPSValid() {
globalStatus.GPS_satellites_locked = mySituation.Satellites
globalStatus.GPS_satellites_tracked = mySituation.SatellitesTracked
if mySituation.quality == 2 {
globalStatus.GPS_solution = "DGPS (WAAS)"
globalStatus.GPS_solution = "DGPS (SBAS / WAAS)"
} else if mySituation.quality == 1 {
globalStatus.GPS_solution = "3D GPS"
} else if mySituation.quality == 6 {
globalStatus.GPS_solution = "Dead Reckoning"
} else {
globalStatus.GPS_solution = "N/A"
}
@ -985,6 +988,7 @@ type status struct {
ES_messages_last_minute uint
ES_messages_max uint
GPS_satellites_locked uint16
GPS_satellites_tracked uint16
GPS_connected bool
GPS_solution string
RY835AI_connected bool
@ -1107,7 +1111,8 @@ func printStats() {
log.Printf(" - CPUTemp=%.02f deg C, MemStats.Alloc=%s, MemStats.Sys=%s, totalNetworkMessagesSent=%s\n", globalStatus.CPUTemp, humanize.Bytes(uint64(memstats.Alloc)), humanize.Bytes(uint64(memstats.Sys)), humanize.Comma(int64(totalNetworkMessagesSent)))
log.Printf(" - UAT/min %s/%s [maxSS=%.02f%%], ES/min %s/%s\n, Total traffic targets tracked=%s", humanize.Comma(int64(globalStatus.UAT_messages_last_minute)), humanize.Comma(int64(globalStatus.UAT_messages_max)), float64(maxSignalStrength)/10.0, humanize.Comma(int64(globalStatus.ES_messages_last_minute)), humanize.Comma(int64(globalStatus.ES_messages_max)), humanize.Comma(int64(len(seenTraffic))))
if globalSettings.GPS_Enabled {
log.Printf(" - Last GPS fix: %s, GPS solution type: %d, NACp: %d, est accuracy %.02f m\n", humanize.Time(mySituation.LastFixLocalTime), mySituation.quality, mySituation.NACp, mySituation.Accuracy)
log.Printf(" - Last GPS fix: %s, GPS solution type: %d using %v satellites (%v tracked), NACp: %d, est accuracy %.02f m\n", humanize.Time(mySituation.LastFixLocalTime), mySituation.quality, mySituation.Satellites, mySituation.SatellitesTracked, mySituation.NACp, mySituation.Accuracy)
log.Printf(" - GPS vertical velocity: %.02f ft/sec; GPS vertical accuracy: %v m\n", mySituation.GPSVertVel, mySituation.AccuracyVert)
}
}
}

Wyświetl plik

@ -29,12 +29,13 @@ type SituationData struct {
Lat float32
Lng float32
quality uint8
Satellites uint16
Satellites uint16 // satellites used in solution
SatellitesTracked uint16 // satellites tracked
Accuracy float32 // Meters.
NACp uint8 // NACp categories are defined in AC 20-165A
Alt float32 // Feet.
alt_accuracy float32
vertVelGPS float32 // GPS vertical velocity, feet per second
AccuracyVert float32
GPSVertVel float32 // GPS vertical velocity, feet per second
LastFixLocalTime time.Time
TrueCourse uint16
GroundSpeed uint16
@ -106,6 +107,8 @@ func initGPSSerial() bool {
device = "/dev/ttyAMA0"
}
log.Printf("Using %s for GPS\n", device)
/* Developer option -- allow "hot" configuration of GPS (assume it comes up at 115.2 kpbs on reboot)
serialConfig = &serial.Config{Name: device, Baud: 115200}
p, err := serial.OpenPort(serialConfig)
if err != nil {
@ -150,10 +153,11 @@ func initGPSSerial() bool {
p.Write(makeUBXCFG(0x06, 0x00, 20, cfg1))
p.Close()
}
*/
// Open port at 9600 baud for config.
serialConfig = &serial.Config{Name: device, Baud: 9600}
p, err = serial.OpenPort(serialConfig)
p, err := serial.OpenPort(serialConfig)
if err != nil {
log.Printf("serial port err: %s\n", err.Error())
return false
@ -174,7 +178,7 @@ func initGPSSerial() bool {
p.Write(makeUBXCFG(0x06, 0x24, 36, nav))
// GNSS configuration CFG-GNSS, p. 125
// GNSS configuration CFG-GNSS for ublox 7 higher, p. 125 (v8)
//
cfgGnss := []byte{0x00, 0x20, 0x20, 0x05}
gps := []byte{0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01}
@ -189,16 +193,16 @@ func initGPSSerial() bool {
cfgGnss = append(cfgGnss, glonass...)
p.Write(makeUBXCFG(0x06, 0x3E, uint16(len(cfgGnss)), cfgGnss))
// SBAS configuration
// SBAS configuration for ublox 6 and higher
p.Write(makeUBXCFG(0x06, 0x16, 8, []byte{0x01, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}))
// Message output configuration
// Message output configuration -- disable standard NMEA messages
// Msg DDC UART1 UART2 USB I2C Res
p.Write(makeUBXCFG(0x06, 0x01, 8, []byte{0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01})) // GGA
p.Write(makeUBXCFG(0x06, 0x01, 8, []byte{0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01})) // GLL
p.Write(makeUBXCFG(0x06, 0x01, 8, []byte{0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01})) // GSA
p.Write(makeUBXCFG(0x06, 0x01, 8, []byte{0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01})) // GSV
p.Write(makeUBXCFG(0x06, 0x01, 8, []byte{0xF0, 0x04, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x01})) // RMC
p.Write(makeUBXCFG(0x06, 0x01, 8, []byte{0xF0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01})) // RMC
p.Write(makeUBXCFG(0x06, 0x01, 8, []byte{0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01})) // VGT
p.Write(makeUBXCFG(0x06, 0x01, 8, []byte{0xF0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})) // GRS
p.Write(makeUBXCFG(0x06, 0x01, 8, []byte{0xF0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})) // GST
@ -229,7 +233,7 @@ func initGPSSerial() bool {
cfg[7] = 0x00
// Baud rate. Little endian order.
bdrt := uint32(115200)
bdrt := uint32(38400)
cfg[11] = byte((bdrt >> 24) & 0xFF)
cfg[10] = byte((bdrt >> 16) & 0xFF)
cfg[9] = byte((bdrt >> 8) & 0xFF)
@ -252,8 +256,8 @@ func initGPSSerial() bool {
p.Write(makeUBXCFG(0x06, 0x00, 20, cfg))
p.Close()
// Re-open port at 115200 baud so we can read messages
serialConfig = &serial.Config{Name: device, Baud: 115200}
// Re-open port at 38400 baud so we can read messages
serialConfig = &serial.Config{Name: device, Baud: 38400}
p, err = serial.OpenPort(serialConfig)
if err != nil {
log.Printf("serial port err: %s\n", err.Error())
@ -422,7 +426,7 @@ func processNMEALine(l string) bool {
if err != nil {
return false
}
mySituation.alt_accuracy = float32(vAcc)
mySituation.AccuracyVert = float32(vAcc)
// field 11 = groundspeed, km/h
@ -462,7 +466,7 @@ func processNMEALine(l string) bool {
if err != nil {
return false
}
mySituation.vertVelGPS = float32(vv*3.28084) // convert to ft/sec
mySituation.GPSVertVel = float32(vv*-3.28084) // convert to ft/sec; positive = up
@ -478,10 +482,60 @@ func processNMEALine(l string) bool {
mySituation.LastFixLocalTime = time.Now()
} // else if 03 or 04 message -- TODO
} else if (x[1] == "03") { // satellite status message
// field 2 = number of satellites tracked
satTracked, err := strconv.Atoi(x[2])
if err != nil {
return false
}
mySituation.SatellitesTracked = uint16(satTracked)
// fields 3-8 are repeated block
/*
for i:= 0; i < satTracked; i++ {
x[3+6*i] // sv number
x[4+6*i] // status [ U | e | - ] for used / ephemeris / not used
x[5+6*i] // azimuth, deg, 0-359
x[6+6*i] // elevation, deg, 0-90
x[7+6*i] // signal strength dB-Hz
x[8+6*i] // lock time, sec, 0-64
*/
} else if (x[1] == "04") { // clock message
// field 2 is UTC time
if len(x[2]) < 9 {
return false
}
hr, err1 := strconv.Atoi(x[2][0:2])
min, err2 := strconv.Atoi(x[2][2:4])
sec, err3 := strconv.Atoi(x[2][4:6])
if err1 != nil || err2 != nil || err3 != nil {
return false
}
mySituation.lastFixSinceMidnightUTC = uint32((hr * 60 * 60) + (min * 60) + sec)
// field 3 is date
if len(x[3]) == 6 {
// Date of Fix, i.e 191115 = 19 November 2015 UTC field 9
gpsTimeStr := fmt.Sprintf("%s %d:%d:%d", x[3], hr, min, sec)
gpsTime, err := time.Parse("020106 15:04:05", gpsTimeStr)
if err == nil {
if time.Since(gpsTime) > 10*time.Minute {
log.Printf("setting system time to: %s\n", gpsTime)
setStr := gpsTime.Format("20060102 15:04:05")
if err := exec.Command("date", "-s", setStr).Run(); err != nil {
log.Printf("Set Date failure: %s error\n", err)
}
}
}
}
}
// otherwise look for NMEA standard messages and process them
} else if (x[0] == "GNVTG") || (x[0] == "GPVTG") { // Ground track information.
mySituation.mu_GPS.Lock()
defer mySituation.mu_GPS.Unlock()
@ -615,7 +669,7 @@ func processNMEALine(l string) bool {
mySituation.Alt = float32(alt * 3.28084) // Convert to feet.
//TODO: Altitude accuracy.
mySituation.alt_accuracy = 0
mySituation.AccuracyVert = 0
// Timestamp.
mySituation.LastFixLocalTime = time.Now()

Wyświetl plik

@ -18,10 +18,10 @@
<div class="row">
<strong class="col-xs-6 text-center">Location:</strong>
<strong class="col-xs-6 text-center">Track:</strong>
</div>
</div>
<div class="row">
<span class="col-xs-6 text-center">{{gps_lat}}, {{gps_lon}} &plusmn; {{gps_accuracy}} m</span>
<span class="col-xs-6 text-center">{{gps_track}}&deg; @ {{gps_speed}}KTS @ {{gps_alt}} ft</span>
<span class="col-xs-6 text-center">{{gps_lat}}, {{gps_lon}} &plusmn; {{gps_accuracy}} m <br> {{gps_alt}} &plusmn; {{gps_vert_accuracy}} ft @ {{gps_vert_speed}} ft/min</span>
<span class="col-xs-6 text-center">{{gps_track}}&deg; @ {{gps_speed}} KTS</span>
</div>
</div>
</div>
@ -63,4 +63,4 @@
</div>
</div>
</div>
-->
-->

Wyświetl plik

@ -60,18 +60,22 @@ function GPSCtrl($rootScope, $scope, $state, $http, $interval) {
/* not currently used
$scope.gps_satellites = status.Satellites;
*/
$scope.gps_accuracy = Math.round(status.Accuracy);
$scope.gps_accuracy = status.Accuracy.toFixed(1);
$scope.gps_vert_accuracy = (status.AccuracyVert*3.2808).toFixed(1); // accuracy is in meters, need to display in ft
// NACp should be an integer value in the range of 0 .. 11
// var accuracies = ["≥ 10 NM", "< 10 NM", "< 4 NM", "< 2 NM", "< 1 NM", "< 0.5 NM", "< 0.3 NM", "< 0.1 NM", "< 100 m", "< 30 m", "< 10 m", "< 3 m"];
// $scope.gps_accuracy = accuracies[status.NACp];
// "LastFixLocalTime":"2015-10-11T16:47:03.523085162Z"
$scope.gps_lat = status.Lat.toPrecision(6); // result is string
$scope.gps_lon = status.Lng.toPrecision(6); // result is string
$scope.gps_lat = status.Lat.toFixed(5); // result is string
$scope.gps_lon = status.Lng.toFixed(5); // result is string
$scope.gps_alt = Math.round(status.Alt);
$scope.gps_track = status.TrueCourse;
$scope.gps_speed = status.GroundSpeed;
$scope.gps_vert_speed = status.GPSVertVel.toFixed(1);
// "LastGroundTrackTime":"0001-01-01T00:00:00Z"
/* not currently used
@ -103,9 +107,9 @@ function GPSCtrl($rootScope, $scope, $state, $http, $interval) {
};
var updateStatus = $interval(function () {
// refresh GPS/AHRS status once each second (aka polling)
// refresh GPS/AHRS status once each half second (aka polling)
getStatus();
}, (1 * 1000), 0, false);
}, (1 * 500), 0, false);
$state.get('gps').onEnter = function () {
// everything gets handled correctly by the controller
@ -122,4 +126,4 @@ function GPSCtrl($rootScope, $scope, $state, $http, $interval) {
ahrs.init();
ahrs.orientation(0, 0, 0);
};
};

Wyświetl plik

@ -49,6 +49,7 @@ function StatusCtrl($rootScope, $scope, $state, $http, $interval) {
$scope.ES_messages_last_minute = status.ES_messages_last_minute;
$scope.ES_messages_max = status.ES_messages_max;
$scope.GPS_satellites_locked = status.GPS_satellites_locked;
$scope.GPS_satellites_tracked = status.GPS_satellites_tracked;
$scope.GPS_solution = status.GPS_solution;
$scope.RY835AI_connected = status.RY835AI_connected;

Wyświetl plik

@ -62,7 +62,7 @@
</div>
<div class="row" ng-class="{'section_invisible': !visible_gps}">
<label class="col-xs-6">GPS satellites:</label>
<span class="col-xs-6">{{GPS_satellites_locked}}</span>
<span class="col-xs-6">{{GPS_satellites_locked}} used; {{GPS_satellites_tracked}} tracked</span>
</div>
<div class="row" ng-class="{'section_invisible': !visible_ahrs}">
<label class="col-xs-6">AHRS:</label>