LogAnalyzer: changed command flags a little, tidy, started on TestPitchRollCoupling

This commit is contained in:
Andrew Chapman 2014-02-02 21:21:30 -08:00 committed by Andrew Tridgell
parent e0ada31872
commit 5aa1e6a2dd
3 changed files with 54 additions and 9 deletions

View File

@ -201,17 +201,17 @@ def main():
parser = argparse.ArgumentParser(description='Analyze an APM Dataflash log for known issues')
parser.add_argument('logfile', type=argparse.FileType('r'), help='path to Dataflash log file')
parser.add_argument('-q', '--quiet', metavar='', action='store_const', const=True, help='quiet mode, do not print results')
parser.add_argument('-s', '--stats', metavar='', action='store_const', const=True, help='output performance stats')
parser.add_argument('-i', '--ignore', metavar='', action='store_const', const=True, help='ignore bad data lines')
parser.add_argument('-p', '--profile', metavar='', action='store_const', const=True, help='output performance profiling data')
parser.add_argument('-s', '--skip_bad', metavar='', action='store_const', const=True, help='skip over corrupt dataflash lines')
parser.add_argument('-e', '--empty', metavar='', action='store_const', const=True, help='run an initial check for an empty log')
parser.add_argument('-x', '--xml', type=str, metavar='XML file', nargs='?', const='', default='', help='write output to specified XML file')
args = parser.parse_args()
# load the log
startTime = time.time()
logdata = DataflashLog.DataflashLog(args.logfile.name, ignoreBadlines=args.ignore) # read log
logdata = DataflashLog.DataflashLog(args.logfile.name, ignoreBadlines=args.skip_bad) # read log
endTime = time.time()
if args.stats:
if args.profile:
print "Log file read time: %.2f seconds" % (endTime-startTime)
# check for empty log if requested
@ -226,12 +226,12 @@ def main():
startTime = time.time()
testSuite.run(logdata) # run tests
endTime = time.time()
if args.stats:
if args.profile:
print "Test suite run time: %.2f seconds" % (endTime-startTime)
# deal with output
if not args.quiet:
testSuite.outputPlainText(args.stats)
testSuite.outputPlainText(args.profile)
if args.xml:
testSuite.outputXML(args.xml)
if not args.quiet:

View File

@ -10,24 +10,25 @@ class TestParams(Test):
def __init__(self):
self.name = "Parameters"
# helper functions
def __checkParamIsEqual(self, paramName, expectedValue, logdata):
value = logdata.parameters[paramName]
if value != expectedValue:
self.result.status = TestResult.StatusType.FAIL
self.result.extraFeedback = self.result.extraFeedback + "%s set to %s, expecting %s\n" % (paramName, `value`, `expectedValue`)
def __checkParamIsLessThan(self, paramName, maxValue, logdata):
value = logdata.parameters[paramName]
if value >= maxValue:
self.result.status = TestResult.StatusType.FAIL
self.result.extraFeedback = self.result.extraFeedback + "%s set to %s, expecting less than %s\n" % (paramName, `value`, `maxValue`)
def __checkParamIsMoreThan(self, paramName, minValue, logdata):
value = logdata.parameters[paramName]
if value <= minValue:
self.result.status = TestResult.StatusType.FAIL
self.result.extraFeedback = self.result.extraFeedback + "%s set to %s, expecting less than %s\n" % (paramName, `value`, `minValue`)
def run(self, logdata):
self.result = TestResult()
self.result.status = TestResult.StatusType.PASS # PASS by default, tests below will override it if they fail

View File

@ -15,4 +15,48 @@ class TestPitchRollCoupling(Test):
# TODO: implement pitch/roll input/output divergence testing -
# note: names changed from PitchIn to DesPitch at some point, check for both
# what to test for?
# - only analyse while we're airborne
# - absolute diff between in+out?
# - accumulated diff between in+out?
# - slope diff between in+out curves?
# - roll/pitch over max in non-acro modes?
# - if direct control use CTUN roll+pitch, if auto mode use NTUN data
# figure out where each mode begins and ends, so we can treat auto and manual modes differently
# TODO: fill in all known modes here
autoModes = ["RTL","AUTO","LAND","LOITER"] # use NTUN DRol+DPit
manualModes = ["STABILIZE","DRIFT","ALT_HOLD"] # use CTUN RollIn/DesRoll + PitchIn/DesPitch
acroModes = ["ACRO","SPORT"] # ignore data from acro modes
autoSegments = [] # list of (startLine,endLine) pairs
manualSegments = [] # list of (startLine,endLine) pairs
orderedModes = collections.OrderedDict(sorted(logdata.modeChanges.items(), key=lambda t: t[0]))
isAuto = False # always start in a manual control mode
prevLine = 1
for line,modepair in orderedModes.iteritems():
mode = modepair[0].upper()
if mode in autoModes:
print "On line %d mode changed to %s (AUTO)" % (line,mode)
if not isAuto:
manualSegments.append((prevLine,line-1))
print " Previous manual segment: " + `(prevLine,line-1)`
isAuto = True
elif mode in manualModes:
print "On line %d mode changed to %s (MANUAL)" % (line,mode)
if isAuto:
autoSegments.append((prevLine,line-1))
print " Previous auto segment: " + `(prevLine,line-1)`
isAuto = False
elif mode in acroModes:
pass
else:
raise Exception("Unknown mode: %s" % mode)
prevLine = line
if isAuto:
autoSegments.append((prevLine,logdata.lineCount))
print " Previous auto segment: " + `(prevLine,logdata.lineCount)`
else:
manualSegments.append((prevLine,logdata.lineCount))
print " Previous manual segment: " + `(prevLine,logdata.lineCount)`