2014-01-27 02:38:57 -04:00
from LogAnalyzer import Test , TestResult
import DataflashLog
2014-06-15 18:40:09 -03:00
class TestThrust ( Test ) :
2014-08-12 12:54:15 -03:00
''' test for sufficient thrust (copter only for now) '''
2014-01-27 02:38:57 -04:00
2014-08-12 12:54:15 -03:00
def __init__ ( self ) :
Test . __init__ ( self )
self . name = " Thrust "
def run ( self , logdata , verbose ) :
self . result = TestResult ( )
self . result . status = TestResult . StatusType . GOOD
2014-01-27 02:38:57 -04:00
2014-08-12 12:54:15 -03:00
if logdata . vehicleType != " ArduCopter " :
self . result . status = TestResult . StatusType . NA
return
2014-01-27 02:38:57 -04:00
2014-08-12 12:54:15 -03:00
if not " CTUN " in logdata . channels :
self . result . status = TestResult . StatusType . UNKNOWN
self . result . statusMessage = " No CTUN log data "
return
if not " ATT " in logdata . channels :
self . result . status = TestResult . StatusType . UNKNOWN
self . result . statusMessage = " No ATT log data "
return
2014-02-22 15:36:30 -04:00
2014-08-12 12:54:15 -03:00
# check for throttle (CTUN.ThrOut) above 700 for a chunk of time with copter not rising
2014-02-22 15:36:30 -04:00
2014-08-12 12:54:15 -03:00
highThrottleThreshold = 700
tiltThreshold = 20 # ignore high throttle when roll or tilt is above this value
climbThresholdWARN = 100
climbThresholdFAIL = 50
minSampleLength = 50
2014-02-22 15:36:30 -04:00
2014-08-12 12:54:15 -03:00
highThrottleSegments = [ ]
2014-02-22 15:36:30 -04:00
2014-08-12 12:54:15 -03:00
# find any contiguous chunks where CTUN.ThrOut > highThrottleThreshold, ignore high throttle if tilt > tiltThreshold, and discard any segments shorter than minSampleLength
start = None
data = logdata . channels [ " CTUN " ] [ " ThrOut " ] . listData
for i in range ( 0 , len ( data ) ) :
( lineNumber , value ) = data [ i ]
isBelowTiltThreshold = True
if value > highThrottleThreshold :
( roll , meh ) = logdata . channels [ " ATT " ] [ " Roll " ] . getNearestValue ( lineNumber )
( pitch , meh ) = logdata . channels [ " ATT " ] [ " Pitch " ] . getNearestValue ( lineNumber )
if ( abs ( roll ) > tiltThreshold ) or ( abs ( pitch ) > tiltThreshold ) :
isBelowTiltThreshold = False
if ( value > highThrottleThreshold ) and isBelowTiltThreshold :
if start == None :
start = i
elif start != None :
if ( i - start ) > minSampleLength :
#print "Found high throttle chunk from line %d to %d (%d samples)" % (data[start][0],data[i][0],i-start+1)
highThrottleSegments . append ( ( start , i ) )
start = None
2014-02-22 15:36:30 -04:00
2014-08-12 12:54:15 -03:00
climbRate = " CRate "
if " CRate " not in logdata . channels [ " CTUN " ] :
climbRate = " CRt "
2014-03-19 20:37:23 -03:00
2014-08-12 12:54:15 -03:00
# loop through each checking climbRate, if < 50 FAIL, if < 100 WARN
# TODO: we should filter climbRate and use its slope rather than value for this test
for seg in highThrottleSegments :
( startLine , endLine ) = ( data [ seg [ 0 ] ] [ 0 ] , data [ seg [ 1 ] ] [ 0 ] )
avgClimbRate = logdata . channels [ " CTUN " ] [ climbRate ] . getSegment ( startLine , endLine ) . avg ( )
avgThrOut = logdata . channels [ " CTUN " ] [ " ThrOut " ] . getSegment ( startLine , endLine ) . avg ( )
if avgClimbRate < climbThresholdFAIL :
self . result . status = TestResult . StatusType . FAIL
self . result . statusMessage = " Avg climb rate %.2f cm/s for throttle avg %d " % ( avgClimbRate , avgThrOut )
return
if avgClimbRate < climbThresholdWARN :
self . result . status = TestResult . StatusType . WARN
self . result . statusMessage = " Avg climb rate %.2f cm/s for throttle avg %d " % ( avgClimbRate , avgThrOut )
2014-02-22 15:36:30 -04:00