Add feedforward support

10.4.x-maintenance
Miguel Angel Mulero Martinez 2018-07-09 18:17:08 +02:00
parent 863708ad94
commit 25e4e7f6ca
6 changed files with 103 additions and 20 deletions

View File

@ -1276,6 +1276,12 @@
"receiverRcInterpolationInterval": { "receiverRcInterpolationInterval": {
"message": "RC Interpolation Interval [ms]" "message": "RC Interpolation Interval [ms]"
}, },
"pidTuningFeedforwardTransition": {
"message": "Feedforward transition"
},
"pidTuningFeedforwardTransitionHelp": {
"message": "With this parameter, the Feedforward term can be reduced near the center of the sticks, which results in smoother end of flips and rolls.<br> The value represents a point of stick deflection: 0 - stick centered, 1 - full deflection. When the stick is above that point, Feedforward is kept constant at its configured value. When the stick is positioned below that point, Feedforward is reduced proportionally, reaching 0 at the stick center position.<br> Value of 1 gives maximum smoothing effect, while value of 0 keeps the Feedforward fixed at its configured value over the whole stick range."
},
"pidTuningDtermSetpointTransition": { "pidTuningDtermSetpointTransition": {
"message": "D Setpoint transition" "message": "D Setpoint transition"
}, },
@ -1300,6 +1306,9 @@
"pidTuningDerivative": { "pidTuningDerivative": {
"message": "Derivative" "message": "Derivative"
}, },
"pidTuningFeedforward": {
"message": "Feedforward"
},
"pidTuningRcRate": { "pidTuningRcRate": {
"message": "RC Rate" "message": "RC Rate"
}, },

View File

