1
0
Fork 0
mirror of https://github.com/betaflight/betaflight-configurator.git synced 2025-07-24 00:35:26 +03:00

Rearrange configuration and motor tab

This commit is contained in:
Mark Haslinghuis 2020-12-25 11:18:16 +01:00
parent de071bc136
commit 4d64cda9aa
10 changed files with 1821 additions and 1737 deletions

View file

@ -1,38 +1,46 @@
'use strict';
TABS.motors = {
feature3DEnabled: false,
escProtocolIsDshot: false,
sensor: "gyro",
sensorGyroRate: 20,
sensorGyroScale: 2000,
sensorAccelRate: 20,
sensorAccelScale: 2,
sensorSelectValues: {
"gyroScale": {"10" : 10,
"25" : 25,
"50" : 50,
"100" : 100,
"200" : 200,
"300" : 300,
"400" : 400,
"500" : 500,
"1000" : 1000,
"2000" : 2000},
"accelScale": {"0.05" : 0.05,
"0.1" : 0.1,
"0.2" : 0.2,
"0.3" : 0.3,
"0.4" : 0.4,
"0.5" : 0.5,
"1" : 1,
"2" : 2}
previousDshotBidir: null,
previousFilterDynQ: null,
previousFilterDynWidth: null,
analyticsChanges: {},
isDirty: false,
feature3DEnabled: false,
sensor: "gyro",
sensorGyroRate: 20,
sensorGyroScale: 2000,
sensorAccelRate: 20,
sensorAccelScale: 2,
sensorSelectValues: {
"gyroScale": {
"10" : 10,
"25" : 25,
"50" : 50,
"100" : 100,
"200" : 200,
"300" : 300,
"400" : 400,
"500" : 500,
"1000" : 1000,
"2000" : 2000,
},
// These are translated into proper Dshot values on the flight controller
DSHOT_DISARMED_VALUE: 1000,
DSHOT_MAX_VALUE: 2000,
DSHOT_3D_NEUTRAL: 1500,
numberOfValidOutputs: -1,
"accelScale": {
"0.05" : 0.05,
"0.1" : 0.1,
"0.2" : 0.2,
"0.3" : 0.3,
"0.4" : 0.4,
"0.5" : 0.5,
"1" : 1,
"2" : 2,
},
},
// These are translated into proper Dshot values on the flight controller
DSHOT_PROTOCOL_MIN_VALUE: 0,
DSHOT_DISARMED_VALUE: 1000,
DSHOT_MAX_VALUE: 2000,
DSHOT_3D_NEUTRAL: 1500,
};
TABS.motors.initialize = function (callback) {
@ -41,59 +49,33 @@ TABS.motors.initialize = function (callback) {
self.armed = false;
self.escProtocolIsDshot = false;
// Update filtering defaults based on API version
const FILTER_DEFAULT = FC.getFilterDefaults();
if (GUI.active_tab != 'motors') {
GUI.active_tab = 'motors';
}
function get_arm_status() {
MSP.send_message(MSPCodes.MSP_STATUS, false, false, load_feature_config);
}
function load_feature_config() {
MSP.send_message(MSPCodes.MSP_FEATURE_CONFIG, false, false, load_motor_3d_config);
}
function load_motor_3d_config() {
MSP.send_message(MSPCodes.MSP_MOTOR_3D_CONFIG, false, false, load_esc_protocol);
}
function load_esc_protocol() {
MSP.send_message(MSPCodes.MSP_ADVANCED_CONFIG, false, false, load_motor_output_reordering);
}
function load_motor_output_reordering() {
MSP.send_message(MSPCodes.MSP2_MOTOR_OUTPUT_REORDERING, false, false, load_motor_data);
}
function load_motor_data() {
MSP.send_message(MSPCodes.MSP_MOTOR, false, false, load_motor_telemetry_data);
}
function load_motor_telemetry_data() {
if (FC.MOTOR_CONFIG.use_dshot_telemetry || FC.MOTOR_CONFIG.use_esc_sensor) {
MSP.send_message(MSPCodes.MSP_MOTOR_TELEMETRY, false, false, load_mixer_config);
} else {
load_mixer_config();
}
}
function load_mixer_config() {
MSP.send_message(MSPCodes.MSP_MIXER_CONFIG, false, false, load_html);
}
Promise
.resolve(true)
.then(() => { return MSP.promise(MSPCodes.MSP_STATUS); })
.then(() => { return MSP.promise(MSPCodes.MSP_FEATURE_CONFIG); })
.then(() => { return MSP.promise(MSPCodes.MSP_MIXER_CONFIG); })
.then(() => { return (FC.MOTOR_CONFIG.use_dshot_telemetry || FC.MOTOR_CONFIG.use_esc_sensor) ? MSP.promise(MSPCodes.MSP_MOTOR_TELEMETRY) : true; })
.then(() => { return MSP.promise(MSPCodes.MSP_MOTOR_CONFIG); })
.then(() => { return MSP.promise(MSPCodes.MSP_MOTOR_3D_CONFIG); })
.then(() => { return MSP.promise(MSPCodes.MSP2_MOTOR_OUTPUT_REORDERING); })
.then(() => { return MSP.promise(MSPCodes.MSP_ADVANCED_CONFIG); })
.then(() => { return MSP.promise(MSPCodes.MSP_ARMING_CONFIG); })
.then(() => { return (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_42)) ? MSP.promise(MSPCodes.MSP_FILTER_CONFIG) : true; })
.then(() => { return MSP.promise(MSPCodes.MSP_MIXER_CONFIG); })
.then(() => { return (semver.gte(FC.CONFIG.apiVersion, "1.8.0")) ? MSP.promise(MSPCodes.MSP_ARMING_CONFIG) : true; })
.then(() => { load_html(); });
function load_html() {
$('#content').load("./tabs/motors.html", process_html);
}
// Get information from Betaflight
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_36)) {
// BF 3.2.0+
MSP.send_message(MSPCodes.MSP_MOTOR_CONFIG, false, false, get_arm_status);
} else {
// BF 3.1.x or older
MSP.send_message(MSPCodes.MSP_MISC, false, false, get_arm_status);
}
function update_arm_status() {
self.armed = bit_check(FC.CONFIG.mode, 0);
}
@ -241,8 +223,10 @@ TABS.motors.initialize = function (callback) {
update_arm_status();
self.feature3DEnabled = FC.FEATURE_CONFIG.features.isEnabled('3D');
const motorsEnableTestModeElement = $('#motorsEnableTestMode');
self.analyticsChanges = {};
$('#motorsEnableTestMode').prop('checked', false);
motorsEnableTestModeElement.prop('checked', false);
if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_42) || !(FC.MOTOR_CONFIG.use_dshot_telemetry || FC.MOTOR_CONFIG.use_esc_sensor)) {
$(".motor_testing .telemetry").hide();
@ -253,6 +237,80 @@ TABS.motors.initialize = function (callback) {
}
}
const toolButtons = $('.tool-buttons');
function setContentToolbarButtons() {
if (self.isDirty) {
// save and reboot button appears after changing settings
toolButtons.hide();
$('.save_btn').show();
} else {
// hide save and reboot until settings are actually changed.
// if done this way we don't have to stop motors because it can't activate after settings changed.
$('.save_btn').hide();
}
}
setContentToolbarButtons();
// Stop motor testing on configuration changes
function disableHandler(e) {
if (e.target !== e.currentTarget) {
self.isDirty = true;
disableMotorTest();
setContentToolbarButtons();
}
e.stopPropagation();
}
// Add EventListener for configuration changes
document.querySelectorAll('.configuration').forEach(elem => elem.addEventListener('change', disableHandler));
/*
* MIXER
*/
const mixerListElement = $('select.mixerList');
for (let selectIndex = 0; selectIndex < mixerList.length; selectIndex++) {
mixerList.forEach(function (mixerEntry, mixerIndex) {
if (mixerEntry.pos === selectIndex) {
mixerListElement.append(`<option value="${(mixerIndex + 1)}">${mixerEntry.name}</option>`);
}
});
}
function refreshMixerPreview() {
const mixer = FC.MIXER_CONFIG.mixer;
const reverse = FC.MIXER_CONFIG.reverseMotorDir ? "_reversed" : "";
$('.mixerPreview img').attr('src', `./resources/motor_order/${mixerList[mixer - 1].image}${reverse}.svg`);
}
const reverseMotorSwitchElement = $('#reverseMotorSwitch');
reverseMotorSwitchElement.change(function() {
FC.MIXER_CONFIG.reverseMotorDir = $(this).prop('checked') ? 1 : 0;
refreshMixerPreview();
});
reverseMotorSwitchElement.prop('checked', FC.MIXER_CONFIG.reverseMotorDir !== 0).change();
mixerListElement.change(function () {
const mixerValue = parseInt($(this).val());
let newValue;
if (mixerValue !== FC.MIXER_CONFIG.mixer) {
newValue = $(this).find('option:selected').text();
}
self.analyticsChanges['Mixer'] = newValue;
FC.MIXER_CONFIG.mixer = mixerValue;
refreshMixerPreview();
});
// select current mixer configuration
mixerListElement.val(FC.MIXER_CONFIG.mixer).change();
update_model(FC.MIXER_CONFIG.mixer);
// Always start with default/empty sensor data array, clean slate all
@ -272,15 +330,15 @@ TABS.motors.initialize = function (callback) {
let accelOffsetEstablished = false;
// cached elements
const motorVoltage = $('.motors-bat-voltage'),
motor_mah_drawing_e = $('.motors-bat-mah-drawing'),
motor_mah_drawn_e = $('.motors-bat-mah-drawn');
const motorVoltage = $('.motors-bat-voltage');
const motorMahDrawingElement = $('.motors-bat-mah-drawing');
const motorMahDrawnElement = $('.motors-bat-mah-drawn');
const rawDataTextElements = {
x: [],
y: [],
z: [],
rms: []
x: [],
y: [],
z: [],
rms: []
};
$('.plot_control .x, .plot_control .y, .plot_control .z, .plot_control .rms').each(function () {
@ -373,7 +431,7 @@ TABS.motors.initialize = function (callback) {
accelOffset[0] + FC.SENSOR_DATA.accelerometer[0],
accelOffset[1] + FC.SENSOR_DATA.accelerometer[1],
accelOffset[2] + FC.SENSOR_DATA.accelerometer[2],
];
];
updateGraphHelperSize(accelHelpers);
samplesAccel = addSampleToData(accelData, samplesAccel, accelWithOffset);
@ -421,7 +479,6 @@ TABS.motors.initialize = function (callback) {
}
});
// set refresh speeds according to configuration saved in storage
ConfigStorage.get(['motors_tab_sensor_settings', 'motors_tab_gyro_settings', 'motors_tab_accel_settings'], function (result) {
if (result.motors_tab_sensor_settings) {
@ -440,12 +497,11 @@ TABS.motors.initialize = function (callback) {
$('.tab-motors .sensor select:first').change();
});
// Amperage
function power_data_pull() {
motorVoltage.text(i18n.getMessage('motorsVoltageValue', [FC.ANALOG.voltage]));
motor_mah_drawing_e.text(i18n.getMessage('motorsADrawingValue', [FC.ANALOG.amperage.toFixed(2)]));
motor_mah_drawn_e.text(i18n.getMessage('motorsmAhDrawnValue', [FC.ANALOG.mAhdrawn]));
motorMahDrawingElement.text(i18n.getMessage('motorsADrawingValue', [FC.ANALOG.amperage.toFixed(2)]));
motorMahDrawnElement.text(i18n.getMessage('motorsmAhDrawnValue', [FC.ANALOG.mAhdrawn]));
}
GUI.interval_add('motors_power_data_pull_slow', power_data_pull, 250, true); // 4 fps
@ -472,42 +528,206 @@ TABS.motors.initialize = function (callback) {
neutral3d = (FC.MOTOR_3D_CONFIG.neutral > 1575 || FC.MOTOR_3D_CONFIG.neutral < 1425) ? 1500 : FC.MOTOR_3D_CONFIG.neutral;
}
const motorsWrapper = $('.motors .bar-wrapper'),
servos_wrapper = $('.servos .bar-wrapper');
const motorsWrapper = $('.motors .bar-wrapper');
for (let i = 0; i < 8; i++) {
motorsWrapper.append(`\
<div class="m-block motor-${i}">\
<div class="meter-bar">\
<div class="label"></div>\
<div class="indicator">\
<div class="label">\
<div class="label"></div>\
</div>\
</div>\
</div>\
</div>\
<div class="m-block motor-${i}">\
<div class="meter-bar">\
<div class="label"></div>\
<div class="indicator">\
<div class="label">\
<div class="label"></div>\
</div>\
</div>\
</div>\
</div>\
`);
servos_wrapper.append('\
<div class="m-block servo-' + (7 - i) + '">\
<div class="meter-bar">\
<div class="label"></div>\
<div class="indicator">\
<div class="label">\
<div class="label"></div>\
</div>\
</div>\
</div>\
</div>\
');
}
$('div.sliders input').prop('min', rangeMin)
.prop('max', rangeMax);
$('div.values li:not(:last)').text(rangeMin);
// UI hooks
const featuresElement = $('.tab-motors .features');
FC.FEATURE_CONFIG.features.generateElements(featuresElement);
/*
* ESC protocol
*/
const escProtocols = EscProtocols.GetAvailableProtocols(FC.CONFIG.apiVersion);
const escProtocolElement = $('select.escprotocol');
for (let j = 0; j < escProtocols.length; j++) {
escProtocolElement.append(`<option value="${j + 1}">${escProtocols[j]}</option>`);
}
const unsyncedPWMSwitchElement = $("input[id='unsyncedPWMSwitch']");
const divUnsyncedPWMFreq = $('div.unsyncedpwmfreq');
unsyncedPWMSwitchElement.on("change", function () {
if ($(this).is(':checked')) {
divUnsyncedPWMFreq.show();
} else {
divUnsyncedPWMFreq.hide();
}
});
const dshotBidirElement = $('input[id="dshotBidir"]');
unsyncedPWMSwitchElement.prop('checked', FC.PID_ADVANCED_CONFIG.use_unsyncedPwm !== 0).trigger("change");
$('input[name="unsyncedpwmfreq"]').val(FC.PID_ADVANCED_CONFIG.motor_pwm_rate);
$('input[name="digitalIdlePercent"]').val(FC.PID_ADVANCED_CONFIG.digitalIdlePercent);
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_42)) {
dshotBidirElement.prop('checked', FC.MOTOR_CONFIG.use_dshot_telemetry).trigger("change");
self.previousDshotBidir = FC.MOTOR_CONFIG.use_dshot_telemetry;
self.previousFilterDynQ = FC.FILTER_CONFIG.dyn_notch_q;
self.previousFilterDynWidth = FC.FILTER_CONFIG.dyn_notch_width_percent;
dshotBidirElement.on("change", function () {
const value = $(this).prop('checked');
const newValue = (value !== FC.MOTOR_CONFIG.use_dshot_telemetry) ? 'On' : 'Off';
self.analyticsChanges['BidirectionalDshot'] = newValue;
FC.MOTOR_CONFIG.use_dshot_telemetry = value;
FC.FILTER_CONFIG.dyn_notch_width_percent = self.previousFilterDynWidth;
FC.FILTER_CONFIG.dyn_notch_q = self.previousFilterDynQ;
if (FC.FILTER_CONFIG.gyro_rpm_notch_harmonics !== 0) { // if rpm filter is active
if (value && !self.previousDshotBidir) {
FC.FILTER_CONFIG.dyn_notch_width_percent = FILTER_DEFAULT.dyn_notch_width_percent_rpm;
FC.FILTER_CONFIG.dyn_notch_q = FILTER_DEFAULT.dyn_notch_q_rpm;
} else if (!value && self.previousDshotBidir) {
FC.FILTER_CONFIG.dyn_notch_width_percent = FILTER_DEFAULT.dyn_notch_width_percent;
FC.FILTER_CONFIG.dyn_notch_q = FILTER_DEFAULT.dyn_notch_q;
}
}
if (FC.FILTER_CONFIG.dyn_notch_width_percent !== self.previousFilterDynWidth) {
showDialogDynFiltersChange();
}
});
$('input[name="motorPoles"]').val(FC.MOTOR_CONFIG.motor_poles);
}
$('#escProtocolTooltip').toggle(semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_42));
$('#escProtocolTooltipNoDSHOT1200').toggle(semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_42));
function updateVisibility() {
// Hide unused settings
const protocolName = $('select.escprotocol option:selected').text();
const protocolConfigured = protocolName !== 'DISABLED';
let digitalProtocol = false;
switch (protocolName) {
case 'DSHOT150':
case 'DSHOT300':
case 'DSHOT600':
case 'DSHOT1200':
case 'PROSHOT1000':
digitalProtocol = true;
break;
default:
}
const rpmFeaturesVisible = digitalProtocol && dshotBidirElement.is(':checked') || $("input[name='ESC_SENSOR']").is(':checked');
$('div.minthrottle').toggle(protocolConfigured && !digitalProtocol);
$('div.maxthrottle').toggle(protocolConfigured && !digitalProtocol);
$('div.mincommand').toggle(protocolConfigured && !digitalProtocol);
$('div.checkboxPwm').toggle(protocolConfigured && !digitalProtocol);
divUnsyncedPWMFreq.toggle(protocolConfigured && !digitalProtocol);
$('div.digitalIdlePercent').toggle(protocolConfigured && digitalProtocol);
$('.escSensor').toggle(protocolConfigured && digitalProtocol);
$('div.checkboxDshotBidir').toggle(protocolConfigured && semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_42) && digitalProtocol);
$('div.motorPoles').toggle(protocolConfigured && rpmFeaturesVisible && semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_42));
$('.escMotorStop').toggle(protocolConfigured);
$('#escProtocolDisabled').toggle(!protocolConfigured);
//trigger change unsyncedPWMSwitch to show/hide Motor PWM freq input
unsyncedPWMSwitchElement.trigger("change");
}
escProtocolElement.val(FC.PID_ADVANCED_CONFIG.fast_pwm_protocol + 1);
escProtocolElement.on("change", function () {
const escProtocolValue = parseInt($(this).val()) - 1;
let newValue = undefined;
if (escProtocolValue !== FC.PID_ADVANCED_CONFIG.fast_pwm_protocol) {
newValue = $(this).find('option:selected').text();
}
self.analyticsChanges['EscProtocol'] = newValue;
updateVisibility();
}).trigger("change");
//trigger change dshotBidir and ESC_SENSOR to show/hide Motor Poles tab
dshotBidirElement.change(updateVisibility).trigger("change");
$("input[name='ESC_SENSOR']").on("change", updateVisibility).trigger("change");
// fill throttle
$('input[name="minthrottle"]').val(FC.MOTOR_CONFIG.minthrottle);
$('input[name="maxthrottle"]').val(FC.MOTOR_CONFIG.maxthrottle);
$('input[name="mincommand"]').val(FC.MOTOR_CONFIG.mincommand);
//fill 3D
$('.tab-motors ._3d').show();
$('input[name="3ddeadbandlow"]').val(FC.MOTOR_3D_CONFIG.deadband3d_low);
$('input[name="3ddeadbandhigh"]').val(FC.MOTOR_3D_CONFIG.deadband3d_high);
$('input[name="3dneutral"]').val(FC.MOTOR_3D_CONFIG.neutral);
/*
* UI hooks
*/
function checkUpdate3dControls() {
if (FC.FEATURE_CONFIG.features.isEnabled('3D')) {
$('._3dSettings').show();
} else {
$('._3dSettings').hide();
}
}
$('input.feature', featuresElement).on("change", function () {
const element = $(this);
FC.FEATURE_CONFIG.features.updateData(element);
updateTabList(FC.FEATURE_CONFIG.features);
switch (element.attr('name')) {
case 'MOTOR_STOP':
break;
case '3D':
checkUpdate3dControls();
break;
default:
break;
}
});
$(featuresElement).filter('select').change(function () {
const element = $(this);
FC.FEATURE_CONFIG.features.updateData(element);
updateTabList(FC.FEATURE_CONFIG.features);
});
checkUpdate3dControls();
/*
* MOTOR TESTING
*/
function setSlidersDefault() {
// change all values to default
if (self.feature3DEnabled) {
@ -521,13 +741,15 @@ TABS.motors.initialize = function (callback) {
if (isEnabled && !self.armed) {
$('div.sliders input').slice(0, self.numberOfValidOutputs).prop('disabled', false);
// unlock master slider
// unlock master slider and hide tool-buttons
$('div.sliders input:last').prop('disabled', false);
toolButtons.hide();
} else {
setSlidersDefault();
// disable sliders / min max
// disable sliders / min max and show tool-buttons
$('div.sliders input').prop('disabled', true);
toolButtons.show();
}
$('div.sliders input').trigger('input');
@ -535,9 +757,25 @@ TABS.motors.initialize = function (callback) {
setSlidersDefault();
$('#motorsEnableTestMode').change(function () {
const enabled = $(this).is(':checked');
// disables Motor Testing if settings are being changed (must save and reboot).
function disableMotorTest() {
self.isDirty = true;
motorsEnableTestModeElement.trigger("change");
}
motorsEnableTestModeElement.change(function () {
let enabled = $(this).is(':checked');
// prevent testing if dirty flag is set.
if (self.isDirty) {
// if enabled or trying to enable - Inform the user to save settings if silent flag is not set
if (enabled) {
const message = i18n.getMessage('motorsDialogSettingsChanged');
showDialogSettingsChanged(message);
}
enabled = false;
// disable input
motorsEnableTestModeElement.prop('checked', false);
}
setSlidersEnabled(enabled);
$('div.sliders input').trigger('input');
@ -596,7 +834,7 @@ TABS.motors.initialize = function (callback) {
}
if (motorsRunning) {
$('#motorsEnableTestMode').prop('checked', true).change();
motorsEnableTestModeElement.prop('checked', true).change();
// motors are running adjust sliders to current values
@ -636,16 +874,12 @@ TABS.motors.initialize = function (callback) {
function get_motor_telemetry_data() {
if (FC.MOTOR_CONFIG.use_dshot_telemetry || FC.MOTOR_CONFIG.use_esc_sensor) {
MSP.send_message(MSPCodes.MSP_MOTOR_TELEMETRY, false, false, get_servo_data);
MSP.send_message(MSPCodes.MSP_MOTOR_TELEMETRY, false, false, update_ui);
} else {
get_servo_data();
update_ui();
}
}
function get_servo_data() {
MSP.send_message(MSPCodes.MSP_SERVO, false, false, update_ui);
}
const fullBlockScale = rangeMax - rangeMin;
function update_ui() {
@ -681,15 +915,13 @@ TABS.motors.initialize = function (callback) {
rpmMotorValue = rpmMotorValue.toString().padStart(MAX_VALUE_SIZE);
let telemetryText = i18n.getMessage('motorsRPM', {motorsRpmValue: rpmMotorValue});
if (FC.MOTOR_CONFIG.use_dshot_telemetry) {
let invalidPercent = FC.MOTOR_TELEMETRY_DATA.invalidPercent[i];
let classError = (invalidPercent > MAX_INVALID_PERCENT) ? "warning" : "";
invalidPercent = (invalidPercent / 100).toFixed(2).toString().padStart(MAX_VALUE_SIZE);
telemetryText += "<br><span class='" + classError + "'>";
telemetryText += `<br><span class="${classError}">`;
telemetryText += i18n.getMessage('motorsRPMError', {motorsErrorValue: invalidPercent});
telemetryText += "</span>";
}
@ -697,40 +929,71 @@ TABS.motors.initialize = function (callback) {
if (FC.MOTOR_CONFIG.use_esc_sensor) {
let escTemperature = FC.MOTOR_TELEMETRY_DATA.temperature[i];
escTemperature = escTemperature.toString().padStart(MAX_VALUE_SIZE);
telemetryText += "<br>";
escTemperature = escTemperature.toString().padStart(MAX_VALUE_SIZE);
telemetryText += i18n.getMessage('motorsESCTemperature', {motorsESCTempValue: escTemperature});
}
$('.motor_testing .telemetry .motor-' + i).html(telemetryText);
$(`.motor_testing .telemetry .motor-${i}`).html(telemetryText);
}
}
// servo indicators are still using old (not flexible block scale), it will be changed in the future accordingly
for (let i = 0; i < FC.SERVO_DATA.length; i++) {
const data = FC.SERVO_DATA[i] - 1000,
marginTop = blockHeight - (data * (blockHeight / 1000)).clamp(0, blockHeight),
height = (data * (blockHeight / 1000)).clamp(0, blockHeight),
color = parseInt(data * 0.009);
$(`.servo-${i} .label`, servos_wrapper).text(FC.SERVO_DATA[i]);
$(`.servo-${i} .indicator`, servos_wrapper).css({
'margin-top' : `${marginTop}px`,
'height' : `${height}px`,
'background-color' : `rgba(255,187,0,1${color})`,
});
}
//keep the following here so at least we get a visual cue of our motor setup
update_arm_status();
if (previousArmState != self.armed) {
console.log('arm state change detected');
$('#motorsEnableTestMode').change();
motorsEnableTestModeElement.change();
}
}
$('a.save').on('click', function() {
// gather data that doesn't have automatic change event bound
FC.MOTOR_CONFIG.minthrottle = parseInt($('input[name="minthrottle"]').val());
FC.MOTOR_CONFIG.maxthrottle = parseInt($('input[name="maxthrottle"]').val());
FC.MOTOR_CONFIG.mincommand = parseInt($('input[name="mincommand"]').val());
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_42)) {
FC.MOTOR_CONFIG.motor_poles = parseInt($('input[name="motorPoles"]').val());
}
FC.MOTOR_3D_CONFIG.deadband3d_low = parseInt($('input[name="3ddeadbandlow"]').val());
FC.MOTOR_3D_CONFIG.deadband3d_high = parseInt($('input[name="3ddeadbandhigh"]').val());
FC.MOTOR_3D_CONFIG.neutral = parseInt($('input[name="3dneutral"]').val());
FC.PID_ADVANCED_CONFIG.fast_pwm_protocol = parseInt(escProtocolElement.val() - 1);
FC.PID_ADVANCED_CONFIG.use_unsyncedPwm = unsyncedPWMSwitchElement.is(':checked') ? 1 : 0;
FC.PID_ADVANCED_CONFIG.motor_pwm_rate = parseInt($('input[name="unsyncedpwmfreq"]').val());
FC.PID_ADVANCED_CONFIG.digitalIdlePercent = parseFloat($('input[name="digitalIdlePercent"]').val());
if (semver.gte(FC.CONFIG.apiVersion, "1.25.0") && semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_41)) {
FC.PID_ADVANCED_CONFIG.gyroUse32kHz = $('input[id="gyroUse32kHz"]').is(':checked') ? 1 : 0;
}
Promise
.resolve(true)
.then(() => { return MSP.promise(MSPCodes.MSP_SET_FEATURE_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_FEATURE_CONFIG)); })
.then(() => { return MSP.promise(MSPCodes.MSP_SET_MIXER_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_MIXER_CONFIG)); })
.then(() => { return MSP.promise(MSPCodes.MSP_SET_MOTOR_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_MOTOR_CONFIG)); })
.then(() => { return MSP.promise(MSPCodes.MSP_SET_MOTOR_3D_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_MOTOR_3D_CONFIG)); })
.then(() => { return MSP.promise(MSPCodes.MSP_SET_ADVANCED_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_ADVANCED_CONFIG)); })
.then(() => { return MSP.promise(MSPCodes.MSP_SET_ARMING_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_ARMING_CONFIG)); })
.then(() => { return (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_42)) ? MSP.promise(MSPCodes.MSP_SET_FILTER_CONFIG,
mspHelper.crunch(MSPCodes.MSP_SET_FILTER_CONFIG)) : true; })
.then(() => { return MSP.promise(MSPCodes.MSP_EEPROM_WRITE); })
.then(() => {
GUI.log(i18n.getMessage('configurationEepromSaved'));
MSP.send_message(MSPCodes.MSP_SET_REBOOT, false, false);
reinitialiseConnection(self);
});
analytics.sendChangeEvents(analytics.EVENT_CATEGORIES.FLIGHT_CONTROLLER, self.analyticsChanges);
self.analyticsChanges = {};
self.isDirty = false;
});
// enable Status and Motor data pulling
GUI.interval_add('motor_and_status_pull', get_status, 50, true);
@ -750,7 +1013,20 @@ TABS.motors.initialize = function (callback) {
GUI.content_ready(callback);
}
GUI.content_ready(callback);
GUI.content_ready(callback);
}
function showDialogSettingsChanged(message) {
const dialogSettingsChanged = $('#dialog-settings-changed')[0];
$('#dialog-settings-changed-content').html(message);
if (!dialogSettingsChanged.hasAttribute('open')) {
dialogSettingsChanged.showModal();
$('#dialog-settings-changed-confirmbtn').click(function() {
dialogSettingsChanged.close();
});
}
}
function setup_motor_output_reordering_dialog(callbackFunction, zeroThrottleValue)