mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-02-27 02:04:00 -04:00
LogAnalyzer - Improve Autotune Test
- previously version could report failed autotune sessions as valid and valid sessions as failed
This commit is contained in:
parent
c2030de4ec
commit
789fd06192
@ -1,10 +1,51 @@
|
|||||||
from LogAnalyzer import Test,TestResult
|
from LogAnalyzer import Test,TestResult
|
||||||
import DataflashLog
|
import DataflashLog
|
||||||
|
|
||||||
|
# from ArduCopter/defines.h
|
||||||
|
AUTOTUNE_INITIALISED = 30
|
||||||
|
AUTOTUNE_OFF = 31
|
||||||
|
AUTOTUNE_RESTART = 32
|
||||||
|
AUTOTUNE_SUCCESS = 33
|
||||||
|
AUTOTUNE_FAILED = 34
|
||||||
|
AUTOTUNE_REACHED_LIMIT = 35
|
||||||
|
AUTOTUNE_PILOT_TESTING = 36
|
||||||
|
AUTOTUNE_SAVEDGAINS = 37
|
||||||
|
|
||||||
|
AUTOTUNE_EVENTS = frozenset([AUTOTUNE_INITIALISED,
|
||||||
|
AUTOTUNE_OFF,
|
||||||
|
AUTOTUNE_RESTART,
|
||||||
|
AUTOTUNE_SUCCESS,
|
||||||
|
AUTOTUNE_FAILED,
|
||||||
|
AUTOTUNE_REACHED_LIMIT,
|
||||||
|
AUTOTUNE_PILOT_TESTING,
|
||||||
|
AUTOTUNE_SAVEDGAINS])
|
||||||
|
|
||||||
class TestAutotune(Test):
|
class TestAutotune(Test):
|
||||||
'''test for autotune success (copter only)'''
|
'''test for autotune success (copter only)'''
|
||||||
|
|
||||||
|
class AutotuneSession(object):
|
||||||
|
def __init__(self, events):
|
||||||
|
self.events = events
|
||||||
|
@property
|
||||||
|
def linestart(self):
|
||||||
|
return self.events[0][0]
|
||||||
|
@property
|
||||||
|
def linestop(self):
|
||||||
|
return self.events[-1][0]
|
||||||
|
@property
|
||||||
|
def success(self):
|
||||||
|
return AUTOTUNE_SUCCESS in [i for _,i in self.events]
|
||||||
|
@property
|
||||||
|
def failure(self):
|
||||||
|
return AUTOTUNE_FAILED in [i for _,i in self.events]
|
||||||
|
@property
|
||||||
|
def limit(self):
|
||||||
|
return AUTOTUNE_REACHED_LIMIT in [i for _,i in self.events]
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<AutotuneSession {}-{}>".format(self.linestart,self.linestop)
|
||||||
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Test.__init__(self)
|
Test.__init__(self)
|
||||||
self.name = "Autotune"
|
self.name = "Autotune"
|
||||||
@ -26,27 +67,22 @@ class TestAutotune(Test):
|
|||||||
if r:
|
if r:
|
||||||
return
|
return
|
||||||
|
|
||||||
for line,ev in logdata.channels["EV"]["Id"].listData:
|
events = filter(lambda x: x[1] in AUTOTUNE_EVENTS, logdata.channels["EV"]["Id"].listData)
|
||||||
if ev != 30: # Autotune Start
|
attempts = []
|
||||||
continue
|
|
||||||
nextline = startline = line
|
|
||||||
nextev = -1
|
|
||||||
while nextev not in(35,34):
|
|
||||||
try:
|
|
||||||
(nextev,nextline) = logdata.channels["EV"]["Id"].getNearestValueFwd(nextline+1)
|
|
||||||
except:
|
|
||||||
break
|
|
||||||
|
|
||||||
if nextev not in(35,34): # autotune is still running
|
j = None
|
||||||
continue
|
for i in range(0,len(events)):
|
||||||
|
line,ev = events[i]
|
||||||
|
if ev == AUTOTUNE_INITIALISED:
|
||||||
|
if j is not None:
|
||||||
|
attempts.append(TestAutotune.AutotuneSession(events[j:i]))
|
||||||
|
j = i
|
||||||
|
|
||||||
if nextev == 34: # autotune failed
|
# last attempt
|
||||||
self.result.status = TestResult.StatusType.FAIL
|
if j is not None:
|
||||||
s = "[-]"
|
attempts.append(TestAutotune.AutotuneSession(events[j:]))
|
||||||
else:
|
|
||||||
self.result.status = TestResult.StatusType.GOOD
|
|
||||||
s = "[+]"
|
|
||||||
|
|
||||||
|
for a in attempts:
|
||||||
# this should not be necessary!
|
# this should not be necessary!
|
||||||
def class_from_channel(c):
|
def class_from_channel(c):
|
||||||
members = dict({'__init__':lambda x: setattr(x,i,None) for i in logdata.channels[c]})
|
members = dict({'__init__':lambda x: setattr(x,i,None) for i in logdata.channels[c]})
|
||||||
@ -57,18 +93,33 @@ class TestAutotune(Test):
|
|||||||
)
|
)
|
||||||
return cls
|
return cls
|
||||||
|
|
||||||
atde = class_from_channel('ATDE')()
|
# last wins
|
||||||
for key in logdata.channels['ATDE']:
|
if a.success:
|
||||||
setattr(atde, key, logdata.channels['ATDE'][key].getNearestValueBack(nextline)[0])
|
self.result.status = TestResult.StatusType.GOOD
|
||||||
|
s = "[+]"
|
||||||
atun = class_from_channel('ATUN')()
|
elif a.failure:
|
||||||
for key in logdata.channels['ATUN']:
|
self.result.status = TestResult.StatusType.FAIL
|
||||||
setattr(atun, key, logdata.channels['ATUN'][key].getNearestValueBack(nextline)[0])
|
s = "[-]"
|
||||||
self.result.statusMessage += '{s} ATDE Angle:{atde.Angle} Rate:{atde.Rate} ATUN RPGain:{atun.RPGain} RDGain:{atun.RDGain} SPGain:{atun.SPGain} (@line:{l})\n'.format(l=nextline,s=s,atde=atde, atun=atun)
|
else:
|
||||||
|
self.result.status = TestResult.StatusType.UNKNOWN
|
||||||
if nextev not in(35,34):
|
s = "[?]"
|
||||||
self.result.statusMessage += "incomplete autotune attempt started @{l}\n".format(l=startline)
|
|
||||||
|
|
||||||
|
|
||||||
|
s += " Autotune {}-{}\n".format(a.linestart,a.linestop)
|
||||||
|
self.result.statusMessage += s
|
||||||
|
|
||||||
|
if verbose:
|
||||||
|
linenext = a.linestart + 1
|
||||||
|
while linenext < a.linestop:
|
||||||
|
try:
|
||||||
|
line = logdata.channels['ATUN']['RateMax'].getNearestValueFwd(linenext)[1]
|
||||||
|
if line > a.linestop:
|
||||||
|
break
|
||||||
|
except:
|
||||||
|
break
|
||||||
|
atun = class_from_channel('ATUN')()
|
||||||
|
for key in logdata.channels['ATUN']:
|
||||||
|
setattr(atun, key, logdata.channels['ATUN'][key].getNearestValueFwd(linenext)[0])
|
||||||
|
linenext = logdata.channels['ATUN'][key].getNearestValueFwd(linenext)[1] + 1
|
||||||
|
self.result.statusMessage += 'ATUN Axis:{atun.Axis} TuneStep:{atun.TuneStep} RateMin:{atun.RateMin:5.0f} RateMax:{atun.RateMax:5.0f} RPGain:{atun.RPGain:1.4f} RDGain:{atun.RDGain:1.4f} SPGain:{atun.SPGain:1.1f} (@line:{l})\n'.format(l=linenext,s=s, atun=atun)
|
||||||
|
self.result.statusMessage += '\n'
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user