@ -244,12 +244,12 @@
padding: 5px; padding: 5px;
text-align: left; text-align: left;
border-right: 1px solid #ccc; border-right: 1px solid #ccc;
width: 12.5%; width: calc(100% / 9);
} }
.tab-pid_tuning .pid_titlebar th:first-child { .tab-pid_tuning .pid_titlebar th:first-child {
text-align: left; text-align: left;
width: 12.5%; width: calc(100% / 9);
} }
.tab-pid_tuning .pid_titlebar th:last-child { .tab-pid_tuning .pid_titlebar th:last-child {
@ -336,7 +336,7 @@
.tab-pid_tuning table td { .tab-pid_tuning table td {
padding: 1px; padding: 1px;
padding-left: 5px; padding-left: 5px;
width: 12.5%; width: calc(100% / 9);
border-right: 1px solid #ccc; border-right: 1px solid #ccc;
} }

View File

@ -376,6 +376,10 @@ var FC = {
absoluteControlGain: 0, absoluteControlGain: 0,
throttleBoost: 0, throttleBoost: 0,
acroTrainerAngleLimit: 0, acroTrainerAngleLimit: 0,
feedforwardRoll: 0,
feedforwardPitch: 0,
feedforwardYaw: 0,
feedforwardTransition: 0,
}; };
SENSOR_CONFIG = { SENSOR_CONFIG = {

View File

@ -878,7 +878,11 @@ MspHelper.prototype.process_data = function(dataHandler) {
ADVANCED_TUNING.deltaMethod = data.readU8(); ADVANCED_TUNING.deltaMethod = data.readU8();
ADVANCED_TUNING.vbatPidCompensation = data.readU8(); ADVANCED_TUNING.vbatPidCompensation = data.readU8();
if (semver.gte(CONFIG.apiVersion, "1.20.0")) { if (semver.gte(CONFIG.apiVersion, "1.20.0")) {
ADVANCED_TUNING.dtermSetpointTransition = data.readU8(); if (semver.gte(CONFIG.apiVersion, "1.40.0")) {
ADVANCED_TUNING.feedforwardTransition = data.readU8();
} else {
ADVANCED_TUNING.dtermSetpointTransition = data.readU8();
}
ADVANCED_TUNING.dtermSetpointWeight = data.readU8(); ADVANCED_TUNING.dtermSetpointWeight = data.readU8();
ADVANCED_TUNING.toleranceBand = data.readU8(); ADVANCED_TUNING.toleranceBand = data.readU8();
ADVANCED_TUNING.toleranceBandReduction = data.readU8(); ADVANCED_TUNING.toleranceBandReduction = data.readU8();
@ -904,6 +908,9 @@ MspHelper.prototype.process_data = function(dataHandler) {
ADVANCED_TUNING.absoluteControlGain = data.readU8(); ADVANCED_TUNING.absoluteControlGain = data.readU8();
ADVANCED_TUNING.throttleBoost = data.readU8(); ADVANCED_TUNING.throttleBoost = data.readU8();
ADVANCED_TUNING.acroTrainerAngleLimit = data.readU8(); ADVANCED_TUNING.acroTrainerAngleLimit = data.readU8();
ADVANCED_TUNING.feedforwardRoll = data.readU16();
ADVANCED_TUNING.feedforwardPitch = data.readU16();
ADVANCED_TUNING.feedforwardYaw = data.readU16();
} }
} }
} }
@ -1542,14 +1549,20 @@ MspHelper.prototype.crunch = function(code) {
.push16(ADVANCED_TUNING.yawItermIgnoreRate) .push16(ADVANCED_TUNING.yawItermIgnoreRate)
.push16(ADVANCED_TUNING.yaw_p_limit) .push16(ADVANCED_TUNING.yaw_p_limit)
.push8(ADVANCED_TUNING.deltaMethod) .push8(ADVANCED_TUNING.deltaMethod)
.push8(ADVANCED_TUNING.vbatPidCompensation) .push8(ADVANCED_TUNING.vbatPidCompensation);
.push8(ADVANCED_TUNING.dtermSetpointTransition)
.push8(Math.min(ADVANCED_TUNING.dtermSetpointWeight, 254)) if (semver.gte(CONFIG.apiVersion, "1.40.0")) {
.push8(ADVANCED_TUNING.toleranceBand) buffer.push8(ADVANCED_TUNING.feedforwardTransition);
.push8(ADVANCED_TUNING.toleranceBandReduction) } else {
.push8(ADVANCED_TUNING.itermThrottleGain) buffer.push8(ADVANCED_TUNING.dtermSetpointTransition);
.push16(ADVANCED_TUNING.pidMaxVelocity) }
.push16(ADVANCED_TUNING.pidMaxVelocityYaw);
buffer.push8(Math.min(ADVANCED_TUNING.dtermSetpointWeight, 254))
.push8(ADVANCED_TUNING.toleranceBand)
.push8(ADVANCED_TUNING.toleranceBandReduction)
.push8(ADVANCED_TUNING.itermThrottleGain)
.push16(ADVANCED_TUNING.pidMaxVelocity)
.push16(ADVANCED_TUNING.pidMaxVelocityYaw);
if (semver.gte(CONFIG.apiVersion, "1.24.0")) { if (semver.gte(CONFIG.apiVersion, "1.24.0")) {
buffer.push8(ADVANCED_TUNING.levelAngleLimit) buffer.push8(ADVANCED_TUNING.levelAngleLimit)
@ -1569,9 +1582,11 @@ MspHelper.prototype.crunch = function(code) {
.push8(ADVANCED_TUNING.itermRelaxType) .push8(ADVANCED_TUNING.itermRelaxType)
.push8(ADVANCED_TUNING.absoluteControlGain) .push8(ADVANCED_TUNING.absoluteControlGain)
.push8(ADVANCED_TUNING.throttleBoost) .push8(ADVANCED_TUNING.throttleBoost)
.push8(ADVANCED_TUNING.acroTrainerAngleLimit); .push8(ADVANCED_TUNING.acroTrainerAngleLimit)
.push16(ADVANCED_TUNING.feedforwardRoll)
.push16(ADVANCED_TUNING.feedforwardPitch)
.push16(ADVANCED_TUNING.feedforwardYaw);
} }
} }
} }
} }

View File

