Merge pull request #557 from AvSquirrel/10Hz-gps

GPS configuration and detection improvements
pull/554/merge
cyoung 2017-01-30 00:27:24 -05:00 zatwierdzone przez GitHub
commit 490e3d9900
7 zmienionych plików z 183 dodań i 122 usunięć

Wyświetl plik

@ -77,12 +77,22 @@ const (
LON_LAT_RESOLUTION = float32(180.0 / 8388608.0)
TRACK_RESOLUTION = float32(360.0 / 256.0)
GPS_TYPE_NMEA = 0x01
GPS_TYPE_UBX = 0x02
GPS_TYPE_SIRF = 0x03
GPS_TYPE_MEDIATEK = 0x04
GPS_TYPE_FLARM = 0x05
GPS_TYPE_GARMIN = 0x06
/*
GPS_TYPE_NMEA = 0x01
GPS_TYPE_UBX = 0x02
GPS_TYPE_SIRF = 0x03
GPS_TYPE_MEDIATEK = 0x04
GPS_TYPE_FLARM = 0x05
GPS_TYPE_GARMIN = 0x06
*/
GPS_TYPE_UBX8 = 0x08
GPS_TYPE_UBX7 = 0x07
GPS_TYPE_UBX6 = 0x06
GPS_TYPE_PROLIFIC = 0x02
GPS_TYPE_UART = 0x01
GPS_PROTOCOL_NMEA = 0x10
GPS_PROTOCOL_UBX = 0x30
// other GPS types to be defined as needed
)

Wyświetl plik

