mirror of
https://github.com/iNavFlight/inav-configurator.git
synced 2025-07-19 14:25:13 +03:00
Merge branch 'master' into advanced-tuning-tab
This commit is contained in:
commit
01569e7df8
45 changed files with 1179 additions and 1774 deletions
|
@ -1927,5 +1927,8 @@
|
|||
},
|
||||
"tabAdvancedTuningTitle": {
|
||||
"message": "Advanced tuning"
|
||||
},
|
||||
"presetApplyHead": {
|
||||
"message": "Applies following settings:"
|
||||
}
|
||||
}
|
20
images/icons/peset_default.svg
Normal file
20
images/icons/peset_default.svg
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 76.5 76.3" style="enable-background:new 0 0 76.5 76.3;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;stroke:#37A8DB;stroke-width:5;stroke-miterlimit:10;}
|
||||
.st1{fill:#37A8DB;}
|
||||
</style>
|
||||
<g>
|
||||
<g>
|
||||
<circle class="st0" cx="39.4" cy="38.4" r="33.3"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st1" d="M29.5,25.4l-4.9-4.9h-2.5v2.5l4.9,4.9L29.5,25.4z M32,18h2.5v4.9H32V18L32,18z M41.9,30.3h4.9v2.5h-4.9V30.3z
|
||||
M44.3,22.9v-2.5h-2.5l-4.9,5l2.5,2.5L44.3,22.9z M19.6,30.3h4.9v2.5h-4.9V30.3z M32,40.2h2.5v4.9H32V40.2L32,40.2z M22.1,40.2
|
||||
v2.5h2.5l4.9-4.9l-2.5-2.5L22.1,40.2z M58.6,52L34.1,27.5c-0.7-0.7-1.9-0.7-2.6,0l-2.3,2.3c-0.7,0.7-0.7,1.9,0,2.6L53.7,57
|
||||
c0.7,0.7,1.9,0.7,2.6,0l2.3-2.3C59.4,53.9,59.4,52.7,58.6,52z M38.2,39l-7.4-7.4l2.5-2.5l7.4,7.4L38.2,39z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
36
images/icons/peset_plane.svg
Normal file
36
images/icons/peset_plane.svg
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 76.5 76.3" style="enable-background:new 0 0 76.5 76.3;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;stroke:#ADADAD;stroke-width:5;stroke-miterlimit:10;}
|
||||
.st1{fill:#FFFFFF;}
|
||||
.st2{fill:#37A8DB;}
|
||||
.st3{fill:none;stroke:#606060;stroke-miterlimit:10;}
|
||||
</style>
|
||||
<g>
|
||||
<g>
|
||||
<circle class="st0" cx="39.4" cy="38.4" r="33.3"/>
|
||||
<g>
|
||||
<circle class="st1" cx="15.1" cy="15.9" r="11.4"/>
|
||||
<circle class="st2" cx="15.1" cy="15.9" r="9.3"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st1" d="M18.9,14.6l-0.2-0.4c0.6-1.4,0.6-1.4,0.5-1.5l-0.8-0.8l-0.1-0.1h-0.1c0,0-0.2,0-1.4,0.5l-0.4-0.2
|
||||
c-0.6-1.4-0.6-1.4-0.8-1.4h-1.1c-0.2,0-0.2,0-0.8,1.4l-0.4,0.2c-0.8-0.3-1.3-0.5-1.4-0.5h-0.1l-0.8,0.8
|
||||
c-0.1,0.1-0.2,0.2,0.5,1.5l-0.2,0.4c-1.4,0.6-1.4,0.6-1.4,0.8v1.1c0,0.2,0,0.2,1.4,0.7l0.2,0.4c-0.6,1.4-0.6,1.4-0.5,1.5
|
||||
l0.8,0.8l0.1,0.1h0.1c0,0,0.2,0,1.4-0.5l0.4,0.2c0.6,1.4,0.6,1.4,0.8,1.4h1.1c0.2,0,0.2,0,0.8-1.4l0.4-0.2
|
||||
c0.8,0.3,1.3,0.5,1.4,0.5h0.1l0.8-0.8c0.1-0.1,0.2-0.2-0.5-1.5l0.2-0.4c1.4-0.6,1.4-0.6,1.4-0.8v-1.1
|
||||
C20.3,15.2,20.3,15.1,18.9,14.6z M15.1,17.7c-1,0-1.8-0.8-1.8-1.8s0.8-1.8,1.8-1.8s1.8,0.8,1.8,1.8
|
||||
C16.9,16.9,16.1,17.7,15.1,17.7z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<path class="st3" d="M62.1,45.7v-5.9l-19.2-9.2c0.1-2.9,0.2-6.6,0.2-7.6c0-4.1-3.3-5.5-3.6-5.6l0,0l0,0c-0.3,0.2-3.6,1.5-3.6,5.6
|
||||
c0,0.9,0.1,4.6,0.2,7.6L16,39.8l0,5.9l20.9-4.3c0.2,3.9,0.1,5.2,0.3,8.4l-4.6,3.2v2.7l5.2-1.6c0.1,2.1,1.3,3.4,1.3,3.4h0.3h0h0.3
|
||||
c0,0,1.2-1.2,1.3-3.4l5.2,1.6v-2.7l-4.6-3.2c0.2-3.3,0.1-4.5,0.3-8.4L62.1,45.7z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
58
images/icons/peset_quad.svg
Normal file
58
images/icons/peset_quad.svg
Normal file
|
@ -0,0 +1,58 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="-61 62.7 76.5 76.3" style="enable-background:new -61 62.7 76.5 76.3;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;stroke:#ADADAD;stroke-width:5;stroke-miterlimit:10;}
|
||||
.st1{fill:#FFFFFF;}
|
||||
.st2{fill:#37A8DB;}
|
||||
.st3{fill:none;stroke:#606060;stroke-miterlimit:10;}
|
||||
.st4{fill:#606060;}
|
||||
</style>
|
||||
<g>
|
||||
<g>
|
||||
<circle class="st0" cx="-21.6" cy="101.1" r="33.3"/>
|
||||
<g>
|
||||
<circle class="st1" cx="-45.9" cy="78.6" r="11.4"/>
|
||||
<circle class="st2" cx="-45.9" cy="78.6" r="9.3"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st1" d="M-42.1,77.3l-0.2-0.4c0.6-1.4,0.6-1.4,0.5-1.5l-0.8-0.8l-0.1-0.1h-0.1c0,0-0.2,0-1.4,0.5l-0.4-0.2
|
||||
c-0.6-1.4-0.6-1.4-0.8-1.4h-1.1c-0.2,0-0.2,0-0.8,1.4l-0.4,0.2c-0.8-0.3-1.3-0.5-1.4-0.5h-0.1l-0.8,0.8
|
||||
c-0.1,0.1-0.2,0.2,0.5,1.5l-0.2,0.4c-1.4,0.6-1.4,0.6-1.4,0.8v1.1c0,0.2,0,0.2,1.4,0.7l0.2,0.4c-0.6,1.4-0.6,1.4-0.5,1.5
|
||||
l0.8,0.8l0.1,0.1h0.1c0,0,0.2,0,1.4-0.5l0.4,0.2c0.6,1.4,0.6,1.4,0.8,1.4h1.1c0.2,0,0.2,0,0.8-1.4l0.4-0.2
|
||||
c0.8,0.3,1.3,0.5,1.4,0.5h0.1l0.8-0.8c0.1-0.1,0.2-0.2-0.5-1.5l0.2-0.4c1.4-0.6,1.4-0.6,1.4-0.8V78
|
||||
C-40.7,77.9-40.7,77.8-42.1,77.3z M-45.9,80.4c-1,0-1.8-0.8-1.8-1.8s0.8-1.8,1.8-1.8s1.8,0.8,1.8,1.8S-44.9,80.4-45.9,80.4z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st3" d="M-9.4,110.7c-0.1,0-0.1-0.1-0.2-0.1c-1.6-0.7-2.8-1.3-4.2-3.6s-2.1-3.4-2.2-5.1c0.1-1.6,0.9-2.7,2.2-5
|
||||
s2.6-2.9,4.2-3.6c0.1,0,0.1-0.1,0.2-0.1c0.7-0.3,1.2-1.1,1.2-1.9c0-1.2-0.9-2.1-2.1-2.1c-0.9,0-1.7,0.6-2,1.4
|
||||
c-1.3,2.1-2.3,3-4.2,4.5s-4,2.4-5.1,2.4h-0.2c-1.1,0-3.2-0.9-5.1-2.4c-1.8-1.5-2.9-2.3-4.2-4.5c-0.3-0.8-1.1-1.4-2-1.4
|
||||
c-1.2,0-2.1,0.9-2.1,2.1c0,0.8,0.5,1.6,1.2,1.9c0.1,0,0.1,0.1,0.2,0.1c1.7,0.7,2.9,1.3,4.3,3.6c1.4,2.3,2.1,3.4,2.2,5.1
|
||||
c-0.1,1.6-0.9,2.7-2.2,5c-1.4,2.3-2.6,2.9-4.2,3.6c-0.1,0-0.1,0.1-0.2,0.1c-0.7,0.3-1.2,1.1-1.2,1.9c0,1.2,0.9,2.1,2.1,2.1
|
||||
c0.9,0,1.7-0.6,2-1.4c1.3-2.1,2.3-3,4.2-4.5c1.9-1.5,4-2.4,5.1-2.4h0.2c1.1,0,3.2,0.9,5.1,2.4c1.8,1.5,2.9,2.3,4.2,4.5
|
||||
c0.3,0.8,1.1,1.4,2,1.4c1.2,0,2.1-0.9,2.1-2.1C-8.2,111.8-8.7,111-9.4,110.7z"/>
|
||||
</g>
|
||||
</g>
|
||||
<path class="st4" d="M-32,96c-0.3,0.1-0.7,0.1-1,0.1c-2.7,0-4.8-2.2-4.8-4.8s2.2-4.8,4.8-4.8s4.8,2.2,4.8,4.8c0,0.2,0,0.4-0.1,0.7
|
||||
l0.9,0.6c0.1-0.4,0.1-0.8,0.1-1.3c0-3.2-2.6-5.8-5.8-5.8s-5.8,2.6-5.8,5.8c0,3.2,2.6,5.8,5.8,5.8c0.6,0,1.1-0.1,1.7-0.2L-32,96z"
|
||||
/>
|
||||
<path class="st4" d="M-10.2,85.5c-3.2,0-5.8,2.6-5.8,5.8c0,0.5,0.1,0.9,0.2,1.3l0.9-0.6c0-0.2-0.1-0.5-0.1-0.7
|
||||
c0-2.7,2.2-4.8,4.8-4.8s4.8,2.2,4.8,4.8c0,2.6-2.2,4.8-4.8,4.8c-0.3,0-0.6,0-1-0.1l-0.6,0.9c0.5,0.1,1,0.2,1.6,0.2
|
||||
c3.2,0,5.8-2.6,5.8-5.8C-4.4,88.1-7,85.5-10.2,85.5z"/>
|
||||
<path class="st4" d="M-32,108c-0.3-0.1-0.7-0.1-1-0.1c-2.7,0-4.8,2.2-4.8,4.8s2.2,4.8,4.8,4.8s4.8-2.2,4.8-4.8
|
||||
c0-0.2,0-0.4-0.1-0.7l0.9-0.6c0.1,0.4,0.1,0.8,0.1,1.3c0,3.2-2.6,5.8-5.8,5.8s-5.8-2.6-5.8-5.8s2.6-5.8,5.8-5.8
|
||||
c0.6,0,1.1,0.1,1.7,0.2L-32,108z"/>
|
||||
<path class="st4" d="M-10.2,118.5c-3.2,0-5.8-2.6-5.8-5.8c0-0.5,0.1-0.9,0.2-1.3l0.9,0.6c0,0.2-0.1,0.5-0.1,0.7
|
||||
c0,2.7,2.2,4.8,4.8,4.8s4.8-2.2,4.8-4.8s-2.2-4.8-4.8-4.8c-0.3,0-0.6,0-1,0.1l-0.6-0.9c0.5-0.1,1-0.2,1.6-0.2
|
||||
c3.2,0,5.8,2.6,5.8,5.8C-4.4,115.9-7,118.5-10.2,118.5z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.4 KiB |
38
images/icons/peset_wing.svg
Normal file
38
images/icons/peset_wing.svg
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 76.5 76.3" style="enable-background:new 0 0 76.5 76.3;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;stroke:#ADADAD;stroke-width:5;stroke-miterlimit:10;}
|
||||
.st1{fill:#FFFFFF;}
|
||||
.st2{fill:#37A8DB;}
|
||||
.st3{fill:none;stroke:#606060;stroke-miterlimit:10;}
|
||||
</style>
|
||||
<g>
|
||||
<g>
|
||||
<circle class="st0" cx="39.4" cy="38.4" r="33.3"/>
|
||||
<g>
|
||||
<circle class="st1" cx="15.1" cy="15.9" r="11.4"/>
|
||||
<circle class="st2" cx="15.1" cy="15.9" r="9.3"/>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st1" d="M18.9,14.6l-0.2-0.4c0.6-1.4,0.6-1.4,0.5-1.5l-0.8-0.8l-0.1-0.1h-0.1c0,0-0.2,0-1.4,0.5l-0.4-0.2
|
||||
c-0.6-1.4-0.6-1.4-0.8-1.4h-1.1c-0.2,0-0.2,0-0.8,1.4l-0.4,0.2c-0.8-0.3-1.3-0.5-1.4-0.5h-0.1l-0.8,0.8
|
||||
c-0.1,0.1-0.2,0.2,0.5,1.5l-0.2,0.4c-1.4,0.6-1.4,0.6-1.4,0.8v1.1c0,0.2,0,0.2,1.4,0.7l0.2,0.4c-0.6,1.4-0.6,1.4-0.5,1.5
|
||||
l0.8,0.8l0.1,0.1h0.1c0,0,0.2,0,1.4-0.5l0.4,0.2c0.6,1.4,0.6,1.4,0.8,1.4h1.1c0.2,0,0.2,0,0.8-1.4l0.4-0.2
|
||||
c0.8,0.3,1.3,0.5,1.4,0.5h0.1l0.8-0.8c0.1-0.1,0.2-0.2-0.5-1.5l0.2-0.4c1.4-0.6,1.4-0.6,1.4-0.8v-1.1
|
||||
C20.3,15.2,20.3,15.1,18.9,14.6z M15.1,17.7c-1,0-1.8-0.8-1.8-1.8s0.8-1.8,1.8-1.8s1.8,0.8,1.8,1.8S16.1,17.7,15.1,17.7z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path class="st3" d="M42.1,26c-0.3-0.1-0.5-0.3-0.7-0.3c-0.3,0-1.6,0-2.1,0c-0.1,0-0.2,0-0.2,0c-0.5,0-1.8,0-2.1,0
|
||||
c-0.2,0-0.4,0.1-0.7,0.3C35.6,26.3,16,37.8,16,37.8v8.4l0.6-0.1v-1.6l18.2-3.3l0.4-0.5v-1.5h3v1.3h2.1v-1.3h3v1.5l0.4,0.5
|
||||
l18.2,3.3v1.6l0.6,0.1v-8.4C62.4,37.8,42.8,26.3,42.1,26z"/>
|
||||
<path class="st3" d="M39.7,40.9c0,0.5-0.2,0.7-0.5,0.9c-0.2-0.1-0.5-0.4-0.5-0.9v-0.2h1.1V40.9z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
|
@ -1,817 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
// code below is highly experimental, although it runs fine on latest firmware
|
||||
// the data inside nested objects needs to be verified if deep copy works properly
|
||||
function configuration_backup(callback) {
|
||||
var activeProfile = null,
|
||||
profilesN = 3;
|
||||
|
||||
var configuration = {
|
||||
'generatedBy': chrome.runtime.getManifest().version,
|
||||
'apiVersion': CONFIG.apiVersion,
|
||||
'profiles': [],
|
||||
};
|
||||
|
||||
var profileSpecificData = [
|
||||
MSPCodes.MSP_PID,
|
||||
MSPCodes.MSP_RC_TUNING,
|
||||
MSPCodes.MSP_ACC_TRIM,
|
||||
MSPCodes.MSP_SERVO_CONFIGURATIONS,
|
||||
MSPCodes.MSP_MODE_RANGES,
|
||||
MSPCodes.MSP_ADJUSTMENT_RANGES
|
||||
];
|
||||
|
||||
function update_profile_specific_data_list() {
|
||||
if (semver.lt(CONFIG.apiVersion, "1.12.0")) {
|
||||
profileSpecificData.push(MSPCodes.MSP_CHANNEL_FORWARDING);
|
||||
} else {
|
||||
profileSpecificData.push(MSPCodes.MSP_SERVO_MIX_RULES);
|
||||
}
|
||||
if (semver.gte(CONFIG.apiVersion, "1.15.0")) {
|
||||
profileSpecificData.push(MSPCodes.MSP_RC_DEADBAND);
|
||||
}
|
||||
}
|
||||
|
||||
update_profile_specific_data_list();
|
||||
|
||||
MSP.send_message(MSPCodes.MSP_STATUS, false, false, function () {
|
||||
activeProfile = CONFIG.profile;
|
||||
select_profile();
|
||||
});
|
||||
|
||||
function select_profile() {
|
||||
if (activeProfile > 0) {
|
||||
MSP.send_message(MSPCodes.MSP_SELECT_SETTING, [0], false, fetch_specific_data);
|
||||
} else {
|
||||
fetch_specific_data();
|
||||
}
|
||||
}
|
||||
|
||||
function fetch_specific_data() {
|
||||
var fetchingProfile = 0,
|
||||
codeKey = 0;
|
||||
|
||||
function fetch_specific_data_item() {
|
||||
if (fetchingProfile < profilesN) {
|
||||
MSP.send_message(profileSpecificData[codeKey], false, false, function () {
|
||||
codeKey++;
|
||||
|
||||
if (codeKey < profileSpecificData.length) {
|
||||
fetch_specific_data_item();
|
||||
} else {
|
||||
configuration.profiles.push({
|
||||
'PID': jQuery.extend(true, {}, PID),
|
||||
'PIDs': jQuery.extend(true, [], PIDs),
|
||||
'RC': jQuery.extend(true, {}, RC_tuning),
|
||||
'AccTrim': jQuery.extend(true, [], CONFIG.accelerometerTrims),
|
||||
'ServoConfig': jQuery.extend(true, [], SERVO_CONFIG),
|
||||
'ServoRules': jQuery.extend(true, [], SERVO_RULES),
|
||||
'ModeRanges': jQuery.extend(true, [], MODE_RANGES),
|
||||
'AdjustmentRanges': jQuery.extend(true, [], ADJUSTMENT_RANGES)
|
||||
});
|
||||
|
||||
if (semver.gte(CONFIG.apiVersion, "1.15.0")) {
|
||||
configuration.profiles[fetchingProfile].RCdeadband = jQuery.extend(true, {}, RC_deadband);
|
||||
}
|
||||
codeKey = 0;
|
||||
fetchingProfile++;
|
||||
|
||||
MSP.send_message(MSPCodes.MSP_SELECT_SETTING, [fetchingProfile], false, fetch_specific_data_item);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
MSP.send_message(MSPCodes.MSP_SELECT_SETTING, [activeProfile], false, fetch_unique_data);
|
||||
}
|
||||
}
|
||||
|
||||
// start fetching
|
||||
fetch_specific_data_item();
|
||||
}
|
||||
|
||||
var uniqueData = [
|
||||
MSPCodes.MSP_MISC,
|
||||
MSPCodes.MSP_RX_MAP,
|
||||
MSPCodes.MSP_BF_CONFIG,
|
||||
MSPCodes.MSP_CF_SERIAL_CONFIG,
|
||||
MSPCodes.MSP_LED_STRIP_CONFIG,
|
||||
MSPCodes.MSP_LED_COLORS
|
||||
];
|
||||
|
||||
function update_unique_data_list() {
|
||||
if (semver.gte(CONFIG.apiVersion, "1.8.0")) {
|
||||
uniqueData.push(MSPCodes.MSP_LOOP_TIME);
|
||||
uniqueData.push(MSPCodes.MSP_ARMING_CONFIG);
|
||||
}
|
||||
if (semver.gte(CONFIG.apiVersion, "1.14.0")) {
|
||||
uniqueData.push(MSPCodes.MSP_3D);
|
||||
}
|
||||
if (semver.gte(CONFIG.apiVersion, "1.15.0")) {
|
||||
uniqueData.push(MSPCodes.MSP_SENSOR_ALIGNMENT);
|
||||
uniqueData.push(MSPCodes.MSP_RX_CONFIG);
|
||||
uniqueData.push(MSPCodes.MSP_FAILSAFE_CONFIG);
|
||||
uniqueData.push(MSPCodes.MSP_RXFAIL_CONFIG);
|
||||
}
|
||||
if (semver.gte(CONFIG.apiVersion, "1.19.0")) {
|
||||
uniqueData.push(MSPCodes.MSP_LED_STRIP_MODECOLOR);
|
||||
}
|
||||
}
|
||||
|
||||
update_unique_data_list();
|
||||
|
||||
function fetch_unique_data() {
|
||||
var codeKey = 0;
|
||||
|
||||
function fetch_unique_data_item() {
|
||||
if (codeKey < uniqueData.length) {
|
||||
MSP.send_message(uniqueData[codeKey], false, false, function () {
|
||||
codeKey++;
|
||||
fetch_unique_data_item();
|
||||
});
|
||||
} else {
|
||||
configuration.MISC = jQuery.extend(true, {}, MISC);
|
||||
configuration.RCMAP = jQuery.extend(true, [], RC_MAP);
|
||||
configuration.BF_CONFIG = jQuery.extend(true, {}, BF_CONFIG);
|
||||
configuration.SERIAL_CONFIG = jQuery.extend(true, {}, SERIAL_CONFIG);
|
||||
configuration.LED_STRIP = jQuery.extend(true, [], LED_STRIP);
|
||||
configuration.LED_COLORS = jQuery.extend(true, [], LED_COLORS);
|
||||
|
||||
if (semver.gte(CONFIG.apiVersion, "1.19.0")) {
|
||||
configuration.LED_MODE_COLORS = jQuery.extend(true, [], LED_MODE_COLORS);
|
||||
}
|
||||
if (semver.gte(CONFIG.apiVersion, "1.8.0")) {
|
||||
configuration.FC_CONFIG = jQuery.extend(true, {}, FC_CONFIG);
|
||||
configuration.ARMING_CONFIG = jQuery.extend(true, {}, ARMING_CONFIG);
|
||||
}
|
||||
if (semver.gte(CONFIG.apiVersion, "1.14.0")) {
|
||||
configuration._3D = jQuery.extend(true, {}, _3D);
|
||||
}
|
||||
if (semver.gte(CONFIG.apiVersion, "1.15.0")) {
|
||||
configuration.SENSOR_ALIGNMENT = jQuery.extend(true, {}, SENSOR_ALIGNMENT);
|
||||
configuration.RX_CONFIG = jQuery.extend(true, {}, RX_CONFIG);
|
||||
configuration.FAILSAFE_CONFIG = jQuery.extend(true, {}, FAILSAFE_CONFIG);
|
||||
configuration.RXFAIL_CONFIG = jQuery.extend(true, [], RXFAIL_CONFIG);
|
||||
}
|
||||
|
||||
save();
|
||||
}
|
||||
}
|
||||
|
||||
// start fetching
|
||||
fetch_unique_data_item();
|
||||
}
|
||||
|
||||
function save() {
|
||||
var chosenFileEntry = null;
|
||||
|
||||
var accepts = [{
|
||||
extensions: ['txt']
|
||||
}];
|
||||
|
||||
// generate timestamp for the backup file
|
||||
var d = new Date(),
|
||||
now = (d.getMonth() + 1) + '.' + d.getDate() + '.' + d.getFullYear() + '.' + d.getHours() + '.' + d.getMinutes();
|
||||
|
||||
// create or load the file
|
||||
chrome.fileSystem.chooseEntry({type: 'saveFile', suggestedName: 'inav_backup_' + now, accepts: accepts}, function (fileEntry) {
|
||||
if (chrome.runtime.lastError) {
|
||||
console.error(chrome.runtime.lastError.message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fileEntry) {
|
||||
console.log('No file selected, backup aborted.');
|
||||
return;
|
||||
}
|
||||
|
||||
chosenFileEntry = fileEntry;
|
||||
|
||||
// echo/console log path specified
|
||||
chrome.fileSystem.getDisplayPath(chosenFileEntry, function (path) {
|
||||
console.log('Backup file path: ' + path);
|
||||
});
|
||||
|
||||
// change file entry from read only to read/write
|
||||
chrome.fileSystem.getWritableEntry(chosenFileEntry, function (fileEntryWritable) {
|
||||
// check if file is writable
|
||||
chrome.fileSystem.isWritableEntry(fileEntryWritable, function (isWritable) {
|
||||
if (isWritable) {
|
||||
chosenFileEntry = fileEntryWritable;
|
||||
|
||||
// crunch the config object
|
||||
var serialized_config_object = JSON.stringify(configuration);
|
||||
var blob = new Blob([serialized_config_object], {type: 'text/plain'}); // first parameter for Blob needs to be an array
|
||||
|
||||
chosenFileEntry.createWriter(function (writer) {
|
||||
writer.onerror = function (e) {
|
||||
console.error(e);
|
||||
};
|
||||
|
||||
var truncated = false;
|
||||
writer.onwriteend = function () {
|
||||
if (!truncated) {
|
||||
// onwriteend will be fired again when truncation is finished
|
||||
truncated = true;
|
||||
writer.truncate(blob.size);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Write SUCCESSFUL');
|
||||
if (callback) callback();
|
||||
};
|
||||
|
||||
writer.write(blob);
|
||||
}, function (e) {
|
||||
console.error(e);
|
||||
});
|
||||
} else {
|
||||
// Something went wrong or file is set to read only and cannot be changed
|
||||
console.log('File appears to be read only, sorry.');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function configuration_restore(callback) {
|
||||
var chosenFileEntry = null;
|
||||
|
||||
var accepts = [{
|
||||
extensions: ['txt']
|
||||
}];
|
||||
|
||||
// load up the file
|
||||
chrome.fileSystem.chooseEntry({type: 'openFile', accepts: accepts}, function (fileEntry) {
|
||||
if (chrome.runtime.lastError) {
|
||||
console.error(chrome.runtime.lastError.message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fileEntry) {
|
||||
console.log('No file selected, restore aborted.');
|
||||
return;
|
||||
}
|
||||
|
||||
chosenFileEntry = fileEntry;
|
||||
|
||||
// echo/console log path specified
|
||||
chrome.fileSystem.getDisplayPath(chosenFileEntry, function (path) {
|
||||
console.log('Restore file path: ' + path);
|
||||
});
|
||||
|
||||
// read contents into variable
|
||||
chosenFileEntry.file(function (file) {
|
||||
var reader = new FileReader();
|
||||
|
||||
reader.onprogress = function (e) {
|
||||
if (e.total > 1048576) { // 1 MB
|
||||
// dont allow reading files bigger then 1 MB
|
||||
console.log('File limit (1 MB) exceeded, aborting');
|
||||
reader.abort();
|
||||
}
|
||||
};
|
||||
|
||||
reader.onloadend = function (e) {
|
||||
if (e.total != 0 && e.total == e.loaded) {
|
||||
console.log('Read SUCCESSFUL');
|
||||
|
||||
try { // check if string provided is a valid JSON
|
||||
var configuration = JSON.parse(e.target.result);
|
||||
} catch (e) {
|
||||
// data provided != valid json object
|
||||
console.log('Data provided != valid JSON string, restore aborted.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// validate
|
||||
if (typeof configuration.generatedBy !== 'undefined' && compareVersions(configuration.generatedBy, CONFIGURATOR.backupFileMinVersionAccepted)) {
|
||||
|
||||
if (!migrate(configuration)) {
|
||||
GUI.log(chrome.i18n.getMessage('backupFileUnmigratable'));
|
||||
return;
|
||||
}
|
||||
|
||||
configuration_upload(configuration, callback);
|
||||
|
||||
} else {
|
||||
GUI.log(chrome.i18n.getMessage('backupFileIncompatible'));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
reader.readAsText(file);
|
||||
});
|
||||
});
|
||||
|
||||
function compareVersions(generated, required) {
|
||||
if (generated == undefined) {
|
||||
return false;
|
||||
}
|
||||
return semver.gte(generated, required);
|
||||
}
|
||||
|
||||
|
||||
function migrate(configuration) {
|
||||
var appliedMigrationsCount = 0;
|
||||
var migratedVersion = configuration.generatedBy;
|
||||
GUI.log(chrome.i18n.getMessage('configMigrationFrom', [migratedVersion]));
|
||||
|
||||
if (!compareVersions(migratedVersion, '0.59.1')) {
|
||||
|
||||
// variable was renamed
|
||||
configuration.MISC.rssi_channel = configuration.MISC.rssi_aux_channel;
|
||||
configuration.MISC.rssi_aux_channel = undefined;
|
||||
|
||||
migratedVersion = '0.59.1';
|
||||
GUI.log(chrome.i18n.getMessage('configMigratedTo', [migratedVersion]));
|
||||
appliedMigrationsCount++;
|
||||
}
|
||||
|
||||
if (!compareVersions(migratedVersion, '0.60.1')) {
|
||||
|
||||
// LED_STRIP support was added.
|
||||
if (!configuration.LED_STRIP) {
|
||||
configuration.LED_STRIP = [];
|
||||
}
|
||||
|
||||
migratedVersion = '0.60.1';
|
||||
GUI.log(chrome.i18n.getMessage('configMigratedTo', [migratedVersion]));
|
||||
appliedMigrationsCount++;
|
||||
}
|
||||
|
||||
if (!compareVersions(migratedVersion, '0.61.0')) {
|
||||
|
||||
// Changing PID controller via UI was added.
|
||||
if (!configuration.PIDs && configuration.PID) {
|
||||
configuration.PIDs = configuration.PID;
|
||||
}
|
||||
|
||||
migratedVersion = '0.61.0';
|
||||
GUI.log(chrome.i18n.getMessage('configMigratedTo', [migratedVersion]));
|
||||
appliedMigrationsCount++;
|
||||
}
|
||||
|
||||
if (!compareVersions(migratedVersion, '0.63.0')) {
|
||||
|
||||
// LED Strip was saved as object instead of array.
|
||||
if (typeof(configuration.LED_STRIP) == 'object') {
|
||||
var fixed_led_strip = [];
|
||||
|
||||
var index = 0;
|
||||
while (configuration.LED_STRIP[index]) {
|
||||
fixed_led_strip.push(configuration.LED_STRIP[index++]);
|
||||
}
|
||||
configuration.LED_STRIP = fixed_led_strip;
|
||||
}
|
||||
|
||||
|
||||
for (var profileIndex = 0; profileIndex < 3; profileIndex++) {
|
||||
var RC = configuration.profiles[profileIndex].RC;
|
||||
// TPA breakpoint was added
|
||||
if (!RC.dynamic_THR_breakpoint) {
|
||||
RC.dynamic_THR_breakpoint = 1500; // firmware default
|
||||
}
|
||||
|
||||
// Roll and pitch rates were split
|
||||
RC.roll_rate = RC.roll_pitch_rate;
|
||||
RC.pitch_rate = RC.roll_pitch_rate;
|
||||
}
|
||||
|
||||
migratedVersion = '0.63.0';
|
||||
GUI.log(chrome.i18n.getMessage('configMigratedTo', [migratedVersion]));
|
||||
appliedMigrationsCount++;
|
||||
}
|
||||
|
||||
if (configuration.apiVersion == undefined) {
|
||||
configuration.apiVersion = "1.0.0" // a guess that will satisfy the rest of the code
|
||||
}
|
||||
// apiVersion previously stored without patchlevel
|
||||
if (!semver.parse(configuration.apiVersion)) {
|
||||
configuration.apiVersion += ".0";
|
||||
if (!semver.parse(configuration.apiVersion)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (compareVersions(migratedVersion, '0.63.0') && !compareVersions(configuration.apiVersion, '1.7.0')) {
|
||||
// Serial configuation redesigned, 0.63.0 saves old and new configurations.
|
||||
var ports = [];
|
||||
for (var portIndex = 0; portIndex < configuration.SERIAL_CONFIG.ports.length; portIndex++) {
|
||||
var oldPort = configuration.SERIAL_CONFIG.ports[portIndex];
|
||||
|
||||
var newPort = {
|
||||
identifier: oldPort.identifier,
|
||||
functions: [],
|
||||
msp_baudrate: String(configuration.SERIAL_CONFIG.mspBaudRate),
|
||||
gps_baudrate: String(configuration.SERIAL_CONFIG.gpsBaudRate),
|
||||
telemetry_baudrate: 'AUTO',
|
||||
blackbox_baudrate: '115200',
|
||||
};
|
||||
|
||||
switch(oldPort.scenario) {
|
||||
case 1: // MSP, CLI, TELEMETRY, SMARTPORT TELEMETRY, GPS-PASSTHROUGH
|
||||
case 5: // MSP, CLI, GPS-PASSTHROUGH
|
||||
case 8: // MSP ONLY
|
||||
newPort.functions.push('MSP');
|
||||
break;
|
||||
case 2: // GPS
|
||||
newPort.functions.push('GPS');
|
||||
break;
|
||||
case 3: // RX_SERIAL
|
||||
newPort.functions.push('RX_SERIAL');
|
||||
break;
|
||||
case 10: // BLACKBOX ONLY
|
||||
newPort.functions.push('BLACKBOX');
|
||||
break;
|
||||
case 11: // MSP, CLI, BLACKBOX, GPS-PASSTHROUGH
|
||||
newPort.functions.push('MSP');
|
||||
newPort.functions.push('BLACKBOX');
|
||||
break;
|
||||
}
|
||||
|
||||
ports.push(newPort);
|
||||
}
|
||||
configuration.SERIAL_CONFIG = {
|
||||
ports: ports
|
||||
};
|
||||
|
||||
appliedMigrationsCount++;
|
||||
}
|
||||
|
||||
if (compareVersions(migratedVersion, '0.63.0') && !compareVersions(configuration.apiVersion, '1.8.0')) {
|
||||
// api 1.8 exposes looptime and arming config
|
||||
|
||||
if (configuration.FC_CONFIG == undefined) {
|
||||
configuration.FC_CONFIG = {
|
||||
loopTime: 3500
|
||||
};
|
||||
}
|
||||
|
||||
if (configuration.ARMING_CONFIG == undefined) {
|
||||
configuration.ARMING_CONFIG = {
|
||||
auto_disarm_delay: 5,
|
||||
disarm_kill_switch: 1
|
||||
};
|
||||
}
|
||||
appliedMigrationsCount++;
|
||||
}
|
||||
|
||||
if (compareVersions(migratedVersion, '0.63.0')) {
|
||||
// backups created with 0.63.0 for firmwares with api < 1.8 were saved with incorrect looptime
|
||||
if (configuration.FC_CONFIG.loopTime == 0) {
|
||||
//reset it to the default
|
||||
configuration.FC_CONFIG.loopTime = 3500;
|
||||
}
|
||||
}
|
||||
|
||||
if (semver.lt(migratedVersion, '0.66.0')) {
|
||||
// api 1.12 updated servo configuration protocol and added servo mixer rules
|
||||
for (var profileIndex = 0; profileIndex < configuration.profiles.length; profileIndex++) {
|
||||
|
||||
if (semver.eq(configuration.apiVersion, '1.10.0')) {
|
||||
// drop two unused servo configurations
|
||||
while (configuration.profiles[profileIndex].ServoConfig.length > 8) {
|
||||
configuration.profiles[profileIndex].ServoConfig.pop();
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < configuration.profiles[profileIndex].ServoConfig.length; i++) {
|
||||
var servoConfig = profiles[profileIndex].ServoConfig;
|
||||
|
||||
servoConfig[i].angleAtMin = 45;
|
||||
servoConfig[i].angleAtMax = 45;
|
||||
servoConfig[i].reversedInputSources = 0;
|
||||
|
||||
// set the rate to 0 if an invalid value is detected.
|
||||
if (servoConfig[i].rate < -100 || servoConfig[i].rate > 100) {
|
||||
servoConfig[i].rate = 0;
|
||||
}
|
||||
}
|
||||
|
||||
configuration.profiles[profileIndex].ServoRules = [];
|
||||
}
|
||||
|
||||
migratedVersion = '0.66.0';
|
||||
|
||||
appliedMigrationsCount++;
|
||||
}
|
||||
|
||||
if (compareVersions(migratedVersion, '0.66.0') && !compareVersions(configuration.apiVersion, '1.14.0')) {
|
||||
// api 1.14 exposes 3D configuration
|
||||
|
||||
if (configuration._3D == undefined) {
|
||||
configuration._3D = {
|
||||
deadband3d_low: 1406,
|
||||
deadband3d_high: 1514,
|
||||
neutral3d: 1460,
|
||||
deadband3d_throttle: 50
|
||||
};
|
||||
}
|
||||
appliedMigrationsCount++;
|
||||
}
|
||||
|
||||
|
||||
if (compareVersions(migratedVersion, '0.66.0') && !compareVersions(configuration.apiVersion, '1.15.0')) {
|
||||
// api 1.15 exposes RCdeadband and sensor alignment
|
||||
|
||||
|
||||
for (var profileIndex = 0; profileIndex < configuration.profiles.length; profileIndex++) {
|
||||
if (configuration.profiles[profileIndex].RCdeadband == undefined) {
|
||||
configuration.profiles[profileIndex].RCdeadband = {
|
||||
deadband: 0,
|
||||
yaw_deadband: 0,
|
||||
alt_hold_deadband: 40,
|
||||
};
|
||||
}
|
||||
}
|
||||
if (configuration.SENSOR_ALIGNMENT == undefined) {
|
||||
configuration.SENSOR_ALIGNMENT = {
|
||||
align_gyro: 0,
|
||||
align_acc: 0,
|
||||
align_mag: 0
|
||||
};
|
||||
}
|
||||
|
||||
// api 1.15 exposes RX_CONFIG, FAILSAFE_CONFIG and RXFAIL_CONFIG configuration
|
||||
|
||||
if (configuration.RX_CONFIG == undefined) {
|
||||
configuration.RX_CONFIG = {
|
||||
serialrx_provider: 0,
|
||||
spektrum_sat_bind: 0,
|
||||
midrc: 1500,
|
||||
mincheck: 1100,
|
||||
maxcheck: 1900,
|
||||
rx_min_usec: 885,
|
||||
rx_max_usec: 2115,
|
||||
nrf24rx_protocol: 0,
|
||||
nrf24rx_id: 0
|
||||
};
|
||||
}
|
||||
|
||||
if (configuration.FAILSAFE_CONFIG == undefined) {
|
||||
configuration.FAILSAFE_CONFIG = {
|
||||
failsafe_delay: 10,
|
||||
failsafe_off_delay: 200,
|
||||
failsafe_throttle: 1000,
|
||||
failsafe_kill_switch: 0,
|
||||
failsafe_throttle_low_delay: 100,
|
||||
failsafe_procedure: 0
|
||||
};
|
||||
}
|
||||
|
||||
if (configuration.RXFAIL_CONFIG == undefined) {
|
||||
configuration.RXFAIL_CONFIG = [
|
||||
{mode: 0, value: 1500},
|
||||
{mode: 0, value: 1500},
|
||||
{mode: 0, value: 1500},
|
||||
{mode: 0, value: 875}
|
||||
];
|
||||
|
||||
for (var i = 0; i < 14; i++) {
|
||||
var rxfailChannel = {
|
||||
mode: 1,
|
||||
value: 1500
|
||||
};
|
||||
configuration.RXFAIL_CONFIG.push(rxfailChannel);
|
||||
}
|
||||
}
|
||||
|
||||
appliedMigrationsCount++;
|
||||
}
|
||||
|
||||
if (compareVersions(migratedVersion, '1.2.0')) {
|
||||
// old version of the configurator incorrectly had a 'disabled' option for GPS SBAS mode.
|
||||
if (MISC.gps_ubx_sbas < 0) {
|
||||
MISC.gps_ubx_sbas = 0;
|
||||
}
|
||||
migratedVersion = '1.2.0';
|
||||
|
||||
appliedMigrationsCount++;
|
||||
}
|
||||
|
||||
if (!compareVersions(migratedVersion, '1.2.0')) {
|
||||
|
||||
// LED_COLORS & LED_MODE_COLORS support was added.
|
||||
if (!configuration.LED_COLORS) {
|
||||
configuration.LED_COLORS = [];
|
||||
}
|
||||
if (!configuration.LED_MODE_COLORS) {
|
||||
configuration.LED_MODE_COLORS = [];
|
||||
}
|
||||
|
||||
migratedVersion = '1.3.1';
|
||||
GUI.log(chrome.i18n.getMessage('configMigratedTo', [migratedVersion]));
|
||||
appliedMigrationsCount++;
|
||||
}
|
||||
|
||||
if (appliedMigrationsCount > 0) {
|
||||
GUI.log(chrome.i18n.getMessage('configMigrationSuccessful', [appliedMigrationsCount]));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function configuration_upload(configuration, callback) {
|
||||
function upload() {
|
||||
var activeProfile = null,
|
||||
profilesN = 3;
|
||||
|
||||
var profileSpecificData = [
|
||||
MSPCodes.MSP_SET_PID,
|
||||
MSPCodes.MSP_SET_RC_TUNING,
|
||||
MSPCodes.MSP_SET_ACC_TRIM
|
||||
];
|
||||
|
||||
if (semver.gte(CONFIG.apiVersion, "1.15.0")) {
|
||||
profileSpecificData.push(MSPCodes.MSP_SET_RC_DEADBAND);
|
||||
}
|
||||
|
||||
MSP.send_message(MSPCodes.MSP_STATUS, false, false, function () {
|
||||
activeProfile = CONFIG.profile;
|
||||
select_profile();
|
||||
});
|
||||
|
||||
function select_profile() {
|
||||
if (activeProfile > 0) {
|
||||
MSP.send_message(MSPCodes.MSP_SELECT_SETTING, [0], false, upload_specific_data);
|
||||
} else {
|
||||
upload_specific_data();
|
||||
}
|
||||
}
|
||||
|
||||
function upload_specific_data() {
|
||||
var savingProfile = 0,
|
||||
codeKey = 0;
|
||||
|
||||
function load_objects(profile) {
|
||||
PID = configuration.profiles[profile].PID;
|
||||
PIDs = configuration.profiles[profile].PIDs;
|
||||
RC_tuning = configuration.profiles[profile].RC;
|
||||
CONFIG.accelerometerTrims = configuration.profiles[profile].AccTrim;
|
||||
SERVO_CONFIG = configuration.profiles[profile].ServoConfig;
|
||||
SERVO_RULES = configuration.profiles[profile].ServoRules;
|
||||
MODE_RANGES = configuration.profiles[profile].ModeRanges;
|
||||
ADJUSTMENT_RANGES = configuration.profiles[profile].AdjustmentRanges;
|
||||
RC_deadband = configuration.profiles[profile].RCdeadband;
|
||||
}
|
||||
|
||||
function upload_using_specific_commands() {
|
||||
MSP.send_message(profileSpecificData[codeKey], mspHelper.crunch(profileSpecificData[codeKey]), false, function () {
|
||||
codeKey++;
|
||||
|
||||
if (codeKey < profileSpecificData.length) {
|
||||
upload_using_specific_commands();
|
||||
} else {
|
||||
codeKey = 0;
|
||||
savingProfile++;
|
||||
|
||||
if (savingProfile < profilesN) {
|
||||
load_objects(savingProfile);
|
||||
|
||||
MSP.send_message(MSPCodes.MSP_EEPROM_WRITE, false, false, function () {
|
||||
MSP.send_message(MSPCodes.MSP_SELECT_SETTING, [savingProfile], false, upload_using_specific_commands);
|
||||
});
|
||||
} else {
|
||||
MSP.send_message(MSPCodes.MSP_EEPROM_WRITE, false, false, function () {
|
||||
MSP.send_message(MSPCodes.MSP_SELECT_SETTING, [activeProfile], false, upload_unique_data);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function upload_servo_mix_rules() {
|
||||
mspHelper.sendServoMixRules(upload_servo_configuration);
|
||||
}
|
||||
|
||||
function upload_servo_configuration() {
|
||||
mspHelper.sendServoConfigurations(upload_mode_ranges);
|
||||
}
|
||||
|
||||
function upload_mode_ranges() {
|
||||
mspHelper.sendModeRanges(upload_adjustment_ranges);
|
||||
}
|
||||
|
||||
function upload_adjustment_ranges() {
|
||||
mspHelper.sendAdjustmentRanges(upload_using_specific_commands);
|
||||
}
|
||||
// start uploading
|
||||
load_objects(0);
|
||||
upload_servo_configuration();
|
||||
}
|
||||
|
||||
function upload_unique_data() {
|
||||
var codeKey = 0;
|
||||
|
||||
var uniqueData = [
|
||||
MSPCodes.MSP_SET_MISC,
|
||||
MSPCodes.MSP_SET_RX_MAP,
|
||||
MSPCodes.MSP_SET_BF_CONFIG,
|
||||
MSPCodes.MSP_SET_CF_SERIAL_CONFIG
|
||||
];
|
||||
|
||||
function update_unique_data_list() {
|
||||
if (semver.gte(CONFIG.apiVersion, "1.8.0")) {
|
||||
uniqueData.push(MSPCodes.MSP_SET_LOOP_TIME);
|
||||
uniqueData.push(MSPCodes.MSP_SET_ARMING_CONFIG);
|
||||
}
|
||||
if (semver.gte(CONFIG.apiVersion, "1.14.0")) {
|
||||
uniqueData.push(MSPCodes.MSP_SET_3D);
|
||||
}
|
||||
if (semver.gte(CONFIG.apiVersion, "1.15.0")) {
|
||||
uniqueData.push(MSPCodes.MSP_SET_SENSOR_ALIGNMENT);
|
||||
uniqueData.push(MSPCodes.MSP_SET_RX_CONFIG);
|
||||
uniqueData.push(MSPCodes.MSP_SET_FAILSAFE_CONFIG);
|
||||
}
|
||||
}
|
||||
|
||||
function load_objects() {
|
||||
MISC = configuration.MISC;
|
||||
RC_MAP = configuration.RCMAP;
|
||||
BF_CONFIG = configuration.BF_CONFIG;
|
||||
SERIAL_CONFIG = configuration.SERIAL_CONFIG;
|
||||
LED_STRIP = configuration.LED_STRIP;
|
||||
LED_COLORS = configuration.LED_COLORS;
|
||||
LED_MODE_COLORS = configuration.LED_MODE_COLORS;
|
||||
ARMING_CONFIG = configuration.ARMING_CONFIG;
|
||||
FC_CONFIG = configuration.FC_CONFIG;
|
||||
_3D = configuration._3D;
|
||||
SENSOR_ALIGNMENT = configuration.SENSOR_ALIGNMENT;
|
||||
RX_CONFIG = configuration.RX_CONFIG;
|
||||
FAILSAFE_CONFIG = configuration.FAILSAFE_CONFIG;
|
||||
RXFAIL_CONFIG = configuration.RXFAIL_CONFIG;
|
||||
}
|
||||
|
||||
function send_unique_data_item() {
|
||||
if (codeKey < uniqueData.length) {
|
||||
MSP.send_message(uniqueData[codeKey], mspHelper.crunch(uniqueData[codeKey]), false, function () {
|
||||
codeKey++;
|
||||
send_unique_data_item();
|
||||
});
|
||||
} else {
|
||||
send_led_strip_config();
|
||||
}
|
||||
}
|
||||
|
||||
load_objects();
|
||||
|
||||
update_unique_data_list();
|
||||
|
||||
// start uploading
|
||||
send_unique_data_item();
|
||||
}
|
||||
|
||||
function send_led_strip_config() {
|
||||
mspHelper.sendLedStripConfig(send_led_strip_colors);
|
||||
}
|
||||
|
||||
function send_led_strip_colors() {
|
||||
mspHelper.sendLedStripColors(send_led_strip_mode_colors);
|
||||
}
|
||||
|
||||
function send_led_strip_mode_colors() {
|
||||
if (semver.gte(CONFIG.apiVersion, "1.19.0"))
|
||||
mspHelper.sendLedStripModeColors(send_rxfail_config);
|
||||
else
|
||||
send_rxfail_config();
|
||||
}
|
||||
|
||||
function send_rxfail_config() {
|
||||
if (semver.gte(CONFIG.apiVersion, "1.15.0")) {
|
||||
mspHelper.sendRxFailConfig(save_to_eeprom);
|
||||
} else {
|
||||
save_to_eeprom();
|
||||
}
|
||||
}
|
||||
|
||||
function save_to_eeprom() {
|
||||
MSP.send_message(MSPCodes.MSP_EEPROM_WRITE, false, false, reboot);
|
||||
}
|
||||
|
||||
function reboot() {
|
||||
GUI.log(chrome.i18n.getMessage('eeprom_saved_ok'));
|
||||
|
||||
GUI.tab_switch_cleanup(function() {
|
||||
MSP.send_message(MSPCodes.MSP_SET_REBOOT, false, false, reinitialize);
|
||||
});
|
||||
}
|
||||
|
||||
function reinitialize() {
|
||||
GUI.log(chrome.i18n.getMessage('deviceRebooting'));
|
||||
|
||||
GUI.timeout_add('waiting_for_bootup', function waiting_for_bootup() {
|
||||
MSP.send_message(MSPCodes.MSP_IDENT, false, false, function () {
|
||||
GUI.log(chrome.i18n.getMessage('deviceReady'));
|
||||
|
||||
if (callback) callback();
|
||||
});
|
||||
}, 1500); // 1500 ms seems to be just the right amount of delay to prevent data request timeouts
|
||||
}
|
||||
}
|
||||
|
||||
upload();
|
||||
}
|
||||
}
|
77
js/eventFrequencyAnalyzer.js
Normal file
77
js/eventFrequencyAnalyzer.js
Normal file
|
@ -0,0 +1,77 @@
|
|||
'use s';
|
||||
|
||||
var helper = helper || {};
|
||||
|
||||
/**
|
||||
* Simple analyzer that returns frequency of events using 5s buffer
|
||||
* Usage: register periodic events with 'put', then call 'get' to get results
|
||||
*/
|
||||
helper.eventFrequencyAnalyzer = (function () {
|
||||
|
||||
var privateScope = {},
|
||||
publicScope = {},
|
||||
bufferPeriod = 5000;
|
||||
|
||||
privateScope.data = {};
|
||||
privateScope.output = {};
|
||||
privateScope.intervalHandler;
|
||||
|
||||
/**
|
||||
* Periodically executed aggregation task
|
||||
* @returns {{}|*}
|
||||
*/
|
||||
publicScope.analyze = function () {
|
||||
privateScope.output = {};
|
||||
|
||||
for (var i in privateScope.data) {
|
||||
if (privateScope.data.hasOwnProperty(i)) {
|
||||
privateScope.output[i] = privateScope.data[i] / bufferPeriod * 1000;
|
||||
}
|
||||
}
|
||||
|
||||
privateScope.data = {};
|
||||
return privateScope.output;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return event list with frequencies
|
||||
* @returns {{}|*}
|
||||
*/
|
||||
publicScope.get = function () {
|
||||
return privateScope.output;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns raw data
|
||||
* @returns {{}|*}
|
||||
*/
|
||||
publicScope.getRaw = function () {
|
||||
return privateScope.data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Put event into analyzer
|
||||
* @param {object} event
|
||||
*/
|
||||
publicScope.put = function (event) {
|
||||
if (privateScope.data[event]) {
|
||||
privateScope.data[event]++;
|
||||
} else {
|
||||
privateScope.data[event] = 1;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number} buffer buffer length in milliseconds
|
||||
*/
|
||||
publicScope.setBufferPeriod = function (buffer) {
|
||||
bufferPeriod = buffer;
|
||||
clearInterval(privateScope.intervalHandler);
|
||||
privateScope.intervalHandler = setInterval(publicScope.analyze, bufferPeriod);
|
||||
};
|
||||
|
||||
privateScope.intervalHandler = setInterval(publicScope.analyze, bufferPeriod);
|
||||
|
||||
return publicScope;
|
||||
})();
|
3
js/fc.js
3
js/fc.js
|
@ -251,7 +251,8 @@ var FC = {
|
|||
yawItermIgnoreRate: null,
|
||||
yawPLimit: null,
|
||||
axisAccelerationLimitRollPitch: null,
|
||||
axisAccelerationLimitYaw: null
|
||||
axisAccelerationLimitYaw: null,
|
||||
dtermSetpointWeight: null
|
||||
};
|
||||
|
||||
INAV_PID_CONFIG = {
|
||||
|
|
161
js/gui.js
161
js/gui.js
|
@ -11,8 +11,6 @@ var GUI_control = function () {
|
|||
this.active_tab;
|
||||
this.tab_switch_in_progress = false;
|
||||
this.operating_system;
|
||||
this.interval_array = [];
|
||||
this.timeout_array = [];
|
||||
this.defaultAllowedTabsWhenDisconnected = [
|
||||
'landing',
|
||||
'firmware_flasher',
|
||||
|
@ -52,162 +50,6 @@ var GUI_control = function () {
|
|||
else this.operating_system = "Unknown";
|
||||
};
|
||||
|
||||
// Timer managing methods
|
||||
|
||||
// name = string
|
||||
// code = function reference (code to be executed)
|
||||
// interval = time interval in miliseconds
|
||||
// first = true/false if code should be ran initially before next timer interval hits
|
||||
GUI_control.prototype.interval_add = function (name, code, interval, first) {
|
||||
var data = {'name': name, 'timer': null, 'code': code, 'interval': interval, 'fired': 0, 'paused': false};
|
||||
|
||||
if (first == true) {
|
||||
code(); // execute code
|
||||
|
||||
data.fired++; // increment counter
|
||||
}
|
||||
|
||||
data.timer = setInterval(function() {
|
||||
code(); // execute code
|
||||
|
||||
data.fired++; // increment counter
|
||||
}, interval);
|
||||
|
||||
this.interval_array.push(data); // push to primary interval array
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
// name = string
|
||||
GUI_control.prototype.interval_remove = function (name) {
|
||||
for (var i = 0; i < this.interval_array.length; i++) {
|
||||
if (this.interval_array[i].name == name) {
|
||||
clearInterval(this.interval_array[i].timer); // stop timer
|
||||
|
||||
this.interval_array.splice(i, 1); // remove element/object from array
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
// name = string
|
||||
GUI_control.prototype.interval_pause = function (name) {
|
||||
for (var i = 0; i < this.interval_array.length; i++) {
|
||||
if (this.interval_array[i].name == name) {
|
||||
clearInterval(this.interval_array[i].timer);
|
||||
this.interval_array[i].paused = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
// name = string
|
||||
GUI_control.prototype.interval_resume = function (name) {
|
||||
for (var i = 0; i < this.interval_array.length; i++) {
|
||||
if (this.interval_array[i].name == name && this.interval_array[i].paused) {
|
||||
var obj = this.interval_array[i];
|
||||
|
||||
obj.timer = setInterval(function() {
|
||||
obj.code(); // execute code
|
||||
|
||||
obj.fired++; // increment counter
|
||||
}, obj.interval);
|
||||
|
||||
obj.paused = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
// input = array of timers thats meant to be kept, or nothing
|
||||
// return = returns timers killed in last call
|
||||
GUI_control.prototype.interval_kill_all = function (keep_array) {
|
||||
var self = this;
|
||||
var timers_killed = 0;
|
||||
|
||||
for (var i = (this.interval_array.length - 1); i >= 0; i--) { // reverse iteration
|
||||
var keep = false;
|
||||
if (keep_array) { // only run through the array if it exists
|
||||
keep_array.forEach(function (name) {
|
||||
if (self.interval_array[i].name == name) {
|
||||
keep = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!keep) {
|
||||
clearInterval(this.interval_array[i].timer); // stop timer
|
||||
|
||||
this.interval_array.splice(i, 1); // remove element/object from array
|
||||
|
||||
timers_killed++;
|
||||
}
|
||||
}
|
||||
|
||||
return timers_killed;
|
||||
};
|
||||
|
||||
// name = string
|
||||
// code = function reference (code to be executed)
|
||||
// timeout = timeout in miliseconds
|
||||
GUI_control.prototype.timeout_add = function (name, code, timeout) {
|
||||
var self = this;
|
||||
var data = {'name': name, 'timer': null, 'timeout': timeout};
|
||||
|
||||
// start timer with "cleaning" callback
|
||||
data.timer = setTimeout(function() {
|
||||
code(); // execute code
|
||||
|
||||
// remove object from array
|
||||
var index = self.timeout_array.indexOf(data);
|
||||
if (index > -1) self.timeout_array.splice(index, 1);
|
||||
}, timeout);
|
||||
|
||||
this.timeout_array.push(data); // push to primary timeout array
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
// name = string
|
||||
GUI_control.prototype.timeout_remove = function (name) {
|
||||
for (var i = 0; i < this.timeout_array.length; i++) {
|
||||
if (this.timeout_array[i].name == name) {
|
||||
clearTimeout(this.timeout_array[i].timer); // stop timer
|
||||
|
||||
this.timeout_array.splice(i, 1); // remove element/object from array
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
// no input paremeters
|
||||
// return = returns timers killed in last call
|
||||
GUI_control.prototype.timeout_kill_all = function () {
|
||||
var timers_killed = 0;
|
||||
|
||||
for (var i = 0; i < this.timeout_array.length; i++) {
|
||||
clearTimeout(this.timeout_array[i].timer); // stop timer
|
||||
|
||||
timers_killed++;
|
||||
}
|
||||
|
||||
this.timeout_array = []; // drop objects
|
||||
|
||||
return timers_killed;
|
||||
};
|
||||
|
||||
// message = string
|
||||
GUI_control.prototype.log = function (message) {
|
||||
var command_log = $('div#log');
|
||||
|
@ -234,7 +76,8 @@ GUI_control.prototype.log = function (message) {
|
|||
// default switch doesn't require callback to be set
|
||||
GUI_control.prototype.tab_switch_cleanup = function (callback) {
|
||||
MSP.callbacks_cleanup(); // we don't care about any old data that might or might not arrive
|
||||
GUI.interval_kill_all(); // all intervals (mostly data pulling) needs to be removed on tab switch
|
||||
|
||||
helper.interval.killAll(['global_data_refresh']);
|
||||
|
||||
if (this.active_tab) {
|
||||
TABS[this.active_tab].cleanup(callback);
|
||||
|
|
137
js/intervals.js
Normal file
137
js/intervals.js
Normal file
|
@ -0,0 +1,137 @@
|
|||
'use strict';
|
||||
|
||||
var helper = helper || {};
|
||||
|
||||
helper.interval = (function () {
|
||||
|
||||
var privateScope = {},
|
||||
publicScope = {};
|
||||
|
||||
privateScope.intervals = [];
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {Function} code function reference (code to be executed)
|
||||
* @param {int} interval time interval in milliseconds
|
||||
* @param {boolean=} first true/false if code should be ran initially before next timer interval hits
|
||||
* @returns {{name: *, timer: null, code: *, interval: *, fired: number, paused: boolean}}
|
||||
*/
|
||||
publicScope.add = function (name, code, interval, first) {
|
||||
|
||||
/*
|
||||
* Kill existing interval with this name if exists
|
||||
*/
|
||||
publicScope.remove(name);
|
||||
|
||||
var data = {
|
||||
'name': name,
|
||||
'timer': null,
|
||||
'code': code,
|
||||
'interval': interval,
|
||||
'fired': 0,
|
||||
'paused': false
|
||||
};
|
||||
|
||||
if (first == true) {
|
||||
code(); // execute code
|
||||
data.fired++; // increment counter
|
||||
}
|
||||
|
||||
data.timer = setInterval(function() {
|
||||
code();
|
||||
data.fired++;
|
||||
}, interval);
|
||||
|
||||
privateScope.intervals.push(data);
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Method removes and stop execution of interval callback
|
||||
* @param {string} name
|
||||
* @returns {boolean}
|
||||
*/
|
||||
publicScope.remove = function (name) {
|
||||
for (var i = 0; i < privateScope.intervals.length; i++) {
|
||||
if (privateScope.intervals[i].name == name) {
|
||||
clearInterval(privateScope.intervals[i].timer); // stop timer
|
||||
privateScope.intervals.splice(i, 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} name
|
||||
* @returns {boolean}
|
||||
*/
|
||||
publicScope.pause = function (name) {
|
||||
for (var i = 0; i < privateScope.intervals.length; i++) {
|
||||
if (privateScope.intervals[i].name == name) {
|
||||
clearInterval(privateScope.intervals[i].timer);
|
||||
privateScope.intervals[i].paused = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} name
|
||||
* @returns {boolean}
|
||||
*/
|
||||
publicScope.resume = function (name) {
|
||||
for (var i = 0; i < privateScope.intervals.length; i++) {
|
||||
if (privateScope.intervals[i].name == name && privateScope.intervals[i].paused) {
|
||||
var obj = privateScope.intervals[i];
|
||||
|
||||
obj.timer = setInterval(function() {
|
||||
obj.code(); // execute code
|
||||
obj.fired++; // increment counter
|
||||
}, obj.interval);
|
||||
|
||||
obj.paused = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {=} keep_array
|
||||
* @returns {number}
|
||||
*/
|
||||
publicScope.killAll = function (keep_array) {
|
||||
var timers_killed = 0;
|
||||
|
||||
for (var i = (privateScope.intervals.length - 1); i >= 0; i--) { // reverse iteration
|
||||
var keep = false;
|
||||
if (keep_array) { // only run through the array if it exists
|
||||
keep_array.forEach(function (name) {
|
||||
if (privateScope.intervals[i].name == name) {
|
||||
keep = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!keep) {
|
||||
clearInterval(privateScope.intervals[i].timer); // stop timer
|
||||
privateScope.intervals.splice(i, 1); // remove element/object from array
|
||||
timers_killed++;
|
||||
}
|
||||
}
|
||||
|
||||
return timers_killed;
|
||||
};
|
||||
|
||||
return publicScope;
|
||||
})();
|
|
@ -114,6 +114,11 @@ var MSP = {
|
|||
bufView,
|
||||
i;
|
||||
|
||||
/*
|
||||
* For debug reasons, check how ofter MSP frames are executed
|
||||
*/
|
||||
helper.eventFrequencyAnalyzer.put(code);
|
||||
|
||||
// always reserve 6 bytes for protocol overhead !
|
||||
if (data) {
|
||||
var size = data.length + 6,
|
||||
|
@ -172,7 +177,7 @@ var MSP = {
|
|||
console.log('MSP data request timed-out: ' + code);
|
||||
|
||||
serial.send(bufferOut, false);
|
||||
}, 1000); // we should be able to define timeout in the future
|
||||
}, serial.getTimeout()); // we should be able to define timeout in the future
|
||||
}
|
||||
|
||||
MSP.callbacks.push(obj);
|
||||
|
|
|
@ -61,7 +61,7 @@ var MSPCodes = {
|
|||
MSP_SET_SENSOR_CONFIG: 97,
|
||||
|
||||
// Multiwii MSP commands
|
||||
MSP_IDENT: 100,
|
||||
MSP_IDENT: 100, //deprecated, do not use
|
||||
MSP_STATUS: 101,
|
||||
MSP_RAW_IMU: 102,
|
||||
MSP_SERVO: 103,
|
||||
|
|
|
@ -45,6 +45,7 @@ var mspHelper = (function (gui) {
|
|||
|
||||
if (!dataHandler.unsupported) switch (dataHandler.code) {
|
||||
case MSPCodes.MSP_IDENT:
|
||||
//FIXME remove this frame when proven not needed
|
||||
console.log('Using deprecated msp command: MSP_IDENT');
|
||||
// Deprecated
|
||||
CONFIG.version = parseFloat((data.getUint8(0) / 100).toFixed(2));
|
||||
|
@ -53,6 +54,7 @@ var mspHelper = (function (gui) {
|
|||
CONFIG.capability = data.getUint32(3, true);
|
||||
break;
|
||||
case MSPCodes.MSP_STATUS:
|
||||
console.log('Using deprecated msp command: MSP_STATUS');
|
||||
CONFIG.cycleTime = data.getUint16(0, true);
|
||||
CONFIG.i2cError = data.getUint16(2, true);
|
||||
CONFIG.activeSensors = data.getUint16(4, true);
|
||||
|
@ -86,6 +88,7 @@ var mspHelper = (function (gui) {
|
|||
sensor_status(CONFIG.activeSensors);
|
||||
}
|
||||
gui.updateStatusBar();
|
||||
gui.updateProfileChange();
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP_SENSOR_STATUS:
|
||||
|
@ -574,14 +577,12 @@ var mspHelper = (function (gui) {
|
|||
offset++;
|
||||
FAILSAFE_CONFIG.failsafe_throttle = data.getUint16(offset, true);
|
||||
offset += 2;
|
||||
if (semver.gte(CONFIG.apiVersion, "1.15.0")) {
|
||||
FAILSAFE_CONFIG.failsafe_kill_switch = data.getUint8(offset);
|
||||
offset++;
|
||||
FAILSAFE_CONFIG.failsafe_throttle_low_delay = data.getUint16(offset, true);
|
||||
offset += 2;
|
||||
FAILSAFE_CONFIG.failsafe_procedure = data.getUint8(offset);
|
||||
offset++;
|
||||
}
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP_RXFAIL_CONFIG:
|
||||
|
@ -842,6 +843,11 @@ var mspHelper = (function (gui) {
|
|||
PID_ADVANCED.rollPitchItermIgnoreRate = data.getUint16(0, true);
|
||||
PID_ADVANCED.yawItermIgnoreRate = data.getUint16(2, true);
|
||||
PID_ADVANCED.yawPLimit = data.getUint16(4, true);
|
||||
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.6.0")) {
|
||||
PID_ADVANCED.dtermSetpointWeight = data.getUint8(9);
|
||||
}
|
||||
|
||||
PID_ADVANCED.axisAccelerationLimitRollPitch = data.getUint16(13, true);
|
||||
PID_ADVANCED.axisAccelerationLimitYaw = data.getUint16(15, true);
|
||||
break;
|
||||
|
@ -995,10 +1001,7 @@ var mspHelper = (function (gui) {
|
|||
case MSPCodes.MSP_SET_RC_TUNING:
|
||||
buffer.push(Math.round(RC_tuning.RC_RATE * 100));
|
||||
buffer.push(Math.round(RC_tuning.RC_EXPO * 100));
|
||||
if (semver.lt(CONFIG.apiVersion, "1.7.0")) {
|
||||
buffer.push(Math.round(RC_tuning.roll_pitch_rate * 100));
|
||||
buffer.push(Math.round(RC_tuning.yaw_rate * 100));
|
||||
} else if (FC.isRatesInDps()) {
|
||||
if (FC.isRatesInDps()) {
|
||||
buffer.push(Math.round(RC_tuning.roll_rate / 10));
|
||||
buffer.push(Math.round(RC_tuning.pitch_rate / 10));
|
||||
buffer.push(Math.round(RC_tuning.yaw_rate / 10));
|
||||
|
@ -1011,13 +1014,9 @@ var mspHelper = (function (gui) {
|
|||
buffer.push(RC_tuning.dynamic_THR_PID);
|
||||
buffer.push(Math.round(RC_tuning.throttle_MID * 100));
|
||||
buffer.push(Math.round(RC_tuning.throttle_EXPO * 100));
|
||||
if (semver.gte(CONFIG.apiVersion, "1.7.0")) {
|
||||
buffer.push(lowByte(RC_tuning.dynamic_THR_breakpoint));
|
||||
buffer.push(highByte(RC_tuning.dynamic_THR_breakpoint));
|
||||
}
|
||||
if (semver.gte(CONFIG.apiVersion, "1.10.0")) {
|
||||
buffer.push(Math.round(RC_tuning.RC_YAW_EXPO * 100));
|
||||
}
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP_SET_RX_MAP:
|
||||
|
@ -1095,12 +1094,10 @@ var mspHelper = (function (gui) {
|
|||
buffer.push(FAILSAFE_CONFIG.failsafe_off_delay);
|
||||
buffer.push(lowByte(FAILSAFE_CONFIG.failsafe_throttle));
|
||||
buffer.push(highByte(FAILSAFE_CONFIG.failsafe_throttle));
|
||||
if (semver.gte(CONFIG.apiVersion, "1.15.0")) {
|
||||
buffer.push(FAILSAFE_CONFIG.failsafe_kill_switch);
|
||||
buffer.push(lowByte(FAILSAFE_CONFIG.failsafe_throttle_low_delay));
|
||||
buffer.push(highByte(FAILSAFE_CONFIG.failsafe_throttle_low_delay));
|
||||
buffer.push(FAILSAFE_CONFIG.failsafe_procedure);
|
||||
}
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP_SET_TRANSPONDER_CONFIG:
|
||||
|
@ -1262,7 +1259,13 @@ var mspHelper = (function (gui) {
|
|||
buffer.push(0); //BF: currentProfile->pidProfile.deltaMethod
|
||||
buffer.push(0); //BF: currentProfile->pidProfile.vbatPidCompensation
|
||||
buffer.push(0); //BF: currentProfile->pidProfile.setpointRelaxRatio
|
||||
buffer.push(0); //BF: currentProfile->pidProfile.dtermSetpointWeight
|
||||
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.6.0")) {
|
||||
buffer.push(PID_ADVANCED.dtermSetpointWeight);
|
||||
} else {
|
||||
buffer.push(0);
|
||||
}
|
||||
|
||||
buffer.push(0); // reserved
|
||||
buffer.push(0); // reserved
|
||||
buffer.push(0); //BF: currentProfile->pidProfile.itermThrottleGain
|
||||
|
@ -1718,6 +1721,11 @@ var mspHelper = (function (gui) {
|
|||
/*
|
||||
* Basic sending methods used for chaining purposes
|
||||
*/
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @param callback
|
||||
*/
|
||||
self.loadMspIdent = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_IDENT, false, false, callback);
|
||||
};
|
||||
|
@ -1810,14 +1818,18 @@ var mspHelper = (function (gui) {
|
|||
}
|
||||
};
|
||||
|
||||
self.loadRcDeadband = function (callback) {
|
||||
if (semver.gte(CONFIG.apiVersion, "1.15.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_RC_DEADBAND, false, false, callback);
|
||||
self.loadSensorStatus = function (callback) {
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.5.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS, false, false, callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
self.loadRcDeadband = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_RC_DEADBAND, false, false, callback);
|
||||
};
|
||||
|
||||
self.loadRcMap = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_RX_MAP, false, false, callback);
|
||||
};
|
||||
|
@ -1830,6 +1842,10 @@ var mspHelper = (function (gui) {
|
|||
MSP.send_message(MSPCodes.MSP_ACC_TRIM, false, false, callback);
|
||||
};
|
||||
|
||||
self.loadAnalog = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_ANALOG, false, false, callback);
|
||||
};
|
||||
|
||||
self.saveToEeprom = function saveToEeprom(callback) {
|
||||
MSP.send_message(MSPCodes.MSP_EEPROM_WRITE, false, false, callback);
|
||||
};
|
||||
|
|
128
js/periodicStatusUpdater.js
Normal file
128
js/periodicStatusUpdater.js
Normal file
|
@ -0,0 +1,128 @@
|
|||
'use strict';
|
||||
|
||||
var helper = helper || {};
|
||||
|
||||
helper.periodicStatusUpdater = (function () {
|
||||
|
||||
var publicScope = {},
|
||||
privateScope = {};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number=} baudSpeed
|
||||
* @returns {number}
|
||||
*/
|
||||
publicScope.getUpdateInterval = function (baudSpeed) {
|
||||
|
||||
if (!baudSpeed) {
|
||||
baudSpeed = 115200;
|
||||
}
|
||||
|
||||
if (baudSpeed >= 115200) {
|
||||
return 200;
|
||||
} else if (baudSpeed >= 57600) {
|
||||
return 400;
|
||||
} else if (baudSpeed >= 38400) {
|
||||
return 500;
|
||||
} else if (baudSpeed >= 19200) {
|
||||
return 600;
|
||||
} else if (baudSpeed >= 9600) {
|
||||
return 750;
|
||||
} else {
|
||||
return 1000;
|
||||
}
|
||||
};
|
||||
|
||||
privateScope.updateView = function () {
|
||||
|
||||
var active = ((Date.now() - MSP.analog_last_received_timestamp) < publicScope.getUpdateInterval(serial.bitrate) * 3);
|
||||
|
||||
for (var i = 0; i < AUX_CONFIG.length; i++) {
|
||||
if (AUX_CONFIG[i] == 'ARM') {
|
||||
if (bit_check(CONFIG.mode, i))
|
||||
$(".armedicon").css({
|
||||
'background-image': 'url(images/icons/cf_icon_armed_active.svg)'
|
||||
});
|
||||
else
|
||||
$(".armedicon").css({
|
||||
'background-image': 'url(images/icons/cf_icon_armed_grey.svg)'
|
||||
});
|
||||
}
|
||||
if (AUX_CONFIG[i] == 'FAILSAFE') {
|
||||
if (bit_check(CONFIG.mode, i))
|
||||
$(".failsafeicon").css({
|
||||
'background-image': 'url(images/icons/cf_icon_failsafe_active.svg)'
|
||||
});
|
||||
else
|
||||
$(".failsafeicon").css({
|
||||
'background-image': 'url(images/icons/cf_icon_failsafe_grey.svg)'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (ANALOG != undefined) {
|
||||
var nbCells = Math.floor(ANALOG.voltage / MISC.vbatmaxcellvoltage) + 1;
|
||||
if (ANALOG.voltage == 0)
|
||||
nbCells = 1;
|
||||
|
||||
var min = MISC.vbatmincellvoltage * nbCells;
|
||||
var max = MISC.vbatmaxcellvoltage * nbCells;
|
||||
var warn = MISC.vbatwarningcellvoltage * nbCells;
|
||||
|
||||
$(".battery-status").css({
|
||||
width: ((ANALOG.voltage - min) / (max - min) * 100) + "%",
|
||||
display: 'inline-block'
|
||||
});
|
||||
|
||||
if (active) {
|
||||
$(".linkicon").css({
|
||||
'background-image': 'url(images/icons/cf_icon_link_active.svg)'
|
||||
});
|
||||
} else {
|
||||
$(".linkicon").css({
|
||||
'background-image': 'url(images/icons/cf_icon_link_grey.svg)'
|
||||
});
|
||||
}
|
||||
|
||||
if (ANALOG.voltage < warn) {
|
||||
$(".battery-status").css('background-color', '#D42133');
|
||||
} else {
|
||||
$(".battery-status").css('background-color', '#59AA29');
|
||||
}
|
||||
|
||||
$(".battery-legend").text(ANALOG.voltage + " V");
|
||||
}
|
||||
|
||||
$('#quad-status_wrapper').show();
|
||||
};
|
||||
|
||||
publicScope.run = function () {
|
||||
|
||||
if (!CONFIGURATOR.connectionValid) {
|
||||
return;
|
||||
}
|
||||
|
||||
$(".quad-status-contents").css({
|
||||
display: 'inline-block'
|
||||
});
|
||||
|
||||
if (GUI.active_tab != 'cli') {
|
||||
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.5.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS, false, false);
|
||||
}
|
||||
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.2.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS_EX, false, false);
|
||||
} else {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS, false, false);
|
||||
}
|
||||
|
||||
MSP.send_message(MSPCodes.MSP_ANALOG, false, false);
|
||||
|
||||
privateScope.updateView();
|
||||
}
|
||||
};
|
||||
|
||||
return publicScope;
|
||||
})();
|
|
@ -112,7 +112,7 @@ PortHandler.check = function () {
|
|||
if (GUI.auto_connect && !GUI.connecting_to && !GUI.connected_to) {
|
||||
// we need firmware flasher protection over here
|
||||
if (GUI.active_tab != 'firmware_flasher') {
|
||||
GUI.timeout_add('auto-connect_timeout', function () {
|
||||
helper.timeout.add('auto-connect_timeout', function () {
|
||||
$('div#port-picker a.connect').click();
|
||||
}, 100); // timeout so bus have time to initialize after being detected by the system
|
||||
}
|
||||
|
|
|
@ -154,7 +154,7 @@ STM32_protocol.prototype.initialize = function () {
|
|||
self.read(info);
|
||||
});
|
||||
|
||||
GUI.interval_add('STM32_timeout', function () {
|
||||
helper.interval.add('STM32_timeout', function () {
|
||||
if (self.upload_process_alive) { // process is running
|
||||
self.upload_process_alive = false;
|
||||
} else {
|
||||
|
@ -166,7 +166,7 @@ STM32_protocol.prototype.initialize = function () {
|
|||
googleAnalytics.sendEvent('Flashing', 'Programming', 'timeout');
|
||||
|
||||
// protocol got stuck, clear timer and disconnect
|
||||
GUI.interval_remove('STM32_timeout');
|
||||
helper.interval.remove('STM32_timeout');
|
||||
|
||||
// exit
|
||||
self.upload_procedure(99);
|
||||
|
@ -361,10 +361,10 @@ STM32_protocol.prototype.upload_procedure = function (step) {
|
|||
$('span.progressLabel').text('Contacting bootloader ...');
|
||||
|
||||
var send_counter = 0;
|
||||
GUI.interval_add('stm32_initialize_mcu', function () { // 200 ms interval (just in case mcu was already initialized), we need to break the 2 bytes command requirement
|
||||
helper.interval.add('stm32_initialize_mcu', function () { // 200 ms interval (just in case mcu was already initialized), we need to break the 2 bytes command requirement
|
||||
self.send([0x7F], 1, function (reply) {
|
||||
if (reply[0] == 0x7F || reply[0] == self.status.ACK || reply[0] == self.status.NACK) {
|
||||
GUI.interval_remove('stm32_initialize_mcu');
|
||||
helper.interval.remove('stm32_initialize_mcu');
|
||||
console.log('STM32 - Serial interface initialized on the MCU side');
|
||||
|
||||
// proceed to next step
|
||||
|
@ -373,7 +373,7 @@ STM32_protocol.prototype.upload_procedure = function (step) {
|
|||
$('span.progressLabel').text('Communication with bootloader failed');
|
||||
self.progress_bar_e.addClass('invalid');
|
||||
|
||||
GUI.interval_remove('stm32_initialize_mcu');
|
||||
helper.interval.remove('stm32_initialize_mcu');
|
||||
|
||||
// disconnect
|
||||
self.upload_procedure(99);
|
||||
|
@ -387,8 +387,8 @@ STM32_protocol.prototype.upload_procedure = function (step) {
|
|||
$('span.progressLabel').text('No response from the bootloader, programming: FAILED');
|
||||
self.progress_bar_e.addClass('invalid');
|
||||
|
||||
GUI.interval_remove('stm32_initialize_mcu');
|
||||
GUI.interval_remove('STM32_timeout');
|
||||
helper.interval.remove('stm32_initialize_mcu');
|
||||
helper.interval.remove('STM32_timeout');
|
||||
|
||||
// exit
|
||||
self.upload_procedure(99);
|
||||
|
@ -749,7 +749,7 @@ STM32_protocol.prototype.upload_procedure = function (step) {
|
|||
break;
|
||||
case 99:
|
||||
// disconnect
|
||||
GUI.interval_remove('STM32_timeout'); // stop STM32 timeout timer (everything is finished now)
|
||||
helper.interval.remove('STM32_timeout'); // stop STM32 timeout timer (everything is finished now)
|
||||
|
||||
// close connection
|
||||
serial.disconnect(function (result) {
|
||||
|
|
12
js/serial.js
12
js/serial.js
|
@ -292,6 +292,18 @@ var serial = {
|
|||
emptyOutputBuffer: function () {
|
||||
this.outputBuffer = [];
|
||||
this.transmitting = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Default timeout value for serial messages
|
||||
* @returns {number} [ms]
|
||||
*/
|
||||
getTimeout: function () {
|
||||
if (serial.bitrate >= 57600) {
|
||||
return 1000;
|
||||
} else {
|
||||
return 2000;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
|
@ -35,8 +35,8 @@ $(document).ready(function () {
|
|||
}, 5000);
|
||||
} else {
|
||||
|
||||
GUI.timeout_add('waiting_for_bootup', function waiting_for_bootup() {
|
||||
MSP.send_message(MSPCodes.MSP_IDENT, false, false, function () {
|
||||
helper.timeout.add('waiting_for_bootup', function waiting_for_bootup() {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS, false, false, function () {
|
||||
//noinspection JSUnresolvedVariable
|
||||
GUI.log(chrome.i18n.getMessage('deviceReady'));
|
||||
//noinspection JSValidateTypes
|
||||
|
@ -98,15 +98,15 @@ $(document).ready(function () {
|
|||
|
||||
serial.connect(selected_port, {bitrate: selected_baud}, onOpen);
|
||||
} else {
|
||||
GUI.timeout_kill_all();
|
||||
GUI.interval_kill_all();
|
||||
var wasConnected = CONFIGURATOR.connectionValid;
|
||||
|
||||
helper.timeout.killAll(['global_data_refresh']);
|
||||
helper.interval.killAll(['global_data_refresh']);
|
||||
GUI.tab_switch_cleanup();
|
||||
GUI.tab_switch_in_progress = false;
|
||||
|
||||
serial.disconnect(onClosed);
|
||||
|
||||
var wasConnected = CONFIGURATOR.connectionValid;
|
||||
|
||||
GUI.connected_to = false;
|
||||
CONFIGURATOR.connectionValid = false;
|
||||
GUI.allowedTabs = GUI.defaultAllowedTabsWhenDisconnected.slice();
|
||||
|
@ -213,7 +213,7 @@ function onOpen(openInfo) {
|
|||
serial.onReceive.addListener(read_serial);
|
||||
|
||||
// disconnect after 10 seconds with error if we don't get IDENT data
|
||||
GUI.timeout_add('connecting', function () {
|
||||
helper.timeout.add('connecting', function () {
|
||||
if (!CONFIGURATOR.connectionValid) {
|
||||
GUI.log(chrome.i18n.getMessage('noConfigurationReceived'));
|
||||
|
||||
|
@ -307,25 +307,24 @@ function onOpen(openInfo) {
|
|||
}
|
||||
|
||||
function onConnect() {
|
||||
GUI.timeout_remove('connecting'); // kill connecting timer
|
||||
helper.timeout.remove('connecting'); // kill connecting timer
|
||||
$('div#connectbutton a.connect_state').text(chrome.i18n.getMessage('disconnect')).addClass('active');
|
||||
$('div#connectbutton a.connect').addClass('active');
|
||||
$('#tabs ul.mode-disconnected').hide();
|
||||
$('#tabs ul.mode-connected').show();
|
||||
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.2.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS_EX, false, false);
|
||||
} else {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS, false, false);
|
||||
}
|
||||
|
||||
MSP.send_message(MSPCodes.MSP_DATAFLASH_SUMMARY, false, false);
|
||||
|
||||
$('#sensor-status').show();
|
||||
$('#portsinput').hide();
|
||||
$('#dataflash_wrapper_global').show();
|
||||
|
||||
startLiveDataRefreshTimer();
|
||||
/*
|
||||
* Get BOXNAMES since it is used for some reason....
|
||||
*/
|
||||
MSP.send_message(MSPCodes.MSP_BOXNAMES, false, false);
|
||||
|
||||
helper.interval.add('global_data_refresh', helper.periodicStatusUpdater.run, helper.periodicStatusUpdater.getUpdateInterval(serial.bitrate), false);
|
||||
}
|
||||
|
||||
function onClosed(result) {
|
||||
|
@ -487,90 +486,6 @@ function update_dataflash_global() {
|
|||
|
||||
}
|
||||
|
||||
function startLiveDataRefreshTimer() {
|
||||
// live data refresh
|
||||
GUI.timeout_add('data_refresh', function () { update_live_status(); }, 100);
|
||||
}
|
||||
|
||||
function update_live_status() {
|
||||
|
||||
var statuswrapper = $('#quad-status_wrapper');
|
||||
|
||||
$(".quad-status-contents").css({
|
||||
display: 'inline-block'
|
||||
});
|
||||
|
||||
if (GUI.active_tab != 'cli') {
|
||||
MSP.send_message(MSPCodes.MSP_BOXNAMES, false, false);
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.2.0"))
|
||||
MSP.send_message(MSPCodes.MSP_STATUS_EX, false, false);
|
||||
else
|
||||
MSP.send_message(MSPCodes.MSP_STATUS, false, false);
|
||||
MSP.send_message(MSPCodes.MSP_ANALOG, false, false);
|
||||
}
|
||||
|
||||
var active = ((Date.now() - MSP.analog_last_received_timestamp) < 300);
|
||||
|
||||
for (var i = 0; i < AUX_CONFIG.length; i++) {
|
||||
if (AUX_CONFIG[i] == 'ARM') {
|
||||
if (bit_check(CONFIG.mode, i))
|
||||
$(".armedicon").css({
|
||||
'background-image': 'url(images/icons/cf_icon_armed_active.svg)'
|
||||
});
|
||||
else
|
||||
$(".armedicon").css({
|
||||
'background-image': 'url(images/icons/cf_icon_armed_grey.svg)'
|
||||
});
|
||||
}
|
||||
if (AUX_CONFIG[i] == 'FAILSAFE') {
|
||||
if (bit_check(CONFIG.mode, i))
|
||||
$(".failsafeicon").css({
|
||||
'background-image': 'url(images/icons/cf_icon_failsafe_active.svg)'
|
||||
});
|
||||
else
|
||||
$(".failsafeicon").css({
|
||||
'background-image': 'url(images/icons/cf_icon_failsafe_grey.svg)'
|
||||
});
|
||||
}
|
||||
}
|
||||
if (ANALOG != undefined) {
|
||||
var nbCells = Math.floor(ANALOG.voltage / MISC.vbatmaxcellvoltage) + 1;
|
||||
if (ANALOG.voltage == 0)
|
||||
nbCells = 1;
|
||||
|
||||
var min = MISC.vbatmincellvoltage * nbCells;
|
||||
var max = MISC.vbatmaxcellvoltage * nbCells;
|
||||
var warn = MISC.vbatwarningcellvoltage * nbCells;
|
||||
|
||||
$(".battery-status").css({
|
||||
width: ((ANALOG.voltage - min) / (max - min) * 100) + "%",
|
||||
display: 'inline-block'
|
||||
});
|
||||
|
||||
if (active) {
|
||||
$(".linkicon").css({
|
||||
'background-image': 'url(images/icons/cf_icon_link_active.svg)'
|
||||
});
|
||||
} else {
|
||||
$(".linkicon").css({
|
||||
'background-image': 'url(images/icons/cf_icon_link_grey.svg)'
|
||||
});
|
||||
}
|
||||
|
||||
if (ANALOG.voltage < warn) {
|
||||
$(".battery-status").css('background-color', '#D42133');
|
||||
} else {
|
||||
$(".battery-status").css('background-color', '#59AA29');
|
||||
}
|
||||
|
||||
$(".battery-legend").text(ANALOG.voltage + " V");
|
||||
}
|
||||
|
||||
statuswrapper.show();
|
||||
GUI.timeout_remove('data_refresh');
|
||||
startLiveDataRefreshTimer();
|
||||
}
|
||||
|
||||
function specificByte(num, pos) {
|
||||
return 0x000000FF & (num >> (8 * pos));
|
||||
}
|
||||
|
|
27
js/tasks.js
Normal file
27
js/tasks.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
'use strict';
|
||||
|
||||
var helper = helper || {};
|
||||
|
||||
helper.task = (function () {
|
||||
|
||||
var publicScope = {},
|
||||
privateScope = {};
|
||||
|
||||
privateScope.getStatusPullInterval = function () {
|
||||
//TODO use serial connection speed to determine update interval
|
||||
return 250;
|
||||
};
|
||||
|
||||
publicScope.statusPullStart = function () {
|
||||
helper.interval.add('status_pull', function () {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS, false, false, function () {
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.5.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS);
|
||||
}
|
||||
});
|
||||
|
||||
}, privateScope.getStatusPullInterval(), true);
|
||||
};
|
||||
|
||||
return publicScope;
|
||||
})();
|
66
js/timeouts.js
Normal file
66
js/timeouts.js
Normal file
|
@ -0,0 +1,66 @@
|
|||
'use strict';
|
||||
|
||||
var helper = helper || {};
|
||||
|
||||
helper.timeout = (function () {
|
||||
|
||||
var privateScope = {},
|
||||
publicScope = {};
|
||||
|
||||
privateScope.timeouts = [];
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} name
|
||||
* @param {function } code
|
||||
* @param {number} timeout
|
||||
* @returns {{name: *, timer: null, timeout: *}}
|
||||
*/
|
||||
publicScope.add = function (name, code, timeout) {
|
||||
var data = {'name': name, 'timer': null, 'timeout': timeout};
|
||||
|
||||
// start timer with "cleaning" callback
|
||||
data.timer = setTimeout(function() {
|
||||
code(); // execute code
|
||||
|
||||
// remove object from array
|
||||
var index = privateScope.timeouts.indexOf(data);
|
||||
if (index > -1) privateScope.timeouts.splice(index, 1);
|
||||
}, timeout);
|
||||
|
||||
privateScope.timeouts.push(data); // push to primary timeout array
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
publicScope.remove = function (name) {
|
||||
for (var i = 0; i < privateScope.timeouts.length; i++) {
|
||||
if (privateScope.timeouts[i].name == name) {
|
||||
clearTimeout(privateScope.timeouts[i].timer); // stop timer
|
||||
privateScope.timeouts.splice(i, 1); // remove element/object from array
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns {number} number of killed timeouts
|
||||
*/
|
||||
publicScope.killAll = function () {
|
||||
var timers_killed = 0;
|
||||
|
||||
for (var i = 0; i < privateScope.timeouts.length; i++) {
|
||||
clearTimeout(privateScope.timeouts[i].timer); // stop timer
|
||||
timers_killed++;
|
||||
}
|
||||
|
||||
privateScope.timeouts = []; // drop objects
|
||||
|
||||
return timers_killed;
|
||||
};
|
||||
|
||||
return publicScope;
|
||||
})();
|
|
@ -51,6 +51,8 @@
|
|||
<script type="text/javascript" src="./js/libraries/inflection.min.js"></script>
|
||||
<script type="text/javascript" src="./js/libraries/bluebird.min.js"></script>
|
||||
<script type="text/javascript" src="./js/injected_methods.js"></script>
|
||||
<script type="text/javascript" src="./js/intervals.js"></script>
|
||||
<script type="text/javascript" src="./js/timeouts.js"></script>
|
||||
<script type="text/javascript" src="./js/gui.js"></script>
|
||||
<script type="text/javascript" src="./js/msp/MSPCodes.js"></script>
|
||||
<script type="text/javascript" src="./js/msp/MSPHelper.js"></script>
|
||||
|
@ -63,11 +65,11 @@
|
|||
<script type="text/javascript" src="./js/data_storage.js"></script>
|
||||
<script type="text/javascript" src="./js/fc.js"></script>
|
||||
<script type="text/javascript" src="./js/msp.js"></script>
|
||||
<script type="text/javascript" src="./js/backup_restore.js"></script>
|
||||
<script type="text/javascript" src="./js/protocols/stm32.js"></script>
|
||||
<script type="text/javascript" src="./js/protocols/stm32usbdfu.js"></script>
|
||||
<script type="text/javascript" src="./js/localization.js"></script>
|
||||
<script type="text/javascript" src="./js/boards.js"></script>
|
||||
<script type="text/javascript" src="./js/tasks.js"></script>
|
||||
<script type="text/javascript" src="./main.js"></script>
|
||||
<script type="text/javascript" src="./tabs/landing.js"></script>
|
||||
<script type="text/javascript" src="./tabs/setup.js"></script>
|
||||
|
@ -92,6 +94,8 @@
|
|||
<script type="text/javascript" src="./tabs/osd.js"></script>
|
||||
<script type="text/javascript" src="./tabs/profiles.js"></script>
|
||||
<script type="text/javascript" src="./tabs/advanced_tuning.js"></script>
|
||||
<script type="text/javascript" src="./js/eventFrequencyAnalyzer.js"></script>
|
||||
<script type="text/javascript" src="./js/periodicStatusUpdater.js"></script>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"manifest_version": 2,
|
||||
"minimum_chrome_version": "38",
|
||||
"version": "1.5.2",
|
||||
"version": "1.6.0",
|
||||
"author": "Several",
|
||||
"name": "INAV - Configurator",
|
||||
"short_name": "INAV",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "inav-configurator",
|
||||
"description": "INAV Configurator",
|
||||
"version": "1.5.0",
|
||||
"version": "1.6.0",
|
||||
"main": "main.html",
|
||||
"default_locale": "en",
|
||||
"scripts": {
|
||||
|
|
|
@ -269,16 +269,7 @@ TABS.adjustments.initialize = function (callback) {
|
|||
update_ui();
|
||||
|
||||
// enable data pulling
|
||||
GUI.interval_add('aux_data_pull', get_rc_data, 50);
|
||||
|
||||
// status data pulled via separate timer with static speed
|
||||
GUI.interval_add('status_pull', function () {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS);
|
||||
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.5.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS);
|
||||
}
|
||||
}, 250, true);
|
||||
helper.interval.add('aux_data_pull', get_rc_data, 50);
|
||||
|
||||
GUI.content_ready(callback);
|
||||
}
|
||||
|
|
|
@ -288,16 +288,7 @@ TABS.auxiliary.initialize = function (callback) {
|
|||
update_ui();
|
||||
|
||||
// enable data pulling
|
||||
GUI.interval_add('aux_data_pull', get_rc_data, 50);
|
||||
|
||||
// status data pulled via separate timer with static speed
|
||||
GUI.interval_add('status_pull', function () {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS);
|
||||
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.5.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS);
|
||||
}
|
||||
}, 250, true);
|
||||
helper.interval.add('aux_data_pull', get_rc_data, 50);
|
||||
|
||||
GUI.content_ready(callback);
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ TABS.cli.initialize = function (callback) {
|
|||
// give input element user focus
|
||||
textarea.focus();
|
||||
|
||||
GUI.timeout_add('enter_cli', function enter_cli() {
|
||||
helper.timeout.add('enter_cli', function enter_cli() {
|
||||
// Enter CLI mode
|
||||
var bufferOut = new ArrayBuffer(1);
|
||||
var bufView = new Uint8Array(bufferOut);
|
||||
|
@ -88,7 +88,7 @@ TABS.cli.history.next = function () {
|
|||
};
|
||||
|
||||
TABS.cli.sendSlowly = function (out_arr, i, timeout_needle) {
|
||||
GUI.timeout_add('CLI_send_slowly', function () {
|
||||
helper.timeout.add('CLI_send_slowly', function () {
|
||||
var bufferOut = new ArrayBuffer(out_arr[i].length + 1);
|
||||
var bufView = new Uint8Array(bufferOut);
|
||||
|
||||
|
@ -202,7 +202,7 @@ TABS.cli.cleanup = function (callback) {
|
|||
// (another approach is however much more complicated):
|
||||
// we can setup an interval asking for data lets say every 200ms, when data arrives, callback will be triggered and tab switched
|
||||
// we could probably implement this someday
|
||||
GUI.timeout_add('waiting_for_bootup', function waiting_for_bootup() {
|
||||
helper.timeout.add('waiting_for_bootup', function waiting_for_bootup() {
|
||||
if (callback) callback();
|
||||
}, 1000); // if we dont allow enough time to reboot, CRC of "first" command sent will fail, keep an eye for this one
|
||||
CONFIGURATOR.cliActive = false;
|
||||
|
|
|
@ -13,7 +13,6 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
var loadChainer = new MSPChainerClass();
|
||||
|
||||
loadChainer.setChain([
|
||||
mspHelper.loadMspIdent,
|
||||
mspHelper.loadBfConfig,
|
||||
mspHelper.loadMisc,
|
||||
mspHelper.loadArmingConfig,
|
||||
|
@ -23,8 +22,7 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
mspHelper.loadSensorAlignment,
|
||||
mspHelper.loadAdvancedConfig,
|
||||
mspHelper.loadINAVPidConfig,
|
||||
mspHelper.loadSensorConfig,
|
||||
mspHelper.loadAccTrim
|
||||
mspHelper.loadSensorConfig
|
||||
]);
|
||||
loadChainer.setExitPoint(load_html);
|
||||
loadChainer.execute();
|
||||
|
@ -632,20 +630,10 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
saveChainer.execute();
|
||||
});
|
||||
|
||||
// status data pulled via separate timer with static speed
|
||||
GUI.interval_add('status_pull', function status_pull() {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS);
|
||||
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.5.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS);
|
||||
}
|
||||
}, 250, true);
|
||||
GUI.interval_add('config_load_analog', function () {
|
||||
MSP.send_message(MSPCodes.MSP_ANALOG, false, false, function () {
|
||||
helper.interval.add('config_load_analog', function () {
|
||||
$('#batteryvoltage').val([ANALOG.voltage.toFixed(1)]);
|
||||
$('#batterycurrent').val([ANALOG.amperage.toFixed(2)]);
|
||||
});
|
||||
}, 250, true); // 4 fps
|
||||
}, 100, true); // 10 fps
|
||||
GUI.content_ready(callback);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -4,60 +4,34 @@
|
|||
<div class="cf_doc_version_bt">
|
||||
<a id="button-documentation" href="https://github.com/iNavFlight/inav/releases" target="_blank"></a>
|
||||
</div>
|
||||
<div class="note newpane">
|
||||
<div class="note">
|
||||
<div class="note_spacer">
|
||||
<p i18n="failsafeFeaturesHelpNew"></p>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="note oldpane">
|
||||
<div class="note_spacer">
|
||||
<p i18n="failsafeFeaturesHelpOld"></p>
|
||||
</p>
|
||||
<p data-i18n="failsafeFeaturesHelpNew"></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="leftWrapper">
|
||||
<div class="gui_box grey oldpane">
|
||||
<div class="gui_box grey">
|
||||
<div class="gui_box_titlebar">
|
||||
<div class="spacer_box_title" i18n="failsafePaneTitleOld"></div>
|
||||
</div>
|
||||
<div class="spacer_box">
|
||||
<div class="checkbox">
|
||||
<div class="numberspacer" >
|
||||
<input type="checkbox" name="failsafe_feature" class="feature toggle rxFailsafe" id="failsafe_feature" />
|
||||
</div>
|
||||
<label for="failsafe_feature"><span i18n="failsafeFeatureItemOld"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="number">
|
||||
<label> <input type="number" name="failsafe_throttle_old" min="0" max="2000" /> <span
|
||||
i18n="failsafeThrottleItemOld"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gui_box grey newpane">
|
||||
<div class="gui_box_titlebar">
|
||||
<div class="spacer_box_title" i18n="failsafePulsrangeTitle"></div>
|
||||
<div class="helpicon cf_tip" i18n_title="failsafePulsrangeHelp"></div>
|
||||
<div class="spacer_box_title" data-i18n="failsafePulsrangeTitle"></div>
|
||||
<div class="helpicon cf_tip" data-i18n_title="failsafePulsrangeHelp"></div>
|
||||
</div>
|
||||
<div class="spacer_box">
|
||||
<div class="number">
|
||||
<label> <input type="number" name="rx_min_usec" min="750" max="2250" /> <span
|
||||
i18n="failsafeRxMinUsecItem"></span>
|
||||
data-i18n="failsafeRxMinUsecItem"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="number">
|
||||
<label> <input type="number" name="rx_max_usec" min="750" max="2250" /> <span
|
||||
i18n="failsafeRxMaxUsecItem"></span>
|
||||
data-i18n="failsafeRxMaxUsecItem"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gui_box grey stage1 newpane">
|
||||
<div class="gui_box grey stage1">
|
||||
<div class="gui_box_titlebar">
|
||||
<div class="spacer_box_title" i18n="failsafeChannelFallbackSettingsTitle"></div>
|
||||
<div class="helpicon cf_tip" i18n_title="failsafeChannelFallbackSettingsHelp"></div>
|
||||
<div class="spacer_box_title" data-i18n="failsafeChannelFallbackSettingsTitle"></div>
|
||||
<div class="helpicon cf_tip" data-i18n_title="failsafeChannelFallbackSettingsHelp"></div>
|
||||
</div>
|
||||
<div class="spacer_box">
|
||||
<div class="activechannellist">
|
||||
|
@ -67,67 +41,67 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="rightWrapper">
|
||||
<div class="gui_box grey newpane">
|
||||
<div class="gui_box grey">
|
||||
<div class="gui_box_titlebar">
|
||||
<div class="spacer_box_title" i18n="failsafeStageTwoSettingsTitle"></div>
|
||||
<div class="spacer_box_title" data-i18n="failsafeStageTwoSettingsTitle"></div>
|
||||
</div>
|
||||
<div class="spacer_box">
|
||||
<div class="checkbox">
|
||||
<div class="numberspacer" >
|
||||
<input type="checkbox" name="failsafe_feature_new" class="feature toggle rxFailsafe" id="failsafe_feature_new" />
|
||||
</div>
|
||||
<label for="failsafe_feature_new"><span i18n="failsafeFeatureItem"></span>
|
||||
<label for="failsafe_feature_new"><span data-i18n="failsafeFeatureItem"></span>
|
||||
</label>
|
||||
<div class="helpicon cf_tip" i18n_title="failsafeFeatureHelp"></div>
|
||||
<div class="helpicon cf_tip" data-i18n_title="failsafeFeatureHelp"></div>
|
||||
</div>
|
||||
<div class="checkbox stage2">
|
||||
<div class="numberspacer" >
|
||||
<input type="checkbox" name="failsafe_kill_switch" class="toggle" id="failsafe_kill_switch" />
|
||||
</div>
|
||||
<label for="failsafe_kill_switch"><span i18n="failsafeKillSwitchItem"></span>
|
||||
<label for="failsafe_kill_switch"><span data-i18n="failsafeKillSwitchItem"></span>
|
||||
</label>
|
||||
<div class="helpicon cf_tip" i18n_title="failsafeKillSwitchHelp"></div>
|
||||
<div class="helpicon cf_tip" data-i18n_title="failsafeKillSwitchHelp"></div>
|
||||
</div>
|
||||
<div class="number stage2">
|
||||
<label> <input type="number" name="failsafe_delay" min="0" max="2000" /> <span
|
||||
i18n="failsafeDelayItem"></span>
|
||||
data-i18n="failsafeDelayItem"></span>
|
||||
</label>
|
||||
<div class="helpicon cf_tip" i18n_title="failsafeDelayHelp"></div>
|
||||
<div class="helpicon cf_tip" data-i18n_title="failsafeDelayHelp"></div>
|
||||
</div>
|
||||
<div class="number stage2">
|
||||
<label> <input type="number" name="failsafe_throttle_low_delay" min="0" max="2000" /> <span
|
||||
i18n="failsafeThrottleLowItem"></span>
|
||||
data-i18n="failsafeThrottleLowItem"></span>
|
||||
</label>
|
||||
<div class="helpicon cf_tip" i18n_title="failsafeThrottleLowHelp"></div>
|
||||
<div class="helpicon cf_tip" data-i18n_title="failsafeThrottleLowHelp"></div>
|
||||
</div>
|
||||
<!-- radio buttons -->
|
||||
<div class="subline stage2" i18n="failsafeSubTitle1"></div>
|
||||
<div class="subline stage2" data-i18n="failsafeSubTitle1"></div>
|
||||
<div class="radioarea pro1 stage2">
|
||||
<div class="radiobuttons"><input class="procedure" id="drop" name="group1" type="radio"/>
|
||||
<label for="drop" i18n="failsafeProcedureItemSelect2"></label>
|
||||
<label for="drop" data-i18n="failsafeProcedureItemSelect2"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="radioarea pro2 stage2">
|
||||
<div class="radiobuttons"><input class="procedure" id="land" name="group1" type="radio" checked/>
|
||||
<label for="land" i18n="failsafeProcedureItemSelect1"></label>
|
||||
<label for="land" data-i18n="failsafeProcedureItemSelect1"></label>
|
||||
</div>
|
||||
<div class="proceduresettings">
|
||||
<div class="number">
|
||||
<label> <input type="number" name="failsafe_throttle" min="0" max="2000" /> <span
|
||||
i18n="failsafeThrottleItem"></span>
|
||||
data-i18n="failsafeThrottleItem"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="number">
|
||||
<label> <input type="number" name="failsafe_off_delay" min="0" max="2000" /> <span
|
||||
i18n="failsafeOffDelayItem"></span>
|
||||
data-i18n="failsafeOffDelayItem"></span>
|
||||
</label>
|
||||
<div class="helpicon cf_tip" i18n_title="failsafeOffDelayHelp"></div>
|
||||
<div class="helpicon cf_tip" data-i18n_title="failsafeOffDelayHelp"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="radioarea pro4 stage2">
|
||||
<div class="radiobuttons"><input class="procedure" id="rth" name="group1" type="radio"/>
|
||||
<label for="rth" i18n="failsafeProcedureItemSelect3"></label>
|
||||
<label for="rth" data-i18n="failsafeProcedureItemSelect3"></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -136,7 +110,7 @@
|
|||
</div>
|
||||
<div class="content_toolbar">
|
||||
<div class="btn save_btn">
|
||||
<a class="save" href="#" i18n="configurationButtonSave"></a>
|
||||
<a class="save" href="#" data-i18n="configurationButtonSave"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
TABS.failsafe = {};
|
||||
|
||||
TABS.failsafe.initialize = function (callback, scrollPosition) {
|
||||
var self = this;
|
||||
|
||||
if (GUI.active_tab != 'failsafe') {
|
||||
GUI.active_tab = 'failsafe';
|
||||
|
@ -38,7 +37,6 @@ TABS.failsafe.initialize = function (callback, scrollPosition) {
|
|||
MSP.send_message(MSPCodes.MSP_RC, false, false, load_config);
|
||||
}
|
||||
|
||||
// BEGIN Support for pre API version 1.15.0
|
||||
function load_config() {
|
||||
MSP.send_message(MSPCodes.MSP_BF_CONFIG, false, false, load_misc);
|
||||
}
|
||||
|
@ -46,22 +44,12 @@ TABS.failsafe.initialize = function (callback, scrollPosition) {
|
|||
function load_misc() {
|
||||
MSP.send_message(MSPCodes.MSP_MISC, false, false, load_html);
|
||||
}
|
||||
// END (Support for pre API version 1.15.0
|
||||
|
||||
function load_html() {
|
||||
$('#content').load("./tabs/failsafe.html", process_html);
|
||||
}
|
||||
|
||||
var apiVersionGte1_15_0 = semver.gte(CONFIG.apiVersion, "1.15.0");
|
||||
|
||||
// Uncomment next line for testing older functionality on newer API version
|
||||
//apiVersionGte1_15_0 = false;
|
||||
|
||||
if(apiVersionGte1_15_0) {
|
||||
MSP.send_message(MSPCodes.MSP_IDENT, false, false, load_rx_config);
|
||||
} else {
|
||||
MSP.send_message(MSPCodes.MSP_IDENT, false, false, load_config);
|
||||
}
|
||||
load_rx_config();
|
||||
|
||||
function process_html() {
|
||||
var failsafeFeature;
|
||||
|
@ -69,18 +57,6 @@ TABS.failsafe.initialize = function (callback, scrollPosition) {
|
|||
// translate to user-selected language
|
||||
localize();
|
||||
|
||||
// Conditionally hide the old or the new control pane's
|
||||
if(apiVersionGte1_15_0) {
|
||||
var oldPane = $('div.oldpane');
|
||||
oldPane.prop("disabled", true);
|
||||
oldPane.hide();
|
||||
} else {
|
||||
var newPane = $('div.newpane');
|
||||
newPane.prop("disabled", true);
|
||||
newPane.hide();
|
||||
}
|
||||
|
||||
if(apiVersionGte1_15_0) {
|
||||
// generate labels for assigned aux modes
|
||||
var auxAssignment = [],
|
||||
i,
|
||||
|
@ -267,19 +243,8 @@ TABS.failsafe.initialize = function (callback, scrollPosition) {
|
|||
// set stage 2 kill switch option
|
||||
$('input[name="failsafe_kill_switch"]').prop('checked', FAILSAFE_CONFIG.failsafe_kill_switch);
|
||||
|
||||
} else {
|
||||
|
||||
// set FAILSAFE feature option (pre API 1.15.0)
|
||||
failsafeFeature = $('input[name="failsafe_feature"]');
|
||||
failsafeFeature.prop('checked', bit_check(BF_CONFIG.features, 8));
|
||||
|
||||
// fill failsafe_throttle field (pre API 1.15.0)
|
||||
$('input[name="failsafe_throttle_old"]').val(MISC.failsafe_throttle);
|
||||
}
|
||||
|
||||
$('a.save').click(function () {
|
||||
// gather data that doesn't have automatic change event bound
|
||||
if(apiVersionGte1_15_0) {
|
||||
RX_CONFIG.rx_min_usec = parseInt($('input[name="rx_min_usec"]').val());
|
||||
RX_CONFIG.rx_max_usec = parseInt($('input[name="rx_max_usec"]').val());
|
||||
|
||||
|
@ -304,17 +269,6 @@ TABS.failsafe.initialize = function (callback, scrollPosition) {
|
|||
}
|
||||
|
||||
FAILSAFE_CONFIG.failsafe_kill_switch = $('input[name="failsafe_kill_switch"]').is(':checked') ? 1 : 0;
|
||||
} else {
|
||||
// get FAILSAFE feature option (pre API 1.15.0)
|
||||
if ($('input[name="failsafe_feature"]').is(':checked')) {
|
||||
BF_CONFIG.features = bit_set(BF_CONFIG.features, 8);
|
||||
} else {
|
||||
BF_CONFIG.features = bit_clear(BF_CONFIG.features, 8);
|
||||
}
|
||||
|
||||
// get failsafe_throttle field value (pre API 1.15.0)
|
||||
MISC.failsafe_throttle = parseInt($('input[name="failsafe_throttle_old"]').val());
|
||||
}
|
||||
|
||||
function save_failssafe_config() {
|
||||
MSP.send_message(MSPCodes.MSP_SET_FAILSAFE_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_FAILSAFE_CONFIG), false, save_rxfail_config);
|
||||
|
@ -328,12 +282,6 @@ TABS.failsafe.initialize = function (callback, scrollPosition) {
|
|||
MSP.send_message(MSPCodes.MSP_SET_BF_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_BF_CONFIG), false, save_to_eeprom);
|
||||
}
|
||||
|
||||
// BEGIN pre API 1.15.0 save functions
|
||||
function save_misc() {
|
||||
MSP.send_message(MSPCodes.MSP_SET_MISC, mspHelper.crunch(MSPCodes.MSP_SET_MISC), false, save_to_eeprom);
|
||||
}
|
||||
// END pre API 1.15.0 save functions
|
||||
|
||||
function save_to_eeprom() {
|
||||
MSP.send_message(MSPCodes.MSP_EEPROM_WRITE, false, false, reboot);
|
||||
}
|
||||
|
@ -351,22 +299,9 @@ TABS.failsafe.initialize = function (callback, scrollPosition) {
|
|||
GUI.handleReconnect($('.tab_failsafe a'));
|
||||
}
|
||||
|
||||
if(apiVersionGte1_15_0) {
|
||||
MSP.send_message(MSPCodes.MSP_SET_RX_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_RX_CONFIG), false, save_failssafe_config);
|
||||
} else {
|
||||
MSP.send_message(MSPCodes.MSP_SET_BF_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_BF_CONFIG), false, save_misc);
|
||||
}
|
||||
});
|
||||
|
||||
// status data pulled via separate timer with static speed
|
||||
GUI.interval_add('status_pull', function status_pull() {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS);
|
||||
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.5.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS);
|
||||
}
|
||||
}, 250, true);
|
||||
|
||||
GUI.content_ready(callback);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -513,7 +513,7 @@ TABS.firmware_flasher.initialize = function (callback) {
|
|||
console.log('Detected: ' + port + ' - triggering flash on connect');
|
||||
|
||||
// Trigger regular Flashing sequence
|
||||
GUI.timeout_add('initialization_timeout', function () {
|
||||
helper.timeout.add('initialization_timeout', function () {
|
||||
$('a.flash_firmware').click();
|
||||
}, 100); // timeout so bus have time to initialize after being detected by the system
|
||||
} else {
|
||||
|
|
14
tabs/gps.js
14
tabs/gps.js
|
@ -13,7 +13,7 @@ TABS.gps.initialize = function (callback) {
|
|||
$('#content').load("./tabs/gps.html", process_html);
|
||||
}
|
||||
|
||||
MSP.send_message(MSPCodes.MSP_STATUS, false, false, load_html);
|
||||
load_html();
|
||||
|
||||
function set_online(){
|
||||
$('#connect').hide();
|
||||
|
@ -102,7 +102,7 @@ TABS.gps.initialize = function (callback) {
|
|||
}
|
||||
|
||||
// enable data pulling
|
||||
GUI.interval_add('gps_pull', function gps_update() {
|
||||
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')) {
|
||||
//return;
|
||||
|
@ -111,16 +111,6 @@ TABS.gps.initialize = function (callback) {
|
|||
get_raw_gps_data();
|
||||
}, 75, true);
|
||||
|
||||
// status data pulled via separate timer with static speed
|
||||
GUI.interval_add('status_pull', function status_pull() {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS);
|
||||
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.5.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS);
|
||||
}
|
||||
}, 250, true);
|
||||
|
||||
|
||||
//check for internet connection on load
|
||||
if (navigator.onLine) {
|
||||
console.log('Online');
|
||||
|
|
|
@ -65,8 +65,8 @@ TABS.logging.initialize = function (callback) {
|
|||
}
|
||||
}
|
||||
|
||||
GUI.interval_add('log_data_poll', log_data_poll, parseInt($('select.speed').val()), true); // refresh rate goes here
|
||||
GUI.interval_add('write_data', function write_data() {
|
||||
helper.interval.add('log_data_poll', log_data_poll, parseInt($('select.speed').val()), true); // refresh rate goes here
|
||||
helper.interval.add('write_data', function write_data() {
|
||||
if (log_buffer.length) { // only execute when there is actual data to write
|
||||
if (fileWriter.readyState == 0 || fileWriter.readyState == 2) {
|
||||
append_to_file(log_buffer.join('\n'));
|
||||
|
@ -87,7 +87,7 @@ TABS.logging.initialize = function (callback) {
|
|||
GUI.log(chrome.i18n.getMessage('loggingErrorOneProperty'));
|
||||
}
|
||||
} else {
|
||||
GUI.interval_kill_all();
|
||||
helper.interval.killAll(['global_data_refresh']);
|
||||
|
||||
$('.speed').prop('disabled', false);
|
||||
$(this).text(chrome.i18n.getMessage('loggingStart'));
|
||||
|
|
|
@ -142,16 +142,7 @@ TABS.modes.initialize = function (callback) {
|
|||
update_ui();
|
||||
|
||||
// enable data pulling
|
||||
GUI.interval_add('aux_data_pull', get_rc_data, 50);
|
||||
|
||||
// status data pulled via separate timer with static speed
|
||||
GUI.interval_add('status_pull', function status_pull() {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS);
|
||||
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.5.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS);
|
||||
}
|
||||
}, 250, true);
|
||||
helper.interval.add('aux_data_pull', get_rc_data, 50);
|
||||
|
||||
GUI.content_ready(callback);
|
||||
}
|
||||
|
|
|
@ -19,10 +19,6 @@ TABS.motors.initialize = function (callback) {
|
|||
googleAnalytics.sendAppView('Motors');
|
||||
}
|
||||
|
||||
function get_arm_status() {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS, false, false, load_config);
|
||||
}
|
||||
|
||||
function load_config() {
|
||||
MSP.send_message(MSPCodes.MSP_BF_CONFIG, false, false, load_3d);
|
||||
}
|
||||
|
@ -40,7 +36,7 @@ TABS.motors.initialize = function (callback) {
|
|||
$('#content').load("./tabs/motors.html", process_html);
|
||||
}
|
||||
|
||||
MSP.send_message(MSPCodes.MSP_MISC, false, false, get_arm_status);
|
||||
MSP.send_message(MSPCodes.MSP_MISC, false, false, load_config);
|
||||
|
||||
function update_arm_status() {
|
||||
self.armed = bit_check(CONFIG.mode, 0);
|
||||
|
@ -182,7 +178,7 @@ TABS.motors.initialize = function (callback) {
|
|||
$motorsEnableTestMode.prop('checked', false);
|
||||
$motorsEnableTestMode.prop('disabled', true);
|
||||
|
||||
update_model(CONFIG.multiType);
|
||||
update_model(BF_CONFIG.mixerConfiguration);
|
||||
|
||||
// Always start with default/empty sensor data array, clean slate all
|
||||
initSensorData();
|
||||
|
@ -239,9 +235,9 @@ TABS.motors.initialize = function (callback) {
|
|||
accelHelpers = initGraphHelpers('#accel', samples_accel_i, [-scale, scale]);
|
||||
|
||||
// timer initialization
|
||||
GUI.interval_kill_all(['motor_and_status_pull']);
|
||||
helper.interval.killAll(['motor_and_status_pull', 'global_data_refresh']);
|
||||
|
||||
GUI.interval_add('IMU_pull', function imu_data_pull() {
|
||||
helper.interval.add('IMU_pull', function imu_data_pull() {
|
||||
MSP.send_message(MSPCodes.MSP_RAW_IMU, false, false, update_accel_graph);
|
||||
}, rate, true);
|
||||
|
||||
|
@ -448,23 +444,6 @@ TABS.motors.initialize = function (callback) {
|
|||
|
||||
$motorsEnableTestMode.change();
|
||||
|
||||
// data pulling functions used inside interval timer
|
||||
|
||||
function periodicUpdateHandler() {
|
||||
|
||||
MSP.send_message(MSPCodes.MSP_STATUS);
|
||||
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.5.0")) {
|
||||
getPeriodicSensorStatus();
|
||||
} else {
|
||||
getPeriodicMotorOutput();
|
||||
}
|
||||
}
|
||||
|
||||
function getPeriodicSensorStatus() {
|
||||
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS, false, false, getPeriodicMotorOutput);
|
||||
}
|
||||
|
||||
function getPeriodicMotorOutput() {
|
||||
MSP.send_message(MSPCodes.MSP_MOTOR, false, false, getPeriodicServoOutput);
|
||||
}
|
||||
|
@ -519,7 +498,7 @@ TABS.motors.initialize = function (callback) {
|
|||
}
|
||||
|
||||
// enable Status and Motor data pulling
|
||||
GUI.interval_add('motor_and_status_pull', periodicUpdateHandler, 75, true);
|
||||
helper.interval.add('motor_and_status_pull', getPeriodicMotorOutput, 75, true);
|
||||
|
||||
GUI.content_ready(callback);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ TABS.pid_tuning.initialize = function (callback) {
|
|||
var loadChainer = new MSPChainerClass();
|
||||
|
||||
loadChainer.setChain([
|
||||
mspHelper.loadStatus,
|
||||
mspHelper.loadPidNames,
|
||||
mspHelper.loadPidData,
|
||||
mspHelper.loadRcTuningData,
|
||||
|
@ -289,11 +288,6 @@ TABS.pid_tuning.initialize = function (callback) {
|
|||
send_pids();
|
||||
});
|
||||
|
||||
// status data pulled via separate timer with static speed
|
||||
GUI.interval_add('status_pull', function status_pull() {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS);
|
||||
}, 250, true);
|
||||
|
||||
GUI.content_ready(callback);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -96,12 +96,6 @@ TABS.ports.initialize = function (callback, scrollPosition) {
|
|||
|
||||
function update_ui() {
|
||||
|
||||
if (semver.lt(CONFIG.apiVersion, "1.6.0")) {
|
||||
|
||||
$(".tab-ports").removeClass("supported");
|
||||
return;
|
||||
}
|
||||
|
||||
$(".tab-ports").addClass("supported");
|
||||
|
||||
var portIdentifierToNameMapping = {
|
||||
|
@ -221,15 +215,6 @@ TABS.ports.initialize = function (callback, scrollPosition) {
|
|||
|
||||
$('a.save').click(on_save_handler);
|
||||
|
||||
// status data pulled via separate timer with static speed
|
||||
GUI.interval_add('status_pull', function status_pull() {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS);
|
||||
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.5.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS);
|
||||
}
|
||||
}, 250, true);
|
||||
|
||||
GUI.content_ready(callback);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,27 +1,148 @@
|
|||
#presets-list option {
|
||||
.tab-configuration #presets-list option {
|
||||
padding: 0.4em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.preset__head {
|
||||
.tab-configuration .preset__head {
|
||||
color: #37a8db;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.tab-configuration .preset__description {
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.tab-configuration .preset__description span {
|
||||
margin-top: 5px;
|
||||
font-family: 'open_sansregular', Arial, serif;
|
||||
}
|
||||
|
||||
.tab-configuration .preset__features {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.tab-configuration .preset__feature {
|
||||
list-style: inside disc;
|
||||
list-style-type: afar;
|
||||
color: #37a8db;
|
||||
}
|
||||
|
||||
.preset__description {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.preset__features {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.preset__feature {
|
||||
list-style: disc;
|
||||
color: #37a8db;
|
||||
margin-left: 1.5em;
|
||||
}
|
||||
|
||||
.preset__feature-text {
|
||||
.tab-configuration .preset__feature-text {
|
||||
color: #000000;
|
||||
margin-left: -0.5em;
|
||||
}
|
||||
|
||||
.tab-configuration #preset-image {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
background-image:url(../images/icons/peset_default.svg);
|
||||
background-size:contain;
|
||||
background-repeat:no-repeat;
|
||||
float: left;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.tab-configuration .clearboth {
|
||||
width:100%;
|
||||
clear:both;
|
||||
}
|
||||
|
||||
.tab-configuration .preset__list-wrapper {
|
||||
background-color: #525252;
|
||||
background: #525252 -webkit-linear-gradient(top, transparent, rgba(0, 0, 0, 0.35));
|
||||
min-height: 400px;
|
||||
border-right: 3px solid #37a8db;
|
||||
overflow:hidden;
|
||||
border-top-left-radius: 3px;
|
||||
border-bottom-left-radius: 3px;
|
||||
box-shadow: inset -10px 0px 20px rgba(50,50,50, 0.5);
|
||||
}
|
||||
|
||||
.tab-configuration .list-menu ul {
|
||||
}
|
||||
|
||||
.tab-configuration .list-menu li {
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.30);
|
||||
}
|
||||
|
||||
.tab-configuration .list-menu li:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
|
||||
.tab-configuration .list-menu li a {
|
||||
font-family: 'open_sansregular', Arial, serif;
|
||||
display:block;
|
||||
height:30px;
|
||||
line-height: 30px;
|
||||
font-size: 13px;
|
||||
padding-left: 10px;
|
||||
text-shadow: 0 1px rgba(0, 0, 0, 0.45);
|
||||
border-top: solid 1px rgba(255, 255, 255, 0.07);
|
||||
color: #999999;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tab-configuration .list-menu li a:hover {
|
||||
background-color: rgba(128, 128, 128, 0.50);
|
||||
color: white;
|
||||
text-shadow: 0 1px rgba(0, 0, 0, 0.45);
|
||||
}
|
||||
|
||||
.tab-configuration .preset {
|
||||
width: calc(75% - 5px);
|
||||
}
|
||||
|
||||
.tab-configuration .preset-spacer {
|
||||
padding: 20px;
|
||||
float:left;
|
||||
width: calc(100% - 38px);
|
||||
}
|
||||
|
||||
.tab-configuration .list-menu li.active a {
|
||||
background-color: #37a8db;
|
||||
text-shadow: 0 1px rgba(0, 0, 0, 0.45);
|
||||
color: white;
|
||||
|
||||
}
|
||||
|
||||
.tab-configuration .airplane {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image:url(../images/icons/peset_plane.svg);
|
||||
}
|
||||
|
||||
.tab-configuration .flyingwing {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image:url(../images/icons/peset_wing.svg);
|
||||
|
||||
}
|
||||
|
||||
.tab-configuration .multirotor {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image:url(../images/icons/peset_quad.svg);
|
||||
}
|
||||
|
||||
.tab-configuration .preset .top {
|
||||
background-color: #e6e6e6;
|
||||
box-shadow: inset 0px -5px 5px rgba(50,50,50, 0.1);
|
||||
border-top-right-radius: 3px;
|
||||
}
|
||||
|
||||
.tab-configuration .preset .bottom {
|
||||
border-bottom-right-radius: 3px;
|
||||
}
|
||||
|
||||
.tab-configuration .modal__content h1 {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.tab-configuration #details-head {
|
||||
display: none;
|
||||
float: left;
|
||||
width: 100%;
|
||||
margin-bottom: 5px;
|
||||
}
|
|
@ -1,37 +1,29 @@
|
|||
<div class="tab-configuration tab-profiles toolbar_fixed_bottom">
|
||||
<div class="content_wrapper">
|
||||
<div class="tab_title" data-i18n="tabPresets">Presets</div>
|
||||
|
||||
<div class="cf_column third_left">
|
||||
<div class="spacer_right">
|
||||
<div class="cf_column full">
|
||||
<div class="gui_box grey">
|
||||
<div class="gui_box_titlebar">
|
||||
<div class="spacer_box_title" data-i18n="presetsPreset"></div>
|
||||
</div>
|
||||
<div class="spacer_box">
|
||||
<div class="cf_column fourth preset__list-wrapper">
|
||||
<div class="select">
|
||||
<select id="presets-list" class="full-width" size="8">
|
||||
<ul id="presets-list" class="full-width list-menu">
|
||||
<!-- list generated here -->
|
||||
</select>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cf_column twothird">
|
||||
<div class="gui_box grey">
|
||||
<div class="gui_box_titlebar">
|
||||
<div class="spacer_box_title" data-i18n="presetsDescription"></div>
|
||||
</div>
|
||||
<div class="spacer_box preset">
|
||||
<div class="threefourth_left preset">
|
||||
<div class="preset-spacer top">
|
||||
<div id="preset-image"></div>
|
||||
<h2 id="preset-name" class="preset__head"></h2>
|
||||
<div id="preset-info" data-i18n="presetApplyDescription"></div>
|
||||
<p id="preset-description" class="preset__description"></p>
|
||||
</div>
|
||||
<div class="preset-spacer bottom">
|
||||
<div id="details-head"><p data-i18n="presetApplyHead"></p></div>
|
||||
<ul id="preset-features" class="preset__features"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div id="presetApplyContent" class="is-hidden">
|
||||
<div class="modal__content">
|
||||
<h1 class="modal__title modal__title--warning" data-i18n="presetsApplyHeader"></h1>
|
||||
|
@ -41,7 +33,6 @@
|
|||
<a id="execute-button" class="modal__button modal__button--main" data-i18n="presetsButtonSaveAndReboot"></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clear-both"></div>
|
||||
</div>
|
||||
<div class="content_toolbar">
|
||||
|
|
102
tabs/profiles.js
102
tabs/profiles.js
|
@ -40,24 +40,25 @@ presets.defaultValues = {
|
|||
presets.presets = [
|
||||
{
|
||||
name: 'Default Preset',
|
||||
description: "INAV default Quad X configuration",
|
||||
features: [],
|
||||
description: "INAV Quad X configuration",
|
||||
features: ["Default INAV Settings"],
|
||||
applyDefaults: ["PIDs", "INAV_PID_CONFIG", "ADVANCED_CONFIG", "RC_tuning", "PID_ADVANCED", "FILTER_CONFIG", "FC_CONFIG"],
|
||||
settings: [
|
||||
presets.elementHelper("BF_CONFIG", "mixerConfiguration", 3)
|
||||
]
|
||||
],
|
||||
type: 'multirotor'
|
||||
},
|
||||
{
|
||||
name: '5" Racer',
|
||||
description: "210-250 class racer with F3/F4 CPU on 4S battery",
|
||||
description: "210-250 class racer with F3/F4 CPU on 4S battery<br>" +
|
||||
"<span>400g-650g weight, 2000KV - 2600KV motors, 5 inch propellers, MPU6000 or MPU6050 gyro, no GPS capabilities</span>",
|
||||
features: [
|
||||
"4S battery",
|
||||
"2000KV - 2600KV motors",
|
||||
"5 inch propellers",
|
||||
"400g-650g weight",
|
||||
"F3 or F4 CPU",
|
||||
"MPU6000 or MPU6050 gyro",
|
||||
"No GPS capabilities"
|
||||
"Asynchronous processing",
|
||||
"OneShot125 at 2kHz",
|
||||
"800dps rates",
|
||||
"Dterm and gyro notch filter",
|
||||
"Increased LPF cutoff frequencies",
|
||||
"Improved PID defaults"
|
||||
],
|
||||
applyDefaults: ["PIDs", "INAV_PID_CONFIG", "ADVANCED_CONFIG", "RC_tuning", "PID_ADVANCED", "FILTER_CONFIG", "FC_CONFIG"],
|
||||
settings: [
|
||||
|
@ -84,17 +85,18 @@ presets.presets = [
|
|||
presets.elementHelper("PIDs", 0, [43, 40, 20]), //ROLL PIDs
|
||||
presets.elementHelper("PIDs", 1, [58, 50, 22]), //PITCH PIDs
|
||||
presets.elementHelper("PIDs", 2, [70, 45, 0]) //YAW PIDs
|
||||
]
|
||||
],
|
||||
type: 'multirotor'
|
||||
},
|
||||
{
|
||||
name: '10" General Purpose',
|
||||
description: "450-600 class general purpose multirotor",
|
||||
description: "450-600 class general purpose multirotor <br><span>10.kg - 1.4kg weight, 10 inch propellers, <br>F1, F3 or F4 CPU, MPU6000 or MPU6050 gyro, GPS optional.</span>",
|
||||
features: [
|
||||
"10 inch propellers",
|
||||
"0.kg - 1.4kg weight",
|
||||
"F1, F3 or F4 CPU",
|
||||
"MPU6000 or MPU6050 gyro",
|
||||
"GPS optional"
|
||||
"Asynchronous gyro processing",
|
||||
"400dps rates",
|
||||
"Dterm and gyro notch filter",
|
||||
"Increased LPF cutoff frequencies",
|
||||
"Improved PID defaults"
|
||||
],
|
||||
applyDefaults: ["PIDs", "INAV_PID_CONFIG", "ADVANCED_CONFIG", "RC_tuning", "PID_ADVANCED", "FILTER_CONFIG", "FC_CONFIG"],
|
||||
settings: [
|
||||
|
@ -121,17 +123,20 @@ presets.presets = [
|
|||
presets.elementHelper("PIDs", 0, [75, 30, 18]), //ROLL PIDs
|
||||
presets.elementHelper("PIDs", 1, [75, 30, 18]), //PITCH PIDs
|
||||
presets.elementHelper("PIDs", 2, [85, 45, 0]) //YAW PIDs
|
||||
]
|
||||
],
|
||||
type: 'multirotor'
|
||||
},
|
||||
{
|
||||
name: '12" General Purpose',
|
||||
description: "550 and above general purpose multirotor",
|
||||
description: "550 and above general purpose multirotor<br>" +
|
||||
"<span>12 inch propellers, 1.4kg-2kg weight, F3 or F4 CPU, MPU6000 or MPU6050 gyro, GPS optional</span>",
|
||||
features: [
|
||||
"12 inch propellers",
|
||||
"1.4kg-2kg weight",
|
||||
"F3 or F4 CPU",
|
||||
"MPU6000 or MPU6050 gyro",
|
||||
"GPS optional"
|
||||
"Asynchronous gyro processing",
|
||||
"180dps rates",
|
||||
"Limited rate acceleration",
|
||||
"Dterm and gyro notch filter",
|
||||
"Increased LPF cutoff frequencies",
|
||||
"Improved PID defaults"
|
||||
],
|
||||
applyDefaults: ["PIDs", "INAV_PID_CONFIG", "ADVANCED_CONFIG", "RC_tuning", "PID_ADVANCED", "FILTER_CONFIG", "FC_CONFIG"],
|
||||
settings: [
|
||||
|
@ -159,12 +164,16 @@ presets.presets = [
|
|||
presets.elementHelper("PIDs", 1, [80, 30, 18]), //PITCH PIDs
|
||||
presets.elementHelper("PIDs", 2, [85, 45, 0]), //YAW PIDs
|
||||
presets.elementHelper("PIDs", 7, [10, 7, 75]) //Level PIDs
|
||||
]
|
||||
],
|
||||
type: 'multirotor'
|
||||
},
|
||||
{
|
||||
name: "Airplane General",
|
||||
description: "General setup for airplanes",
|
||||
features: [
|
||||
"Adjusted gyro filtering",
|
||||
"Adjusted PIDs",
|
||||
"Adjusted rates"
|
||||
],
|
||||
applyDefaults: ["PIDs", "INAV_PID_CONFIG", "ADVANCED_CONFIG", "RC_tuning", "PID_ADVANCED", "FILTER_CONFIG", "FC_CONFIG"],
|
||||
settings: [
|
||||
|
@ -177,14 +186,17 @@ presets.presets = [
|
|||
presets.elementHelper("RC_tuning", "yaw_rate", 90),
|
||||
presets.elementHelper("ADVANCED_CONFIG", "gyroSync", 1),
|
||||
presets.elementHelper("INAV_PID_CONFIG", "gyroscopeLpf", 1)
|
||||
]
|
||||
],
|
||||
type: 'airplane'
|
||||
},
|
||||
{
|
||||
name: "600mm Flying Wing",
|
||||
description: "Small flying wing on multirotor racer parts",
|
||||
description: "Small flying wing on multirotor racer parts<br>" +
|
||||
"<span>300g-500g weight, 3S-4S battery</span>",
|
||||
features: [
|
||||
"3S-4S battery",
|
||||
"300g-500g weight"
|
||||
"Adjusted gyro filtering",
|
||||
"Adjusted PIDs",
|
||||
"Adjusted rates"
|
||||
],
|
||||
applyDefaults: ["PIDs", "INAV_PID_CONFIG", "ADVANCED_CONFIG", "RC_tuning", "PID_ADVANCED", "FILTER_CONFIG", "FC_CONFIG"],
|
||||
settings: [
|
||||
|
@ -195,7 +207,8 @@ presets.presets = [
|
|||
presets.elementHelper("RC_tuning", "pitch_rate", 150),
|
||||
presets.elementHelper("ADVANCED_CONFIG", "gyroSync", 1),
|
||||
presets.elementHelper("INAV_PID_CONFIG", "gyroscopeLpf", 1)
|
||||
]
|
||||
],
|
||||
type: 'flyingwing'
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -256,7 +269,6 @@ TABS.profiles.initialize = function (callback, scrollPosition) {
|
|||
}
|
||||
|
||||
loadChainer.setChain([
|
||||
mspHelper.loadMspIdent,
|
||||
mspHelper.loadBfConfig,
|
||||
mspHelper.loadLoopTime,
|
||||
mspHelper.loadINAVPidConfig,
|
||||
|
@ -322,14 +334,19 @@ TABS.profiles.initialize = function (callback, scrollPosition) {
|
|||
|
||||
var $features = $('#preset-features');
|
||||
|
||||
$('#preset-image').html('<div class="' + preset.type + '"></div>');
|
||||
$('#preset-name').html(preset.name);
|
||||
$('#preset-description').html(preset.description);
|
||||
document.getElementById('preset-info').style.display = "none";
|
||||
document.getElementById('details-head').style.display = "block";
|
||||
|
||||
|
||||
$features.find('*').remove();
|
||||
|
||||
for (var i in preset.features) {
|
||||
if (preset.features.hasOwnProperty(i)) {
|
||||
$features.append('<li class="preset__feature"><span class="preset__feature-text">' + preset.features[i] + "</span></li>");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -339,12 +356,20 @@ TABS.profiles.initialize = function (callback, scrollPosition) {
|
|||
|
||||
var $presetList = $('#presets-list');
|
||||
|
||||
GUI.fillSelect($presetList, presets.model.extractPresetNames(presets.presets));
|
||||
var presetsList = presets.model.extractPresetNames(presets.presets);
|
||||
|
||||
$presetList.change(function () {
|
||||
currentPresetId = $presetList.val();
|
||||
for(var preset in presetsList) {
|
||||
$presetList.append( '<li class="preset__element-wrapper"><a href="#" class="preset__element-link" data-val="' + preset + '">' + presetsList[preset] + '</a></li>');
|
||||
}
|
||||
|
||||
$('.preset__element-link').click(function () {
|
||||
currentPresetId = $(this).data('val');
|
||||
currentPreset = presets.presets[currentPresetId];
|
||||
fillPresetDescription(currentPreset);
|
||||
|
||||
$presetList.find('li').removeClass('active');
|
||||
$(this).parent().addClass('active');
|
||||
|
||||
$('#save-button').removeClass('disabled');
|
||||
});
|
||||
|
||||
|
@ -368,13 +393,6 @@ TABS.profiles.initialize = function (callback, scrollPosition) {
|
|||
content: $('#presetApplyContent')
|
||||
});
|
||||
|
||||
GUI.interval_add('status_pull', function status_pull() {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS);
|
||||
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.5.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS);
|
||||
}
|
||||
}, 250, true);
|
||||
GUI.content_ready(callback);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -43,10 +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));
|
||||
|
||||
if (semver.lt(CONFIG.apiVersion, "1.10.0")) {
|
||||
$('.tunings .yaw_rate input[name="yaw_expo"]').hide();
|
||||
}
|
||||
|
||||
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();
|
||||
|
@ -55,12 +51,8 @@ TABS.receiver.initialize = function (callback) {
|
|||
}
|
||||
});
|
||||
|
||||
if (semver.lt(CONFIG.apiVersion, "1.15.0")) {
|
||||
$('.deadband').hide();
|
||||
} else {
|
||||
$('.deadband input[name="yaw_deadband"]').val(RC_deadband.yaw_deadband);
|
||||
$('.deadband input[name="deadband"]').val(RC_deadband.deadband);
|
||||
}
|
||||
|
||||
// generate bars
|
||||
var bar_names = [
|
||||
|
@ -295,10 +287,8 @@ TABS.receiver.initialize = function (callback) {
|
|||
RC_tuning.RC_EXPO = parseFloat($('.tunings .rate input[name="expo"]').val());
|
||||
RC_tuning.RC_YAW_EXPO = parseFloat($('.tunings .yaw_rate input[name="yaw_expo"]').val());
|
||||
|
||||
if (semver.gte(CONFIG.apiVersion, "1.15.0")) {
|
||||
RC_deadband.yaw_deadband = parseInt($('.deadband input[name="yaw_deadband"]').val());
|
||||
RC_deadband.deadband = parseInt($('.deadband input[name="deadband"]').val());
|
||||
}
|
||||
|
||||
// catch rc map
|
||||
var RC_MAP_Letters = ['A', 'E', 'R', 'T', '1', '2', '3', '4'];
|
||||
|
@ -320,12 +310,7 @@ TABS.receiver.initialize = function (callback) {
|
|||
}
|
||||
|
||||
function save_rc_configs() {
|
||||
var next_callback = save_to_eeprom;
|
||||
if (semver.gte(CONFIG.apiVersion, "1.15.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SET_RC_DEADBAND, mspHelper.crunch(MSPCodes.MSP_SET_RC_DEADBAND), false, next_callback);
|
||||
} else {
|
||||
next_callback();
|
||||
}
|
||||
MSP.send_message(MSPCodes.MSP_SET_RC_DEADBAND, mspHelper.crunch(MSPCodes.MSP_SET_RC_DEADBAND), false, save_to_eeprom);
|
||||
}
|
||||
|
||||
function save_to_eeprom() {
|
||||
|
@ -464,21 +449,12 @@ TABS.receiver.initialize = function (callback) {
|
|||
}
|
||||
|
||||
// timer initialization
|
||||
GUI.interval_remove('receiver_pull');
|
||||
helper.interval.remove('receiver_pull');
|
||||
|
||||
// enable RC data pulling
|
||||
GUI.interval_add('receiver_pull', get_rc_data, plot_update_rate, true);
|
||||
helper.interval.add('receiver_pull', get_rc_data, plot_update_rate, true);
|
||||
});
|
||||
|
||||
// status data pulled via separate timer with static speed
|
||||
GUI.interval_add('status_pull', function status_pull() {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS);
|
||||
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.5.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS);
|
||||
}
|
||||
}, 250, true);
|
||||
|
||||
GUI.content_ready(callback);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -356,29 +356,29 @@ TABS.sensors.initialize = function (callback) {
|
|||
});
|
||||
|
||||
// timer initialization
|
||||
GUI.interval_kill_all(['status_pull']);
|
||||
helper.interval.killAll(['status_pull', 'global_data_refresh']);
|
||||
|
||||
// data pulling timers
|
||||
if (checkboxes[0] || checkboxes[1] || checkboxes[2]) {
|
||||
GUI.interval_add('IMU_pull', function imu_data_pull() {
|
||||
helper.interval.add('IMU_pull', function imu_data_pull() {
|
||||
MSP.send_message(MSPCodes.MSP_RAW_IMU, false, false, update_imu_graphs);
|
||||
}, fastest, true);
|
||||
}
|
||||
|
||||
if (checkboxes[3]) {
|
||||
GUI.interval_add('altitude_pull', function altitude_data_pull() {
|
||||
helper.interval.add('altitude_pull', function altitude_data_pull() {
|
||||
MSP.send_message(MSPCodes.MSP_ALTITUDE, false, false, update_altitude_graph);
|
||||
}, rates.baro, true);
|
||||
}
|
||||
|
||||
if (checkboxes[4]) {
|
||||
GUI.interval_add('sonar_pull', function sonar_data_pull() {
|
||||
helper.interval.add('sonar_pull', function sonar_data_pull() {
|
||||
MSP.send_message(MSPCodes.MSP_SONAR, false, false, update_sonar_graphs);
|
||||
}, rates.sonar, true);
|
||||
}
|
||||
|
||||
if (checkboxes[5]) {
|
||||
GUI.interval_add('debug_pull', function debug_data_pull() {
|
||||
helper.interval.add('debug_pull', function debug_data_pull() {
|
||||
MSP.send_message(MSPCodes.MSP_DEBUG, false, false, update_debug_graphs);
|
||||
}, rates.debug, true);
|
||||
}
|
||||
|
@ -443,15 +443,6 @@ TABS.sensors.initialize = function (callback) {
|
|||
}
|
||||
});
|
||||
|
||||
// status data pulled via separate timer with static speed
|
||||
GUI.interval_add('status_pull', function status_pull() {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS);
|
||||
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.5.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS);
|
||||
}
|
||||
}, 250, true);
|
||||
|
||||
GUI.content_ready(callback);
|
||||
});
|
||||
};
|
||||
|
|
|
@ -14,17 +14,7 @@ TABS.servos.initialize = function (callback) {
|
|||
}
|
||||
|
||||
function get_servo_mix_rules() {
|
||||
MSP.send_message(MSPCodes.MSP_SERVO_MIX_RULES, false, false, get_channel_forwarding);
|
||||
}
|
||||
|
||||
function get_channel_forwarding() {
|
||||
var nextFunction = get_rc_data;
|
||||
|
||||
if (semver.lt(CONFIG.apiVersion, "1.12.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_CHANNEL_FORWARDING, false, false, nextFunction);
|
||||
} else {
|
||||
nextFunction();
|
||||
}
|
||||
MSP.send_message(MSPCodes.MSP_SERVO_MIX_RULES, false, false, get_rc_data);
|
||||
}
|
||||
|
||||
function get_rc_data() {
|
||||
|
@ -39,11 +29,11 @@ TABS.servos.initialize = function (callback) {
|
|||
$('#content').load("./tabs/servos.html", process_html);
|
||||
}
|
||||
|
||||
MSP.send_message(MSPCodes.MSP_IDENT, false, false, get_servo_configurations);
|
||||
get_servo_configurations();
|
||||
|
||||
function update_ui() {
|
||||
|
||||
if (semver.lt(CONFIG.apiVersion, "1.12.0") || SERVO_CONFIG.length == 0) {
|
||||
if (SERVO_CONFIG.length == 0) {
|
||||
|
||||
$(".tab-servos").removeClass("supported");
|
||||
return;
|
||||
|
@ -171,7 +161,7 @@ TABS.servos.initialize = function (callback) {
|
|||
$('table.directions select, table.directions input, table.fields select, table.fields input').change(function () {
|
||||
if ($('div.live input').is(':checked')) {
|
||||
// apply small delay as there seems to be some funky update business going wrong
|
||||
GUI.timeout_add('servos_update', servos_update, 10);
|
||||
helper.timeout.add('servos_update', servos_update, 10);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -188,15 +178,6 @@ TABS.servos.initialize = function (callback) {
|
|||
// translate to user-selected language
|
||||
localize();
|
||||
|
||||
// status data pulled via separate timer with static speed
|
||||
GUI.interval_add('status_pull', function () {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS);
|
||||
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.5.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS);
|
||||
}
|
||||
}, 250, true);
|
||||
|
||||
GUI.content_ready(callback);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -34,18 +34,6 @@
|
|||
<div class="default_btn">
|
||||
<a class="resetSettings" href="#" data-i18n="initialSetupButtonReset"></a>
|
||||
</div>
|
||||
<div class="half">
|
||||
<div class="spacer_right halfbuttons">
|
||||
<div class="default_btn half">
|
||||
<a class="backup" href="#" data-i18n="initialSetupButtonBackup"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="half">
|
||||
<div class="default_btn half">
|
||||
<a class="restore" href="#" data-i18n="initialSetupButtonRestore"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="threefourth_right setupinfo">
|
||||
|
@ -58,9 +46,6 @@
|
|||
<div class="cell_setup">
|
||||
<span data-i18n="initialSetupResetText"></span>
|
||||
</div>
|
||||
<div class="cell_setup">
|
||||
<span data-i18n="initialSetupBackupRestoreText"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modelwrapper"></div>
|
||||
|
|
|
@ -16,8 +16,6 @@ TABS.setup.initialize = function (callback) {
|
|||
var loadChainer = new MSPChainerClass();
|
||||
|
||||
loadChainer.setChain([
|
||||
mspHelper.loadStatus,
|
||||
mspHelper.loadMspIdent,
|
||||
mspHelper.loadBfConfig,
|
||||
mspHelper.loadMisc
|
||||
]);
|
||||
|
@ -36,12 +34,6 @@ TABS.setup.initialize = function (callback) {
|
|||
GUI_control.prototype.log("<span style='color: red; font-weight: bolder'><strong>" + chrome.i18n.getMessage("logPwmOutputDisabled") + "</strong></span>");
|
||||
}
|
||||
|
||||
if (semver.lt(CONFIG.apiVersion, CONFIGURATOR.backupRestoreMinApiVersionAccepted)) {
|
||||
$('#content .backup').addClass('disabled');
|
||||
$('#content .restore').addClass('disabled');
|
||||
|
||||
GUI.log(chrome.i18n.getMessage('initialSetupBackupAndRestoreApiVersion', [CONFIG.apiVersion, CONFIGURATOR.backupRestoreMinApiVersionAccepted]));
|
||||
}
|
||||
// initialize 3D
|
||||
self.initialize3D();
|
||||
|
||||
|
@ -70,15 +62,16 @@ TABS.setup.initialize = function (callback) {
|
|||
|
||||
// During this period MCU won't be able to process any serial commands because its locked in a for/while loop
|
||||
// until this operation finishes, sending more commands through data_poll() will result in serial buffer overflow
|
||||
GUI.interval_pause('setup_data_pull');
|
||||
helper.interval.pause('setup_data_pull');
|
||||
|
||||
MSP.send_message(MSPCodes.MSP_ACC_CALIBRATION, false, false, function () {
|
||||
GUI.log(chrome.i18n.getMessage('initialSetupAccelCalibStarted'));
|
||||
$('#accel_calib_running').show();
|
||||
$('#accel_calib_rest').hide();
|
||||
});
|
||||
|
||||
GUI.timeout_add('button_reset', function () {
|
||||
GUI.interval_resume('setup_data_pull');
|
||||
helper.timeout.add('button_reset', function () {
|
||||
helper.interval.resume('setup_data_pull');
|
||||
|
||||
GUI.log(chrome.i18n.getMessage('initialSetupAccelCalibEnded'));
|
||||
|
||||
|
@ -101,7 +94,7 @@ TABS.setup.initialize = function (callback) {
|
|||
$('#mag_calib_rest').hide();
|
||||
});
|
||||
|
||||
GUI.timeout_add('button_reset', function () {
|
||||
helper.timeout.add('button_reset', function () {
|
||||
GUI.log(chrome.i18n.getMessage('initialSetupMagCalibEnded'));
|
||||
self.removeClass('calibrating');
|
||||
$('#mag_calib_running').hide();
|
||||
|
@ -131,29 +124,6 @@ TABS.setup.initialize = function (callback) {
|
|||
console.log('YAW reset to 0 deg, fix: ' + self.yaw_fix + ' deg');
|
||||
});
|
||||
|
||||
$('#content .backup').click(function () {
|
||||
if ($(this).hasClass('disabled')) {
|
||||
return;
|
||||
}
|
||||
configuration_backup(function () {
|
||||
GUI.log(chrome.i18n.getMessage('initialSetupBackupSuccess'));
|
||||
googleAnalytics.sendEvent('Configuration', 'Backup', 'true');
|
||||
});
|
||||
});
|
||||
|
||||
$('#content .restore').click(function () {
|
||||
if ($(this).hasClass('disabled')) {
|
||||
return;
|
||||
}
|
||||
configuration_restore(function () {
|
||||
GUI.log(chrome.i18n.getMessage('initialSetupRestoreSuccess'));
|
||||
googleAnalytics.sendEvent('Configuration', 'Restore', 'true');
|
||||
|
||||
// get latest settings
|
||||
TABS.setup.initialize();
|
||||
});
|
||||
});
|
||||
|
||||
// cached elements
|
||||
var bat_voltage_e = $('.bat-voltage'),
|
||||
bat_mah_drawn_e = $('.bat-mah-drawn'),
|
||||
|
@ -168,19 +138,6 @@ TABS.setup.initialize = function (callback) {
|
|||
heading_e = $('dd.heading');
|
||||
|
||||
function get_slow_data() {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS);
|
||||
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.5.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS);
|
||||
}
|
||||
|
||||
MSP.send_message(MSPCodes.MSP_ANALOG, false, false, function () {
|
||||
bat_voltage_e.text(chrome.i18n.getMessage('initialSetupBatteryValue', [ANALOG.voltage]));
|
||||
bat_mah_drawn_e.text(chrome.i18n.getMessage('initialSetupBatteryMahValue', [ANALOG.mAhdrawn]));
|
||||
bat_mah_drawing_e.text(chrome.i18n.getMessage('initialSetupBatteryAValue', [ANALOG.amperage.toFixed(2)]));
|
||||
rssi_e.text(chrome.i18n.getMessage('initialSetupRSSIValue', [((ANALOG.rssi / 1023) * 100).toFixed(0)]));
|
||||
});
|
||||
|
||||
if (have_sensor(CONFIG.activeSensors, 'gps')) {
|
||||
MSP.send_message(MSPCodes.MSP_RAW_GPS, false, false, function () {
|
||||
var gpsFixType = chrome.i18n.getMessage('gpsFixNone');
|
||||
|
@ -206,8 +163,14 @@ TABS.setup.initialize = function (callback) {
|
|||
});
|
||||
}
|
||||
|
||||
GUI.interval_add('setup_data_pull_fast', get_fast_data, 33, true); // 30 fps
|
||||
GUI.interval_add('setup_data_pull_slow', get_slow_data, 250, true); // 4 fps
|
||||
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]));
|
||||
bat_mah_drawing_e.text(chrome.i18n.getMessage('initialSetupBatteryAValue', [ANALOG.amperage.toFixed(2)]));
|
||||
rssi_e.text(chrome.i18n.getMessage('initialSetupRSSIValue', [((ANALOG.rssi / 1023) * 100).toFixed(0)]));
|
||||
}, 100, true);
|
||||
|
||||
function updateArminFailure() {
|
||||
var flagNames = FC.getArmingFlags();
|
||||
|
@ -226,7 +189,7 @@ TABS.setup.initialize = function (callback) {
|
|||
/*
|
||||
* 1fps update rate will be fully enough
|
||||
*/
|
||||
GUI.interval_add('updateArminFailure', updateArminFailure, 500, true);
|
||||
helper.interval.add('updateArminFailure', updateArminFailure, 500, true);
|
||||
|
||||
GUI.content_ready(callback);
|
||||
}
|
||||
|
@ -281,7 +244,7 @@ TABS.setup.initialize3D = function () {
|
|||
//
|
||||
// load the model including materials
|
||||
if (useWebGlRenderer) {
|
||||
model_file = mixerList[CONFIG.multiType - 1].model;
|
||||
model_file = mixerList[BF_CONFIG.mixerConfiguration - 1].model;
|
||||
} else {
|
||||
model_file = 'fallback'
|
||||
}
|
||||
|
|
|
@ -91,14 +91,6 @@ TABS.transponder.initialize = function (callback, scrollPosition) {
|
|||
save_transponder_config();
|
||||
});
|
||||
}
|
||||
// status data pulled via separate timer with static speed
|
||||
GUI.interval_add('status_pull', function status_pull() {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS);
|
||||
|
||||
if (semver.gte(CONFIG.flightControllerVersion, "1.5.0")) {
|
||||
MSP.send_message(MSPCodes.MSP_SENSOR_STATUS);
|
||||
}
|
||||
}, 250, true);
|
||||
|
||||
GUI.content_ready(callback);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue