Porównaj commity

...

8 Commity

Autor SHA1 Wiadomość Data
Adrian Batzill 0be072c51f gps accuracy for ublox 10 2024-01-12 13:23:27 +01:00
Stefan Unz 6d6c593257 cleaned comments and logging 2024-01-10 13:55:37 +01:00
Stefan Unz 79fdc0f86d change in javascript comment 2024-01-10 13:55:37 +01:00
Stefan Unz fd5f64a816 synced gps type enumeration in javascript and go code 2024-01-10 13:55:37 +01:00
Stefan Unz e6d1586a9f added ubox10 2024-01-10 13:55:37 +01:00
Stefan Unz dbae1ef6a3 reeneabled log messages 2024-01-10 13:55:37 +01:00
Stefan Unz fbc252eef7 gps manual config 2024-01-10 13:55:37 +01:00
Stefan Unz 1f7acbe762 option to conifgure gps manually 2024-01-10 13:55:37 +01:00
4 zmienionych plików z 179 dodań i 76 usunięć

Wyświetl plik

@ -92,20 +92,31 @@ const (
GPS_TYPE_GARMIN = 0x06
*/
GPS_TYPE_UBX9 = 0x09
GPS_TYPE_UBX8 = 0x08
GPS_TYPE_UBX7 = 0x07
GPS_TYPE_UBX6 = 0x06
GPS_TYPE_PROLIFIC = 0x02
GPS_TYPE_UART = 0x01
GPS_TYPE_SERIAL = 0x0A
GPS_TYPE_OGNTRACKER = 0x03
GPS_TYPE_GXAIRCOM = 0x0F
GPS_TYPE_SOFTRF_DONGLE = 0x0B
GPS_TYPE_NETWORK = 0x0C
GPS_PROTOCOL_NMEA = 0x10
// other GPS types to be defined as needed
// for historical reasons lower nibbe contains gps type, upper nibble containsprotocol type.
// Additionally this enumeration has a javascript duplicte in web/plates/js/status.js, they have to be kept in sync manually
// This is somewhat ugly but difficult to change without breaking backward compatibility
// lower nibble gps type (dont forget to use only numbers form 0 to 15)
GPS_TYPE_ANY = 1 // Any generic GPS - no reconfiguring applied
GPS_TYPE_PROLIFIC = 2
GPS_TYPE_OGNTRACKER = 3
GPS_TYPE_UBX_GEN = 4
GPS_TYPE_UBX10 = 5
//GPS_TYPE_UBX6 = 6
GPS_TYPE_UBX6or7 = 7
GPS_TYPE_UBX8 = 8
GPS_TYPE_UBX9 = 9
GPS_TYPE_SERIAL = 10 // 0x0A
GPS_TYPE_SOFTRF_DONGLE = 11 // 0x0B
GPS_TYPE_NETWORK = 12 // 0x0C
GPS_TYPE_GXAIRCOM = 15 // 0x0F
// upper nibble is used for the protocol
GPS_PROTOCOL_NMEA = 0x10
)
var STRATUX_WWW_DIR = STRATUX_HOME + "www/"
@ -1171,6 +1182,7 @@ type settings struct {
TraceLog bool
AHRSLog bool
PersistentLogging bool
ClearLogOnStart bool
IMUMapping [2]int // Map from aircraft axis to sensor axis: accelerometer
SensorQuaternion [4]float64 // Quaternion mapping from sensor frame to aircraft frame
C, D [3]float64 // IMU Accel, Gyro zero bias
@ -1213,6 +1225,12 @@ type settings struct {
GXPilot string
PWMDutyMin int
// manual GPS config (versus autodetect)
GpsManualConfig bool
GpsManualDevice string // default: /dev/ttyAMA0
GpsManualChip string // ublox8, ublox9, ublox
GpsManualTargetBaud int // default: 115200
}
type status struct {
@ -1317,6 +1335,13 @@ func defaultSettings() {
globalSettings.PWMDutyMin = 0
globalSettings.OGNI2CTXEnabled = true
globalSettings.ClearLogOnStart = true
globalSettings.GpsManualConfig = false
globalSettings.GpsManualDevice = "/dev/ttyAMA0"
globalSettings.GpsManualTargetBaud = 115200
globalSettings.GpsManualChip = "ublox"
}
func readSettings() {
@ -1665,10 +1690,14 @@ func main() {
}
initLogging()
// Read settings.
readSettings()
// Clear the logfile on startup
if globalSettings.ClearLogOnStart { clearDebugLogFile() }
log.Printf("Stratux %s (%s) starting.\n", stratuxVersion, stratuxBuild)
if *writeNetworkConfig {
log.Printf("Only writing network settings...")

Wyświetl plik

@ -4,7 +4,9 @@
that can be found in the LICENSE file, herein included
as part of this header.
---
gps.go: GPS functions, GPS init, AHRS status messages, other external sensor monitoring.
compile and install: clear && make www && make gen_gdl90 && mv gen_gdl90 /opt/stratux/bin/ && stxrestart
*/
package main
@ -206,9 +208,21 @@ func makeNMEACmd(cmd string) []byte {
return []byte(fmt.Sprintf("$%s*%02x\x0d\x0a", cmd, chk_sum))
}
func logChipConfig(line1 string, chip string, device string, baudrate int, append string) {
if line1 == "auto" {
logInf("Gps - autodected gps, using following parameters:")
} else if line1 == "man" {
logInf("GPS - manual configuration with following parameters from /boot/stratux.conf:")
}
msg := "GPS - chip: %s, device: %s, baudrate: %d"
if(append != "") { msg += ", " + append}
logInf(msg, chip, device, baudrate)
}
func initGPSSerial() bool {
var device string
var targetBaudRate int = 115200
if (globalStatus.GPS_detected_type & 0x0f) == GPS_TYPE_NETWORK {
return true
}
@ -218,19 +232,64 @@ func initGPSSerial() bool {
ognTrackerConfigured = false;
globalStatus.GPS_detected_type = 0 // reset detected type on each initialization
if _, err := os.Stat("/dev/ublox9"); err == nil { // u-blox 8 (RY83xAI over USB).
if globalSettings.GpsManualConfig {
//logInf("GPS - manual configuration with parameters from /boot/stratux.conf:")
var chip string = globalSettings.GpsManualChip
device = globalSettings.GpsManualDevice
targetBaudRate = globalSettings.GpsManualTargetBaud
baudrates = []int{115200, 38400, 9600, 230400, 500000, 1000000, 2000000}
switch chip {
case "ublox6":
case "ublox7":
globalStatus.GPS_detected_type = GPS_TYPE_UBX6or7
logChipConfig("man", "ublox 6 or 7", device, targetBaudRate, "")
break;
case "ublox8":
globalStatus.GPS_detected_type = GPS_TYPE_UBX8
logChipConfig("man", "ublox 8", device, targetBaudRate, "")
break;
case "ublox9":
globalStatus.GPS_detected_type = GPS_TYPE_UBX9
logChipConfig("man", "ublox 9", device, targetBaudRate, "")
break;
case "ublox10":
globalStatus.GPS_detected_type = GPS_TYPE_UBX10
logChipConfig("man", "ublox 10", device, targetBaudRate, "")
break;
case "ublox":
globalStatus.GPS_detected_type = GPS_TYPE_UBX_GEN
logChipConfig("man", "generic ublox", device, targetBaudRate, "")
break;
default:
globalStatus.GPS_detected_type = GPS_TYPE_ANY
logInf("GPS - configuring gps chip as other -> no further configuration will be done, use gps as it is")
}
} else if _, err := os.Stat("/dev/ublox9"); err == nil {
device = "/dev/ublox9"
globalStatus.GPS_detected_type = GPS_TYPE_UBX9
} else if _, err := os.Stat("/dev/ublox8"); err == nil { // u-blox 8 (RY83xAI or GPYes 2.0).
logChipConfig("auto", "ublox 9", device, targetBaudRate, "")
} else if _, err := os.Stat("/dev/ublox8"); err == nil { // u-blox 8 (RY83xAI or GPYes 2.0).
device = "/dev/ublox8"
globalStatus.GPS_detected_type = GPS_TYPE_UBX8
gpsTimeOffsetPpsMs = 80 * time.Millisecond // Ublox 8 seems to have higher delay
} else if _, err := os.Stat("/dev/ublox7"); err == nil { // u-blox 7 (VK-172, VK-162 Rev 2, GPYes, RY725AI over USB).
gpsTimeOffsetPpsMs = 80 * time.Millisecond // Ublox 8 seems to have higher delay
logChipConfig("auto", "ublox 8", device, targetBaudRate, "")
} else if _, err := os.Stat("/dev/ublox7"); err == nil { // u-blox 7 (VK-172, VK-162 Rev 2, GPYes, RY725AI over USB).
device = "/dev/ublox7"
globalStatus.GPS_detected_type = GPS_TYPE_UBX7
} else if _, err := os.Stat("/dev/ublox6"); err == nil { // u-blox 6 (VK-162 Rev 1).
globalStatus.GPS_detected_type = GPS_TYPE_UBX6or7
logChipConfig("auto", "ublox 7", device, targetBaudRate, "")
} 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
globalStatus.GPS_detected_type = GPS_TYPE_UBX6or7
logChipConfig("auto", "ublox 6", device, targetBaudRate, "")
} 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
@ -248,19 +307,21 @@ func initGPSSerial() bool {
device = "/dev/softrf_dongle"
globalStatus.GPS_detected_type = GPS_TYPE_SOFTRF_DONGLE
baudrates[0] = 115200
} else if _, err := os.Stat("/dev/ttyAMA0"); err == nil { // ttyAMA0 is PL011 UART (GPIO pins 8 and 10) on all RPi.
} else if _, err := os.Stat("/dev/ttyAMA0"); err == nil {
// ttyAMA0 is PL011 UART (GPIO pins 8 and 10) on all RPi.
// assume that any GPS connected to serial GPIO is ublox
device = "/dev/ttyAMA0"
globalStatus.GPS_detected_type = GPS_TYPE_UART
globalStatus.GPS_detected_type = GPS_TYPE_UBX_GEN
baudrates = []int{115200, 38400, 9600}
logInf("GPS - device detected at serial port /dev/ttyAMA0, assuming this is an ublox device, configuring as generic ublox:")
logChipConfig("", "generic ublox", device, targetBaudRate, "")
logInf("GPS - consider to configure this device manually in /boot/stratux.conf for optimal performance")
} else {
if globalSettings.DEBUG {
log.Printf("No GPS device found.\n")
}
logDbg("GPS - no gps device found.\n")
return false
}
if globalSettings.DEBUG {
log.Printf("Using %s for GPS\n", device)
}
logDbg("GPS - using device: %s", device)
// try to open port with previously defined baud rate
// port remains opend if detectOpenSerialPort finds matching baurate parameter
@ -268,7 +329,7 @@ func initGPSSerial() bool {
p, err := detectOpenSerialPort(device, baudrates)
if err != nil {
log.Printf("serial port/baudrate detection err: %s\n", err.Error())
log.Printf("GPS - serial port/baudrate detection err: %s\n", err.Error())
return false
}
@ -293,9 +354,13 @@ func initGPSSerial() bool {
if globalSettings.DEBUG {
log.Printf("Finished writing SiRF GPS config to %s. Opening port to test connection.\n", device)
}
} else if globalStatus.GPS_detected_type == GPS_TYPE_UBX6 || globalStatus.GPS_detected_type == GPS_TYPE_UBX7 ||
globalStatus.GPS_detected_type == GPS_TYPE_UBX8 || globalStatus.GPS_detected_type == GPS_TYPE_UBX9 ||
globalStatus.GPS_detected_type == GPS_TYPE_UART {
} else if (
globalStatus.GPS_detected_type == GPS_TYPE_UBX6or7 ||
globalStatus.GPS_detected_type == GPS_TYPE_UBX8 ||
globalStatus.GPS_detected_type == GPS_TYPE_UBX9 ||
globalStatus.GPS_detected_type == GPS_TYPE_UBX10 ||
globalStatus.GPS_detected_type == GPS_TYPE_UBX_GEN ) {
// Byte order for UBX configuration is little endian.
@ -313,21 +378,15 @@ func initGPSSerial() bool {
//time.Sleep(100* time.Millisecond) // pause and wait for the GPS to finish configuring itself before closing / reopening the port
if globalStatus.GPS_detected_type == GPS_TYPE_UBX9 {
if globalSettings.DEBUG {
log.Printf("ublox 9 detected\n")
}
logDbg("GPS - configuring as ublox 9\n")
// ublox 9
writeUblox9ConfigCommands(p)
} else 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)
if globalSettings.DEBUG {
log.Printf("ublox 8 detected\n")
}
} else if (globalStatus.GPS_detected_type == GPS_TYPE_UBX8) {
logDbg("GPS - configuring as ublox 8\n")
// ublox 8
writeUblox8ConfigCommands(p)
} else if (globalStatus.GPS_detected_type == GPS_TYPE_UBX7) || (globalStatus.GPS_detected_type == GPS_TYPE_UBX6) {
if globalSettings.DEBUG {
log.Printf("ublox 6 or 7 detected\n")
}
} else if (globalStatus.GPS_detected_type == GPS_TYPE_UBX6or7) {
logDbg("GPS - configuring as ublox 6 or 7\n")
// ublox 6,7
cfgGnss := []byte{0x00, 0x00, 0xFF, 0x04} // numTrkChUse=0xFF: number of tracking channels to use will be set to number of tracking channels available in hardware
gps := []byte{0x00, 0x04, 0xFF, 0x00, 0x01, 0x00, 0x01, 0x01} // enable GPS with 4-255 channels (ublox default)
@ -360,7 +419,7 @@ func initGPSSerial() bool {
cfg[7] = 0x00
// Baud rate. Little endian order.
bdrt := uint32(115200)
bdrt := uint32(targetBaudRate)
cfg[11] = byte((bdrt >> 24) & 0xFF)
cfg[10] = byte((bdrt >> 16) & 0xFF)
cfg[9] = byte((bdrt >> 8) & 0xFF)
@ -384,12 +443,9 @@ func initGPSSerial() bool {
p.Write(makeUBXCFG(0x06, 0x00, 20, cfg))
// time.Sleep(100* time.Millisecond) // pause and wait for the GPS to finish configuring itself before closing / reopening the port
baudrates[0] = int(bdrt)
if globalSettings.DEBUG {
log.Printf("Finished writing u-blox GPS config to %s. Opening port to test connection.\n", device)
}
//baudrates[0] = int(bdrt) // replaced by line below -> insert at pos 0 instead of overwriting ...
baudrates = append([]int{targetBaudRate}, baudrates...)
logDbg("GPS - finished writing u-blox GPS config to %s. Opening port to test connection.\n", device)
} else if globalStatus.GPS_detected_type == GPS_TYPE_SOFTRF_DONGLE {
p.Write([]byte("@GNS 0x7\r\n")) // enable SBAS
p.Flush()
@ -407,7 +463,7 @@ func initGPSSerial() bool {
p, err = detectOpenSerialPort(device, baudrates)
if err != nil {
log.Printf("serial port err: %s\n", err.Error())
logErr("GPS - serial port err: %s\n", err.Error())
return false
}
@ -422,6 +478,7 @@ func detectOpenSerialPort(device string, baudrates []int) (*(serial.Port), error
return serial.OpenPort(serialConfig)
} else {
for _, baud := range baudrates {
logDbg("GPS - trying to open serial with %d baud ...", baud)
serialConfig := &serial.Config{Name: device, Baud: baud, ReadTimeout: time.Millisecond * 2500}
p, err := serial.OpenPort(serialConfig)
if err != nil {
@ -436,17 +493,19 @@ func detectOpenSerialPort(device string, baudrates []int) (*(serial.Port), error
_, validNMEAcs := validateNMEAChecksum(line)
if validNMEAcs {
// looks a lot like NMEA.. use it
log.Printf("Detected serial port %s with baud %d", device, baud)
logInf("GPS - successfully opened serial port %s with baud %d (Valid NMEA msg received)", device, baud)
// Make sure the NMEA is immediately parsed once, so updateStatus() doesn't see the GPS as disconnected before
// first msg arrives
processNMEALine(line)
return p, nil
}
}
logDbg("GPS - could not open serial port with %d baud, no valid NMea received ...", baud)
p.Close()
time.Sleep(250 * time.Millisecond)
}
return nil, errors.New("Failed to detect GPS serial baud rate")
logErr("GPS - none of the baud rates worked, gps not connected ...")
return nil, errors.New("GPS - Failed to detect gps serial baud rate")
}
}
@ -550,7 +609,7 @@ func writeUbloxGenericCommands(navrate uint16, p *serial.Port) {
p.Write(makeUBXCFG(0x06, 0x08, 6, []byte{0xE8, 0x03, 0x01, 0x00, 0x01, 0x00})) // 1000ms & 1 cycle -> 1Hz (UBX-CFG-RATE payload bytes: little endian!)
}
logDbg("GPS - applying generic ublox settings (refresh rate: %d)" , navrate)
}
@ -1032,15 +1091,11 @@ func calculateNavRate() float64 {
var halfwidth float64
dt_avg, valid := common.Mean(tempSpeedTime)
if valid && dt_avg > 0 {
if globalSettings.DEBUG {
log.Printf("GPS attitude: Average delta time is %.2f s (%.1f Hz)\n", dt_avg, 1/dt_avg)
}
logDbg("GPS attitude: Average delta time is %.2f s (%.1f Hz)\n", dt_avg, 1/dt_avg)
halfwidth = 9 * dt_avg
mySituation.GPSPositionSampleRate = 1 / dt_avg
} else {
if globalSettings.DEBUG {
log.Printf("GPS attitude: Couldn't determine sample rate\n")
}
// logDbg("GPS attitude: Couldn't determine sample rate\n")
halfwidth = 3.5
mySituation.GPSPositionSampleRate = 0
}
@ -1493,13 +1548,13 @@ func processNMEALineLow(l string, fakeGpsTimeToCurr bool) (sentenceUsed bool) {
return false
}
if tmpSituation.GPSFixQuality == 2 { // Rough 95% confidence estimate for SBAS solution
if globalStatus.GPS_detected_type == GPS_TYPE_UBX9 {
if globalStatus.GPS_detected_type == GPS_TYPE_UBX9 || globalStatus.GPS_detected_type == GPS_TYPE_UBX10 {
tmpSituation.GPSHorizontalAccuracy = float32(hdop * 3.0) // ublox 9
} else {
tmpSituation.GPSHorizontalAccuracy = float32(hdop * 4.0) // ublox 6/7/8
}
} else { // Rough 95% confidence estimate non-SBAS solution
if globalStatus.GPS_detected_type == GPS_TYPE_UBX9 {
if globalStatus.GPS_detected_type == GPS_TYPE_UBX9 || globalStatus.GPS_detected_type == GPS_TYPE_UBX10 {
tmpSituation.GPSHorizontalAccuracy = float32(hdop * 4.0) // ublox 9
} else {
tmpSituation.GPSHorizontalAccuracy = float32(hdop * 5.0) // ublox 6/7/8
@ -1556,9 +1611,7 @@ func processNMEALineLow(l string, fakeGpsTimeToCurr bool) (sentenceUsed bool) {
lenGSV := len(x)
satsThisMsg := (lenGSV - 4) / 4
if globalSettings.DEBUG {
log.Printf("%s message [%d of %d] is %v fields long and describes %v satellites\n", x[0], msgIndex, msgNum, lenGSV, satsThisMsg)
}
logDbg("%s message [%d of %d] is %v fields long and describes %v satellites\n", x[0], msgIndex, msgNum, lenGSV, satsThisMsg)
var sv, elev, az, cno int
var svType uint8
@ -1653,8 +1706,9 @@ func processNMEALineLow(l string, fakeGpsTimeToCurr bool) (sentenceUsed bool) {
}
}
if globalSettings.DEBUG {
inSolnStr := " "
inSolnStr := " "
if thisSatellite.InSolution {
inSolnStr = "+"
}
@ -2182,9 +2236,7 @@ func gpsAttitudeSender() {
<-timer.C
if !isGPSValid() || !calcGPSAttitude() {
if globalSettings.DEBUG {
log.Printf("Couldn't calculate GPS-based attitude statistics\n")
}
logDbg("Couldn't calculate GPS-based attitude statistics\n")
} else {
mySituation.muGPSPerformance.Lock()
index := len(myGPSPerfStats) - 1
@ -2309,3 +2361,7 @@ func initGPS(isReplayMode bool) {
go pollGPS()
}
}

Wyświetl plik

@ -163,4 +163,18 @@ func openLogFile() {
func initLogging() {
openLogFile()
go logFileWatcher();
}
// Log allways
func logInf(msg string, args ... any) { log.Printf(msg, args...) }
// Log on error (no special proccessing right now)
func logErr(msg string, args ... any) { log.Printf(msg, args...) }
// Log if debug enabled ("verbose message log" in settings tab)
func logDbg(msg string, args ... any) {
if globalSettings.DEBUG {
log.Printf(msg, args...)
}
}

Wyświetl plik

@ -86,8 +86,9 @@ function StatusCtrl($rootScope, $scope, $state, $http, $interval, craftService)
var gpsHardwareCode = (status.GPS_detected_type & 0x0f);
var tempGpsHardwareString = "Not installed";
switch(gpsHardwareCode) {
// Keep in mind that this must be in sync with the enumeration in gen_gdl90.go
case 1:
tempGpsHardwareString = "Serial port";
tempGpsHardwareString = "Generic GPS device";
break;
case 2:
tempGpsHardwareString = "Prolific USB-serial bridge";
@ -95,20 +96,23 @@ function StatusCtrl($rootScope, $scope, $state, $http, $interval, craftService)
case 3:
tempGpsHardwareString = "OGN Tracker";
break;
case 6:
tempGpsHardwareString = "USB u-blox 6 GPS receiver";
case 4:
tempGpsHardwareString = "generic u-blox device";
break;
case 5:
tempGpsHardwareString = "u-blox 10 GNSS receiver";
break;
case 7:
tempGpsHardwareString = "USB u-blox 7 GNSS receiver";
tempGpsHardwareString = "u-blox 6 or 7 GNSS receiver";
break;
case 8:
tempGpsHardwareString = "USB u-blox 8 GNSS receiver";
tempGpsHardwareString = "u-blox 8 GNSS receiver";
break;
case 9:
tempGpsHardwareString = "USB u-blox 9 GNSS receiver";
tempGpsHardwareString = "u-blox 9 GNSS receiver";
break;
case 10:
tempGpsHardwareString = "USB Serial IN";
tempGpsHardwareString = "USB/Serial IN";
break;
case 11:
tempGpsHardwareString = "SoftRF Dongle";