2016-07-05 11:30:19 +00:00
'use strict' ;
var minRc = 1000 ;
var midRc = 1500 ;
var maxRc = 2000 ;
var RateCurve = function ( useLegacyCurve ) {
this . useLegacyCurve = useLegacyCurve ;
2016-09-18 13:14:54 +00:00
this . maxAngularVel = null ;
2016-07-05 11:30:19 +00:00
2016-07-07 21:21:32 +00:00
this . constrain = function ( value , min , max ) {
2016-07-05 11:30:19 +00:00
return Math . max ( min , Math . min ( value , max ) ) ;
2016-08-27 00:34:05 +00:00
} ;
2016-09-07 20:49:54 +00:00
this . rcCommand = function ( rcData , rcRate , deadband ) {
var tmp = Math . min ( Math . max ( Math . abs ( rcData - midRc ) - deadband , 0 ) , 500 ) ;
2016-07-05 11:30:19 +00:00
2016-08-27 00:34:05 +00:00
var result = tmp * rcRate ;
2016-07-05 11:30:19 +00:00
2016-08-27 00:34:05 +00:00
if ( rcData < midRc ) {
2016-07-05 11:30:19 +00:00
result = - result ;
}
return result ;
2016-08-27 00:34:05 +00:00
} ;
2016-07-05 11:30:19 +00:00
2016-09-07 20:49:54 +00:00
this . drawRateCurve = function ( rate , rcRate , rcExpo , superExpoActive , deadband , maxAngularVel , context , width , height ) {
2016-07-05 11:30:19 +00:00
var canvasHeightScale = height / ( 2 * maxAngularVel ) ;
var stepWidth = context . lineWidth ;
context . save ( ) ;
context . translate ( width / 2 , height / 2 ) ;
context . beginPath ( ) ;
var rcData = minRc ;
2016-09-07 20:49:54 +00:00
context . moveTo ( - 500 , - canvasHeightScale * this . rcCommandRawToDegreesPerSecond ( rcData , rate , rcRate , rcExpo , superExpoActive , deadband ) ) ;
2016-07-05 11:30:19 +00:00
rcData = rcData + stepWidth ;
while ( rcData <= maxRc ) {
2016-09-07 20:49:54 +00:00
context . lineTo ( rcData - midRc , - canvasHeightScale * this . rcCommandRawToDegreesPerSecond ( rcData , rate , rcRate , rcExpo , superExpoActive , deadband ) ) ;
2016-07-05 11:30:19 +00:00
rcData = rcData + stepWidth ;
}
context . stroke ( ) ;
context . restore ( ) ;
2016-08-27 00:34:05 +00:00
} ;
2016-07-05 11:30:19 +00:00
this . drawLegacyRateCurve = function ( rate , rcRate , rcExpo , context , width , height ) {
// math magic by englishman
var rateY = height * rcRate ;
2016-09-07 20:49:54 +00:00
rateY = rateY + ( 1 / ( 1 - ( ( rateY / height ) * rate ) ) ) ;
2016-07-05 11:30:19 +00:00
// draw
context . beginPath ( ) ;
context . moveTo ( 0 , height ) ;
context . quadraticCurveTo ( width * 11 / 20 , height - ( ( rateY / 2 ) * ( 1 - rcExpo ) ) , width , height - rateY ) ;
context . stroke ( ) ;
}
2016-09-18 13:14:54 +00:00
this . drawStickPosition = function ( rcData , rate , rcRate , rcExpo , superExpoActive , deadband , maxAngularVel , context , stickColor ) {
const DEFAULT _SIZE = 60 ; // canvas units, relative size of the stick indicator (larger value is smaller indicator)
const rateScaling = ( context . canvas . height / 2 ) / maxAngularVel ;
var currentValue = this . rcCommandRawToDegreesPerSecond ( rcData , rate , rcRate , rcExpo , superExpoActive , deadband ) ;
if ( rcData != undefined ) {
context . save ( ) ;
context . fillStyle = stickColor || '#000000' ;
context . translate ( context . canvas . width / 2 , context . canvas . height / 2 ) ;
context . beginPath ( ) ;
context . arc ( rcData - 1500 , - rateScaling * currentValue , context . canvas . height / DEFAULT _SIZE , 0 , 2 * Math . PI ) ;
context . fill ( ) ;
context . restore ( ) ;
}
return ( Math . abs ( currentValue ) < 0.5 ) ? 0 : currentValue . toFixed ( 0 ) ; // The calculated value in deg/s is returned from the function call for further processing.
}
2016-08-27 00:34:05 +00:00
} ;
2016-07-05 11:30:19 +00:00
2016-09-07 20:49:54 +00:00
RateCurve . prototype . rcCommandRawToDegreesPerSecond = function ( rcData , rate , rcRate , rcExpo , superExpoActive , deadband ) {
2016-07-07 21:21:32 +00:00
var angleRate ;
if ( rate !== undefined && rcRate !== undefined && rcExpo !== undefined ) {
2016-09-06 22:48:35 +00:00
if ( rcRate > 2 ) {
rcRate = rcRate + ( rcRate - 2 ) * 14.54 ;
}
2016-09-07 21:16:28 +00:00
2016-09-07 20:49:54 +00:00
var inputValue = this . rcCommand ( rcData , rcRate , deadband ) ;
2016-08-27 00:34:05 +00:00
var maxRc = 500 * rcRate ;
2016-09-05 23:22:51 +00:00
var expoPower ;
var rcRateConstant ;
if ( semver . gte ( CONFIG . flightControllerVersion , "3.0.0" ) ) {
expoPower = 3 ;
rcRateConstant = 200 ;
} else {
expoPower = 2 ;
rcRateConstant = 205.85 ;
}
2016-07-07 21:21:32 +00:00
2016-08-27 00:34:05 +00:00
if ( rcExpo > 0 ) {
var absRc = Math . abs ( inputValue ) / maxRc ;
2016-09-05 23:17:30 +00:00
inputValue = inputValue * Math . pow ( absRc , expoPower ) * rcExpo + inputValue * ( 1 - rcExpo ) ;
2016-08-27 00:34:05 +00:00
}
var rcInput = inputValue / maxRc ;
2016-07-07 21:21:32 +00:00
2016-08-27 00:34:05 +00:00
if ( superExpoActive ) {
var rcFactor = 1 / this . constrain ( 1 - Math . abs ( rcInput ) * rate , 0.01 , 1 ) ;
2016-09-05 23:22:51 +00:00
angleRate = rcRateConstant * rcRate * rcInput ; // 200 should be variable checked on version (older versions it's 205,9)
2016-08-27 00:34:05 +00:00
angleRate = angleRate * rcFactor ;
2016-07-07 21:21:32 +00:00
} else {
2016-08-27 00:34:05 +00:00
angleRate = ( ( ( rate * 100 ) + 27 ) * inputValue / 16 ) / 4.1 ; // Only applies to old versions ?
2016-07-07 21:21:32 +00:00
}
2016-08-27 00:34:05 +00:00
angleRate = this . constrain ( angleRate , - 1998 , 1998 ) ; // Rate limit protection
2016-07-07 21:21:32 +00:00
}
return angleRate ;
} ;
2016-09-07 20:49:54 +00:00
RateCurve . prototype . getMaxAngularVel = function ( rate , rcRate , rcExpo , superExpoActive , deadband ) {
2016-07-05 11:30:19 +00:00
var maxAngularVel ;
2016-07-07 21:21:32 +00:00
if ( ! this . useLegacyCurve ) {
2016-09-07 20:49:54 +00:00
maxAngularVel = this . rcCommandRawToDegreesPerSecond ( maxRc , rate , rcRate , rcExpo , superExpoActive , deadband ) ;
2016-07-05 11:30:19 +00:00
}
return maxAngularVel ;
2016-08-27 00:34:05 +00:00
} ;
2016-07-05 11:30:19 +00:00
2016-09-18 13:14:54 +00:00
RateCurve . prototype . setMaxAngularVel = function ( value ) {
this . maxAngularVel = Math . ceil ( value / 200 ) * 200 ;
return this . maxAngularVel ;
} ;
2016-09-07 20:49:54 +00:00
RateCurve . prototype . draw = function ( rate , rcRate , rcExpo , superExpoActive , deadband , maxAngularVel , context ) {
2016-07-05 11:30:19 +00:00
if ( rate !== undefined && rcRate !== undefined && rcExpo !== undefined ) {
var height = context . canvas . height ;
var width = context . canvas . width ;
if ( this . useLegacyCurve ) {
this . drawLegacyRateCurve ( rate , rcRate , rcExpo , context , width , height ) ;
} else {
2016-09-07 20:49:54 +00:00
this . drawRateCurve ( rate , rcRate , rcExpo , superExpoActive , deadband , maxAngularVel , context , width , height ) ;
2016-07-05 11:30:19 +00:00
}
}
2016-08-27 00:34:05 +00:00
} ;