2022-07-18 10:52:56 -03:00
|
|
|
# AP_FLAKE8_CLEAN
|
|
|
|
|
2022-07-18 11:09:04 -03:00
|
|
|
from LogAnalyzer import Test, TestResult
|
2017-09-29 02:21:28 -03:00
|
|
|
from VehicleType import VehicleType
|
2014-07-04 10:43:24 -03:00
|
|
|
|
2014-07-27 12:25:32 -03:00
|
|
|
# from ArduCopter/defines.h
|
2022-07-18 11:09:04 -03:00
|
|
|
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,
|
|
|
|
]
|
|
|
|
)
|
|
|
|
|
2014-07-04 10:43:24 -03:00
|
|
|
|
|
|
|
class TestAutotune(Test):
|
|
|
|
'''test for autotune success (copter only)'''
|
|
|
|
|
2014-07-27 12:25:32 -03:00
|
|
|
class AutotuneSession(object):
|
|
|
|
def __init__(self, events):
|
|
|
|
self.events = events
|
2022-07-18 11:09:04 -03:00
|
|
|
|
2014-07-27 12:25:32 -03:00
|
|
|
@property
|
|
|
|
def linestart(self):
|
|
|
|
return self.events[0][0]
|
2022-07-18 11:09:04 -03:00
|
|
|
|
2014-07-27 12:25:32 -03:00
|
|
|
@property
|
|
|
|
def linestop(self):
|
|
|
|
return self.events[-1][0]
|
2022-07-18 11:09:04 -03:00
|
|
|
|
2014-07-27 12:25:32 -03:00
|
|
|
@property
|
|
|
|
def success(self):
|
2022-07-18 11:09:04 -03:00
|
|
|
return AUTOTUNE_SUCCESS in [i for _, i in self.events]
|
|
|
|
|
2014-07-27 12:25:32 -03:00
|
|
|
@property
|
|
|
|
def failure(self):
|
2022-07-18 11:09:04 -03:00
|
|
|
return AUTOTUNE_FAILED in [i for _, i in self.events]
|
|
|
|
|
2014-07-27 12:25:32 -03:00
|
|
|
@property
|
|
|
|
def limit(self):
|
2022-07-18 11:09:04 -03:00
|
|
|
return AUTOTUNE_REACHED_LIMIT in [i for _, i in self.events]
|
2014-07-27 12:25:32 -03:00
|
|
|
|
|
|
|
def __repr__(self):
|
2022-07-18 11:09:04 -03:00
|
|
|
return "<AutotuneSession {}-{}>".format(self.linestart, self.linestop)
|
2014-07-27 12:25:32 -03:00
|
|
|
|
2014-07-04 10:43:24 -03:00
|
|
|
def __init__(self):
|
2014-07-08 17:49:42 -03:00
|
|
|
Test.__init__(self)
|
2014-07-04 10:43:24 -03:00
|
|
|
self.name = "Autotune"
|
|
|
|
|
|
|
|
def run(self, logdata, verbose):
|
|
|
|
self.result = TestResult()
|
|
|
|
self.result.status = TestResult.StatusType.GOOD
|
|
|
|
|
2017-09-23 22:51:51 -03:00
|
|
|
if logdata.vehicleType != VehicleType.Copter:
|
2014-07-04 10:43:24 -03:00
|
|
|
self.result.status = TestResult.StatusType.NA
|
|
|
|
return
|
|
|
|
|
2022-07-18 11:09:04 -03:00
|
|
|
for i in ['EV', 'ATDE', 'ATUN']:
|
2014-07-04 10:43:24 -03:00
|
|
|
r = False
|
2022-07-18 10:52:56 -03:00
|
|
|
if i not in logdata.channels:
|
2014-07-04 10:43:24 -03:00
|
|
|
self.result.status = TestResult.StatusType.UNKNOWN
|
|
|
|
self.result.statusMessage = "No {} log data".format(i)
|
|
|
|
r = True
|
|
|
|
if r:
|
|
|
|
return
|
|
|
|
|
2020-07-16 20:22:10 -03:00
|
|
|
events = list(filter(lambda x: x[1] in AUTOTUNE_EVENTS, logdata.channels["EV"]["Id"].listData))
|
2014-07-27 12:25:32 -03:00
|
|
|
attempts = []
|
|
|
|
|
|
|
|
j = None
|
2022-07-18 11:09:04 -03:00
|
|
|
for i in range(0, len(events)):
|
|
|
|
line, ev = events[i]
|
2014-07-27 12:25:32 -03:00
|
|
|
if ev == AUTOTUNE_INITIALISED:
|
|
|
|
if j is not None:
|
|
|
|
attempts.append(TestAutotune.AutotuneSession(events[j:i]))
|
|
|
|
j = i
|
2014-07-04 10:43:24 -03:00
|
|
|
|
2014-07-27 12:25:32 -03:00
|
|
|
# last attempt
|
|
|
|
if j is not None:
|
|
|
|
attempts.append(TestAutotune.AutotuneSession(events[j:]))
|
|
|
|
|
|
|
|
for a in attempts:
|
2022-07-18 11:09:04 -03:00
|
|
|
# this should not be necessary!
|
|
|
|
def class_from_channel(c):
|
|
|
|
members = dict({'__init__': lambda x: setattr(x, i, None) for i in logdata.channels[c]})
|
|
|
|
cls = type('Channel__{:s}'.format(c), (object,), members)
|
|
|
|
return cls
|
|
|
|
|
|
|
|
# last wins
|
|
|
|
if a.success:
|
|
|
|
self.result.status = TestResult.StatusType.GOOD
|
|
|
|
s = "[+]"
|
|
|
|
elif a.failure:
|
|
|
|
self.result.status = TestResult.StatusType.FAIL
|
|
|
|
s = "[-]"
|
|
|
|
else:
|
|
|
|
self.result.status = TestResult.StatusType.UNKNOWN
|
|
|
|
s = "[?]"
|
|
|
|
|
|
|
|
s += " Autotune {}-{}\n".format(a.linestart, a.linestop)
|
|
|
|
self.result.statusMessage += s
|
2014-07-04 10:43:24 -03:00
|
|
|
|
2022-07-18 11:09:04 -03:00
|
|
|
if verbose:
|
|
|
|
linenext = a.linestart + 1
|
|
|
|
while linenext < a.linestop:
|
|
|
|
try:
|
|
|
|
line = logdata.channels['ATUN']['RateMax'].getNearestValueFwd(linenext)[1]
|
|
|
|
if line > a.linestop:
|
|
|
|
break
|
2022-07-11 09:30:25 -03:00
|
|
|
except ValueError:
|
2022-07-18 11:09:04 -03:00
|
|
|
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
|
2022-07-18 10:52:56 -03:00
|
|
|
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, atun=atun)
|
2022-07-18 11:09:04 -03:00
|
|
|
self.result.statusMessage += '\n'
|