mirror of
https://github.com/iNavFlight/inav-configurator.git
synced 2025-07-26 09:45:23 +03:00
dynamic polling interval on receiver page
This commit is contained in:
parent
9569c0b5ee
commit
297ad70c5d
9 changed files with 161 additions and 142 deletions
|
@ -442,6 +442,11 @@ function sensor_status_hash(hw_status)
|
|||
* @deprecated
|
||||
*/
|
||||
function sensor_status(sensors_detected) {
|
||||
|
||||
if (typeof SENSOR_STATUS === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
SENSOR_STATUS.isHardwareHealthy = 1;
|
||||
SENSOR_STATUS.gyroHwStatus = have_sensor(sensors_detected, 'gyro') ? 1 : 0;
|
||||
SENSOR_STATUS.accHwStatus = have_sensor(sensors_detected, 'acc') ? 1 : 0;
|
||||
|
|
|
@ -10,9 +10,9 @@ helper.mspQueue = (function (serial, MSP) {
|
|||
privateScope.handlerFrequency = 100;
|
||||
privateScope.balancerFrequency = 10;
|
||||
|
||||
privateScope.loadFilter = new classes.SimpleSmoothFilter(0.5, 0.996);
|
||||
privateScope.roundtripFilter = new classes.SimpleSmoothFilter(20, 0.996);
|
||||
privateScope.hardwareRoundtripFilter = new classes.SimpleSmoothFilter(5, 0.996);
|
||||
privateScope.loadFilter = new classes.SimpleSmoothFilter(0.5, 0.995);
|
||||
privateScope.roundtripFilter = new classes.SimpleSmoothFilter(20, 0.95);
|
||||
privateScope.hardwareRoundtripFilter = new classes.SimpleSmoothFilter(5, 0.95);
|
||||
|
||||
/**
|
||||
* Target load for MSP queue. When load is above target, throttling might start to appear
|
||||
|
@ -29,7 +29,7 @@ helper.mspQueue = (function (serial, MSP) {
|
|||
*/
|
||||
privateScope.loadPidController = new classes.PidController();
|
||||
privateScope.loadPidController.setTarget(privateScope.targetLoad);
|
||||
privateScope.loadPidController.setOutput(0, 97, 0);
|
||||
privateScope.loadPidController.setOutput(0, 99, 0);
|
||||
privateScope.loadPidController.setGains(16, 6, 4);
|
||||
privateScope.loadPidController.setItermLimit(0, 90);
|
||||
|
||||
|
@ -223,7 +223,7 @@ helper.mspQueue = (function (serial, MSP) {
|
|||
* Also, check if port lock if hanging. Free is so
|
||||
*/
|
||||
var currentTimestamp = new Date().getTime(),
|
||||
threshold = publicScope.getHardwareRoundtrip() * 4;
|
||||
threshold = publicScope.getHardwareRoundtrip() * 3;
|
||||
|
||||
if (threshold > 1000) {
|
||||
threshold = 1000;
|
||||
|
@ -248,6 +248,23 @@ helper.mspQueue = (function (serial, MSP) {
|
|||
return (Math.round(Math.random()*100) < (privateScope.dropRatio * privateScope.statusDropFactor));
|
||||
};
|
||||
|
||||
/**
|
||||
* This method return periodic for polling interval that should populate queue in 75% or less
|
||||
* @param {number} requestedInterval
|
||||
* @param {number} messagesInInterval
|
||||
* @returns {number}
|
||||
*/
|
||||
publicScope.getIntervalPrediction = function (requestedInterval, messagesInInterval) {
|
||||
var openWindow = publicScope.getRoundtrip() * 1.25,
|
||||
requestedWindow = requestedInterval / messagesInInterval;
|
||||
|
||||
if (requestedWindow < openWindow) {
|
||||
return openWindow;
|
||||
} else {
|
||||
return requestedInterval;
|
||||
}
|
||||
};
|
||||
|
||||
setInterval(publicScope.executor, Math.round(1000 / privateScope.handlerFrequency));
|
||||
setInterval(publicScope.balancer, Math.round(1000 / privateScope.balancerFrequency));
|
||||
|
||||
|
|
4
main.css
4
main.css
|
@ -176,6 +176,10 @@ input[type="number"]::-webkit-inner-spin-button {
|
|||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.portsinput__top-element--inline span {
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
.portsinput__top-element--port-override {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
|
|
@ -150,9 +150,9 @@
|
|||
<div class="portsinput__row">
|
||||
<div class="portsinput__top-element portsinput__top-element--inline">
|
||||
<label for="wireless-mode">
|
||||
<span class="auto_connect" data-i18n="wirelessModeSwitch"></span>
|
||||
<span class="" data-i18n="wirelessModeSwitch"></span>
|
||||
</label>
|
||||
<input id="wireless-mode" class="auto_connect togglesmall" type="checkbox"/>
|
||||
<input id="wireless-mode" class=" togglesmall" type="checkbox"/>
|
||||
</div>
|
||||
|
||||
<div class="portsinput__top-element portsinput__top-element--inline">
|
||||
|
|
|
@ -28,7 +28,6 @@ TABS.gps.initialize = function (callback) {
|
|||
}
|
||||
|
||||
function process_html() {
|
||||
// translate to user-selected languageconsole.log('Online');
|
||||
localize();
|
||||
|
||||
function get_raw_gps_data() {
|
||||
|
@ -101,7 +100,10 @@ TABS.gps.initialize = function (callback) {
|
|||
}
|
||||
}
|
||||
|
||||
// enable data pulling
|
||||
/*
|
||||
* enable data pulling
|
||||
* GPS is usually refreshed at 5Hz, there is no reason to pull it much more often, really...
|
||||
*/
|
||||
helper.interval.add('gps_pull', function gps_update() {
|
||||
// avoid usage of the GPS commands until a GPS sensor is detected for targets that are compiled without GPS support.
|
||||
if (!have_sensor(CONFIG.activeSensors, 'gps')) {
|
||||
|
@ -113,7 +115,7 @@ TABS.gps.initialize = function (callback) {
|
|||
}
|
||||
|
||||
get_raw_gps_data();
|
||||
}, 75, true);
|
||||
}, 250, true);
|
||||
|
||||
//check for internet connection on load
|
||||
if (navigator.onLine) {
|
||||
|
|
|
@ -330,11 +330,6 @@
|
|||
background-position: center;
|
||||
}
|
||||
|
||||
.tab-receiver select[name="rx_refresh_rate"] {
|
||||
float: right;
|
||||
border: 1px solid silver;
|
||||
}
|
||||
|
||||
.tab-receiver #RX_plot {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
|
|
|
@ -105,18 +105,6 @@
|
|||
<div class="clear-both"></div>
|
||||
<div class="gui_box grey" style="padding-top: 10px; padding-bottom: 10px; margin-top: 20px;">
|
||||
<div class="spacer">
|
||||
<select name="rx_refresh_rate" data-i18n_title="receiverRefreshRateTitle">
|
||||
<option value="10">10 ms</option>
|
||||
<option value="20">20 ms</option>
|
||||
<option value="30">30 ms</option>
|
||||
<option value="40">40 ms</option>
|
||||
<option value="50" selected="selected">50 ms</option>
|
||||
<option value="100">100 ms</option>
|
||||
<option value="250">250 ms</option>
|
||||
<option value="500">500 ms</option>
|
||||
<option value="1000">1000 ms</option>
|
||||
</select>
|
||||
<div class="clear-both"></div>
|
||||
<svg id="RX_plot">
|
||||
<g class="grid x" transform="translate(40, 180)"></g>
|
||||
<g class="grid y" transform="translate(40, 10)"></g>
|
||||
|
|
|
@ -43,14 +43,6 @@ TABS.receiver.initialize = function (callback) {
|
|||
$('.tunings .rate input[name="expo"]').val(RC_tuning.RC_EXPO.toFixed(2));
|
||||
$('.tunings .yaw_rate input[name="yaw_expo"]').val(RC_tuning.RC_YAW_EXPO.toFixed(2));
|
||||
|
||||
chrome.storage.local.get('rx_refresh_rate', function (result) {
|
||||
if (result.rx_refresh_rate) {
|
||||
$('select[name="rx_refresh_rate"]').val(result.rx_refresh_rate).change();
|
||||
} else {
|
||||
$('select[name="rx_refresh_rate"]').change(); // start with default value
|
||||
}
|
||||
});
|
||||
|
||||
$('.deadband input[name="yaw_deadband"]').val(RC_deadband.yaw_deadband);
|
||||
$('.deadband input[name="deadband"]').val(RC_deadband.deadband);
|
||||
|
||||
|
@ -100,7 +92,7 @@ TABS.receiver.initialize = function (callback) {
|
|||
|
||||
var meter_label_array = [];
|
||||
$('.meter', bar_container).each(function () {
|
||||
meter_label_array.push($('.label' , this));
|
||||
meter_label_array.push($('.label', this));
|
||||
});
|
||||
|
||||
// correct inner label margin on window resize (i don't know how we could do this in css)
|
||||
|
@ -125,15 +117,16 @@ TABS.receiver.initialize = function (callback) {
|
|||
}
|
||||
|
||||
// reconstruct
|
||||
var str = strBuffer.join('');
|
||||
var str = strBuffer.join(''),
|
||||
$rcMap = $('input[name="rcmap"]');
|
||||
|
||||
// set current value
|
||||
$('input[name="rcmap"]').val(str);
|
||||
$rcMap.val(str);
|
||||
|
||||
// validation / filter
|
||||
var last_valid = str;
|
||||
|
||||
$('input[name="rcmap"]').on('input', function () {
|
||||
$rcMap.on('input', function () {
|
||||
var val = $(this).val();
|
||||
|
||||
// limit length to max 8
|
||||
|
@ -143,7 +136,7 @@ TABS.receiver.initialize = function (callback) {
|
|||
}
|
||||
});
|
||||
|
||||
$('input[name="rcmap"]').focusout(function () {
|
||||
$rcMap.focusout(function () {
|
||||
var val = $(this).val(),
|
||||
strBuffer = val.split(''),
|
||||
duplicityBuffer = [];
|
||||
|
@ -172,7 +165,7 @@ TABS.receiver.initialize = function (callback) {
|
|||
// handle helper
|
||||
$('select[name="rcmap_helper"]').val(0); // go out of bounds
|
||||
$('select[name="rcmap_helper"]').change(function () {
|
||||
$('input[name="rcmap"]').val($(this).val());
|
||||
$rcMap.val($(this).val());
|
||||
});
|
||||
|
||||
// rssi
|
||||
|
@ -212,7 +205,7 @@ TABS.receiver.initialize = function (callback) {
|
|||
midxl = midx * 0.5,
|
||||
midxr = (((200 - midx) * 0.5) + midx),
|
||||
midy = rateHeight - (midx * (rateHeight / 200)),
|
||||
midyl = rateHeight - ((rateHeight - midy) * 0.5 *(expo + 1)),
|
||||
midyl = rateHeight - ((rateHeight - midy) * 0.5 * (expo + 1)),
|
||||
midyr = (midy / 2) * (expo + 1);
|
||||
|
||||
// draw
|
||||
|
@ -322,7 +315,7 @@ TABS.receiver.initialize = function (callback) {
|
|||
MSP.send_message(MSPCodes.MSP_SET_RC_TUNING, mspHelper.crunch(MSPCodes.MSP_SET_RC_TUNING), false, save_rc_map);
|
||||
});
|
||||
|
||||
$("a.sticks").click(function() {
|
||||
$("a.sticks").click(function () {
|
||||
var
|
||||
windowWidth = 370,
|
||||
windowHeight = 510;
|
||||
|
@ -335,9 +328,9 @@ TABS.receiver.initialize = function (callback) {
|
|||
maxWidth: windowWidth, maxHeight: windowHeight
|
||||
},
|
||||
alwaysOnTop: true
|
||||
}, function(createdWindow) {
|
||||
}, function (createdWindow) {
|
||||
// Give the window a callback it can use to send the channels (otherwise it can't see those objects)
|
||||
createdWindow.contentWindow.setRawRx = function(channels) {
|
||||
createdWindow.contentWindow.setRawRx = function (channels) {
|
||||
if (CONFIGURATOR.connectionValid && GUI.active_tab != 'cli') {
|
||||
mspHelper.setRawRx(channels);
|
||||
return true;
|
||||
|
@ -351,13 +344,18 @@ TABS.receiver.initialize = function (callback) {
|
|||
// Only show the MSP control sticks if the MSP Rx feature is enabled
|
||||
$(".sticks_btn").toggle(bit_check(BF_CONFIG.features, 14 /* RX_MSP */));
|
||||
|
||||
$('select[name="rx_refresh_rate"]').change(function () {
|
||||
var plot_update_rate = parseInt($(this).val(), 10);
|
||||
|
||||
// save update rate
|
||||
chrome.storage.local.set({'rx_refresh_rate': plot_update_rate});
|
||||
|
||||
function get_rc_data() {
|
||||
|
||||
/*
|
||||
* Throttling
|
||||
*/
|
||||
if (helper.mspQueue.shouldDrop()) {
|
||||
update_ui();
|
||||
return;
|
||||
}
|
||||
|
||||
MSP.send_message(MSPCodes.MSP_RC, false, false, update_ui);
|
||||
}
|
||||
|
||||
|
@ -382,20 +380,22 @@ TABS.receiver.initialize = function (callback) {
|
|||
}
|
||||
|
||||
function update_ui() {
|
||||
var i;
|
||||
|
||||
// update bars with latest data
|
||||
for (var i = 0; i < RC.active_channels; i++) {
|
||||
for (i = 0; i < RC.active_channels; i++) {
|
||||
meter_fill_array[i].css('width', ((RC.channels[i] - meter_scale.min) / (meter_scale.max - meter_scale.min) * 100).clamp(0, 100) + '%');
|
||||
meter_label_array[i].text(RC.channels[i]);
|
||||
}
|
||||
|
||||
// push latest data to the main array
|
||||
for (var i = 0; i < RC.active_channels; i++) {
|
||||
for (i = 0; i < RC.active_channels; i++) {
|
||||
RX_plot_data[i].push([samples, RC.channels[i]]);
|
||||
}
|
||||
|
||||
// Remove old data from array
|
||||
while (RX_plot_data[0].length > 300) {
|
||||
for (var i = 0; i < RX_plot_data.length; i++) {
|
||||
for (i = 0; i < RX_plot_data.length; i++) {
|
||||
RX_plot_data[i].shift();
|
||||
}
|
||||
}
|
||||
|
@ -424,16 +424,24 @@ TABS.receiver.initialize = function (callback) {
|
|||
var xAxis = d3.svg.axis().
|
||||
scale(widthScale).
|
||||
orient("bottom").
|
||||
tickFormat(function (d) {return d;});
|
||||
tickFormat(function (d) {
|
||||
return d;
|
||||
});
|
||||
|
||||
var yAxis = d3.svg.axis().
|
||||
scale(heightScale).
|
||||
orient("left").
|
||||
tickFormat(function (d) {return d;});
|
||||
tickFormat(function (d) {
|
||||
return d;
|
||||
});
|
||||
|
||||
var line = d3.svg.line().
|
||||
x(function (d) {return widthScale(d[0]);}).
|
||||
y(function (d) {return heightScale(d[1]);});
|
||||
x(function (d) {
|
||||
return widthScale(d[0]);
|
||||
}).
|
||||
y(function (d) {
|
||||
return heightScale(d[1]);
|
||||
});
|
||||
|
||||
svg.select(".x.grid").call(xGrid);
|
||||
svg.select(".y.grid").call(yGrid);
|
||||
|
@ -441,19 +449,18 @@ TABS.receiver.initialize = function (callback) {
|
|||
svg.select(".y.axis").call(yAxis);
|
||||
|
||||
var data = svg.select("g.data"),
|
||||
lines = data.selectAll("path").data(RX_plot_data, function (d, i) {return i;}),
|
||||
newLines = lines.enter().append("path").attr("class", "line");
|
||||
lines = data.selectAll("path").data(RX_plot_data, function (d, i) {
|
||||
return i;
|
||||
});
|
||||
|
||||
lines.enter().append("path").attr("class", "line");
|
||||
|
||||
lines.attr('d', line);
|
||||
|
||||
samples++;
|
||||
}
|
||||
|
||||
// timer initialization
|
||||
helper.interval.remove('receiver_pull');
|
||||
|
||||
// enable RC data pulling
|
||||
helper.interval.add('receiver_pull', get_rc_data, plot_update_rate, true);
|
||||
});
|
||||
helper.interval.add('receiver_pull', get_rc_data, helper.mspQueue.getIntervalPrediction(35, 1), true);
|
||||
|
||||
GUI.content_ready(callback);
|
||||
}
|
||||
|
|
|
@ -181,6 +181,7 @@ TABS.setup.initialize = function (callback) {
|
|||
|
||||
helper.interval.add('setup_data_pull_fast', get_fast_data, 40, true); // 25 fps
|
||||
helper.interval.add('setup_data_pull_slow', get_slow_data, 250, true); // 4 fps
|
||||
|
||||
helper.interval.add('gui_analog_update', function () {
|
||||
bat_voltage_e.text(chrome.i18n.getMessage('initialSetupBatteryValue', [ANALOG.voltage]));
|
||||
bat_mah_drawn_e.text(chrome.i18n.getMessage('initialSetupBatteryMahValue', [ANALOG.mAhdrawn]));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue