Added new rc rate calculation to rates curve. Removed SUPER_EXPO feature for >= 3.0.

Added support for RC Expo Power setting.

fixed titlebar in pid tuning tab

request from @mikeller #252
fixed titlebar from pid tuning and accel
10.3.x-maintenance
mikeller 2016-08-27 12:34:05 +12:00 committed by Michael Keller
parent 158a415bfc
commit 1da5219bf2
8 changed files with 165 additions and 159 deletions

View File

@ -850,6 +850,9 @@
"pidTuningRcRate": {
"message": "RC Rate"
},
"pidTuningMaxVel": {
"message": "Max Vel (deg/s)"
},
"pidTuningRate": {
"message": "Rate"
},
@ -872,19 +875,10 @@
"message": "Frequency"
},
"pidTuningRatesCurve": {
"message": "Rates"
},
"pidTuningMaxAngularVelRoll": {
"message": "Max roll speed (deg/s):"
},
"pidTuningMaxAngularVelPitch": {
"message": "Max pitch speed (deg/s):"
},
"pidTuningMaxAngularVelYaw": {
"message": "Max yaw speed (deg/s):"
"message": "Rates"
},
"throttle": {
"message": "Throttle"
"message": "Throttle"
},
"pidTuningButtonSave": {
"message": "Save"
@ -1607,6 +1601,12 @@
"pidTuningYawJumpPreventionHelp": {
"message": "Keeps the craft from jumping up at the end of yaws. Higher number gives more damping at the end of yaw moves (works like old yaw D, which was not a real D like on other axis)"
},
"pidTuningRcExpoPower": {
"message": "RC Expo Power"
},
"pidTuningRcExpoPowerHelp": {
"message": "The exponent that is used when calculating RC Expo. In Betaflight versions prior to 3.0, value is fixed at 3."
},
"pidTuningLevel": {
"message": "Angle/Horizon"
},

View File

@ -46,17 +46,26 @@ var Features = function (config) {
);
}
if (config.flightControllerVersion !== '' && semver.gte(config.flightControllerVersion, "3.0.0")) {
features.push(
{bit: 18, group: 'other', name: 'OSD', haveTip: true}
);
}
if (config.flightControllerVersion !== '') {
if (semver.gte(config.flightControllerVersion, "2.8.0")) {
features.push(
{bit: 22, group: 'other', name: 'AIRMODE'}
);
}
if (semver.gte(config.flightControllerVersion, "2.8.0") && !semver.gte(config.flightControllerVersion, "3.0.0")) {
features.push(
{bit: 23, group: 'pidTuning', name: 'SUPEREXPO_RATES'}
);
}
if (semver.gte(config.flightControllerVersion, "3.0.0")) {
features.push(
{bit: 18, group: 'other', name: 'OSD', haveTip: true}
);
}
if (config.flightControllerVersion !== '' && semver.gte(config.flightControllerVersion, "2.8.0")) {
features.push(
{bit: 22, group: 'other', name: 'AIRMODE'},
{bit: 23, group: 'pidTuning', name: 'SUPEREXPO_RATES'}
);
}
self._features = features;

View File

@ -9,18 +9,24 @@ var RateCurve = function (useLegacyCurve) {
this.constrain = function (value, min, max) {
return Math.max(min, Math.min(value, max));
}
};
this.rcCommand = function (rcData, rcRate, rcExpo) {
var tmp = Math.min(Math.abs(rcData - midRc), 500) / 100;
this.rcCommand = function (rcData, rcRate) {
var tmp = Math.min(Math.abs(rcData - midRc), 500);
rcRate = rcRate;
var result = ((2500 + rcExpo * (tmp * tmp - 25)) * tmp * rcRate / 2500).toFixed(0);
if (rcData < midRc) {
if (rcRate > 2) {
rcRate = rcRate + (rcRate - 2) * 14.54;
}
var result = tmp * rcRate;
if (rcData < midRc) {
result = -result;
}
return result;
}
};
this.drawRateCurve = function (rate, rcRate, rcExpo, superExpoActive, maxAngularVel, context, width, height) {
var canvasHeightScale = height / (2 * maxAngularVel);
@ -42,7 +48,7 @@ var RateCurve = function (useLegacyCurve) {
context.stroke();
context.restore();
}
};
this.drawLegacyRateCurve = function (rate, rcRate, rcExpo, context, width, height) {
// math magic by englishman
@ -55,28 +61,31 @@ var RateCurve = function (useLegacyCurve) {
context.quadraticCurveTo(width * 11 / 20, height - ((rateY / 2) * (1 - rcExpo)), width, height - rateY);
context.stroke();
}
}
};
RateCurve.prototype.rcCommandRawToDegreesPerSecond = function (rcData, rate, rcRate, rcExpo, superExpoActive) {
var angleRate;
if (rate !== undefined && rcRate !== undefined && rcExpo !== undefined) {
rate = rate * 100;
rcRate = rcRate * 100;
rcExpo = rcExpo * 100;
var inputValue = this.rcCommand(rcData, rcRate, rcExpo);
var inputValue = this.rcCommand(rcData, rcRate);
var maxRc = 500 * rcRate;
if (superExpoActive) {
var rcFactor = Math.abs(inputValue) / (500 * rcRate / 100);
rcFactor = 1 / this.constrain(1 - rcFactor * rate / 100, 0.01, 1);
angleRate = rcFactor * 27 * inputValue / 16;
} else {
angleRate = (rate + 27) * inputValue / 16;
if (rcExpo > 0) {
var absRc = Math.abs(inputValue) / maxRc;
inputValue = inputValue * ((rcExpo * absRc * absRc * absRc) + absRc * (1-rcExpo)); // absRc should be wrapped in function using expo power
}
angleRate = this.constrain(angleRate, -8190, 8190); // Rate limit protection
angleRate = angleRate >> 2; // the shift by 2 is to counterbalance the divide by 4 that occurs on the gyro to calculate the error
var rcInput = inputValue / maxRc;
if (superExpoActive) {
var rcFactor = 1 / this.constrain(1 - Math.abs(rcInput) * rate, 0.01, 1);
angleRate = 200 * rcRate * rcInput; // 200 should be variable checked on version (older versions it's 205,9)
angleRate = angleRate * rcFactor;
} else {
angleRate = (((rate * 100) + 27) * inputValue / 16) / 4.1; // Only applies to old versions ?
}
angleRate = this.constrain(angleRate, -1998, 1998); // Rate limit protection
}
return angleRate;
@ -89,7 +98,7 @@ RateCurve.prototype.getMaxAngularVel = function (rate, rcRate, rcExpo, superExpo
}
return maxAngularVel;
}
};
RateCurve.prototype.draw = function (rate, rcRate, rcExpo, superExpoActive, maxAngularVel, context) {
if (rate !== undefined && rcRate !== undefined && rcExpo !== undefined) {
@ -102,4 +111,4 @@ RateCurve.prototype.draw = function (rate, rcRate, rcExpo, superExpoActive, maxA
this.drawRateCurve(rate, rcRate, rcExpo, superExpoActive, maxAngularVel, context, width, height);
}
}
}
};