@ -78,6 +78,7 @@ type SituationData struct {
LastGPSTimeTime time.Time // stratuxClock time since last GPS time received.
LastValidNMEAMessageTime time.Time // time valid NMEA message last seen
LastValidNMEAMessage string // last NMEA message processed.
PositionSampleRate float64 // calculated sample rate of GPS positions
// From BMP180 pressure sensor.
Temp float64
@ -188,17 +189,22 @@ func initGPSSerial() bool {
if _, err := os.Stat("/dev/ublox8"); err == nil { // u-blox 8 (RY83xAI over USB).
device = "/dev/ublox8"
} else if _, err := os.Stat("/dev/ublox7"); err == nil { // u-blox 7 (VK-172, RY725AI over USB).
globalStatus.GPS_detected_type = GPS_TYPE_UBX8
} else if _, err := os.Stat("/dev/ublox7"); err == nil { // u-blox 7 (VK-172, VK-162 Rev 2, RY725AI over USB).
device = "/dev/ublox7"
} else if _, err := os.Stat("/dev/ublox6"); err == nil { // u-blox 6 (VK-162).
globalStatus.GPS_detected_type = GPS_TYPE_UBX7
} else if _, err := os.Stat("/dev/ublox6"); err == nil { // u-blox 6 (VK-162 Rev 1).
device = "/dev/ublox6"
globalStatus.GPS_detected_type = GPS_TYPE_UBX6
} else if _, err := os.Stat("/dev/prolific0"); err == nil { // Assume it's a BU-353-S4 SIRF IV.
//TODO: Check a "serialout" flag and/or deal with multiple prolific devices.
isSirfIV = true
baudrate = 4800
device = "/dev/prolific0"
globalStatus.GPS_detected_type = GPS_TYPE_PROLIFIC
} else if _, err := os.Stat("/dev/ttyAMA0"); err == nil { // ttyAMA0 is PL011 UART (GPIO pins 8 and 10) on all RPi.
device = "/dev/ttyAMA0"
globalStatus.GPS_detected_type = GPS_TYPE_UART
} else {
log.Printf("No suitable device found.\n")
return false
@ -245,9 +251,11 @@ func initGPSSerial() bool {
log.Printf("Finished writing SiRF GPS config to %s. Opening port to test connection.\n", device)
}
} else {
// Set 5 Hz update. Little endian order.
//p.Write(makeUBXCFG(0x06, 0x08, 6, []byte{0x64, 0x00, 0x01, 0x00, 0x01, 0x00})) // 10 Hz
p.Write(makeUBXCFG(0x06, 0x08, 6, []byte{0xc8, 0x00, 0x01, 0x00, 0x01, 0x00})) // 5 Hz
// Byte order for UBX configuration is little endian.
// Set 10 Hz update to make gpsattitude more responsive for ublox7/8.
p.Write(makeUBXCFG(0x06, 0x08, 6, []byte{0x64, 0x00, 0x01, 0x00, 0x01, 0x00})) // 10 Hz
//p.Write(makeUBXCFG(0x06, 0x08, 6, []byte{0xc8, 0x00, 0x01, 0x00, 0x01, 0x00})) // 5 Hz
// Set navigation settings.
nav := make([]byte, 36)
@ -260,20 +268,25 @@ func initGPSSerial() bool {
p.Write(makeUBXCFG(0x06, 0x24, 36, nav))
// GNSS configuration CFG-GNSS for ublox 7 higher, p. 125 (v8)
// NOTE: Max position rate = 5 Hz if GPS+GLONASS used.
// TESTING: 5Hz unified GPS + GLONASS
// Disable GLONASS to enable 10 Hz solution rate. GLONASS is not used
// for SBAS (WAAS), so little real-world impact.
// Notes: ublox8 is multi-GNSS capable (simultaneous decoding of GPS and GLONASS, or
// GPS and Galileo) if SBAS (e.g. WAAS) is unavailable. This may provide robustness
// against jamming / interference on one set of frequencies. However, this will drop the
// position reporting rate to 5 Hz during times multi-GNSS is in use. This shouldn't affect
// gpsattitude too much -- without WAAS corrections, the algorithm could get jumpy at higher
// sampling rates.
cfgGnss := []byte{0x00, 0x20, 0x20, 0x05}
gps := []byte{0x00, 0x08, 0x10, 0x00, 0x01, 0x00, 0x01, 0x01} // enable GPS with 8-16 tracking channels
sbas := []byte{0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x01, 0x01} // enable SBAS (WAAS) with 2-3 tracking channels
beidou := []byte{0x03, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x01}
qzss := []byte{0x05, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x01}
//glonass := []byte{0x06, 0x04, 0x0E, 0x00, 0x00, 0x00, 0x01, 0x01} // this disables GLONASS
glonass := []byte{0x06, 0x08, 0x0E, 0x00, 0x01, 0x00, 0x01, 0x01} // this enables GLONASS with 8-14 tracking channels
glonass := []byte{0x06, 0x04, 0x0E, 0x00, 0x00, 0x00, 0x01, 0x01} // this disables GLONASS
if (globalStatus.GPS_detected_type == GPS_TYPE_UBX8) || (globalStatus.GPS_detected_type == GPS_TYPE_UART) { // assume that any GPS connected to serial GPIO is ublox8 (RY835/6AI)
//log.Printf("UBX8 device detected on USB, or GPS serial connection in use. Attempting GLONASS configuration.\n")
glonass = []byte{0x06, 0x08, 0x0E, 0x00, 0x01, 0x00, 0x01, 0x01} // this enables GLONASS with 8-14 tracking channels
}
cfgGnss = append(cfgGnss, gps...)
cfgGnss = append(cfgGnss, sbas...)
cfgGnss = append(cfgGnss, beidou...)
@ -291,9 +304,7 @@ func initGPSSerial() bool {
p.Write(makeUBXCFG(0x06, 0x01, 8, []byte{0xF0, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x01})) // GGA enabled every 5th message
p.Write(makeUBXCFG(0x06, 0x01, 8, []byte{0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01})) // GLL disabled
p.Write(makeUBXCFG(0x06, 0x01, 8, []byte{0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01})) // GSA disabled
//p.Write(makeUBXCFG(0x06, 0x01, 8, []byte{0xF0, 0x02, 0x00, 0x05, 0x00, 0x05, 0x00, 0x01})) // GSA enabled disabled every 5th position (used for testing only)
p.Write(makeUBXCFG(0x06, 0x01, 8, []byte{0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01})) // GSV disabled
//p.Write(makeUBXCFG(0x06, 0x01, 8, []byte{0xF0, 0x03, 0x00, 0x05, 0x00, 0x05, 0x00, 0x01})) // GSV enabled for every 5th position (used for testing only)
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
@ -304,9 +315,9 @@ func initGPSSerial() bool {
p.Write(makeUBXCFG(0x06, 0x01, 8, []byte{0xF0, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})) // GNS
p.Write(makeUBXCFG(0x06, 0x01, 8, []byte{0xF0, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})) // ???
p.Write(makeUBXCFG(0x06, 0x01, 8, []byte{0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})) // VLW
p.Write(makeUBXCFG(0x06, 0x01, 8, []byte{0xF1, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00})) // Ublox,0
p.Write(makeUBXCFG(0x06, 0x01, 8, []byte{0xF1, 0x03, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00})) // Ublox,3
p.Write(makeUBXCFG(0x06, 0x01, 8, []byte{0xF1, 0x04, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x00})) // Ublox,4
p.Write(makeUBXCFG(0x06, 0x01, 8, []byte{0xF1, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00})) // Ublox,0
p.Write(makeUBXCFG(0x06, 0x01, 8, []byte{0xF1, 0x03, 0x00, 0x05, 0x00, 0x05, 0x00, 0x00})) // Ublox,3
p.Write(makeUBXCFG(0x06, 0x01, 8, []byte{0xF1, 0x04, 0x00, 0x0A, 0x00, 0x0A, 0x00, 0x00})) // Ublox,4
// Reconfigure serial port.
cfg := make([]byte, 20)
@ -427,7 +438,7 @@ Method uses stored performance statistics from myGPSPerfStats[]. Ideally, calcul
assuming 10 Hz sampling frequency. Lower frequency sample rates will increase calculation window for smoother response, at the
cost of slightly increased lag.
(c) 2016 AvSquirrel (https://github.com/AvSquirrel) . All rights reserved.
(c) 2016 Keith Tschohl. All rights reserved.
Distributable under the terms of the "BSD-New" License that can be found in
the LICENSE file, herein included as part of this header.
*/
@ -517,9 +528,9 @@ func calcGPSAttitude() bool {
var tempHdg, tempHdgUnwrapped, tempHdgTime, tempSpeed, tempVV, tempSpeedTime, tempRegWeights []float64 // temporary arrays for regression calculation
var valid bool
var lengthHeading, lengthSpeed int
var halfwidth float64 // width of regression evaluation window. Minimum of 1.5 seconds and maximum of 3.5 seconds.
center := float64(myGPSPerfStats[index].nmeaTime) // current time for calculating regression weights
halfwidth := float64(1.4) // width of regression evaluation window. Default of 1.4 seconds for 5 Hz sampling; can increase to 3.5 sec @ 1 Hz
// frequency detection
tempSpeedTime = make([]float64, 0)
@ -535,19 +546,23 @@ func calcGPSAttitude() bool {
if globalSettings.DEBUG {
log.Printf("GPS attitude: Average delta time is %.2f s (%.1f Hz)\n", dt_avg, 1/dt_avg)
}
halfwidth = 7 * dt_avg
halfwidth = 9 * dt_avg
mySituation.PositionSampleRate = 1 / dt_avg
} else {
if globalSettings.DEBUG {
log.Printf("GPS attitude: Couldn't determine sample rate\n")
}
halfwidth = 3.5
mySituation.PositionSampleRate = 0
}
if halfwidth > 3.5 {
halfwidth = 3.5 // limit calculation window to 3.5 seconds of data for 1 Hz or slower samples
} else if halfwidth < 1.5 {
halfwidth = 1.5 // use minimum of 1.5 seconds for sample rates faster than 5 Hz
}
if globalStatus.GPS_detected_type == GPS_TYPE_UBX { // UBX reports vertical speed, so we can just walk through all of the PUBX messages in order
if (globalStatus.GPS_detected_type & 0xf0) == GPS_PROTOCOL_UBX { // UBX reports vertical speed, so we can just walk through all of the PUBX messages in order
// Speed and VV. Use all values in myGPSPerfStats; perform regression.
tempSpeedTime = make([]float64, length, length) // all are length of original slice
tempSpeed = make([]float64, length, length)
@ -850,8 +865,8 @@ func processNMEALine(l string) (sentenceUsed bool) {
// set the global GPS type to UBX as soon as we see our first (valid length)
// PUBX,01 position message, even if we don't have a fix
if globalStatus.GPS_detected_type != GPS_TYPE_UBX {
globalStatus.GPS_detected_type = GPS_TYPE_UBX
if (globalStatus.GPS_detected_type & 0xf0) != GPS_PROTOCOL_UBX {
globalStatus.GPS_detected_type |= GPS_PROTOCOL_UBX
log.Printf("GPS detected: u-blox NMEA position message seen.\n")
}
@ -1251,8 +1266,8 @@ func processNMEALine(l string) (sentenceUsed bool) {
}
// use RMC / GGA message detection to sense "NMEA" type.
if globalStatus.GPS_detected_type == 0 {
globalStatus.GPS_detected_type = GPS_TYPE_NMEA
if (globalStatus.GPS_detected_type & 0xf0) == 0 {
globalStatus.GPS_detected_type |= GPS_PROTOCOL_NMEA
}
// Quality indicator.
@ -1274,7 +1289,7 @@ func processNMEALine(l string) (sentenceUsed bool) {
}
tmpSituation.LastFixSinceMidnightUTC = float32(3600*hr+60*min) + float32(sec)
if globalStatus.GPS_detected_type != GPS_TYPE_UBX {
if (globalStatus.GPS_detected_type & 0xf0) != GPS_PROTOCOL_UBX {
thisGpsPerf.nmeaTime = tmpSituation.LastFixSinceMidnightUTC
}
@ -1315,7 +1330,7 @@ func processNMEALine(l string) (sentenceUsed bool) {
return false
}
tmpSituation.Alt = float32(alt * 3.28084) // Convert to feet.
if globalStatus.GPS_detected_type != GPS_TYPE_UBX {
if (globalStatus.GPS_detected_type & 0xf0) != GPS_PROTOCOL_UBX {
thisGpsPerf.alt = float32(tmpSituation.Alt)
}
@ -1332,7 +1347,7 @@ func processNMEALine(l string) (sentenceUsed bool) {
// Timestamp.
tmpSituation.LastFixLocalTime = stratuxClock.Time
if globalStatus.GPS_detected_type != GPS_TYPE_UBX {
if (globalStatus.GPS_detected_type & 0xf0) != GPS_PROTOCOL_UBX {
updateGPSPerf = true
thisGpsPerf.msgType = x[0]
}
@ -1376,8 +1391,8 @@ func processNMEALine(l string) (sentenceUsed bool) {
}
// use RMC / GGA message detection to sense "NMEA" type.
if globalStatus.GPS_detected_type == 0 {
globalStatus.GPS_detected_type = GPS_TYPE_NMEA
if (globalStatus.GPS_detected_type & 0xf0) == 0 {
globalStatus.GPS_detected_type |= GPS_PROTOCOL_NMEA
}
if x[2] != "A" { // invalid fix
@ -1396,7 +1411,7 @@ func processNMEALine(l string) (sentenceUsed bool) {
return false
}
tmpSituation.LastFixSinceMidnightUTC = float32(3600*hr+60*min) + float32(sec)
if globalStatus.GPS_detected_type != GPS_TYPE_UBX {
if (globalStatus.GPS_detected_type & 0xf0) != GPS_PROTOCOL_UBX {
thisGpsPerf.nmeaTime = tmpSituation.LastFixSinceMidnightUTC
}
@ -1455,7 +1470,7 @@ func processNMEALine(l string) (sentenceUsed bool) {
return false
}
tmpSituation.GroundSpeed = uint16(groundspeed)
if globalStatus.GPS_detected_type != GPS_TYPE_UBX {
if (globalStatus.GPS_detected_type & 0xf0) != GPS_PROTOCOL_UBX {
thisGpsPerf.gsf = float32(groundspeed)
}
@ -1469,17 +1484,17 @@ func processNMEALine(l string) (sentenceUsed bool) {
trueCourse = float32(tc)
setTrueCourse(uint16(groundspeed), tc)
tmpSituation.TrueCourse = trueCourse
if globalStatus.GPS_detected_type != GPS_TYPE_UBX {
if (globalStatus.GPS_detected_type & 0xf0) != GPS_PROTOCOL_UBX {
thisGpsPerf.coursef = float32(tc)
}
} else {
if globalStatus.GPS_detected_type != GPS_TYPE_UBX {
if (globalStatus.GPS_detected_type & 0xf0) != GPS_PROTOCOL_UBX {
thisGpsPerf.coursef = -999.9
}
// Negligible movement. Don't update course, but do use the slow speed.
//TODO: use average course over last n seconds?
}
if globalStatus.GPS_detected_type != GPS_TYPE_UBX {
if (globalStatus.GPS_detected_type & 0xf0) != GPS_PROTOCOL_UBX {
updateGPSPerf = true
thisGpsPerf.msgType = x[0]
}
@ -1949,7 +1964,7 @@ func isGPSConnected() bool {
isGPSValid returns true only if a valid position fix has been seen in the last 15 seconds,
and if the GPS subsystem has recently detected a GPS device.
If false, 'Quality` is set to 0 ("No fix"), as is the number of satellites in solution.
If false, 'Quality` is set to 0 ("No fix"), NACp == 0, and horizontal / vertical accuracy set to large numbers
*/
func isGPSValid() bool {
@ -1959,6 +1974,9 @@ func isGPSValid() bool {
} else {
mySituation.Quality = 0
mySituation.Satellites = 0
mySituation.Accuracy = 999999
mySituation.AccuracyVert = 999999
mySituation.NACp = 0
}
return isValid
}

Wyświetl plik

@ -83,7 +83,7 @@
<div class="panel-footer">
<div class="row">
<label class="col-xs-6">GPS solution:</label>
<span class="col-xs-6">{{SolutionText}}</span>
<span class="col-xs-6">{{SolutionText}} @ {{PositionSampleRate}} Hz</span>
</div>
<div class="row">
<label class="col-xs-6">Summary:</label>

Wyświetl plik

@ -72,6 +72,9 @@ function GPSCtrl($rootScope, $scope, $state, $http, $interval) {
}
$scope.SolutionText = solutionText;
$scope.PositionSampleRate = (status.Quality ? status.PositionSampleRate.toFixed(1) : "N/A");
$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

Wyświetl plik

@ -54,7 +54,54 @@ function StatusCtrl($rootScope, $scope, $state, $http, $interval) {
$scope.GPS_satellites_tracked = status.GPS_satellites_tracked;
$scope.GPS_satellites_seen = status.GPS_satellites_seen;
$scope.GPS_solution = status.GPS_solution;
$scope.GPS_position_accuracy = String(status.GPS_solution ? ", " + status.GPS_position_accuracy.toFixed(1) + " m" : " ");
switch(status.GPS_solution) {
case "Disconnected":
case "No Fix":
case "Unknown":
$scope.GPS_position_accuracy = "";
break;
default:
$scope.GPS_position_accuracy = ", " + status.GPS_position_accuracy.toFixed(1) + " m";
}
var gpsHardwareCode = (status.GPS_detected_type & 0x0f);
var tempGpsHardwareString = "Not installed";
switch(gpsHardwareCode) {
case 1:
tempGpsHardwareString = "Serial port";
break;
case 2:
tempGpsHardwareString = "Prolific USB-serial bridge";
break;
case 6:
tempGpsHardwareString = "USB u-blox 6 GPS receiver";
break;
case 7:
tempGpsHardwareString = "USB u-blox 7 GNSS receiver";
break;
case 8:
tempGpsHardwareString = "USB u-blox 8 GNSS receiver";
break;
default:
tempGpsHardwareString = "Not installed";
}
$scope.GPS_hardware = tempGpsHardwareString;
var gpsProtocol = (status.GPS_detected_type >> 4);
var tempGpsProtocolString = "Not communicating";
switch(gpsProtocol) {
case 1:
tempGpsProtocolString = "NMEA protocol";
break;
case 3:
tempGpsProtocolString = "NMEA-UBX protocol";
break;
default:
tempGpsProtocolString = "Not communicating";
}
$scope.GPS_protocol = tempGpsProtocolString;
var MiBFree = status.DiskBytesFree/1048576;
$scope.DiskSpace = MiBFree.toFixed(1);
$scope.UAT_METAR_total = status.UAT_METAR_total;
$scope.UAT_TAF_total = status.UAT_TAF_total;
$scope.UAT_NEXRAD_total = status.UAT_NEXRAD_total;
@ -81,7 +128,7 @@ function StatusCtrl($rootScope, $scope, $state, $http, $interval) {
var boardtemp = status.CPUTemp;
if (boardtemp != undefined) {
/* boardtemp is celcius to tenths */
$scope.CPUTemp = String(boardtemp.toFixed(1) + 'C / ' + ((boardtemp * 9 / 5) + 32.0).toFixed(1) + 'F');
$scope.CPUTemp = String(boardtemp.toFixed(1) + '°C / ' + ((boardtemp * 9 / 5) + 32.0).toFixed(1) + '°F');
} else {
// $('#CPUTemp').text('unavailable');
}

Wyświetl plik

@ -1,13 +1,12 @@
<div class="section text-left help-page">
<p>The <strong>Status</strong> page provides an overview of your Stratux device.</p>
<p>The current state of you device is shown at the top - <code>Connected</code> in green or <code>Disconected</code>in red.</p>
<p>Depending on the hardware you have installed in your Stratux, status messages will be shown for the following:</p>
<ul class="list-simple">
<li><strong>Messages</strong> is the number of messages received by the UAT (978 MHz) and 1090 MHz radios. "Current" is the 60-second rolling total for each receiver; "Peak" is the maximum 60-second total. The 1090 total includes all 1090 MHz Mode S messages received, including all-call and TCAS interrogations that do not carry ADS-B position information. If a UAT radio is receiving uplinks from one or more ground-based transceivers (GBT), this will be indicated under <strong>UAT Towers</strong>, with more details available on the Towers page.</li>
<li><strong>GPS</strong> indicates the connection status of any attached GPS receivers. Reported data includes the type of position solution, the number of satellites used in that solution, the number of satellites being received, and the number of satellites tracked in the GPS almanac data. Position and accuracy details can be viewed on the <strong>GPS/AHRS</strong> page.</li>
</ul>
<p class="text-warning">Devices must be manually enabled on the <strong>Settings</strong> page.</p>
<p>Additional statistics include the number of detected software-defined radios (SDRs), number of current DHCP network clients, uptime, temperature of the Raspberry Pi CPU, and the current clock settings on both the Raspberry Pi and the device / browser used to view this page.</p>
<p>The <strong>Status</strong> page provides an overview of your Stratux device.</p>
<p>Status of the connection to your device is shown at the top of the page: <code style="color: #25C666">Connected</code> in green or <code>Disconnected</code>in red.</p>
<p class="text-warning">Note: SDR and GPS devices must be manually enabled on the <strong>Settings</strong> page.</p>
<p>Depending on the hardware you have installed in your Stratux, status messages will be shown for the following:</p>
<ul class="list-simple">
<li><strong>Messages</strong> is the number of messages received by the UAT (978 MHz) and 1090 MHz radios. "Current" is the 60-second rolling total for each receiver; "Peak" is the maximum 60-second total. The 1090 total includes all 1090 MHz Mode S messages received, including all-call and TCAS interrogations that do not carry ADS-B position information.</li>
<li><strong>UAT Statistics</strong> provides the status of the UAT / FIS-B uplink. The number of ground-based transceivers (GBT) currently received is indicated in the column labeled "Towers". Additional details are available on the <strong>Towers</strong> page. Counts of FIS-B weather and information messages are listed under the appropriate categories.</li>
<li><strong>GPS hardware</strong> indicates the type and connection status of any attached GPS receivers. <strong>GPS solution</strong> indicates the current position solution type and estimated horizontal accuracy. <strong>GPS satellites</strong> indicates the number of satellites used in that solution, the number of satellites being received, and the number of satellites tracked in the GPS almanac data. Additional position and accuracy details can be viewed on the <strong>GPS/AHRS</strong> page.</li>
</ul>
<p>Additional statistics listed include the number of detected software-defined radios (SDRs), number of current DHCP network clients, Stratux application uptime, the temperature of the Raspberry Pi CPU, and the total amount of available space on the micro SD card.</p>
</div>

Wyświetl plik

@ -1,13 +1,13 @@
<div class="col-sm-12">
<div class="text-center">
<a ng-click="VersionClick()" class="btn btn-hidden"<strong>Version: <span>{{Version}} ({{Build}})</span></strong></a>
</div>
<a ng-click="VersionClick()" class="btn btn-hidden"<strong>Version: <span>{{Version}} ({{Build}})</span></strong></a>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<span class="panel_label">Status</span>
<span ng-show="ConnectState == 'Connected'" class="label label-success">{{ConnectState}}</span>
<span ng-hide="ConnectState == 'Connected'" class="label label-danger">{{ConnectState}}</span>
<span ng-show="DeveloperMode == true" class="label label-warning">Developer Mode</span>
<span ng-show="DeveloperMode == true" class="label label-warning">Developer Mode</span>
</div>
<div class="panel-body">
<div class="form-horizontal">
@ -46,23 +46,50 @@
<span class="col-xs-6"><div class="bar_container"><div class="bar_display traffic-style1" ng-attr-style="width:{{ES_messages_max ? 100*ES_messages_last_minute / ES_messages_max : 0}}%;">{{ES_messages_last_minute}}</div></div></span>
<span class="col-xs-2 text-right">{{ES_messages_max}}</span>
</div>
<!--
<div id="uat_products" style="display: none;">
<div class="row"><span class="col-xs-1">&nbsp;</span></div>
<div class="row">
<label class="col-xs-6">UAT Products</label>
<label class="col-xs-3 text-right">Last Minute</label>
<label class="col-xs-3"></label>
</div>
<div>{{product_rows}}</div>
</div>
-->
<div class="row" ng-class="{ 'section_invisible': (!visible_gps && !visible_ahrs && !visible_uat)}">
<span class="col-xs-1">&nbsp;</span>
</div>
<div class="row" ng-class="{'section_invisible': !visible_uat}">
<label class="col-xs-6">UAT Towers:</label>
<span class="col-xs-6">{{UAT_Towers}}</span>
<div class="col-sm-6">
<span><strong>UAT Statistics</strong></span>
</div>
</div>
<div class="row" ng-class="{'section_invisible': !visible_uat}">
<div class="col-sm-12">
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">Towers</span>
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">METARS</span>
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">TAFS</span>
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">NEXRAD</span>
</div>
</div>
<div class="row" ng-class="{'section_invisible': !visible_uat}">
<div class="col-sm-12">
<span align="center" class="col-xs-3">{{UAT_Towers}}</span>
<span align="center" class="col-xs-3">{{UAT_METAR_total}}</span>
<span align="center" class="col-xs-3">{{UAT_TAF_total}}</span>
<span align="center" class="col-xs-3">{{UAT_NEXRAD_total}}</span>
</div>
</div>
<div class="row" ng-class="{'section_invisible': !visible_uat}">
<div class="col-sm-12">
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">PIREP</span>
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">SIGMET</span>
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">NOTAMS</span>
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">Other</span>
</div>
</div>
<div class="row" ng-class="{'section_invisible': !visible_uat}">
<div class="col-sm-12">
<span align="center" class="col-xs-3">{{UAT_PIREP_total}}</span>
<span align="center" class="col-xs-3">{{UAT_SIGMET_total}}</span>
<span align="center" class="col-xs-3">{{UAT_NOTAM_total}}</span>
<span align="center" class="col-xs-3">{{UAT_OTHER_total}}</span>
</div>
</div>
<div class="separator"></div>
<div class="row" ng-class="{'section_invisible': !visible_gps}">
<label class="col-xs-6">GPS hardware:</label>
<span class="col-xs-6">{{GPS_hardware}} ({{GPS_protocol}})</span>
</div>
<div class="row" ng-class="{'section_invisible': !visible_gps}">
<label class="col-xs-6">GPS solution:</label>
@ -72,47 +99,6 @@
<label class="col-xs-6">GPS satellites:</label>
<span class="col-xs-6">{{GPS_satellites_locked}} in solution; {{GPS_satellites_seen}} seen; {{GPS_satellites_tracked}} tracked</span>
</div>
<div class="row"><span class="col-xs-1">&nbsp;</span></div>
<div class="separator"></div>
<div class="row" ng-class="{'section_invisible': !visible_uat}">
<div class="col-sm-6">
<span><strong>UAT Statistics</strong></span>
</div>
</div>
<div class="row" ng-class="{'section_invisible': !visible_uat}">
<div class="col-sm-12">
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">METARS</span>
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">TAFS</span>
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">NEXRAD</span>
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">PIREP</span>
</div>
</div>
<div class="row" ng-class="{'section_invisible': !visible_uat}">
<div class="col-sm-12">
<span align="center" class="col-xs-3">{{UAT_METAR_total}}</span>
<span align="center" class="col-xs-3">{{UAT_TAF_total}}</span>
<span align="center" class="col-xs-3">{{UAT_NEXRAD_total}}</span>
<span align="center" class="col-xs-3">{{UAT_PIREP_total}}</span>
</div>
</div>
<div class="row" ng-class="{'section_invisible': !visible_uat}">
<div class="col-sm-12">
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">SIGMET</span>
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">NOTAMS</span>
<span align="center" style="background-color: #f7f7f7" class="col-xs-3">Other</span>
</div>
</div>
<div class="row" ng-class="{'section_invisible': !visible_uat}">
<div class="col-sm-12">
<span align="center" class="col-xs-3">{{UAT_SIGMET_total}}</span>
<span align="center" class="col-xs-3">{{UAT_NOTAM_total}}</span>
<span align="center" class="col-xs-3">{{UAT_OTHER_total}}</span>
</div>
</div>
</div>
<div class="row" ng-class="{'section_invisible': !visible_uat}">
<div class="separator"></div>
<div class="row"><span class="col-xs-1">&nbsp;</span></div>
<div class="separator"></div>
<div class="row">
<div class="col-sm-4 label_adj">
@ -123,12 +109,15 @@
<span class="col-xs-5"><strong>CPU Temp:</strong></span>
<span class="col-xs-7">{{CPUTemp}}</span>
</div>
<div class="col-sm-4 label_adj">
<span class="col-xs-5"><strong>Free Storage:</strong></span>
<span class="col-xs-7">{{DiskSpace}} MiB</span>
</div>
</div>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel panel-default" ng-class="{'section_invisible': !visible_errors}">
<div class="panel-heading" ng-class="{'section_invisible': !visible_errors}">
<span class="panel_label">Errors</span>
</div>
@ -137,12 +126,7 @@
<li class="status-error" ng-repeat="err in Errors">
<span class="fa fa-exclamation-triangle icon-red"></span> <span class="icon-red">{{err}}</span>
</li>
</ul>
</div>
</ul>
</div>
</div>
</div>