2022-07-18 10:52:56 -03:00
|
|
|
# AP_FLAKE8_CLEAN
|
|
|
|
|
|
|
|
|
2017-09-27 22:44:54 -03:00
|
|
|
from LogAnalyzer import Test, TestResult
|
2014-01-27 02:38:57 -04:00
|
|
|
|
|
|
|
|
|
|
|
class TestGPSGlitch(Test):
|
2017-09-27 22:34:40 -03:00
|
|
|
'''test for GPS glitch reporting or bad GPS data (satellite count, hdop)'''
|
2014-01-27 02:38:57 -04:00
|
|
|
|
2017-09-27 22:34:40 -03:00
|
|
|
def __init__(self):
|
|
|
|
Test.__init__(self)
|
|
|
|
self.name = "GPS"
|
2014-01-27 02:38:57 -04:00
|
|
|
|
2017-09-27 22:34:40 -03:00
|
|
|
def findSatsChan(self, channels):
|
2017-09-27 22:44:54 -03:00
|
|
|
for chan in "NSats", "NSat", "numSV":
|
2017-09-27 22:34:40 -03:00
|
|
|
if chan in channels:
|
|
|
|
return channels[chan]
|
2015-09-09 00:10:36 -03:00
|
|
|
|
2017-09-27 22:34:40 -03:00
|
|
|
def findHDopChan(self, channels):
|
2017-09-27 22:44:54 -03:00
|
|
|
for chan in "HDop", "HDp", "EPH":
|
2017-09-27 22:34:40 -03:00
|
|
|
if chan in channels:
|
|
|
|
return channels[chan]
|
2015-09-09 00:10:36 -03:00
|
|
|
|
2017-09-27 22:34:40 -03:00
|
|
|
def run(self, logdata, verbose):
|
|
|
|
self.result = TestResult()
|
|
|
|
self.result.status = TestResult.StatusType.GOOD
|
2014-01-30 05:33:25 -04:00
|
|
|
|
2017-09-27 22:34:40 -03:00
|
|
|
if "GPS" not in logdata.channels:
|
|
|
|
self.result.status = TestResult.StatusType.UNKNOWN
|
|
|
|
self.result.statusMessage = "No GPS log data"
|
|
|
|
return
|
2014-01-30 05:33:25 -04:00
|
|
|
|
2017-09-27 22:44:54 -03:00
|
|
|
# glitch protection is currently copter-only, but might be
|
|
|
|
# added to other vehicle types later and there's no harm in
|
|
|
|
# leaving the test in for all
|
2017-09-27 22:34:40 -03:00
|
|
|
gpsGlitchCount = 0
|
|
|
|
if "ERR" in logdata.channels:
|
2022-07-18 11:09:04 -03:00
|
|
|
assert len(logdata.channels["ERR"]["Subsys"].listData) == len(logdata.channels["ERR"]["ECode"].listData)
|
2017-09-27 22:34:40 -03:00
|
|
|
for i in range(len(logdata.channels["ERR"]["Subsys"].listData)):
|
|
|
|
subSys = logdata.channels["ERR"]["Subsys"].listData[i][1]
|
2017-09-27 22:44:54 -03:00
|
|
|
eCode = logdata.channels["ERR"]["ECode"].listData[i][1]
|
2017-09-27 22:34:40 -03:00
|
|
|
if subSys == 11 and (eCode == 2):
|
|
|
|
gpsGlitchCount += 1
|
|
|
|
if gpsGlitchCount:
|
|
|
|
self.result.status = TestResult.StatusType.FAIL
|
2022-07-18 11:09:04 -03:00
|
|
|
self.result.statusMessage = "GPS glitch errors found (%d)" % gpsGlitchCount
|
2014-02-26 08:50:55 -04:00
|
|
|
|
2017-09-27 22:44:54 -03:00
|
|
|
# define and check different thresholds for WARN level and
|
|
|
|
# FAIL level
|
|
|
|
# TODO: for plane, only check after first instance of throttle
|
|
|
|
# > 0, or after takeoff if we can reliably detect it
|
2017-09-27 22:34:40 -03:00
|
|
|
minSatsWARN = 6
|
|
|
|
minSatsFAIL = 5
|
|
|
|
maxHDopWARN = 3.0
|
|
|
|
maxHDopFAIL = 10.0
|
|
|
|
satsChan = self.findSatsChan(logdata.channels["GPS"])
|
|
|
|
hdopChan = self.findHDopChan(logdata.channels["GPS"])
|
|
|
|
foundBadSatsWarn = satsChan.min() < minSatsWARN
|
2017-09-27 22:44:54 -03:00
|
|
|
foundBadHDopWarn = hdopChan.max() > maxHDopWARN
|
2017-09-27 22:34:40 -03:00
|
|
|
foundBadSatsFail = satsChan.min() < minSatsFAIL
|
2017-09-27 22:44:54 -03:00
|
|
|
foundBadHDopFail = hdopChan.max() > maxHDopFAIL
|
2022-07-18 11:09:04 -03:00
|
|
|
satsMsg = "Min satellites: %s, Max HDop: %s" % (satsChan.min(), hdopChan.max())
|
2017-09-27 22:34:40 -03:00
|
|
|
if gpsGlitchCount:
|
2022-07-18 11:09:04 -03:00
|
|
|
self.result.statusMessage = "\n".join([self.result.statusMessage, satsMsg])
|
2017-09-27 22:34:40 -03:00
|
|
|
if foundBadSatsFail or foundBadHDopFail:
|
|
|
|
if not gpsGlitchCount:
|
|
|
|
self.result.status = TestResult.StatusType.FAIL
|
|
|
|
self.result.statusMessage = satsMsg
|
|
|
|
elif foundBadSatsWarn or foundBadHDopWarn:
|
|
|
|
if not gpsGlitchCount:
|
|
|
|
self.result.status = TestResult.StatusType.WARN
|
|
|
|
self.result.statusMessage = satsMsg
|