@ -370,6 +370,28 @@ TABS.pid_tuning.initialize = function (callback) {
}); });
acroTrainerAngleLimitNumberElement.val(ADVANCED_TUNING.acroTrainerAngleLimit).change(); acroTrainerAngleLimitNumberElement.val(ADVANCED_TUNING.acroTrainerAngleLimit).change();
// Yaw D
$('.pid_tuning .YAW input[name="d"]').val(PIDs[2][2]); // PID Yaw D
// Feedforward
$('.pid_tuning .ROLL input[name="f"]').val(ADVANCED_TUNING.feedforwardRoll);
$('.pid_tuning .PITCH input[name="f"]').val(ADVANCED_TUNING.feedforwardPitch);
$('.pid_tuning .YAW input[name="f"]').val(ADVANCED_TUNING.feedforwardYaw);
var feedforwardTransitionNumberElement = $('input[name="feedforwardTransition-number"]');
var feedforwardTransitionRangeElement = $('input[name="feedforwardTransition-range"]');
feedforwardTransitionNumberElement.val(ADVANCED_TUNING.feedforwardTransition / 100);
feedforwardTransitionRangeElement.val(ADVANCED_TUNING.feedforwardTransition / 100);
feedforwardTransitionNumberElement.change(function () {
feedforwardTransitionRangeElement.val($(this).val());
});
feedforwardTransitionRangeElement.change(function () {
feedforwardTransitionNumberElement.val($(this).val());
});
} else { } else {
$('.itermrotation').hide(); $('.itermrotation').hide();
$('.smartfeedforward').hide(); $('.smartfeedforward').hide();
@ -377,6 +399,11 @@ TABS.pid_tuning.initialize = function (callback) {
$('.absoluteControlGain').hide(); $('.absoluteControlGain').hide();
$('.throttleBoost').hide(); $('.throttleBoost').hide();
$('.acroTrainerAngleLimit').hide(); $('.acroTrainerAngleLimit').hide();
$('.pid_tuning .YAW input[name="d"]').hide();
$('.pid_tuning .ROLL input[name="f"]').hide();
$('.pid_tuning .PITCH input[name="f"]').hide();
$('.pid_tuning .YAW input[name="f"]').hide();
$('#pid-tuning .feedForwardTransition').hide();
} }
$('input[id="gyroNotch1Enabled"]').change(function() { $('input[id="gyroNotch1Enabled"]').change(function() {
@ -609,6 +636,7 @@ TABS.pid_tuning.initialize = function (callback) {
} }
if (semver.gte(CONFIG.apiVersion, "1.40.0")) { if (semver.gte(CONFIG.apiVersion, "1.40.0")) {
ADVANCED_TUNING.itermRotation = $('input[id="itermrotation"]').is(':checked') ? 1 : 0; ADVANCED_TUNING.itermRotation = $('input[id="itermrotation"]').is(':checked') ? 1 : 0;
ADVANCED_TUNING.smartFeedforward = $('input[id="smartfeedforward"]').is(':checked') ? 1 : 0; ADVANCED_TUNING.smartFeedforward = $('input[id="smartfeedforward"]').is(':checked') ? 1 : 0;
@ -620,8 +648,13 @@ TABS.pid_tuning.initialize = function (callback) {
ADVANCED_TUNING.throttleBoost = $('input[name="throttleBoost-number"]').val(); ADVANCED_TUNING.throttleBoost = $('input[name="throttleBoost-number"]').val();
ADVANCED_TUNING.acroTrainerAngleLimit = $('input[name="acroTrainerAngleLimit-number"]').val(); ADVANCED_TUNING.acroTrainerAngleLimit = $('input[name="acroTrainerAngleLimit-number"]').val();
}
ADVANCED_TUNING.feedforwardRoll = parseInt($('.pid_tuning .ROLL input[name="f"]').val());
ADVANCED_TUNING.feedforwardPitch = parseInt($('.pid_tuning .PITCH input[name="f"]').val());
ADVANCED_TUNING.feedforwardYaw = parseInt($('.pid_tuning .YAW input[name="f"]').val());
ADVANCED_TUNING.feedforwardTransition = parseInt($('input[name="feedforwardTransition-number"]').val() * 100);
}
} }
function showAllPids() { function showAllPids() {
@ -1467,8 +1500,13 @@ TABS.pid_tuning.updatePidControllerParameters = function () {
} else { } else {
$('.pid_tuning .YAW_JUMP_PREVENTION').hide(); $('.pid_tuning .YAW_JUMP_PREVENTION').hide();
$('#pid-tuning .dtermSetpointTransition').show(); if (semver.gte(CONFIG.apiVersion, "1.40.0")) {
$('#pid-tuning .dtermSetpoint').show(); $('#pid-tuning .dtermSetpointTransition').hide();
$('#pid-tuning .dtermSetpoint').hide();
} else {
$('#pid-tuning .dtermSetpointTransition').show();
$('#pid-tuning .dtermSetpoint').show();
}
$('#pid-tuning .delta').hide(); $('#pid-tuning .delta').hide();
} }

View File

@ -72,6 +72,7 @@
<th class="proportional" i18n="pidTuningProportional"></th> <th class="proportional" i18n="pidTuningProportional"></th>
<th class="integral" i18n="pidTuningIntegral"></th> <th class="integral" i18n="pidTuningIntegral"></th>
<th class="derivative" i18n="pidTuningDerivative"></th> <th class="derivative" i18n="pidTuningDerivative"></th>
<th class="feedforward" i18n="pidTuningFeedforward"></th>
<th class="rc_rate" i18n="pidTuningRcRate"></th> <th class="rc_rate" i18n="pidTuningRcRate"></th>
<th class="rate" i18n="pidTuningRate"></th> <th class="rate" i18n="pidTuningRate"></th>
<th class="new_rates maxVel" i18n="pidTuningMaxVel"></th> <th class="new_rates maxVel" i18n="pidTuningMaxVel"></th>
@ -80,7 +81,7 @@
</table> </table>
<table id="pid_main" class="pid_tuning"> <table id="pid_main" class="pid_tuning">
<tr> <tr>
<th colspan="8"> <th colspan="9">
<div class="pid_mode"> <div class="pid_mode">
<div i18n="pidTuningBasic" style="float:left;"></div> <div i18n="pidTuningBasic" style="float:left;"></div>
<div class="helpicon cf_tip" i18n_title="pidTuningPidTuningTip"></div> <div class="helpicon cf_tip" i18n_title="pidTuningPidTuningTip"></div>
@ -93,6 +94,7 @@
<td class="pid_data"><input type="number" name="p" step="1" min="0" max="255" /></td> <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 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="pid_data"><input type="number" name="d" step="1" min="0" max="255" /></td>
<td class="pid_data"><input type="number" name="f" step="1" min="0" max="255" /></td>
<td rowspan="2" style="background-color:white;"> <td rowspan="2" style="background-color:white;">
<input type="number" name="rc_rate" step="0.01" min="0" max="2.55" /> <input type="number" name="rc_rate" step="0.01" min="0" max="2.55" />
<div class="bracket"></div> <div class="bracket"></div>
@ -111,6 +113,7 @@
<td class="pid_data"><input type="number" name="p" step="1" min="0" max="255" /></td> <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 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="pid_data"><input type="number" name="d" step="1" min="0" max="255" /></td>
<td class="pid_data"><input type="number" name="f" 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="pitch_rate"><input type="number" name="pitch_rate" step="0.01" min="0" max="1.00" /></td>
<td class="new_rates maxAngularVelPitch"></td> <td class="new_rates maxAngularVelPitch"></td>
</tr> </tr>
@ -119,7 +122,8 @@
<td bgcolor="#8080FF"></td> <td bgcolor="#8080FF"></td>
<td class="pid_data"><input type="number" name="p" step="1" min="0" max="255" /></td> <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 class="pid_data"><input type="number" name="i" step="1" min="0" max="255" /></td>
<td></td> <td class="pid_data"><input type="number" name="d" step="1" min="0" max="255" /></td>
<td class="pid_data"><input type="number" name="f" step="1" min="0" max="255" /></td>
<td rowspan="1"><input type="number" name="rc_rate_yaw" step="0.01" min="0" max="2.55" /></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><input type="number" name="yaw_rate" step="0.01" min="0" max="2.55" /></td>
<td class="new_rates maxAngularVelYaw"></td> <td class="new_rates maxAngularVelYaw"></td>
@ -293,7 +297,7 @@
</div> </div>
</td> </td>
</tr> </tr>
<tr class="dtermSetpoint"> <tr class="dtermSetpoint" style="height:30px;">
<td><input type="number" name="dtermSetpoint-number" step="0.01" min="0.00" max="20"/></td> <td><input type="number" name="dtermSetpoint-number" step="0.01" min="0.00" max="20"/></td>
<td class="slider"><input type="range" name="dtermSetpoint-range" step="0.01" min="0.00" max="20"/></td> <td class="slider"><input type="range" name="dtermSetpoint-range" step="0.01" min="0.00" max="20"/></td>
<td> <td>
@ -323,6 +327,19 @@
</td> </td>
</tr> </tr>
<tr class="feedforwardTransition" style="height:30px;">
<td><input type="number" name="feedforwardTransition-number" step="0.01" min="0.00" max="1.00"/></td>
<td class="slider"><input type="range" name="feedforwardTransition-range" step="0.01" min="0.00" max="1.00"/></td>
<td>
<div>
<label>
<span i18n="pidTuningFeedforwardTransition"></span>
</label>
<div class="helpicon cf_tip" i18n_title="pidTuningFeedforwardTransitionHelp"></div>
</div>
</td>
</tr>
<tr class="acroTrainerAngleLimit"> <tr class="acroTrainerAngleLimit">
<td><input type="number" name="acroTrainerAngleLimit-number" step="1" min="0" max="80"/></td> <td><input type="number" name="acroTrainerAngleLimit-number" step="1" min="0" max="80"/></td>
<td class="slider"><input type="range" name="acroTrainerAngleLimit-range" step="1" min="0" max="80"/></td> <td class="slider"><input type="range" name="acroTrainerAngleLimit-range" step="1" min="0" max="80"/></td>