View File

@ -112,7 +112,8 @@ var FC = {
throttle_EXPO: 0,
dynamic_THR_breakpoint: 0,
RC_YAW_EXPO: 0,
rcYawRate: 0
rcYawRate: 0,
rcExpoPower: 3
};
AUX_CONFIG = [];

View File

@ -140,6 +140,11 @@ MspHelper.prototype.process_data = function(dataHandler) {
} else {
RC_tuning.RC_YAW_EXPO = 0;
}
if (semver.gte(CONFIG.apiVersion, "1.20.0")) {
RC_tuning.rcExpoPower = data.readU8();
} else {
RC_tuning.rcExpoPower = 3;
}
break;
case MSPCodes.MSP_PID:
// PID data arrived, we need to scale it and save to appropriate bank / array
@ -954,6 +959,9 @@ MspHelper.prototype.crunch = function(code) {
buffer.push8(Math.round(RC_tuning.rcYawRate * 100));
}
}
if (semver.gte(CONFIG.apiVersion, "1.20.0")) {
buffer.push8(RC_tuning.rcExpoPower);
}
break;
case MSPCodes.MSP_SET_RX_MAP:
for (var i = 0; i < RC_MAP.length; i++) {

View File

@ -242,13 +242,13 @@
padding: 5px;
text-align: left;
border-right: 1px solid #ccc;
width: 14%;
width: 12.5%;
}
.tab-pid_tuning .pid_titlebar th:first-child {
text-align: left;
width: 14%;
width: 12.5%;
}
.tab-pid_tuning .pid_titlebar th:last-child {
@ -288,7 +288,7 @@
.tab-pid_tuning table td {
padding: 1px;
width: 14%;
width: 12.5%;
border-right: 1px solid #ccc;
}
@ -370,32 +370,8 @@
border-top-right-radius: 3px;
}
.tab-pid_tuning .name {
width: 14%;
}
.tab-pid_tuning .proportional {
width: 14%;
}
.tab-pid_tuning .integral {
width: 14%;
}
.tab-pid_tuning .derivative {
width: 14%;
}
.tab-pid_tuning .rc_rate {
width: 14%;
}
.tab-pid_tuning .rate {
width: 14%;
}
.tab-pid_tuning .rc_expo {
width: 14%;
.tab-pid_tuning .new_rates {
text-align: left;
}
.tab-pid_tuning .tpa {
@ -711,7 +687,6 @@ width: 40%;
.tab-pid_tuning .rc_curve_bg {
float: left;
padding-bottom: 20px;
background: #ddd;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
@ -757,4 +732,4 @@ width: 40%;
border-bottom-left-radius: 8px;
border-top: 0px solid silver;
background: #f9f9f9;
}
}

View File

@ -72,6 +72,7 @@
<th class="derivative" i18n="pidTuningDerivative"></th>
<th class="rc_rate" i18n="pidTuningRcRate"></th>
<th class="rate" i18n="pidTuningRate"></th>
<th class="maxVel" i18n="pidTuningMaxVel"></th>
<th class="rc_expo" i18n="pidTuningRcExpo"></th>
</tr>
</table>
@ -91,11 +92,12 @@
<td class="pid_data"><input type="number" name="i" step="1" min="0" max="255" /></td>
<td class="pid_data"><input type="number" name="d" step="1" min="0" max="255" /></td>
<td rowspan="2" style="background-color:white;">
<input type="number" name="rc_rate" step="0.01" min="0" max="2.5" />
<input type="number" name="rc_rate" step="0.01" min="0" max="2.55" />
<div class="bracket"></div>
</td>
<td class="roll_rate"><input type="number" name="roll_rate" step="0.01" min="0" max="1.00" /></td>
<td class="roll_pitch_rate" rowspan="2"><input type="number" name="roll_pitch_rate" step="0.01" min="0" max="1.00" /></td>
<td class="new_rates maxAngularVelRoll"></td>
<td rowspan="2" style="background-color:white;">
<input type="number" name="rc_expo" step="0.01" min="0" max="1" />
<div class="bracket"></div>
@ -108,6 +110,7 @@
<td class="pid_data"><input type="number" name="i" step="1" min="0" max="255" /></td>
<td class="pid_data"><input type="number" name="d" step="1" min="0" max="255" /></td>
<td class="pitch_rate"><input type="number" name="pitch_rate" step="0.01" min="0" max="1.00" /></td>
<td class="new_rates maxAngularVelPitch"></td>
</tr>
<tr class="YAW">
<!-- 2 -->
@ -115,8 +118,9 @@
<td class="pid_data"><input type="number" name="p" step="1" min="0" max="255" /></td>
<td class="pid_data"><input type="number" name="i" step="1" min="0" max="255" /></td>
<td></td>
<td rowspan="1"><input type="number" name="rc_rate_yaw" step="0.01" min="0" max="2.5" /></td>
<td rowspan="1"><input type="number" name="rc_rate_yaw" step="0.01" min="0" max="2.55" /></td>
<td><input type="number" name="yaw_rate" step="0.01" min="0" max="2.55" /></td>
<td class="new_rates maxAngularVelYaw"></td>
<td><input type="number" name="rc_yaw_expo" step="0.01" min="0" max="1" /></td>
</tr>
<tr class="YAW_JUMP_PREVENTION">
@ -127,7 +131,16 @@
</div>
</td>
<td class="pid_data"><input type="number" name="d" step="1" min="0" max="255" /></td>
<td colspan=3></td>
<td colspan=4></td>
</tr>
<tr class="RC_EXPO_POWER">
<td colspan = 7>
<div>
<div i18n="pidTuningRcExpoPower" style="float:left;"></div>
<div class="helpicon cf_tip" i18n_title="pidTuningRcExpoPowerHelp"></div>
</div>
</td>
<td class="pid_data"><input type="number" name="rcExpoPower" step="1" min="2" max="4"/></td>
</tr>
</table>
</div>
@ -208,7 +221,7 @@
<div id="pid_accel" class="gui_box grey topspacer pid_tuning">
<table class="pid_titlebar">
<tr>
<th class="third" i18n="pidTuningName" style="width: 17%;"></th>
<th class="third" i18n="pidTuningName" style="width: 24%;"></th>
<th class="third" i18n="pidTuningStrength" style="width: 33%;"></th>
<th class="third" i18n="pidTuningTransition" style="width: 33%;"></th>
</tr>
@ -371,26 +384,14 @@
</thead>
<tbody>
<tr>
<td colspan=2>
<div class="spacer" style="margin-top: 10px; margin-bottom: 10px;">
<td>
<div class="spacer" style="margin-top: 10px;">
<div class="rate_curve">
<canvas height="120px" style="width: 100%; height: 100%"></canvas>
</div>
</div>
</td>
</tr>
<tr class="new_rates">
<td i18n="pidTuningMaxAngularVelRoll" style="width: 70%"></td>
<td class="maxAngularVelRoll"></td>
</tr>
<tr class="new_rates">
<td i18n="pidTuningMaxAngularVelPitch"></td>
<td class="maxAngularVelPitch"></td>
</tr>
<tr class="new_rates">
<td i18n="pidTuningMaxAngularVelYaw"></td>
<td class="maxAngularVelYaw"></td>
</tr>
</tbody>
</table>
</div>

View File

@ -58,28 +58,6 @@ TABS.pid_tuning.initialize = function (callback) {
self.setRateProfile();
}
if (semver.gte(CONFIG.flightControllerVersion, "2.8.1")) {
$('input[id="vbatpidcompensation"]').prop('checked', ADVANCED_TUNING.vbatPidCompensation !== 0);
}
if (semver.gte(CONFIG.flightControllerVersion, "2.8.2")) {
$('#pid-tuning .delta select').val(ADVANCED_TUNING.deltaMethod);
}
if (semver.gte(CONFIG.flightControllerVersion, '3.0.0')) {
$('select[name="rcInterpolation-select"]').val(RX_CONFIG.rcInterpolation);
$('input[name="rcInterpolationInterval-number"]').val(RX_CONFIG.rcInterpolationInterval);
$('input[name="ptermSetpoint-number"]').val(ADVANCED_TUNING.ptermSetpointWeight / 100);
$('input[name="ptermSetpoint-range"]').val(ADVANCED_TUNING.ptermSetpointWeight / 100);
$('input[name="dtermSetpoint-number"]').val(ADVANCED_TUNING.dtermSetpointWeight / 100);
$('input[name="dtermSetpoint-range"]').val(ADVANCED_TUNING.dtermSetpointWeight / 100);
self.updateRcInterpolationParameters();
}
// Fill in the data from PIDs array
var i = 0;
$('.pid_tuning .ROLL input').each(function () {
@ -239,6 +217,14 @@ TABS.pid_tuning.initialize = function (callback) {
$('.pid_tuning input[name="rc_expo"]').attr("rowspan", "3");
}
if (semver.gte(CONFIG.flightControllerVersion, "2.8.1")) {
$('input[id="vbatpidcompensation"]').prop('checked', ADVANCED_TUNING.vbatPidCompensation !== 0);
}
if (semver.gte(CONFIG.flightControllerVersion, "2.8.2")) {
$('#pid-tuning .delta select').val(ADVANCED_TUNING.deltaMethod);
}
if (semver.gte(CONFIG.flightControllerVersion, '2.9.0')) {
$('.pid_tuning input[name="rc_rate_yaw"]').val(RC_tuning.rcYawRate.toFixed(2));
$('.pid_filter input[name="gyroLowpassFrequency"]').val(FILTER_CONFIG.gyro_soft_lpf_hz);
@ -255,34 +241,28 @@ TABS.pid_tuning.initialize = function (callback) {
$('.pid_filter input[name="gyroNotchCutoff"]').val(FILTER_CONFIG.gyro_soft_notch_cutoff);
$('.pid_filter input[name="dTermNotchFrequency"]').val(FILTER_CONFIG.dterm_notch_hz);
$('.pid_filter input[name="dTermNotchCutoff"]').val(FILTER_CONFIG.dterm_notch_cutoff);
$('select[name="rcInterpolation-select"]').val(RX_CONFIG.rcInterpolation);
$('input[name="rcInterpolationInterval-number"]').val(RX_CONFIG.rcInterpolationInterval);
$('input[name="ptermSetpoint-number"]').val(ADVANCED_TUNING.ptermSetpointWeight / 100);
$('input[name="ptermSetpoint-range"]').val(ADVANCED_TUNING.ptermSetpointWeight / 100);
$('input[name="dtermSetpoint-number"]').val(ADVANCED_TUNING.dtermSetpointWeight / 100);
$('input[name="dtermSetpoint-range"]').val(ADVANCED_TUNING.dtermSetpointWeight / 100);
self.updateRcInterpolationParameters();
$('.pid_tuning input[name="rcExpoPower"]').val(RC_tuning.rcExpoPower.toFixed(0)).prop("readonly", false);
} else {
$('.pid_filter .newFilter').hide();
$('.pid_tuning input[name="rcExpoPower"]').val(3).prop("readonly", true);
}
}
function form_to_pid_and_rc() {
if (semver.gte(CONFIG.flightControllerVersion, "2.8.0")) {
BF_CONFIG.features.updateData($('input[name="SUPEREXPO_RATES"]'));
}
if (semver.gte(CONFIG.flightControllerVersion, "2.8.1")) {
ADVANCED_TUNING.vbatPidCompensation = $('input[id="vbatpidcompensation"]').is(':checked') ? 1 : 0;
}
if (semver.gte(CONFIG.flightControllerVersion, "2.8.2")) {
ADVANCED_TUNING.deltaMethod = $('#pid-tuning .delta select').val();
}
if (semver.gte(CONFIG.flightControllerVersion, '3.0.0')) {
RX_CONFIG.rcInterpolation = parseInt($('select[name="rcInterpolation-select"]').val());
RX_CONFIG.rcInterpolationInterval = parseInt($('input[name="rcInterpolationInterval-number"]').val());
ADVANCED_TUNING.ptermSetpointWeight = parseInt($('input[name="ptermSetpoint-number"]').val() * 100);
ADVANCED_TUNING.dtermSetpointWeight = parseInt($('input[name="dtermSetpoint-number"]').val() * 100);
}
// Fill in the data from PIDs array
// Catch all the changes and stuff the inside PIDs array
var i = 0;
@ -360,12 +340,33 @@ TABS.pid_tuning.initialize = function (callback) {
FILTER_CONFIG.dterm_lpf_hz = parseInt($('.pid_filter input[name="dtermLowpassFrequency"]').val());
FILTER_CONFIG.yaw_lpf_hz = parseInt($('.pid_filter input[name="yawLowpassFrequency"]').val());
if (semver.gte(CONFIG.flightControllerVersion, "2.8.0") && !semver.gte(CONFIG.flightControllerVersion, "3.0.0")) {
BF_CONFIG.features.updateData($('input[name="SUPEREXPO_RATES"]'));
}
if (semver.gte(CONFIG.flightControllerVersion, "2.8.1")) {
ADVANCED_TUNING.vbatPidCompensation = $('input[id="vbatpidcompensation"]').is(':checked') ? 1 : 0;
}
if (semver.gte(CONFIG.flightControllerVersion, "2.8.2")) {
ADVANCED_TUNING.deltaMethod = $('#pid-tuning .delta select').val();
}
if (semver.gte(CONFIG.flightControllerVersion, '3.0.0')) {
RX_CONFIG.rcInterpolation = parseInt($('select[name="rcInterpolation-select"]').val());
RX_CONFIG.rcInterpolationInterval = parseInt($('input[name="rcInterpolationInterval-number"]').val());
ADVANCED_TUNING.ptermSetpointWeight = parseInt($('input[name="ptermSetpoint-number"]').val() * 100);
ADVANCED_TUNING.dtermSetpointWeight = parseInt($('input[name="dtermSetpoint-number"]').val() * 100);
FILTER_CONFIG.gyro_soft_notch_hz = parseInt($('.pid_filter input[name="gyroNotchFrequency"]').val());
FILTER_CONFIG.gyro_soft_notch_cutoff = parseInt($('.pid_filter input[name="gyroNotchCutoff"]').val());
FILTER_CONFIG.dterm_notch_hz = parseInt($('.pid_filter input[name="dTermNotchFrequency"]').val());
FILTER_CONFIG.dterm_notch_cutoff = parseInt($('.pid_filter input[name="dTermNotchCutoff"]').val());
RC_tuning.rcExpoPower = parseInt($('.pid_tuning input[name="rcExpoPower"]').val());
}
}
function showAllPids() {
@ -452,7 +453,7 @@ TABS.pid_tuning.initialize = function (callback) {
self.rateCurve = new RateCurve(useLegacyCurve);
function printMaxAngularVel(rate, rcRate, rcExpo, useSuperExpo, maxAngularVelElement) {
var maxAngularVel = self.rateCurve.getMaxAngularVel(rate, rcRate, rcExpo, useSuperExpo);
var maxAngularVel = self.rateCurve.getMaxAngularVel(rate, rcRate, rcExpo, useSuperExpo).toFixed(0);
maxAngularVelElement.text(maxAngularVel);
return maxAngularVel;
@ -486,15 +487,19 @@ TABS.pid_tuning.initialize = function (callback) {
superexpo: BF_CONFIG.features.isEnabled('SUPEREXPO_RATES')
};
if (CONFIG.flightControllerIdentifier !== "BTFL" || semver.lt(CONFIG.flightControllerVersion, "2.8.1")) {
self.currentRates.rc_rate_yaw = self.currentRates.rc_rate;
}
if (semver.lt(CONFIG.apiVersion, "1.7.0")) {
self.currentRates.roll_rate = RC_tuning.roll_pitch_rate;
self.currentRates.pitch_rate = RC_tuning.roll_pitch_rate;
}
if (semver.lt(CONFIG.flightControllerVersion, "2.8.1")) {
self.currentRates.rc_rate_yaw = self.currentRates.rc_rate;
}
if (semver.gte(CONFIG.flightControllerVersion, "3.0.0")) {
self.currentRates.superexpo = true;
}
$('.tab-pid_tuning .tab_container .pid').on('click', function () {
$('.tab-pid_tuning .subtab-pid').show();
$('.tab-pid_tuning .subtab-filter').hide();
@ -673,9 +678,9 @@ TABS.pid_tuning.initialize = function (callback) {
rcCurveElement.width = 1000;
rcCurveElement.height = 1000;
var maxAngularVelRollElement = $('.rc_curve .maxAngularVelRoll');
var maxAngularVelPitchElement = $('.rc_curve .maxAngularVelPitch');
var maxAngularVelYawElement = $('.rc_curve .maxAngularVelYaw');
var maxAngularVelRollElement = $('.pid_tuning .maxAngularVelRoll');
var maxAngularVelPitchElement = $('.pid_tuning .maxAngularVelPitch');
var maxAngularVelYawElement = $('.pid_tuning .maxAngularVelYaw');
var updateNeeded = true;
@ -684,13 +689,13 @@ TABS.pid_tuning.initialize = function (callback) {
var targetElement = $(event.target),
targetValue = checkInput(targetElement);
if (self.currentRates.hasOwnProperty(targetElement.attr('name')) && targetValue) {
if (self.currentRates.hasOwnProperty(targetElement.attr('name')) && targetValue !== undefined) {
self.currentRates[targetElement.attr('name')] = targetValue;
updateNeeded = true;
}
if (targetElement.attr('name') === 'rc_rate' && CONFIG.flightControllerIdentifier !== "BTFL" || semver.lt(CONFIG.flightControllerVersion, "2.8.1")) {
if (targetElement.attr('name') === 'rc_rate' && semver.lt(CONFIG.flightControllerVersion, "2.8.1")) {
self.currentRates.rc_rate_yaw = targetValue;
}
@ -711,7 +716,7 @@ TABS.pid_tuning.initialize = function (callback) {
var curveHeight = rcCurveElement.height;
var curveWidth = rcCurveElement.width;
var maxAngularVel = Math.max(
var maxAngularVel = Math.max(
printMaxAngularVel(self.currentRates.roll_rate, self.currentRates.rc_rate, self.currentRates.rc_expo, self.currentRates.superexpo, maxAngularVelRollElement),
printMaxAngularVel(self.currentRates.pitch_rate, self.currentRates.rc_rate, self.currentRates.rc_expo, self.currentRates.superexpo, maxAngularVelPitchElement),
printMaxAngularVel(self.currentRates.yaw_rate, self.currentRates.rc_rate_yaw, self.currentRates.rc_yaw_expo, self.currentRates.superexpo, maxAngularVelYawElement));
@ -724,11 +729,9 @@ TABS.pid_tuning.initialize = function (callback) {
curveContext.lineWidth = 4;
drawCurve(self.currentRates.roll_rate, self.currentRates.rc_rate, self.currentRates.rc_expo, self.currentRates.superexpo, maxAngularVel, '#ff0000', 0, curveContext);
drawCurve(self.currentRates.pitch_rate, self.currentRates.rc_rate, self.currentRates.rc_expo, self.currentRates.superexpo, maxAngularVel, '#00ff00', -4, curveContext);
drawCurve(self.currentRates.yaw_rate, self.currentRates.rc_rate_yaw, self.currentRates.rc_yaw_expo, self.currentRates.superexpo, maxAngularVel, '#0000ff', 4, curveContext);
drawCurve(self.currentRates.roll_rate, self.currentRates.rc_rate, self.currentRates.rc_expo, self.currentRates.superexpo, maxAngularVel, '#ff0000', 0, curveContext);
drawCurve(self.currentRates.pitch_rate, self.currentRates.rc_rate, self.currentRates.rc_expo, self.currentRates.superexpo, maxAngularVel, '#00ff00', -4, curveContext);
drawCurve(self.currentRates.yaw_rate, self.currentRates.rc_rate_yaw, self.currentRates.rc_yaw_expo, self.currentRates.superexpo, maxAngularVel, '#0000ff', 4, curveContext);
updateNeeded = false;
}
@ -737,8 +740,8 @@ TABS.pid_tuning.initialize = function (callback) {
// UI Hooks
// curves
$('.pid_tuning').on('input change', updateRates);
$('input.feature').on('input change', updateRates).trigger('input');
$('input.feature').on('input change', updateRates);
$('.pid_tuning').on('input change', updateRates).trigger('input');
$('.throttle input').on('input change', function () {
setTimeout(function () { // let global validation trigger and adjust the values first
@ -900,9 +903,9 @@ TABS.pid_tuning.renderModel = function () {
if (RC.channels[0] && RC.channels[1] && RC.channels[2]) {
var delta = this.clock.getDelta();
var roll = delta * this.rateCurve.rcCommandRawToDegreesPerSecond(RC.channels[0], this.currentRates.roll_rate, this.currentRates.rc_rate, this.currentRates.rc_expo, this.currentRates.super_expo),
pitch = delta * this.rateCurve.rcCommandRawToDegreesPerSecond(RC.channels[1], this.currentRates.pitch_rate, this.currentRates.rc_rate, this.currentRates.rc_expo, this.currentRates.super_expo),
yaw = delta * this.rateCurve.rcCommandRawToDegreesPerSecond(RC.channels[2], this.currentRates.yaw_rate, this.currentRates.rc_rate_yaw, this.currentRates.rc_yaw_expo, this.currentRates.super_expo);
var roll = delta * this.rateCurve.rcCommandRawToDegreesPerSecond(RC.channels[0], this.currentRates.roll_rate, this.currentRates.rc_rate, this.currentRates.rc_expo, this.currentRates.superexpo),
pitch = delta * this.rateCurve.rcCommandRawToDegreesPerSecond(RC.channels[1], this.currentRates.pitch_rate, this.currentRates.rc_rate, this.currentRates.rc_expo, this.currentRates.superexpo),
yaw = delta * this.rateCurve.rcCommandRawToDegreesPerSecond(RC.channels[2], this.currentRates.yaw_rate, this.currentRates.rc_rate_yaw, this.currentRates.rc_yaw_expo, this.currentRates.superexpo);
this.model.rotateBy(-degToRad(pitch), -degToRad(yaw), -degToRad(roll));
}