mirror of
https://github.com/iNavFlight/inav-configurator.git
synced 2025-07-14 11:59:51 +03:00
Merge branch 'master' of https://github.com/iNavFlight/inav-configurator into Electron
This commit is contained in:
commit
ca13eefa1b
32 changed files with 2988 additions and 796 deletions
36
gulpfile.js
36
gulpfile.js
|
@ -87,6 +87,7 @@ sources.js = [
|
|||
'./js/simple_smooth_filter.js',
|
||||
'./js/walking_average_filter.js',
|
||||
'./js/gui.js',
|
||||
'./js/serialPortHelper.js',
|
||||
'./js/msp/MSPCodes.js',
|
||||
'./js/msp/MSPHelper.js',
|
||||
'./js/msp/MSPchainer.js',
|
||||
|
@ -141,6 +142,8 @@ sources.js = [
|
|||
'./js/sitl.js',
|
||||
'./js/CliAutoComplete.js',
|
||||
'./node_modules/jquery-textcomplete/dist/jquery.textcomplete.js',
|
||||
'./js/fwApproach.js',
|
||||
'./js/fwApproachCollection.js',
|
||||
'./js/ltmDecoder.js',
|
||||
'./js/groundstation.js'
|
||||
];
|
||||
|
@ -409,18 +412,39 @@ gulp.task('release-osx64', function(done) {
|
|||
archive.directory(src, 'INAV Configurator.app');
|
||||
output.on('close', function() {
|
||||
if (getArguments().notarize) {
|
||||
console.log('Notarizing DMG file: ' + zipFilename);
|
||||
const notarizeArgs = ['macapptool', '-v', '1', 'notarize'];
|
||||
console.log('Notarizing ZIP file: ' + zipFilename);
|
||||
const notarizeArgs = ['xcrun', 'notarytool', 'submit'];
|
||||
notarizeArgs.push(zipFilename);
|
||||
const notarizationUsername = getArguments()['notarization-username'];
|
||||
if (notarizationUsername) {
|
||||
notarizeArgs.push('-u', notarizationUsername)
|
||||
notarizeArgs.push('--apple-id', notarizationUsername)
|
||||
} else {
|
||||
throw new Error('Missing notarization username');
|
||||
}
|
||||
const notarizationPassword = getArguments()['notarization-password'];
|
||||
if (notarizationPassword) {
|
||||
notarizeArgs.push('-p', notarizationPassword)
|
||||
notarizeArgs.push('--password', notarizationPassword)
|
||||
} else {
|
||||
throw new Error('Missing notarization password');
|
||||
}
|
||||
const notarizationTeamId = getArguments()['notarization-team-id'];
|
||||
if (notarizationTeamId) {
|
||||
notarizeArgs.push('--team-id', notarizationTeamId)
|
||||
} else {
|
||||
throw new Error('Missing notarization Team ID');
|
||||
}
|
||||
notarizeArgs.push('--wait');
|
||||
|
||||
const notarizationWebhook = getArguments()['notarization-webhook'];
|
||||
if (notarizationWebhook) {
|
||||
notarizeArgs.push('--webhook', notarizationWebhook);
|
||||
}
|
||||
notarizeArgs.push(zipFilename)
|
||||
execSync.apply(this, notarizeArgs);
|
||||
|
||||
console.log('Stapling ZIP file: ' + zipFilename);
|
||||
const stapleArgs = ['macapptool', '-v', '1', 'staple'];
|
||||
stapleArgs.push(zipFilename)
|
||||
execSync.apply(this, stapleArgs);
|
||||
}
|
||||
done();
|
||||
});
|
||||
|
@ -586,7 +610,7 @@ function release_deb(arch) {
|
|||
`xdg-desktop-menu install ${LINUX_INSTALL_DIR}/${metadata.name}/${metadata.name}.desktop`,
|
||||
],
|
||||
prerm: [`xdg-desktop-menu uninstall ${metadata.name}.desktop`],
|
||||
depends: ['libgconf-2-4', 'libatomic1'],
|
||||
depends: ['libatomic1'],
|
||||
changelog: [],
|
||||
_target: `${LINUX_INSTALL_DIR}/${metadata.name}`,
|
||||
_out: appsDir,
|
||||
|
|
|
@ -1,16 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="283.46px" height="141.73px" viewBox="0 0 283.46 141.73" enable-background="new 0 0 283.46 141.73" xml:space="preserve">
|
||||
<g>
|
||||
<circle fill="#999999" cx="141.73" cy="100.25" r="5.271"/>
|
||||
<path fill="#999999" d="M160.347,114.468h-37.234c0.025,7.52-4.19,12.583-9.941,16.749h57.114
|
||||
C163.099,126.682,160.447,120.906,160.347,114.468z"/>
|
||||
<path fill="#999999" d="M213.125,6H70.336c-2.261,0-4.104,1.843-4.104,4.104v94.594c0,2.262,1.843,4.104,4.104,4.104h142.789
|
||||
c2.262,0,4.104-1.844,4.104-4.104V10.104C217.228,7.843,215.386,6,213.125,6z M141.73,105.521c-2.912,0-5.271-2.359-5.271-5.271
|
||||
s2.359-5.271,5.271-5.271s5.272,2.359,5.272,5.271S144.642,105.521,141.73,105.521z M208.515,88.036
|
||||
c0,1.99-1.633,3.624-3.623,3.624H78.581c-1.99,0-3.625-1.634-3.625-3.624V17.354c-0.012-1.991,1.622-3.625,3.625-3.625h126.311
|
||||
c2.002,0,3.623,1.634,3.623,3.625V88.036z"/>
|
||||
</g>
|
||||
<svg width="100%" height="100%" viewBox="0 0 142 142" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<use xlink:href="#_Image1" x="3.8" y="3.613" width="135px" height="135px"/>
|
||||
<defs>
|
||||
<image id="_Image1" width="135px" height="135px" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIcAAACHCAYAAAA850oKAAAACXBIWXMAAA7EAAAOxAGVKw4bAAALOklEQVR4nO2de4xdVRWHv97yqjwCooWl9QEEiI/yxhZplUd4Ci0FRP8ApIIYBGlNUBIIWEACxKDyFKEx0dKIQcEC1oq8CmjQUFBAtBpAgfADCgam8iq14x/7TDPvOefM3mefc8/+kslkcs9da83c3+x9zl57rT2BRCVI2hDYC5gJ7ANsCUwEOtnXxH7f3wFuBa4zs54oAQMbxHLc7UjaDCeCmdnXNGBSARPTgX2B2f6jy8eEWI67FUkfB84FjsPPP980M/uTBzuFSSOHJyTtApwHHI2bHnwx2aOtQiRxjBNJe+JEMQv/I/GrwAOebeYmiaMkkqYAPwIOD+SiF5hnZq8Hsj8mSRwlkPQZ4GbCDfm9wKlmtjiQ/Vz4nBtbgaQzgLsIL4yFgeznJj2t5ETSxsAPgbkB3dRGGJDEkQtJHwRuAT4V0E2thAFJHGMi6WPAvcA2Ad3UThiQxDEqkiYDfwQ+GtBNLYUB6YZ0RCRNAm6npcKAJI5hkdQBbqRl9xiDSeIYngtwy+ChqL0wIN1zDEHSrsDDhFsgbIQwII0cA8imkxtIwgCSOAZzBrB3INuNEgakaWU9WSLtSWDzAOYbJwxII0d/ziYJYwBp5AAkbQk8D2zq2XRjhQFp5OjjVJIwhtD6kUPSBsAzwBTPpk83s2s926yUNHLAHPwLA+ClADYrJYkDjgpkd04gu5XR6mklW/R6CXhfAPOvAZPN7N0Atiuh7SPHnoQRBriKtv0D2a6EtovjkMD2Q01ZldB2cRwY2P5sSY2dutsujp0D2/8Arka2kbS2biXb6bVtBa7mAA9V4KcUWcH3+bik4/+AXwBnmNkbbR45tqOap7XaPtJmwlgGfBPXAWAz4CRcCUarp5XtK/Kzo6RPVOQrN/2Ese8wLx8radM2i+NDFfqq1egxhjDAjSKT2iyOKu+3aiOOHMLoY02bxbGuQl97SPpwhf6GpYAwIImjUqIuiBUUBiRxVEq0qaWEMNaa2bo2i+Odiv3NlBQqjzMiJYQBsAba/Sj7r4r9TQSOrNJhSWFAEgf/iOCzsqllHMIAWA0tFoeZvQD8t2K3B2UfWlDGKQxwnQXaK46Mf1bsbxPgIUkXSNothAMPwgBYDmkn2CLg+IghPAP8CtfK+vdmNq4nKE/CAJhqZk+0XRzHA4tix5HxMnAbTih3m1mhpymPwngFt72xt+3i2Bq3h3Ri7FgGsRpYihPKUjNbPdrFHoUBcIuZHQMtn1YAJD0AzIgdxyi8A9yNm36WmNnL/V/0LAxwjXGvhCQOJJ0NXBo7jpysA/6AG1FuBVbhVxgAu5rZY9DinWD9eDt2AAXo4Ea5GcDlwH+A93q0/xfg8f7OWoukc4Dvx45jHPgUBsCFZtbb90NrRw5J3wO+ETuOGvEYbqpaT+vEkVW5XQd8JXYsNWPAqAEtE0dWUb8I+GLsWGrG47j23QNojTiyxvY3U3FmtCEMGTWgJeKQtCmwhPAVbk3kceCXw73Q9eLIWjotxZ3UmBjIW8CXhhs1oMvFIen9wJ1AkAxoF/BlM3t0pBe7VhxZ68i7CF8P21QuM7ObRrugKxfBJO2AO1UxCWN4lgLnjHVR1+VWstLD3wEWO5aashJ3kPGYp0521ciRnfG6nCSMkXgdmJ33ONKuEYekGcA9wNaxY6kpLwIHmtnKvG/oCnFIOhj4LbBF7FhqypPAdDNbUeRNjReHpDm447beEzuWmnIP8Gkz+3fRNzZaHJJOwC2JbxQ7lhrSC1wDHFr2yPPGPq1IOg33yzf2dwjI33B91x8cj5FGjhySvgVcSxLGYNYAC4DdxisMaOAfV9LF5FjAaRlrgJ8BlxR5GhmLxogj6+f5A+DM2LHUiFdwG5euMbMXfRtvhDiy3VsLgbmxY8nJuUAPcASwH7CxR9uv43JGdwA/N7O3PNoeQO3FIWlD3AHAx8WOJSeXm9lZfT9ke0kOAg4FpgI7Uazf+ku4mt7luDKEh8xsrb9wR6bW4pC0CW4jyuGxY8nJT4GTRtof0YekrXAi2QFXXN3p9wXwAvA08LSZvRku3NGprTgkbY6rHd0vcih5WQIcW9V/dRXUUhzZf9Yywp4l75N7gcOKFj/XndqJQ9I2uJT71Nix5ORh4ICxip2bSK3EkfXqvAvYMXYsOfk7MNPMXokdSAhqIw5JO+KEEb2Za06eBfY1s+djBxKKWiyfS5oK3E9zhLEKOKibhQE1EIekvYH7qObsEx/0AIeYWYxuhJUSVRySPotrTOK7WjwUbwFHjradv5uIJg5JhwG/ATaPFUNB1gLHmdn9sQOpiijikHQsbtFoUgz/JejFrXzeETuQKqlcHJJOAm4CNqza9zg408wWxw6iaioVh6SvAz+mft37RmOBmV0dO4gYVLbOkbVYurgqf564wszmxw4iFpXUykq6FDi7Cl8eWUTL20IFHTmy3VtXA18L6ScAtwHHdFOGtQzBxCFpIu7+4sRQPgJxHy7D2qQWlEEIIg5JG+E2vB4dwn5AVgD7d2OGtQzexZEdA34rcIhv24Hp6gxrGbyKQ9IWuI2vM33arYBngRlm9lzsQOqEN3FkJxAsA/byZbMiVuGE0fWJtKJ4eZSVZLjdW7U7s30MenC1pEkYwzBucUj6CC6zusP4w6mUt3EZ1kdiB1JXxrV8Lmln4EGaJ4y1wOfblGEtQ2lxSNoVt3trir9wKqEXmNu2DGsZSolD0nTcdvzJfsOphHlmdmPsIJpAYXFIOgB387mV/3CCs8DMroodRFMo9Cgr6QhcJ51NwoQTlCvNbF7sIJpE7pFD0hdwxy40URiLgNam3suSa+SQdDJwPTXYrV6C24Gj255hLcOYH7ak+cANea6tIctxm4KTMEow6gcu6XzcAXm1qYwrwApgVkq9l2fED13Sd4GzRnq95qzEZVhXxQ6kyQwrDknXAV+tOBZfPIerYU0Z1nEyZFqRdC7NFUZfDWsShgcGjBySZuHOTG/iPUYPbhdXSqR5Yr0IJG2HO666KeWJ/Xkbl3pfHjuQbqL/tPIdmimMvhrWJAzPTID1/TH+TPPWMnpxpxsuih1IN9InhvNonjAA5idhhGNCtlv8VYpVvL+JKz1YgVtT2B7YA3cMeFXZ2gvMbEFFvlrJBEmHA78u8J77gJPN7OnBL0jaFteLe7af8EbkKjNLPdAD06FYd+A7cW0VhwgDwMxeNLOjgJ/4CG4EbgRS6r0COuTfMd4DnDJW6+aM+bgWzb65HbfFL08MiXHSIX+jtuvzrjya2WvA5aWjGp6UYa2YDvnPYH24oO2i14/GI6QMa+V0yH8WyF8L2i56/UisxK1+9niyl8hJB3eeRx6KNpD10XD2OeDglHqPQwd3UnEedi9ou+j1g+nLsD47TjuJknRwFeZ5ODE7HGdMsmO3TikdFazGNVDxdphdojgdXDP6POwEXJTz2vnAPqUichnWWUWP1k74Z4KkKbi5PQ/rgPOBy4Z7pMx6gJ2Ge4wtU8KwFteL67YS7014pi8r+yiwW4H3PQJcln1/CnfzuTtu5XK/krGkDGvN6BPHCbjD68rwLn66Ec8zsys92El4oi9Nv5jy6xI+hHFhEkb96ACY2TrcQbkxuMrMvh3Jd2IU1m/wMbMluMq2KllMyrDWlsG7v07HdeqpgjvIcUBvIh5DShAkTcZ17Nk5oN9lwJyUSKs3Q/aNmtnLwHTcBxiCK4AjkjDqz2i1sh3gEly9rI/Nx2/gNgQv9GArUQFjVrZJ+iSupqXsvtB3cTe6F5lZ3iRfogbkLnuUNA2YC3yOfB0En8DddC40s6fKhZeISamaWEm7ANNwu8i2BbbEpdiF2zv6gJk94yvIRBz+D3jMN0x55FT1AAAAAElFTkSuQmCC"/>
|
||||
</defs>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 4.5 KiB |
|
@ -240,7 +240,7 @@
|
|||
</ul>
|
||||
<ul class="mode-connected">
|
||||
<li class="tab_setup">
|
||||
<a href="#" data-i18n="tabSetup" class="tabicon ic_setup" title="Setup"></a>
|
||||
<a href="#" data-i18n="tabSetup" class="tabicon ic_setup" data-i18n_title="tabSetup"></a>
|
||||
</li>
|
||||
<li class="tab_calibration">
|
||||
<a href="#" data-i18n="tabCalibration" class="tabicon ic_calibration" title="Calibration"></a>
|
||||
|
|
17
js/fc.js
17
js/fc.js
|
@ -291,11 +291,6 @@ var FC = {
|
|||
battery_flags: 0
|
||||
};
|
||||
|
||||
this.ARMING_CONFIG = {
|
||||
auto_disarm_delay: 0,
|
||||
disarm_kill_switch: 0
|
||||
};
|
||||
|
||||
this.FC_CONFIG = {
|
||||
loopTime: 0
|
||||
};
|
||||
|
@ -587,6 +582,15 @@ var FC = {
|
|||
rate: null,
|
||||
expo: null
|
||||
};
|
||||
|
||||
|
||||
FW_APPROACH = new FwApproachCollection();
|
||||
|
||||
OSD_CUSTOM_ELEMENTS = {
|
||||
settings: {customElementsCount: 0, customElementTextSize: 0},
|
||||
items: [],
|
||||
};
|
||||
|
||||
},
|
||||
getOutputUsages: function() {
|
||||
return {
|
||||
|
@ -1329,7 +1333,8 @@ var FC = {
|
|||
37: "Rangefinder [cm]",
|
||||
38: "Active MixerProfile",
|
||||
39: "MixerTransition Active",
|
||||
40: "Yaw [deg]"
|
||||
40: "Yaw [deg]",
|
||||
41: "FW Land State"
|
||||
}
|
||||
},
|
||||
3: {
|
||||
|
|
107
js/fwApproach.js
Normal file
107
js/fwApproach.js
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*global $*/
|
||||
'use strict';
|
||||
|
||||
const ApproachDirection = Object.freeze({
|
||||
LEFT: 0,
|
||||
RIGHT: 1,
|
||||
})
|
||||
|
||||
let FwApproach = function (number, approachAltAsl = 0, landAltAsl = 0, approachDirection = 0, landHeading1 = 0, landHeading2 = 0, isSeaLevelRef = 0, elevation = 0) {
|
||||
|
||||
var self = {};
|
||||
|
||||
self.getNumber = function () {
|
||||
return number;
|
||||
};
|
||||
|
||||
self.setNumber = function (data) {
|
||||
number = data;
|
||||
};
|
||||
|
||||
self.getApproachAltAsl = function () {
|
||||
return approachAltAsl;
|
||||
}
|
||||
|
||||
self.setApproachAltAsl = function (data) {
|
||||
approachAltAsl = data;
|
||||
}
|
||||
|
||||
self.getLandAltAsl = function () {
|
||||
return landAltAsl;
|
||||
}
|
||||
|
||||
self.setLandAltAsl = function (data) {
|
||||
landAltAsl = data;
|
||||
}
|
||||
|
||||
self.getApproachDirection = function () {
|
||||
return approachDirection;
|
||||
}
|
||||
|
||||
self.setApproachDirection = function (data) {
|
||||
approachDirection = data;
|
||||
}
|
||||
|
||||
self.getLandHeading1 = function () {
|
||||
return landHeading1;
|
||||
}
|
||||
|
||||
self.setLandHeading1 = function (data) {
|
||||
landHeading1 = data;
|
||||
}
|
||||
|
||||
self.getLandHeading2 = function () {
|
||||
return landHeading2;
|
||||
}
|
||||
|
||||
self.setLandHeading2 = function (data) {
|
||||
landHeading2 = data;
|
||||
}
|
||||
|
||||
self.getIsSeaLevelRef = function () {
|
||||
return isSeaLevelRef;
|
||||
}
|
||||
|
||||
self.setIsSeaLevelRef = function (data) {
|
||||
isSeaLevelRef = data;
|
||||
}
|
||||
|
||||
self.getElevation = function() {
|
||||
return elevation;
|
||||
}
|
||||
|
||||
self.setElevation = function (data) {
|
||||
elevation = data;
|
||||
}
|
||||
|
||||
self.cleanup = function () {
|
||||
approachAltAsl = 0;
|
||||
landAltAsl = 0;
|
||||
approachDirection = 0;
|
||||
landHeading1 = 0;
|
||||
landHeading2 = 0;
|
||||
isSeaLevelRef = 0;
|
||||
elevation = 0
|
||||
};
|
||||
|
||||
self.getElevationFromServer = async function (lon, lat, globalSettings) {
|
||||
let elevation = "N/A";
|
||||
if (globalSettings.mapProviderType == 'bing') {
|
||||
let elevationEarthModel = $('#elevationEarthModel').prop("checked") ? "ellipsoid" : "sealevel";
|
||||
|
||||
const response = await fetch('http://dev.virtualearth.net/REST/v1/Elevation/List?points='+lat+','+lon+'&heights='+elevationEarthModel+'&key='+globalSettings.mapApiKey);
|
||||
const myJson = await response.json();
|
||||
elevation = myJson.resourceSets[0].resources[0].elevations[0];
|
||||
}
|
||||
else {
|
||||
const response = await fetch('https://api.opentopodata.org/v1/aster30m?locations='+lat+','+lon);
|
||||
const myJson = await response.json();
|
||||
if (myJson.status == "OK" && myJson.results[0].elevation != null) {
|
||||
elevation = myJson.results[0].elevation;
|
||||
}
|
||||
}
|
||||
return elevation;
|
||||
}
|
||||
|
||||
return self;
|
||||
};
|
92
js/fwApproachCollection.js
Normal file
92
js/fwApproachCollection.js
Normal file
|
@ -0,0 +1,92 @@
|
|||
'use strict';
|
||||
|
||||
let FwApproachCollection = function () {
|
||||
|
||||
let self = {},
|
||||
data = [],
|
||||
maxFwApproachCount = 17;
|
||||
|
||||
self.setMaxFwApproachCount = function (value) {
|
||||
maxFwApproachCount = value;
|
||||
};
|
||||
|
||||
self.getMaxFwApproachCount = function () {
|
||||
return maxFwApproachCount;
|
||||
}
|
||||
|
||||
self.put = function (element) {
|
||||
element.setNumber(data.length);
|
||||
data.push(element);
|
||||
};
|
||||
|
||||
self.get = function () {
|
||||
return data;
|
||||
};
|
||||
|
||||
self.clean = function (index){
|
||||
data[index].cleanup();
|
||||
};
|
||||
|
||||
self.flush = function () {
|
||||
data = [];
|
||||
};
|
||||
|
||||
self.isEmpty = () => {
|
||||
return data.length == 0;
|
||||
};
|
||||
|
||||
self.fwApproachCount = () => {
|
||||
return data.length;
|
||||
}
|
||||
|
||||
self.drop = (idx) => {
|
||||
data.forEach(f => {
|
||||
if (f.getNumber() >= idx) {
|
||||
f.setNumber(f.getNumber() - 1);
|
||||
}
|
||||
});
|
||||
data.splice(idx, 1);
|
||||
}
|
||||
|
||||
self.insert = (fwApprach, idx) => {
|
||||
data.forEach(f => {
|
||||
if (f.getNumber() >= idx) {
|
||||
f.setNumber(f.getNumber() + 1);
|
||||
}
|
||||
});
|
||||
data.splice(idx, 0, fwApprach);
|
||||
}
|
||||
|
||||
self.updateFwApproach = function(newFwApproach) {
|
||||
data[newFwApproach.getNumber()] = newFwApproach;
|
||||
};
|
||||
|
||||
self.extractBuffer = function(fwApproachId) {
|
||||
let buffer = [];
|
||||
let fwApproach = data[fwApproachId];
|
||||
if (fwApproachId < self.fwApproachCount()) {
|
||||
buffer.push(fwApproach.getNumber()); // sbufReadU8(src); // number
|
||||
buffer.push(specificByte(fwApproach.getApproachAltAsl(), 0));
|
||||
buffer.push(specificByte(fwApproach.getApproachAltAsl(), 1));
|
||||
buffer.push(specificByte(fwApproach.getApproachAltAsl(), 2));
|
||||
buffer.push(specificByte(fwApproach.getApproachAltAsl(), 3));
|
||||
buffer.push(specificByte(fwApproach.getLandAltAsl(), 0));
|
||||
buffer.push(specificByte(fwApproach.getLandAltAsl(), 1));
|
||||
buffer.push(specificByte(fwApproach.getLandAltAsl(), 2));
|
||||
buffer.push(specificByte(fwApproach.getLandAltAsl(), 3));
|
||||
buffer.push(fwApproach.getApproachDirection());
|
||||
buffer.push(specificByte(fwApproach.getLandHeading1(), 0));
|
||||
buffer.push(specificByte(fwApproach.getLandHeading1(), 1));
|
||||
buffer.push(specificByte(fwApproach.getLandHeading2(), 0));
|
||||
buffer.push(specificByte(fwApproach.getLandHeading2(), 1));
|
||||
buffer.push(fwApproach.getIsSeaLevelRef());
|
||||
} else {
|
||||
buffer = Array(15).fill(0);
|
||||
buffer[0] = safehomeId;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
return self;
|
||||
};
|
|
@ -55,4 +55,50 @@ function scaleRangeInt(x, srcMin, srcMax, destMin, destMax) {
|
|||
return Math.round((a / b) + destMin);
|
||||
}
|
||||
|
||||
module.exports = { constrain, zeroPad, generateFilename, scaleRangeInt };
|
||||
function distanceOnLine(start, end, distance)
|
||||
{
|
||||
var vx = end[0] - start[0];
|
||||
var vy = end[1] - start[1];
|
||||
var mag = Math.sqrt(vx * vx + vy * vy);
|
||||
vx /= mag;
|
||||
vy /= mag;
|
||||
|
||||
var px = start[0] + vx * (mag + distance);
|
||||
var py = start[1] + vy * (mag + distance);
|
||||
|
||||
return [px, py];
|
||||
}
|
||||
|
||||
function wrap_360(angle)
|
||||
{
|
||||
if (angle >= 360)
|
||||
angle -= 360;
|
||||
if (angle < 0)
|
||||
angle += 360;
|
||||
return angle;
|
||||
}
|
||||
|
||||
function rad2Deg(rad)
|
||||
{
|
||||
return rad * (180 / Math.PI);
|
||||
}
|
||||
|
||||
function deg2Rad(deg)
|
||||
{
|
||||
return deg * (Math.PI / 180);
|
||||
}
|
||||
|
||||
function calculate_new_cooridatnes(coord, bearing, distance)
|
||||
{
|
||||
var lat = deg2Rad(coord.lat);
|
||||
var lon = deg2Rad(coord.lon);
|
||||
bearing = deg2Rad(bearing);
|
||||
var delta = distance / 637100000; // Earth radius in cm
|
||||
|
||||
var latNew = Math.asin(Math.sin(lat) * Math.cos(delta) + Math.cos(lat) * Math.sin(delta) * Math.cos(bearing));
|
||||
var lonNew = lon + Math.atan2(Math.sin(bearing) * Math.sin(delta) * Math.cos(lat), Math.cos(delta) - Math.sin(lat) * Math.sin(lat));
|
||||
return {
|
||||
lat: rad2Deg(latNew),
|
||||
lon: rad2Deg(lonNew),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,8 +18,6 @@ var MSPCodes = {
|
|||
MSP_CALIBRATION_DATA: 14,
|
||||
MSP_SET_CALIBRATION_DATA: 15,
|
||||
|
||||
MSP_POSITION_ESTIMATION_CONFIG: 16,
|
||||
MSP_SET_POSITION_ESTIMATION_CONFIG: 17,
|
||||
MSP_WP_MISSION_LOAD: 18,
|
||||
MSP_WP_MISSION_SAVE: 19,
|
||||
MSP_WP_GETINFO: 20,
|
||||
|
@ -29,8 +27,6 @@ var MSPCodes = {
|
|||
MSP_SET_FW_CONFIG: 24,
|
||||
|
||||
// MSP commands for Cleanflight original features
|
||||
MSP_CHANNEL_FORWARDING: 32,
|
||||
MSP_SET_CHANNEL_FORWARDING: 33,
|
||||
MSP_MODE_RANGES: 34,
|
||||
MSP_SET_MODE_RANGE: 35,
|
||||
MSP_FEATURE: 36,
|
||||
|
@ -50,8 +46,6 @@ var MSPCodes = {
|
|||
MSP_CF_SERIAL_CONFIG: 54,
|
||||
MSP_SET_CF_SERIAL_CONFIG: 55,
|
||||
MSP_SONAR: 58,
|
||||
MSP_ARMING_CONFIG: 61,
|
||||
MSP_SET_ARMING_CONFIG: 62,
|
||||
MSP_DATAFLASH_SUMMARY: 70,
|
||||
MSP_DATAFLASH_READ: 71,
|
||||
MSP_DATAFLASH_ERASE: 72,
|
||||
|
@ -59,13 +53,9 @@ var MSPCodes = {
|
|||
MSP_SET_LOOP_TIME: 74,
|
||||
MSP_FAILSAFE_CONFIG: 75,
|
||||
MSP_SET_FAILSAFE_CONFIG: 76,
|
||||
MSP_RXFAIL_CONFIG: 77,
|
||||
MSP_SET_RXFAIL_CONFIG: 78,
|
||||
MSP_SDCARD_SUMMARY: 79,
|
||||
MSP_BLACKBOX_CONFIG: 80,
|
||||
MSP_SET_BLACKBOX_CONFIG: 81,
|
||||
MSP_OSD_CONFIG: 84,
|
||||
MSP_SET_OSD_CONFIG: 85,
|
||||
MSP_OSD_CHAR_READ: 86,
|
||||
MSP_OSD_CHAR_WRITE: 87,
|
||||
MSP_VTX_CONFIG: 88,
|
||||
|
@ -239,6 +229,9 @@ var MSPCodes = {
|
|||
MSP2_INAV_LED_STRIP_CONFIG_EX: 0x2048,
|
||||
MSP2_INAV_SET_LED_STRIP_CONFIG_EX: 0x2049,
|
||||
|
||||
MSP2_INAV_FW_APPROACH: 0x204A,
|
||||
MSP2_INAV_SET_FW_APPROACH: 0x204B,
|
||||
|
||||
MSP2_INAV_RATE_DYNAMICS: 0x2060,
|
||||
MSP2_INAV_SET_RATE_DYNAMICS: 0x2061,
|
||||
|
||||
|
@ -248,6 +241,10 @@ var MSPCodes = {
|
|||
MSP2_INAV_SELECT_MIXER_PROFILE: 0x2080,
|
||||
|
||||
MSP2_ADSB_VEHICLE_LIST: 0x2090,
|
||||
|
||||
MSP2_INAV_CUSTOM_OSD_ELEMENTS: 0x2100,
|
||||
MSP2_INAV_SET_CUSTOM_OSD_ELEMENTS: 0x2101,
|
||||
|
||||
};
|
||||
|
||||
module.exports = MSPCodes;
|
|
@ -39,33 +39,6 @@ var mspHelper = (function () {
|
|||
'921600'
|
||||
];
|
||||
|
||||
self.SERIAL_PORT_FUNCTIONS = {
|
||||
'MSP': 0,
|
||||
'GPS': 1,
|
||||
'TELEMETRY_FRSKY': 2,
|
||||
'TELEMETRY_HOTT': 3,
|
||||
'TELEMETRY_LTM': 4, // LTM replaced MSP
|
||||
'TELEMETRY_SMARTPORT': 5,
|
||||
'RX_SERIAL': 6,
|
||||
'BLACKBOX': 7,
|
||||
'TELEMETRY_MAVLINK': 8,
|
||||
'TELEMETRY_IBUS': 9,
|
||||
'RUNCAM_DEVICE_CONTROL': 10,
|
||||
'TBS_SMARTAUDIO': 11,
|
||||
'IRC_TRAMP': 12,
|
||||
'OPFLOW': 14,
|
||||
'LOG': 15,
|
||||
'RANGEFINDER': 16,
|
||||
'VTX_FFPV': 17,
|
||||
'ESC': 18,
|
||||
'GSM_SMS': 19,
|
||||
'FRSKY_OSD': 20,
|
||||
'DJI_FPV': 21,
|
||||
'SBUS_OUTPUT': 22,
|
||||
'SMARTPORT_MASTER': 23,
|
||||
'MSP_DISPLAYPORT': 25,
|
||||
};
|
||||
|
||||
// Required for MSP_DEBUGMSG because console.log() doesn't allow omitting
|
||||
// the newline at the end, so we keep the pending message here until we find a
|
||||
// '\0', then print it. Messages sent by MSP_DEBUGMSG are guaranteed to
|
||||
|
@ -333,10 +306,6 @@ var mspHelper = (function () {
|
|||
FC.PIDs[i][3] = data.getUint8(needle + 3);
|
||||
}
|
||||
break;
|
||||
case MSPCodes.MSP_ARMING_CONFIG:
|
||||
FC.ARMING_CONFIG.auto_disarm_delay = data.getUint8(0);
|
||||
FC.ARMING_CONFIG.disarm_kill_switch = data.getUint8(1);
|
||||
break;
|
||||
case MSPCodes.MSP_LOOP_TIME:
|
||||
FC.FC_CONFIG.loopTime = data.getInt16(0, true);
|
||||
break;
|
||||
|
@ -857,10 +826,6 @@ var mspHelper = (function () {
|
|||
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP_SET_CHANNEL_FORWARDING:
|
||||
console.log('Channel forwarding saved');
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP2_CF_SERIAL_CONFIG:
|
||||
FC.SERIAL_CONFIG.ports = [];
|
||||
var bytesPerPort = 1 + 4 + 4;
|
||||
|
@ -871,7 +836,7 @@ var mspHelper = (function () {
|
|||
|
||||
var serialPort = {
|
||||
identifier: data.getUint8(offset),
|
||||
functions: mspHelper.serialPortFunctionMaskToFunctions(data.getUint32(offset + 1, true)),
|
||||
functions: helper.serialPortHelper.maskToFunctions(data.getUint32(offset + 1, true)),
|
||||
msp_baudrate: BAUD_RATES[data.getUint8(offset + 5)],
|
||||
sensors_baudrate: BAUD_RATES[data.getUint8(offset + 6)],
|
||||
telemetry_baudrate: BAUD_RATES[data.getUint8(offset + 7)],
|
||||
|
@ -927,17 +892,6 @@ var mspHelper = (function () {
|
|||
}
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP_CHANNEL_FORWARDING:
|
||||
for (let i = 0; i < data.byteLength && i < FC.SERVO_CONFIG.length; i++) {
|
||||
var channelIndex = data.getUint8(i);
|
||||
if (channelIndex < 255) {
|
||||
FC.SERVO_CONFIG[i].indexOfChannelToForward = channelIndex;
|
||||
} else {
|
||||
FC.SERVO_CONFIG[i].indexOfChannelToForward = undefined;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP_RX_CONFIG:
|
||||
FC.RX_CONFIG.serialrx_provider = data.getUint8(offset);
|
||||
offset++;
|
||||
|
@ -995,21 +949,6 @@ var mspHelper = (function () {
|
|||
offset++;
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP_RXFAIL_CONFIG:
|
||||
//noinspection JSUndeclaredVariable
|
||||
FC.RXFAIL_CONFIG = []; // empty the array as new data is coming in
|
||||
|
||||
var channelCount = data.byteLength / 3;
|
||||
|
||||
for (let i = 0; offset < data.byteLength && i < channelCount; i++, offset++) {
|
||||
var rxfailChannel = {
|
||||
mode: data.getUint8(offset++),
|
||||
value: data.getUint16(offset++, true)
|
||||
};
|
||||
FC.RXFAIL_CONFIG.push(rxfailChannel);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case MSPCodes.MSP_LED_STRIP_CONFIG:
|
||||
//noinspection JSUndeclaredVariable
|
||||
|
@ -1394,20 +1333,6 @@ var mspHelper = (function () {
|
|||
console.log('Calibration data saved');
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP_POSITION_ESTIMATION_CONFIG:
|
||||
FC.POSITION_ESTIMATOR.w_z_baro_p = data.getUint16(0, true) / 100;
|
||||
FC.POSITION_ESTIMATOR.w_z_gps_p = data.getUint16(2, true) / 100;
|
||||
FC.POSITION_ESTIMATOR.w_z_gps_v = data.getUint16(4, true) / 100;
|
||||
FC.POSITION_ESTIMATOR.w_xy_gps_p = data.getUint16(6, true) / 100;
|
||||
FC.POSITION_ESTIMATOR.w_xy_gps_v = data.getUint16(8, true) / 100;
|
||||
FC.POSITION_ESTIMATOR.gps_min_sats = data.getUint8(10);
|
||||
FC.POSITION_ESTIMATOR.use_gps_velned = data.getUint8(11);
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP_SET_POSITION_ESTIMATION_CONFIG:
|
||||
console.log('POSITION_ESTIMATOR saved');
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP_RTH_AND_LAND_CONFIG:
|
||||
FC.RTH_AND_LAND_CONFIG.minRthDistance = data.getUint16(0, true);
|
||||
FC.RTH_AND_LAND_CONFIG.rthClimbFirst = data.getUint8(2);
|
||||
|
@ -1452,9 +1377,6 @@ var mspHelper = (function () {
|
|||
case MSPCodes.MSP_SET_LOOP_TIME:
|
||||
console.log('Looptime saved');
|
||||
break;
|
||||
case MSPCodes.MSP_SET_ARMING_CONFIG:
|
||||
console.log('Arming config saved');
|
||||
break;
|
||||
case MSPCodes.MSP_SET_RESET_CURR_PID:
|
||||
console.log('Current PID profile reset');
|
||||
break;
|
||||
|
@ -1470,17 +1392,9 @@ var mspHelper = (function () {
|
|||
case MSPCodes.MSP_SET_RX_CONFIG:
|
||||
console.log('Rx config saved');
|
||||
break;
|
||||
case MSPCodes.MSP_SET_RXFAIL_CONFIG:
|
||||
console.log('Rxfail config saved');
|
||||
break;
|
||||
case MSPCodes.MSP_SET_FAILSAFE_CONFIG:
|
||||
console.log('Failsafe config saved');
|
||||
break;
|
||||
case MSPCodes.MSP_OSD_CONFIG:
|
||||
break;
|
||||
case MSPCodes.MSP_SET_OSD_CONFIG:
|
||||
console.log('OSD config set');
|
||||
break;
|
||||
case MSPCodes.MSP_OSD_CHAR_READ:
|
||||
break;
|
||||
case MSPCodes.MSP_OSD_CHAR_WRITE:
|
||||
|
@ -1551,6 +1465,9 @@ var mspHelper = (function () {
|
|||
case MSPCodes.MSP2_INAV_SELECT_BATTERY_PROFILE:
|
||||
console.log('Battery profile selected');
|
||||
break;
|
||||
case MSPCodes.MSP2_INAV_SET_CUSTOM_OSD_ELEMENTS:
|
||||
console.log('OSD custom elements preferences saved');
|
||||
break;
|
||||
case MSPCodes.MSPV2_INAV_OUTPUT_MAPPING:
|
||||
FC.OUTPUT_MAPPING.flush();
|
||||
for (let i = 0; i < data.byteLength; ++i)
|
||||
|
@ -1622,13 +1539,33 @@ var mspHelper = (function () {
|
|||
data.getUint8(0),
|
||||
data.getUint8(1),
|
||||
data.getInt32(2, true),
|
||||
data.getInt32(6, true)
|
||||
));
|
||||
data.getInt32(6, true),
|
||||
);
|
||||
if (safehome.getEnabled()) {
|
||||
SAFEHOMES.put(safehome);
|
||||
}
|
||||
|
||||
break;
|
||||
case MSPCodes.MSP2_INAV_SET_SAFEHOME:
|
||||
console.log('Safehome points saved');
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP2_INAV_FW_APPROACH:
|
||||
FW_APPROACH.put(new FwApproach(
|
||||
data.getUint8(0),
|
||||
data.getInt32(1, true),
|
||||
data.getInt32(5, true),
|
||||
data.getUint8(9, true),
|
||||
data.getInt16(10, true),
|
||||
data.getInt16(12, true),
|
||||
data.getUint8(14, true),
|
||||
));
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP2_INAV_SET_FW_APPROACH:
|
||||
console.log('FW Approach saved');
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP2_INAV_RATE_DYNAMICS:
|
||||
FC.RATE_DYNAMICS.sensitivityCenter = data.getUint8(0);
|
||||
FC.RATE_DYNAMICS.sensitivityEnd = data.getUint8(1);
|
||||
|
@ -1658,6 +1595,54 @@ var mspHelper = (function () {
|
|||
console.log('EzTune settings saved');
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP2_INAV_CUSTOM_OSD_ELEMENTS:
|
||||
OSD_CUSTOM_ELEMENTS.items = [];
|
||||
|
||||
var index = 0;
|
||||
|
||||
if(data.byteLength == 0){
|
||||
OSD_CUSTOM_ELEMENTS.settings.customElementsCount = 0;
|
||||
OSD_CUSTOM_ELEMENTS.settings.customElementTextSize = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
OSD_CUSTOM_ELEMENTS.settings.customElementsCount = data.getUint8(index++);
|
||||
OSD_CUSTOM_ELEMENTS.settings.customElementTextSize = data.getUint8(index++);
|
||||
|
||||
for (i = 0; i < OSD_CUSTOM_ELEMENTS.settings.customElementsCount; i++){
|
||||
var customElement = {
|
||||
customElementItems: [],
|
||||
customElementVisibility: {type: 0, value: 0},
|
||||
customElementText: [],
|
||||
};
|
||||
|
||||
for (let ii = 0; ii < OSD_CUSTOM_ELEMENTS.settings.customElementsCount; ii++){
|
||||
var customElementPart = {type: 0, value: 0,};
|
||||
customElementPart.type = data.getUint8(index++);
|
||||
customElementPart.value = data.getUint16(index, true);
|
||||
index += 2;
|
||||
customElement.customElementItems.push(customElementPart);
|
||||
}
|
||||
|
||||
customElement.customElementVisibility.type = data.getUint8(index++);
|
||||
customElement.customElementVisibility.value = data.getUint16(index, true);
|
||||
index += 2;
|
||||
|
||||
for (let ii = 0; ii < OSD_CUSTOM_ELEMENTS.settings.customElementTextSize; ii++){
|
||||
var char = data.getUint8(index++);
|
||||
if(char === 0){
|
||||
index += (OSD_CUSTOM_ELEMENTS.settings.customElementTextSize - 1) - ii;
|
||||
break;
|
||||
}
|
||||
customElement.customElementText[ii] = char;
|
||||
}
|
||||
|
||||
customElement.customElementText = String.fromCharCode(...customElement.customElementText);
|
||||
|
||||
OSD_CUSTOM_ELEMENTS.items.push(customElement)
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
console.log('Unknown code detected: ' + dataHandler.code);
|
||||
} else {
|
||||
|
@ -1794,10 +1779,6 @@ var mspHelper = (function () {
|
|||
buffer.push(BitHelper.lowByte(FC.CONFIG.accelerometerTrims[1]));
|
||||
buffer.push(BitHelper.highByte(FC.CONFIG.accelerometerTrims[1]));
|
||||
break;
|
||||
case MSPCodes.MSP_SET_ARMING_CONFIG:
|
||||
buffer.push(FC.ARMING_CONFIG.auto_disarm_delay);
|
||||
buffer.push(FC.ARMING_CONFIG.disarm_kill_switch);
|
||||
break;
|
||||
case MSPCodes.MSP_SET_LOOP_TIME:
|
||||
buffer.push(BitHelper.lowByte(FC.FC_CONFIG.loopTime));
|
||||
buffer.push(BitHelper.highByte(FC.FC_CONFIG.loopTime));
|
||||
|
@ -1939,16 +1920,6 @@ var mspHelper = (function () {
|
|||
buffer.push(FC.FAILSAFE_CONFIG.failsafe_min_distance_procedure);
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP_SET_CHANNEL_FORWARDING:
|
||||
for (let i = 0; i < FC.SERVO_CONFIG.length; i++) {
|
||||
var out = FC.SERVO_CONFIG[i].indexOfChannelToForward;
|
||||
if (out == undefined) {
|
||||
out = 255; // Cleanflight defines "CHANNEL_FORWARDING_DISABLED" as "(uint8_t)0xFF"
|
||||
}
|
||||
buffer.push(out);
|
||||
}
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP2_SET_CF_SERIAL_CONFIG:
|
||||
for (let i = 0; i < FC.SERIAL_CONFIG.ports.length; i++) {
|
||||
var serialPort = FC.SERIAL_CONFIG.ports[i];
|
||||
|
@ -2097,26 +2068,6 @@ var mspHelper = (function () {
|
|||
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP_SET_POSITION_ESTIMATION_CONFIG:
|
||||
buffer.push(BitHelper.lowByte(FC.POSITION_ESTIMATOR.w_z_baro_p * 100));
|
||||
buffer.push(BitHelper.highByte(FC.POSITION_ESTIMATOR.w_z_baro_p * 100));
|
||||
|
||||
buffer.push(BitHelper.lowByte(FC.POSITION_ESTIMATOR.w_z_gps_p * 100));
|
||||
buffer.push(BitHelper.highByte(FC.POSITION_ESTIMATOR.w_z_gps_p * 100));
|
||||
|
||||
buffer.push(BitHelper.lowByte(FC.POSITION_ESTIMATOR.w_z_gps_v * 100));
|
||||
buffer.push(BitHelper.highByte(FC.POSITION_ESTIMATOR.w_z_gps_v * 100));
|
||||
|
||||
buffer.push(BitHelper.lowByte(FC.POSITION_ESTIMATOR.w_xy_gps_p * 100));
|
||||
buffer.push(BitHelper.highByte(FC.POSITION_ESTIMATOR.w_xy_gps_p * 100));
|
||||
|
||||
buffer.push(BitHelper.lowByte(FC.POSITION_ESTIMATOR.w_xy_gps_v * 100));
|
||||
buffer.push(BitHelper.highByte(FC.POSITION_ESTIMATOR.w_xy_gps_v * 100));
|
||||
|
||||
buffer.push(FC.POSITION_ESTIMATOR.gps_min_sats);
|
||||
buffer.push(FC.POSITION_ESTIMATOR.use_gps_velned);
|
||||
break;
|
||||
|
||||
case MSPCodes.MSP_SET_RTH_AND_LAND_CONFIG:
|
||||
buffer.push(BitHelper.lowByte(FC.RTH_AND_LAND_CONFIG.minRthDistance));
|
||||
buffer.push(BitHelper.highByte(FC.RTH_AND_LAND_CONFIG.minRthDistance));
|
||||
|
@ -2602,6 +2553,10 @@ var mspHelper = (function () {
|
|||
}
|
||||
};
|
||||
|
||||
self.loadOsdCustomElements = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP2_INAV_CUSTOM_OSD_ELEMENTS, false, false, callback);
|
||||
}
|
||||
|
||||
self.sendModeRanges = function (onCompleteCallback) {
|
||||
var nextFunction = send_next_mode_range;
|
||||
|
||||
|
@ -2667,66 +2622,6 @@ var mspHelper = (function () {
|
|||
});
|
||||
};
|
||||
|
||||
self.sendRxFailConfig = function (onCompleteCallback) {
|
||||
var nextFunction = send_next_rxfail_config;
|
||||
|
||||
var rxFailIndex = 0;
|
||||
|
||||
if (FC.RXFAIL_CONFIG.length == 0) {
|
||||
onCompleteCallback();
|
||||
} else {
|
||||
send_next_rxfail_config();
|
||||
}
|
||||
|
||||
function send_next_rxfail_config() {
|
||||
|
||||
var rxFail = FC.RXFAIL_CONFIG[rxFailIndex];
|
||||
|
||||
var buffer = [];
|
||||
buffer.push(rxFailIndex);
|
||||
buffer.push(rxFail.mode);
|
||||
buffer.push(BitHelper.lowByte(rxFail.value));
|
||||
buffer.push(BitHelper.highByte(rxFail.value));
|
||||
|
||||
// prepare for next iteration
|
||||
rxFailIndex++;
|
||||
if (rxFailIndex == FC.RXFAIL_CONFIG.length) {
|
||||
nextFunction = onCompleteCallback;
|
||||
|
||||
}
|
||||
MSP.send_message(MSPCodes.MSP_SET_RXFAIL_CONFIG, buffer, false, nextFunction);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
self.SERIAL_PORT_FUNCTIONSToMask = function (functions) {
|
||||
var mask = 0;
|
||||
for (var index = 0; index < functions.length; index++) {
|
||||
var key = functions[index];
|
||||
var bitIndex = mspHelper.SERIAL_PORT_FUNCTIONS[key];
|
||||
if (bitIndex >= 0) {
|
||||
mask = bit_set(mask, bitIndex);
|
||||
}
|
||||
}
|
||||
return mask;
|
||||
};
|
||||
|
||||
self.serialPortFunctionMaskToFunctions = function (functionMask) {
|
||||
var functions = [];
|
||||
|
||||
var keys = Object.keys(mspHelper.SERIAL_PORT_FUNCTIONS);
|
||||
for (var index = 0; index < keys.length; index++) {
|
||||
var key = keys[index];
|
||||
var bit = mspHelper.SERIAL_PORT_FUNCTIONS[key];
|
||||
if (bit_check(functionMask, bit)) {
|
||||
functions.push(key);
|
||||
}
|
||||
}
|
||||
return functions;
|
||||
};
|
||||
|
||||
self.sendServoMixRules = function (onCompleteCallback) {
|
||||
// TODO implement
|
||||
onCompleteCallback();
|
||||
|
@ -2979,7 +2874,7 @@ var mspHelper = (function () {
|
|||
MSP.send_message(MSPCodes.MSP2_INAV_TIMER_OUTPUT_MODE, false, false, callback);
|
||||
}
|
||||
|
||||
self.sendTimerOutputModes = function(onCompleteCallback) {
|
||||
self.sendTimerOutputModes = function(callback) {
|
||||
var nextFunction = send_next_output_mode;
|
||||
var idIndex = 0;
|
||||
|
||||
|
@ -3004,7 +2899,7 @@ var mspHelper = (function () {
|
|||
// prepare for next iteration
|
||||
idIndex++;
|
||||
if (idIndex == overrideIds.length) {
|
||||
nextFunction = onCompleteCallback;
|
||||
nextFunction = callback;
|
||||
|
||||
}
|
||||
MSP.send_message(MSPCodes.MSP2_INAV_SET_TIMER_OUTPUT_MODE, buffer, false, nextFunction);
|
||||
|
@ -3016,10 +2911,6 @@ var mspHelper = (function () {
|
|||
MSP.send_message(MSPCodes.MSPV2_BATTERY_CONFIG, false, false, callback);
|
||||
};
|
||||
|
||||
self.loadArmingConfig = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_ARMING_CONFIG, false, false, callback);
|
||||
};
|
||||
|
||||
self.loadRxConfig = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_RX_CONFIG, false, false, callback);
|
||||
};
|
||||
|
@ -3128,10 +3019,6 @@ var mspHelper = (function () {
|
|||
MSP.send_message(MSPCodes.MSP_SET_ACC_TRIM, mspHelper.crunch(MSPCodes.MSP_SET_ACC_TRIM), false, callback);
|
||||
};
|
||||
|
||||
self.saveArmingConfig = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_SET_ARMING_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_ARMING_CONFIG), false, callback);
|
||||
};
|
||||
|
||||
self.saveRxConfig = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_SET_RX_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_RX_CONFIG), false, callback);
|
||||
};
|
||||
|
@ -3148,14 +3035,6 @@ var mspHelper = (function () {
|
|||
MSP.send_message(MSPCodes.MSP_SET_NAV_POSHOLD, mspHelper.crunch(MSPCodes.MSP_SET_NAV_POSHOLD), false, callback);
|
||||
};
|
||||
|
||||
self.loadPositionEstimationConfig = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_POSITION_ESTIMATION_CONFIG, false, false, callback);
|
||||
};
|
||||
|
||||
self.savePositionEstimationConfig = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_SET_POSITION_ESTIMATION_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_POSITION_ESTIMATION_CONFIG), false, callback);
|
||||
};
|
||||
|
||||
self.loadCalibrationData = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP_CALIBRATION_DATA, false, false, callback);
|
||||
};
|
||||
|
@ -3251,6 +3130,37 @@ var mspHelper = (function () {
|
|||
};
|
||||
};
|
||||
|
||||
self.loadFwApproach = function (callback) {
|
||||
FW_APPROACH.flush();
|
||||
let id = 0;
|
||||
MSP.send_message(MSPCodes.MSP2_INAV_FW_APPROACH, [id], false, nextFwApproach);
|
||||
|
||||
function nextFwApproach() {
|
||||
id++;
|
||||
if (id < FW_APPROACH.getMaxFwApproachCount() - 1) {
|
||||
MSP.send_message(MSPCodes.MSP2_INAV_FW_APPROACH, [id], false, nextFwApproach);
|
||||
}
|
||||
else {
|
||||
MSP.send_message(MSPCodes.MSP2_INAV_FW_APPROACH, [id], false, callback);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
self.saveFwApproach = function (callback) {
|
||||
let id = 0;
|
||||
MSP.send_message(MSPCodes.MSP2_INAV_SET_FW_APPROACH, FW_APPROACH.extractBuffer(id), false, nextFwApproach);
|
||||
|
||||
function nextFwApproach() {
|
||||
id++;
|
||||
if (id < FW_APPROACH.getMaxFwApproachCount() - 1) {
|
||||
MSP.send_message(MSPCodes.MSP2_INAV_SET_FW_APPROACH, FW_APPROACH.extractBuffer(id), false, nextFwApproach);
|
||||
}
|
||||
else {
|
||||
MSP.send_message(MSPCodes.MSP2_INAV_SET_FW_APPROACH, FW_APPROACH.extractBuffer(id), false, callback);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
self._getSetting = function (name) {
|
||||
if (FC.SETTINGS[name]) {
|
||||
return Promise.resolve(FC.SETTINGS[name]);
|
||||
|
@ -3366,8 +3276,7 @@ var mspHelper = (function () {
|
|||
return this._getSetting(name).then(function (setting) {
|
||||
|
||||
if (!setting) {
|
||||
console.log("Setting invalid: " + name);
|
||||
return null;
|
||||
throw 'Invalid setting';
|
||||
}
|
||||
|
||||
if (setting.table && !Number.isInteger(value)) {
|
||||
|
@ -3417,11 +3326,10 @@ var mspHelper = (function () {
|
|||
|
||||
self.setSetting = function (name, value, callback) {
|
||||
this.encodeSetting(name, value).then(function (data) {
|
||||
if (data) {
|
||||
return MSP.promise(MSPCodes.MSPV2_SET_SETTING, data).then(callback);
|
||||
} else {
|
||||
return Promise.resolve().then(callback);
|
||||
}
|
||||
}).catch(error => {
|
||||
console.log("Invalid setting: " + name);
|
||||
return new Promise(callback);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -3559,6 +3467,13 @@ var mspHelper = (function () {
|
|||
MSP.send_message(MSPCodes.MSP2_INAV_PROGRAMMING_PID_STATUS, false, false, callback);
|
||||
};
|
||||
|
||||
self.loadSerialPorts = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP2_CF_SERIAL_CONFIG, false, false, callback);
|
||||
};
|
||||
|
||||
self.saveSerialPorts = function (callback) {
|
||||
MSP.send_message(MSPCodes.MSP2_SET_CF_SERIAL_CONFIG, mspHelper.crunch(MSPCodes.MSP2_SET_CF_SERIAL_CONFIG), false, callback);
|
||||
};
|
||||
|
||||
return self;
|
||||
})();
|
||||
|
|
|
@ -15,6 +15,7 @@ var SafehomeCollection = function () {
|
|||
}
|
||||
|
||||
self.put = function (element) {
|
||||
element.setNumber(data.length);
|
||||
data.push(element);
|
||||
};
|
||||
|
||||
|
@ -30,67 +31,31 @@ var SafehomeCollection = function () {
|
|||
data = [];
|
||||
};
|
||||
|
||||
self.inflate = function () {
|
||||
while (self.hasFreeSlots()) {
|
||||
self.put(new Safehome(data.length, 0, 0, 0));
|
||||
}
|
||||
self.isEmpty = () => {
|
||||
return data.length == 0;
|
||||
};
|
||||
|
||||
self.hasFreeSlots = function () {
|
||||
return data.length < self.getMaxSafehomeCount();
|
||||
};
|
||||
|
||||
self.isSafehomeConfigured = function(safehomeId) {
|
||||
|
||||
for (let safehomeIndex in data) {
|
||||
if (data.hasOwnProperty(safehomeIndex)) {
|
||||
let safehome = data[safehomeIndex];
|
||||
|
||||
if (safehome.getNumber() == safehomeId && safehome.isUsed()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
self.getNumberOfConfiguredSafehome = function () {
|
||||
let count = 0;
|
||||
for (let i = 0; i < self.getMaxSafehomeCount(); i ++) {
|
||||
if (self.isSafehomeConfigured(i)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
};
|
||||
|
||||
self.getUsedSafehomeIndexes = function () {
|
||||
let out = [];
|
||||
|
||||
for (let safehomeIndex in data) {
|
||||
if (data.hasOwnProperty(safehomeIndex)) {
|
||||
let safehome = data[safehomeIndex];
|
||||
out.push(safehome.getNumber());
|
||||
}
|
||||
self.safehomeCount = () => {
|
||||
return data.length;
|
||||
}
|
||||
|
||||
let unique = [...new Set(out)];
|
||||
|
||||
return unique.sort(function(a, b) {
|
||||
return a-b;
|
||||
self.drop = (idx) => {
|
||||
data.forEach(safehome => {
|
||||
if (safehome.getNumber() >= idx) {
|
||||
safehome.setNumber(safehome.getNumber() - 1);
|
||||
}
|
||||
});
|
||||
data.splice(idx, 1);
|
||||
}
|
||||
|
||||
self.getSafehome = function(safehomeId) {
|
||||
for (let safehomeIndex in data) {
|
||||
if (data.hasOwnProperty(safehomeIndex)) {
|
||||
let safehome = data[safehomeIndex];
|
||||
if (safehome.getNumber() == safehomeId ) {
|
||||
return safehome;
|
||||
self.insert = (safehome, idx) => {
|
||||
data.forEach(s => {
|
||||
if (s.getNumber() >= idx) {
|
||||
s.setNumber(s.getNumber() + 1);
|
||||
}
|
||||
});
|
||||
data.splice(idx, 0, safehome);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
self.updateSafehome = function(newSafehome) {
|
||||
data[newSafehome.getNumber()] = newSafehome;
|
||||
|
@ -98,9 +63,10 @@ var SafehomeCollection = function () {
|
|||
|
||||
self.extractBuffer = function(safehomeId) {
|
||||
let buffer = [];
|
||||
let safehome = self.getSafehome(safehomeId);
|
||||
let safehome = data[safehomeId];
|
||||
if (safehomeId < self.safehomeCount()) {
|
||||
buffer.push(safehome.getNumber()); // sbufReadU8(src); // number
|
||||
buffer.push(safehome.getEnabled()); // sbufReadU8(src); // action
|
||||
buffer.push(1);
|
||||
buffer.push(specificByte(safehome.getLat(), 0)); // sbufReadU32(src); // lat
|
||||
buffer.push(specificByte(safehome.getLat(), 1));
|
||||
buffer.push(specificByte(safehome.getLat(), 2));
|
||||
|
@ -109,6 +75,10 @@ var SafehomeCollection = function () {
|
|||
buffer.push(specificByte(safehome.getLon(), 1));
|
||||
buffer.push(specificByte(safehome.getLon(), 2));
|
||||
buffer.push(specificByte(safehome.getLon(), 3));
|
||||
} else {
|
||||
buffer = Array(10).fill(0);
|
||||
buffer[0] = safehomeId;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
|
351
js/serialPortHelper.js
Normal file
351
js/serialPortHelper.js
Normal file
|
@ -0,0 +1,351 @@
|
|||
'use strict';
|
||||
|
||||
var helper = helper || {};
|
||||
|
||||
helper.serialPortHelper = (function () {
|
||||
|
||||
let publicScope = {},
|
||||
privateScope = {};
|
||||
|
||||
privateScope.namesGenerated = false;
|
||||
|
||||
// This is a list of all the rules for the serial ports as well as their names
|
||||
privateScope.rules = [
|
||||
{
|
||||
name: 'MSP',
|
||||
groups: ['data']
|
||||
},
|
||||
{
|
||||
name: 'GPS',
|
||||
groups: ['sensors'],
|
||||
defaultBaud: 115200,
|
||||
isUnique: true
|
||||
},
|
||||
{
|
||||
name: 'TELEMETRY_FRSKY',
|
||||
groups: ['telemetry']
|
||||
},
|
||||
{
|
||||
name: 'TELEMETRY_HOTT',
|
||||
groups: ['telemetry']
|
||||
},
|
||||
{
|
||||
name: 'TELEMETRY_SMARTPORT',
|
||||
groups: ['telemetry']
|
||||
},
|
||||
{
|
||||
name: 'TELEMETRY_LTM',
|
||||
groups: ['telemetry']
|
||||
},
|
||||
{
|
||||
name: 'RX_SERIAL',
|
||||
groups: ['rx'],
|
||||
isUnique: true
|
||||
},
|
||||
{
|
||||
name: 'BLACKBOX',
|
||||
groups: ['peripherals']
|
||||
},
|
||||
{
|
||||
name: 'TELEMETRY_MAVLINK',
|
||||
groups: ['telemetry'],
|
||||
},
|
||||
{
|
||||
name: 'TELEMETRY_IBUS',
|
||||
groups: ['telemetry'],
|
||||
},
|
||||
{
|
||||
name: 'RANGEFINDER',
|
||||
groups: ['sensors'],
|
||||
isUnique: true
|
||||
},
|
||||
{
|
||||
name: 'GSM_SMS',
|
||||
groups: ['telemetry'],
|
||||
},
|
||||
{
|
||||
name: 'RUNCAM_DEVICE_CONTROL',
|
||||
groups: ['peripherals'],
|
||||
},
|
||||
{
|
||||
name: 'TBS_SMARTAUDIO',
|
||||
groups: ['peripherals'],
|
||||
isUnique: true
|
||||
},
|
||||
{
|
||||
name: 'IRC_TRAMP',
|
||||
groups: ['peripherals'],
|
||||
isUnique: true
|
||||
},
|
||||
{
|
||||
name: 'VTX_FFPV',
|
||||
groups: ['peripherals'],
|
||||
isUnique: true
|
||||
},
|
||||
{
|
||||
name: 'ESC',
|
||||
groups: ['peripherals'],
|
||||
defaultBaud: 115200,
|
||||
isUnique: true
|
||||
},
|
||||
{
|
||||
name: 'OPFLOW',
|
||||
groups: ['sensors'],
|
||||
isUnique: true
|
||||
},
|
||||
{
|
||||
name: 'FRSKY_OSD',
|
||||
groups: ['peripherals'],
|
||||
defaultBaud: 250000,
|
||||
isUnique: true
|
||||
},
|
||||
{
|
||||
name: 'DJI_FPV',
|
||||
groups: ['peripherals'],
|
||||
defaultBaud: 115200,
|
||||
isUnique: true
|
||||
},
|
||||
{
|
||||
name: 'MSP_DISPLAYPORT',
|
||||
groups: ['peripherals'],
|
||||
isUnique: true
|
||||
},
|
||||
{
|
||||
name: 'SMARTPORT_MASTER',
|
||||
groups: ['peripherals'],
|
||||
defaultBaud: 57600
|
||||
},
|
||||
{
|
||||
name: 'SBUS_OUTPUT',
|
||||
groups: ['peripherals'],
|
||||
defaultBaud: 115200
|
||||
}
|
||||
];
|
||||
|
||||
// This is a mapping of the function names to their IDs required by the firmware and MSP protocol
|
||||
privateScope.functionIDs = {
|
||||
'MSP': 0,
|
||||
'GPS': 1,
|
||||
'TELEMETRY_FRSKY': 2,
|
||||
'TELEMETRY_HOTT': 3,
|
||||
'TELEMETRY_LTM': 4, // LTM replaced MSP
|
||||
'TELEMETRY_SMARTPORT': 5,
|
||||
'RX_SERIAL': 6,
|
||||
'BLACKBOX': 7,
|
||||
'TELEMETRY_MAVLINK': 8,
|
||||
'TELEMETRY_IBUS': 9,
|
||||
'RUNCAM_DEVICE_CONTROL': 10,
|
||||
'TBS_SMARTAUDIO': 11,
|
||||
'IRC_TRAMP': 12,
|
||||
'OPFLOW': 14,
|
||||
'LOG': 15,
|
||||
'RANGEFINDER': 16,
|
||||
'VTX_FFPV': 17,
|
||||
'ESC': 18,
|
||||
'GSM_SMS': 19,
|
||||
'FRSKY_OSD': 20,
|
||||
'DJI_FPV': 21,
|
||||
'SBUS_OUTPUT': 22,
|
||||
'SMARTPORT_MASTER': 23,
|
||||
'MSP_DISPLAYPORT': 25,
|
||||
};
|
||||
|
||||
privateScope.identifierToName = {
|
||||
0: 'UART1',
|
||||
1: 'UART2',
|
||||
2: 'UART3',
|
||||
3: 'UART4',
|
||||
4: 'UART5',
|
||||
5: 'UART6',
|
||||
6: 'UART7',
|
||||
7: 'UART8',
|
||||
20: 'USB VCP',
|
||||
30: 'SOFTSERIAL1',
|
||||
31: 'SOFTSERIAL2'
|
||||
};
|
||||
|
||||
privateScope.bauds = {
|
||||
'SENSOR': [
|
||||
'9600',
|
||||
'19200',
|
||||
'38400',
|
||||
'57600',
|
||||
'115200',
|
||||
'230400'
|
||||
],
|
||||
'MSP': [
|
||||
'2400',
|
||||
'4800',
|
||||
'9600',
|
||||
'19200',
|
||||
'38400',
|
||||
'57600',
|
||||
'115200'
|
||||
],
|
||||
'TELEMETRY': [
|
||||
'AUTO',
|
||||
'1200',
|
||||
'2400',
|
||||
'4800',
|
||||
'9600',
|
||||
'19200',
|
||||
'38400',
|
||||
'57600',
|
||||
'115200'
|
||||
],
|
||||
'PERIPHERAL': [
|
||||
'19200',
|
||||
'38400',
|
||||
'57600',
|
||||
'115200',
|
||||
'230400',
|
||||
'250000'
|
||||
]
|
||||
};
|
||||
|
||||
privateScope.generateNames = function () {
|
||||
if (privateScope.namesGenerated) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < privateScope.rules.length; i++) {
|
||||
privateScope.rules[i].displayName = chrome.i18n.getMessage('portsFunction_' + privateScope.rules[i].name);
|
||||
}
|
||||
|
||||
privateScope.namesGenerated = true;
|
||||
};
|
||||
|
||||
publicScope.getRules = function () {
|
||||
privateScope.generateNames();
|
||||
|
||||
return privateScope.rules;
|
||||
};
|
||||
|
||||
publicScope.getRuleByName = function (name) {
|
||||
for (var i = 0; i < privateScope.rules.length; i++) {
|
||||
if (privateScope.rules[i].name === name) {
|
||||
return privateScope.rules[i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {array} functions
|
||||
* @returns {number}
|
||||
*/
|
||||
publicScope.functionsToMask = function (functions) {
|
||||
let mask = 0;
|
||||
for (let index = 0; index < functions.length; index++) {
|
||||
let key = functions[index];
|
||||
let bitIndex = privateScope.functionIDs[key];
|
||||
if (bitIndex >= 0) {
|
||||
mask = bit_set(mask, bitIndex);
|
||||
}
|
||||
}
|
||||
return mask;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number} mask
|
||||
* @returns {array}
|
||||
*/
|
||||
publicScope.maskToFunctions = function (mask) {
|
||||
let functions = [];
|
||||
|
||||
let keys = Object.keys(privateScope.functionIDs);
|
||||
for (let index = 0; index < keys.length; index++) {
|
||||
let key = keys[index];
|
||||
let bit = privateScope.functionIDs[key];
|
||||
if (bit_check(mask, bit)) {
|
||||
functions.push(key);
|
||||
}
|
||||
}
|
||||
return functions;
|
||||
};
|
||||
|
||||
publicScope.getPortName = function (identifier) {
|
||||
return privateScope.identifierToName[identifier];
|
||||
};
|
||||
|
||||
publicScope.getPortIdentifiersForFunction = function (functionName) {
|
||||
let identifiers = [];
|
||||
|
||||
for (let index = 0; index < SERIAL_CONFIG.ports.length; index++) {
|
||||
let config = SERIAL_CONFIG.ports[index];
|
||||
if (config.functions.indexOf(functionName) != -1) {
|
||||
identifiers.push(config.identifier);
|
||||
}
|
||||
}
|
||||
|
||||
return identifiers;
|
||||
}
|
||||
|
||||
publicScope.getPortList = function () {
|
||||
|
||||
let list = [];
|
||||
|
||||
for (let index = 0; index < SERIAL_CONFIG.ports.length; index++) {
|
||||
let config = SERIAL_CONFIG.ports[index];
|
||||
|
||||
//exclude USB VCP port
|
||||
if (config.identifier == 20) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let port = {
|
||||
identifier: config.identifier,
|
||||
displayName: privateScope.identifierToName[config.identifier]
|
||||
};
|
||||
list.push(port);
|
||||
}
|
||||
return list;
|
||||
};
|
||||
|
||||
publicScope.getBauds = function (functionName) {
|
||||
return privateScope.bauds[functionName];
|
||||
};
|
||||
|
||||
publicScope.getPortByIdentifier = function (identifier) {
|
||||
for (let index = 0; index < SERIAL_CONFIG.ports.length; index++) {
|
||||
let config = SERIAL_CONFIG.ports[index];
|
||||
if (config.identifier == identifier) {
|
||||
return config;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
publicScope.clearByFunction = function (functionName) {
|
||||
for (let index = 0; index < SERIAL_CONFIG.ports.length; index++) {
|
||||
let config = SERIAL_CONFIG.ports[index];
|
||||
if (config.functions.indexOf(functionName) != -1) {
|
||||
config.functions = [];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
publicScope.set = function(port, functionName, baudrate) {
|
||||
|
||||
publicScope.clearByFunction(functionName);
|
||||
|
||||
let config = publicScope.getPortByIdentifier(port);
|
||||
if (config) {
|
||||
|
||||
config.functions = [functionName];
|
||||
|
||||
//set baudrate
|
||||
//TODO add next entries as we progress
|
||||
if (functionName == 'MSP') {
|
||||
config.msp_baudrate = baudrate;
|
||||
} else if (functionName == 'GPS') {
|
||||
config.sensors_baudrate = baudrate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return publicScope;
|
||||
})();
|
|
@ -83,6 +83,8 @@ var Settings = (function () {
|
|||
if (input.prop('tagName') == 'SELECT' || s.setting.table) {
|
||||
if (input.attr('type') == 'checkbox') {
|
||||
input.prop('checked', s.value > 0);
|
||||
} else if (input.attr('type') == 'radio') {
|
||||
input.prop( 'checked', s.value == input.attr('value') );
|
||||
} else {
|
||||
input.empty();
|
||||
let option = null;
|
||||
|
@ -537,6 +539,10 @@ var Settings = (function () {
|
|||
if (setting.table) {
|
||||
if (input.attr('type') == 'checkbox') {
|
||||
value = input.prop('checked') ? 1 : 0;
|
||||
} else if (input.attr('type') == 'radio') {
|
||||
if (input.prop('checked')) {
|
||||
value = parseInt(input.val());
|
||||
}
|
||||
} else {
|
||||
value = parseInt(input.val());
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*global $*/
|
||||
'use strict';
|
||||
|
||||
var Waypoint = function (number, action, lat, lon, alt=0, p1=0, p2=0, p3=0, endMission=0, isUsed=true, isAttached=false, attachedId="") {
|
||||
let Waypoint = function (number, action, lat, lon, alt=0, p1=0, p2=0, p3=0, endMission=0, isUsed=true, isAttached=false, attachedId="", multiMissionIdx = 0) {
|
||||
|
||||
var self = {};
|
||||
let layerNumber = "undefined";
|
||||
|
@ -136,6 +136,14 @@ var Waypoint = function (number, action, lat, lon, alt=0, p1=0, p2=0, p3=0, endM
|
|||
attachedNumber = data;
|
||||
};
|
||||
|
||||
self.setMultiMissionIdx = function(data) {
|
||||
multiMissionIdx = data;
|
||||
}
|
||||
|
||||
self.getMultiMissionIdx = function() {
|
||||
return multiMissionIdx;
|
||||
}
|
||||
|
||||
self.getElevation = async function (globalSettings) {
|
||||
let elevation = "N/A";
|
||||
if (globalSettings.mapProviderType == 'bing') {
|
||||
|
|
|
@ -442,7 +442,7 @@ let WaypointCollection = function () {
|
|||
|
||||
let elevation = "N/A";
|
||||
if (globalSettings.mapProviderType == 'bing') {
|
||||
let elevationEarthModel = $('#elevationEarthModel').prop("checked") ? "sealevel" : "ellipsoid";
|
||||
let elevationEarthModel = $('#elevationEarthModel').prop("checked") ? "ellipsoid" : "sealevel";
|
||||
|
||||
if (point2measure.length >1) {
|
||||
const response = await fetch('http://dev.virtualearth.net/REST/v1/Elevation/Polyline?points='+point2measure+'&heights='+elevationEarthModel+'&samples='+String(samples+1)+'&key='+globalSettings.mapApiKey);
|
||||
|
|
|
@ -101,7 +101,7 @@
|
|||
"message": "Documentation & Support"
|
||||
},
|
||||
"tabSetup": {
|
||||
"message": "Setup"
|
||||
"message": "Status"
|
||||
},
|
||||
"tabCalibration": {
|
||||
"message": "Calibration"
|
||||
|
@ -867,7 +867,7 @@
|
|||
"message": "External PWM servo driver"
|
||||
},
|
||||
"featurePWM_SERVO_DRIVERTip": {
|
||||
"message": "Use external PCA9685 PMW driver to connect up to 16 servos to flight controller. PCA9685 has to be connected to enable this feature."
|
||||
"message": "Use external PCA9685 PWM driver to connect up to 16 servos to flight controller. PCA9685 has to be connected to enable this feature."
|
||||
},
|
||||
"featureRSSI_ADCTip": {
|
||||
"message": "RSSI is a measurement of signal strength and is very handy so you know when your aircraft is going out of range or if it is suffering RF interference."
|
||||
|
@ -2075,6 +2075,12 @@
|
|||
"gpsSignalStr": {
|
||||
"message": "Signal Strength"
|
||||
},
|
||||
"gpsPort": {
|
||||
"message": "Serial Port"
|
||||
},
|
||||
"gpsBaud": {
|
||||
"message": "Baud Rate"
|
||||
},
|
||||
"magnetometerHead": {
|
||||
"message": "Alignment tool"
|
||||
},
|
||||
|
@ -3010,8 +3016,8 @@
|
|||
"posholdHoverThrottle": {
|
||||
"message": "Hover throttle"
|
||||
},
|
||||
"posholdHoverMidThrottle": {
|
||||
"message": "Use mid. throttle for ALTHOLD"
|
||||
"navmcAltholdThrottle": {
|
||||
"message": "Stick position for althold hover"
|
||||
},
|
||||
"mcWpSlowdown": {
|
||||
"message": "Slow down when approaching waypoint"
|
||||
|
@ -3388,6 +3394,54 @@
|
|||
"fixedWingNavigationConfiguration": {
|
||||
"message": "Fixed Wing Navigation Settings"
|
||||
},
|
||||
"fixedWingLandingConfiguration": {
|
||||
"message": "Fixed Wing Landing Settings"
|
||||
},
|
||||
"MissionPlannerOnlyOneLandWp": {
|
||||
"message": "You can set only one LAND Waypoint per mission."
|
||||
},
|
||||
"fwLandApproachLength" : {
|
||||
"message": "Final approach length"
|
||||
},
|
||||
"fwLandApproachLengthHelp": {
|
||||
"message": "Length of the final approach, also includes the glide and intercept phase. This is the length from the safe home point to the final turn point."
|
||||
},
|
||||
"fwLandFinalApproachPitch2throttle": {
|
||||
"message": "Modifier for pitch to throttle ratio at final approach"
|
||||
},
|
||||
"fwLandFinalApproachPitch2throttleHelp": {
|
||||
"message": "This value is multiplied by the \"pitch to throttle ratio\" value during the final approach. Allows the velocity to be reduced."
|
||||
},
|
||||
"fwLandGlideAlt" : {
|
||||
"message": "Initial altitude of the glide phase"
|
||||
},
|
||||
"fwLandGlideAltHelp" : {
|
||||
"message": "At this altitude (measured from the altitude of the landing point) the engine is switched off and the aircraft glides from here."
|
||||
},
|
||||
"fwLandFlareAlt" : {
|
||||
"message": "Initial altitude of the flare phase"
|
||||
},
|
||||
"fwLandFlareAltHelp" : {
|
||||
"message": "At this altitude (measured from the altitude of the landing point) the last phase of landing is executed."
|
||||
},
|
||||
"fwLandGlidePitch" : {
|
||||
"message": "Pitch value for glide phase"
|
||||
},
|
||||
"fwLandGlidePitchHelp" : {
|
||||
"message": "This pitch angle is held during the glide phase."
|
||||
},
|
||||
"fwLandFlarePitch" : {
|
||||
"message": "Pitch value for flare phase"
|
||||
},
|
||||
"fwLandFlarePitchHelp" : {
|
||||
"message": "This pitch angle is held during the flare phase."
|
||||
},
|
||||
"fwLandMaxTailwind": {
|
||||
"message": "Max. tailwind"
|
||||
},
|
||||
"fwLandMaxTailwindHelp": {
|
||||
"message": "This value is used when no headwind landing is possible and wind speeds below this value are ignored (inaccuracies in INAV wind measurement)."
|
||||
},
|
||||
"osd_unsupported_msg1": {
|
||||
"message": "Your flight controller isn't responding to OSD commands. This probably means that it does not have an integrated OSD."
|
||||
},
|
||||
|
@ -3472,6 +3526,12 @@
|
|||
"osd_hud_settings": {
|
||||
"message": "Heads up Display settings"
|
||||
},
|
||||
"osd_custom_element_settings": {
|
||||
"message": "Custom OSD elements"
|
||||
},
|
||||
"custom_element": {
|
||||
"message": "Custom element"
|
||||
},
|
||||
"osd_hud_settings_HELP": {
|
||||
"message": "This section allows tweaking the behavior of HUD elements."
|
||||
},
|
||||
|
@ -4342,6 +4402,12 @@
|
|||
"SafehomeSafeRadius": {
|
||||
"message": "Safe Radius (m):"
|
||||
},
|
||||
"SafehomeFwAppraoch": {
|
||||
"message": "FW Approach:"
|
||||
},
|
||||
"safehomeEdit": {
|
||||
"message": "Edit Safehome"
|
||||
},
|
||||
"missionTitleHide": {
|
||||
"message": "Hide"
|
||||
},
|
||||
|
@ -4372,6 +4438,9 @@
|
|||
"missionTitleSaveEepromMission": {
|
||||
"message": "Save Eeprom mission"
|
||||
},
|
||||
"missionTitleDelete": {
|
||||
"message": "Delete"
|
||||
},
|
||||
"missionTitleRemoveAll": {
|
||||
"message": "Remove all"
|
||||
},
|
||||
|
@ -4396,6 +4465,60 @@
|
|||
"missionTitlEditMission": {
|
||||
"message": "Edit Mission"
|
||||
},
|
||||
"MissionPlannerFwLAndingAltitudeChangeReset": {
|
||||
"message": "Altitude below min land altitude. Change ignored"
|
||||
},
|
||||
"missionWpType": {
|
||||
"message": "Type:"
|
||||
},
|
||||
"missionWpLat": {
|
||||
"message": "Lat:"
|
||||
},
|
||||
"missionWpLon": {
|
||||
"message": "Lon:"
|
||||
},
|
||||
"missionSeaLevelRef": {
|
||||
"message": "Sea level Ref: "
|
||||
},
|
||||
"missionElevation": {
|
||||
"message": "Elevation (m):"
|
||||
},
|
||||
"missionNA": {
|
||||
"message": "N/A"
|
||||
},
|
||||
"missionGroundDist": {
|
||||
"message": "Grd Dist (m):"
|
||||
},
|
||||
"missionParameter1": {
|
||||
"message": "Parameter 1:"
|
||||
},
|
||||
"missionParameter2": {
|
||||
"message": "Parameter 2:"
|
||||
},
|
||||
"missionUserActions": {
|
||||
"message": "User Actions:"
|
||||
},
|
||||
"missionFwLandingSettings": {
|
||||
"message": "Fixed Wing landing settings:"
|
||||
},
|
||||
"missionFwApproachAlt": {
|
||||
"message": "Approach Alt: (cm):"
|
||||
},
|
||||
"missionFwLandAlt": {
|
||||
"message": "Land Alt: (cm):"
|
||||
},
|
||||
"missionFwApproachDir": {
|
||||
"message": "Approach direction:"
|
||||
},
|
||||
"missionFwLandHeading1": {
|
||||
"message": "Heading 1: (deg):"
|
||||
},
|
||||
"missionFwLandHeading2": {
|
||||
"message": "Heading 2: (deg):"
|
||||
},
|
||||
"missionExclusive": {
|
||||
"message": "Excl."
|
||||
},
|
||||
"missionRTHsettingsTitle": {
|
||||
"message": "RTH settings"
|
||||
},
|
||||
|
@ -4411,6 +4534,12 @@
|
|||
"missionSafehomeHead": {
|
||||
"message": "Safe Home manager"
|
||||
},
|
||||
"missionSafehomeAvailableSafehomes" : {
|
||||
"message": "Available Safehomes:"
|
||||
},
|
||||
"missionSafehomeMaxSafehomesReached": {
|
||||
"message": "Maximum number of safehomes reached."
|
||||
},
|
||||
"missionMultiMissionHead": {
|
||||
"message": "Multi Missions"
|
||||
},
|
||||
|
@ -4925,10 +5054,10 @@
|
|||
"message": "Illegal state. Restart required."
|
||||
},
|
||||
"motor_direction_inverted": {
|
||||
"message": "Normal motor direction / Props In configuration"
|
||||
"message": "Normal motor direction / Props-in configuration"
|
||||
},
|
||||
"motor_direction_isInverted": {
|
||||
"message": "Reversed motor direction / Props Out configuration"
|
||||
"message": "Reversed motor direction / Props-out configuration"
|
||||
},
|
||||
"motor_direction_inverted_hint": {
|
||||
"message": "Enable if the motor direction is reversed and the props are mounted in the opposite direction."
|
||||
|
|
405
package-lock.json
generated
405
package-lock.json
generated
File diff suppressed because it is too large
Load diff
Binary file not shown.
Binary file not shown.
|
@ -236,10 +236,17 @@
|
|||
margin-bottom: 5px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.tab-mission-control .point-label {
|
||||
width: 80px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.tab-mission-control .point-label-safehome {
|
||||
width: 120px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.tab-mission-control .point-radio input{
|
||||
width: 25px;
|
||||
padding-left: 3px;
|
||||
|
@ -511,7 +518,6 @@
|
|||
|
||||
.tab-mission-control .fill{
|
||||
border:none;
|
||||
border-bottom:5px dotted #88CC3E;
|
||||
display:inline-block;
|
||||
width:20px;
|
||||
}
|
||||
|
@ -519,9 +525,6 @@
|
|||
.tab-mission-control .textLegend{
|
||||
margin:2px;
|
||||
}
|
||||
.tab-mission-control .valueLegend{
|
||||
float:right;
|
||||
}
|
||||
|
||||
.tab-mission-control .userActionContainer {
|
||||
display: inline-block;
|
||||
|
|
|
@ -720,3 +720,17 @@ button {
|
|||
.tab-osd .unit_wrapper {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.osdCustomElement_main_table {
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.osdCustomElement_main_table td{
|
||||
max-width: 80px;
|
||||
}
|
||||
|
||||
.osdCustomElement_main_table select, .osdCustomElement_main_table input{
|
||||
width: 100% !important;
|
||||
}
|
|
@ -68,6 +68,49 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="config-section gui_box grey">
|
||||
<div class="gui_box_titlebar">
|
||||
<div class="spacer_box_title" data-i18n="fixedWingLandingConfiguration"></div>
|
||||
</div>
|
||||
<div class="spacer_box">
|
||||
<div class="number">
|
||||
<input id="fwLandApproachLength" type="number" data-unit="cm" data-setting="nav_fw_land_approach_length" data-setting-multiplier="1" step="1" min="100" max="100000" />
|
||||
<label for="fwLandApproachLength"><span data-i18n="fwLandApproachLength"></span></label>
|
||||
<div for="fwLandApproachLength" class="helpicon cf_tip" data-i18n_title="fwLandApproachLengthHelp"></div>
|
||||
</div>
|
||||
<div class="number">
|
||||
<input id="fwLandFinalApproachPitch2throttle" type="number" data-unit="percent" data-setting="nav_fw_land_final_approach_pitch2throttle_mod" data-setting-multiplier="1" step="1" min="100" max="400" />
|
||||
<label for="fwLandFinalApproachPitch2throttle"><span data-i18n="fwLandFinalApproachPitch2throttle"></span></label>
|
||||
<div for="fwLandFinalApproachPitch2throttle" class="helpicon cf_tip" data-i18n_title="fwLandFinalApproachPitch2throttleHelp"></div>
|
||||
</div>
|
||||
<div class="number">
|
||||
<input id="fwLandGlideAlt" type="number" data-unit="cm" data-setting="nav_fw_land_glide_alt" data-setting-multiplier="1" step="1" min="100" max="5000" />
|
||||
<label for="fwLandGlideAlt"><span data-i18n="fwLandGlideAlt"></span></label>
|
||||
<div for="fwLandGlideAlt" class="helpicon cf_tip" data-i18n_title="fwLandGlideAltHelp"></div>
|
||||
</div>
|
||||
<div class="number">
|
||||
<input id="fwLandFlareAlt" type="number" data-unit="cm" data-setting="nav_fw_land_flare_alt" data-setting-multiplier="1" step="1" min="0" max="10000" />
|
||||
<label for="fwLandFlareAlt"><span data-i18n="fwLandFlareAlt"></span></label>
|
||||
<div for="fwLandFlareAlt" class="helpicon cf_tip" data-i18n_title="fwLandFlareAltHelp"></div>
|
||||
</div>
|
||||
<div class="number">
|
||||
<input id="fwLandGlidePitch" type="number" data-unit="deg" data-setting="nav_fw_land_glide_pitch" data-setting-multiplier="1" step="1" min="0" max="45" />
|
||||
<label for="fwLandGlidePitch"><span data-i18n="fwLandGlidePitch"></span></label>
|
||||
<div for="fwLandGlidePitch" class="helpicon cf_tip" data-i18n_title="fwLandGlidePitchHelp"></div>
|
||||
</div>
|
||||
<div class="number">
|
||||
<input id="fwLandFlarePitch" type="number" data-unit="deg" data-setting="nav_fw_land_flare_pitch" data-setting-multiplier="1" step="1" min="0" max="45" />
|
||||
<label for="fwLandFlarePitch"><span data-i18n="fwLandFlarePitch"></span></label>
|
||||
<div for="fwLandFlarePitch" class="helpicon cf_tip" data-i18n_title="fwLandFlarePitchHelp"></div>
|
||||
</div>
|
||||
<div class="number">
|
||||
<input id="fwLandMaxTailwind" type="number" data-unit="cms" data-setting="nav_fw_land_max_tailwind" data-setting-multiplier="1" step="1" min="0" max="3000" />
|
||||
<label for="fwLandMaxTailwind"><span data-i18n="fwLandMaxTailwind"></span></label>
|
||||
<div for="fwLandMaxTailwind" class="helpicon cf_tip" data-i18n_title="fwLandMaxTailwindHelp"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="config-section gui_box grey">
|
||||
<div class="gui_box_titlebar">
|
||||
<div class="spacer_box_title" data-i18n="powerConfiguration"></div>
|
||||
|
@ -257,10 +300,12 @@
|
|||
<label for="max-bank-angle"><span data-i18n="posholdMaxBankAngle"></span></label>
|
||||
<div for="max-bank-angle" class="helpicon cf_tip" data-i18n_title="posholdMaxBankAngleHelp"></div>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" class="toggle update_preview" id="use-mid-throttle" data-setting="nav_use_midthr_for_althold" data-live="true" />
|
||||
<label for="use-mid-throttle"><span data-i18n="posholdHoverMidThrottle"></span></label>
|
||||
|
||||
<div class="select">
|
||||
<select id="nav-mc-althold-throttle" data-setting="nav_mc_althold_throttle"></select>
|
||||
<label for="nav-mc-althold-throttle"><span data-i18n="navmcAltholdThrottle"></span></label>
|
||||
</div>
|
||||
|
||||
<div class="number">
|
||||
<input id="hover-throttle" type="number" data-unit="us" data-setting="nav_mc_hover_thr" data-setting-multiplier="1" step="1" min="1000" max="2000" />
|
||||
<label for="hover-throttle"><span data-i18n="posholdHoverThrottle"></span></label>
|
||||
|
|
|
@ -14,7 +14,6 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
|
||||
var loadChain = [
|
||||
mspHelper.loadFeatures,
|
||||
mspHelper.loadArmingConfig,
|
||||
mspHelper.loadSensorAlignment,
|
||||
mspHelper.loadAdvancedConfig,
|
||||
mspHelper.loadVTXConfig,
|
||||
|
@ -31,7 +30,6 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
|
||||
var saveChain = [
|
||||
mspHelper.saveAccTrim,
|
||||
mspHelper.saveArmingConfig,
|
||||
mspHelper.saveAdvancedConfig,
|
||||
mspHelper.saveVTXConfig,
|
||||
mspHelper.saveCurrentMeterConfig,
|
||||
|
@ -260,8 +258,6 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
|||
//UPDATE: moved to GPS tab and hidden
|
||||
//MISC.mag_declination = parseFloat($('#mag_declination').val());
|
||||
|
||||
ARMING_CONFIG.auto_disarm_delay = parseInt($('input[name="autodisarmdelay"]').val());
|
||||
|
||||
MISC.battery_cells = parseInt($('#cells').val());
|
||||
MISC.voltage_source = parseInt($('#voltagesource').val());
|
||||
MISC.vbatdetectcellvoltage = parseFloat($('#celldetectvoltage').val());
|
||||
|
|
|
@ -20,6 +20,14 @@
|
|||
<label for="feature-7"><span data-i18n="featureGPS"></span></label>
|
||||
<div for="feature-7" class="helpicon cf_tip" data-i18n_title="featureGPSTip"></div>
|
||||
</div>
|
||||
<div class="select">
|
||||
<select id="gps_port" class="gps_port"></select>
|
||||
<label for="gps_port"><span data-i18n="gpsPort"></span></label>
|
||||
</div>
|
||||
<div class="select">
|
||||
<select id="gps_baud" class="gps_baud"></select>
|
||||
<label for="gps_baud"><span data-i18n="gpsBaud"></span></label>
|
||||
</div>
|
||||
<div class="select">
|
||||
<select id="gps_protocol" class="gps_protocol">
|
||||
<!-- list generated here -->
|
||||
|
|
54
tabs/gps.js
54
tabs/gps.js
|
@ -36,6 +36,7 @@ TABS.gps.initialize = function (callback) {
|
|||
|
||||
var loadChain = [
|
||||
mspHelper.loadFeatures,
|
||||
mspHelper.loadSerialPorts,
|
||||
mspHelper.loadMiscV2
|
||||
];
|
||||
|
||||
|
@ -47,6 +48,7 @@ TABS.gps.initialize = function (callback) {
|
|||
|
||||
var saveChain = [
|
||||
mspHelper.saveMiscV2,
|
||||
mspHelper.saveSerialPorts,
|
||||
saveSettings,
|
||||
mspHelper.saveToEeprom
|
||||
];
|
||||
|
@ -91,6 +93,42 @@ TABS.gps.initialize = function (callback) {
|
|||
|
||||
helper.features.updateUI($('.tab-gps'), FEATURES);
|
||||
|
||||
//Generate serial port options
|
||||
let $port = $('#gps_port');
|
||||
let $baud = $('#gps_baud');
|
||||
|
||||
let ports = helper.serialPortHelper.getPortIdentifiersForFunction('GPS');
|
||||
|
||||
let currentPort = null;
|
||||
|
||||
if (ports.length == 1) {
|
||||
currentPort = ports[0];
|
||||
}
|
||||
|
||||
let availablePorts = helper.serialPortHelper.getPortList();
|
||||
|
||||
//Generate port select
|
||||
$port.append('<option value="-1">NONE</option>');
|
||||
for (let i = 0; i < availablePorts.length; i++) {
|
||||
let port = availablePorts[i];
|
||||
$port.append('<option value="' + port.identifier + '">' + port.displayName + '</option>');
|
||||
}
|
||||
|
||||
//Generate baud select
|
||||
helper.serialPortHelper.getBauds('SENSOR').forEach(function (baud) {
|
||||
$baud.append('<option value="' + baud + '">' + baud + '</option>');
|
||||
});
|
||||
|
||||
//Select defaults
|
||||
if (currentPort !== null) {
|
||||
$port.val(currentPort);
|
||||
let portConfig = helper.serialPortHelper.getPortByIdentifier(currentPort);
|
||||
$baud.val(portConfig.sensors_baudrate);
|
||||
} else {
|
||||
$port.val(-1);
|
||||
$baud.val(helper.serialPortHelper.getRuleByName('GPS').defaultBaud);
|
||||
}
|
||||
|
||||
// generate GPS
|
||||
var gpsProtocols = FC.getGpsProtocols();
|
||||
var gpsSbas = FC.getGpsSbasProviders();
|
||||
|
@ -358,6 +396,22 @@ TABS.gps.initialize = function (callback) {
|
|||
|
||||
|
||||
$('a.save').on('click', function () {
|
||||
if (FC.isFeatureEnabled('GPS', features)) {
|
||||
googleAnalytics.sendEvent('Setting', 'GpsProtocol', gpsProtocols[MISC.gps_type]);
|
||||
googleAnalytics.sendEvent('Setting', 'GpsSbas', gpsSbas[MISC.gps_ubx_sbas]);
|
||||
}
|
||||
|
||||
googleAnalytics.sendEvent('Setting', 'GPSEnabled', FC.isFeatureEnabled('GPS', features) ? "true" : "false");
|
||||
|
||||
for (var i = 0; i < features.length; i++) {
|
||||
var featureName = features[i].name;
|
||||
if (FC.isFeatureEnabled(featureName, features)) {
|
||||
googleAnalytics.sendEvent('Setting', 'Feature', featureName);
|
||||
}
|
||||
}
|
||||
|
||||
helper.serialPortHelper.set($port.val(), 'GPS', $baud.val());
|
||||
|
||||
helper.features.reset();
|
||||
helper.features.fromUI($('.tab-gps'));
|
||||
helper.features.execute(function () {
|
||||
|
|
|
@ -86,6 +86,14 @@
|
|||
<label class="point-label" for="MPdefaultSafeRangeSH" data-i18n="missionDefaultSafeRangeSH"></label>
|
||||
<input id="MPdefaultSafeRangeSH" type="text" value="0" required>
|
||||
</div>
|
||||
<div class="point">
|
||||
<label class="point-label" for="MPdefaultFwApproachAlt">FW Approach Alt (m): </label>
|
||||
<input id="MPdefaultFwApproachAlt" type="text" value="0" required>
|
||||
</div>
|
||||
<div class="point">
|
||||
<label class="point-label" for="MPdefaultLandAlt">FW Land Alt (m): </label>
|
||||
<input id="MPdefaultLandAlt" type="text" value="0" required>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -167,7 +175,7 @@
|
|||
</div>
|
||||
<div class="point" id="elevationEarthModelclass" style="display: none">
|
||||
<label class="spacer_box_title" for="elevationEarthModel" data-i18n="missionEllipsoidEarthDEMModel"></label>
|
||||
<input id="elevationEarthModel" type="checkbox" value="0" class="togglemedium" required>
|
||||
<input id="elevationEarthModel" type="checkbox" value="0" class="togglemedium" checked required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -178,39 +186,96 @@
|
|||
<div id="showHideSafehomeButton">
|
||||
<a class="ic_hide" href="#" i18n_title="missionTitleHide"></a>
|
||||
</div>
|
||||
<a id="cancelSafehome" class="ic_cancel" href="#" i18n_title="missionTitleCancel"></a>
|
||||
<a id="cancelSafehome" class="ic_cancel" href="#" title="Cancel"></a>
|
||||
<a id="addSafehome" class="ic_add" href="#" i18n_title="missionTitleAdd"></a>
|
||||
<a id="saveEepromSafehomeButton" class="ic_save2Eprom" href="#" i18n_title="missionTitleSaveEepromSafehome"></a>
|
||||
<a id="loadEepromSafehomeButton" class="ic_loadFromEprom" href="#" i18n_title="missionTitleLoadEepromSafehome"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="spacer" id="SafehomeContent">
|
||||
<div>
|
||||
<table class="safehomesTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 40px" data-i18n="SafehomeSelected"></th>
|
||||
<th style="width: 40px" data-i18n="SafehomeId"></th>
|
||||
<th style="width: 60px" data-i18n="SafehomeEnabled"></th>
|
||||
<th style="width: 140px" data-i18n="SafehomeLat"></th>
|
||||
<th style="width: 140px" data-i18n="SafehomeLon"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="safehomesTableBody">
|
||||
</tbody>
|
||||
</table>
|
||||
<div style="padding-bottom: 2px;">
|
||||
<span data-i18n="missionSafehomeAvailableSafehomes"></span>
|
||||
<span id="availableSafehomes"></span>
|
||||
</div>
|
||||
<div id="SafehomeContentBox" style="display: none;">
|
||||
<div class="gui_box grey missionPlannerSafehomeBox">
|
||||
<div class="gui_box_titlebar">
|
||||
<div class="spacer_box_title" data-i18n="safehomeEdit"></div>
|
||||
<div class="btnMenu btnMenuIcon">
|
||||
<div class="btnMenu-danger">
|
||||
<a id="deleteSafehome" class="ic_removeAll" href="#" i18n_title="missionTitleDelete"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="spacer" id="safehomeSingelContent">
|
||||
<div class="point">
|
||||
<label class="point-label-safehome" for="safeHomeLatitude" data-i18n="gpsLat"></label>
|
||||
<input type="number" id="safehomeLatitude"></input>
|
||||
</div>
|
||||
<div class="point">
|
||||
<label class="point-label-safehome" for="safehomeLongitude" data-i18n="gpsLon"></label>
|
||||
<input type="number" id="safehomeLongitude"></input>
|
||||
</div>
|
||||
<div class="point">
|
||||
<span style="font-weight: bold" data-i18n="missionFwLandingSettings"></span>
|
||||
</div>
|
||||
<div class="point">
|
||||
<label class="point-label-safehome" for="safehomeSeaLevelRef" data-i18n="missionSeaLevelRef"></label>
|
||||
<input id="safehomeSeaLevelRef" type="checkbox" value="0" class="togglemedium" required>
|
||||
</div>
|
||||
<div class="point">
|
||||
<label class="point-label-safehome" for="safehomeApproachAlt" data-i18n="missionFwApproachAlt"></label>
|
||||
<input type="number" id="safehomeApproachAlt"></input>
|
||||
<span id="safehomeApproachAltM"></span>
|
||||
</div>
|
||||
<div class="point">
|
||||
<label class="point-label-safehome" for="safehomeLandAlt" data-i18n="missionFwLandAlt"></label>
|
||||
<input type="number" id="safehomeLandAlt"></input>
|
||||
<span id="safehomeLandAltM"></span>
|
||||
</div>
|
||||
<div class="point">
|
||||
<label class="point-label-safehome" for="safehomeElevation" data-i18n="missionElevation"></label>
|
||||
<span id="safehomeElevation"></span>
|
||||
</div>
|
||||
<div class="point">
|
||||
<label class="point-label-safehome" for="geozoneApproachDirection" data-i18n="missionFwApproachDir"></label>
|
||||
<select name="zoneAction" id="geozoneApproachDirection">
|
||||
<option value="0">Left</option>
|
||||
<option value="1">Right</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="point">
|
||||
<label class="point-label-safehome" for="safehomeLandHeading1" data-i18n="missionFwLandHeading1"></label>
|
||||
<input type="number" id="safehomeLandHeading1"></input>
|
||||
<input id="safehomeLandHeading1Excl" type="checkbox" value="0" class="togglemedium" required>
|
||||
<span data-i18n="missionExclusive"></span>
|
||||
</div>
|
||||
<div class="point">
|
||||
<label class="point-label-safehome" for="safehomeLandHeading2" data-i18n="missionFwLandHeading2"></label>
|
||||
<input type="number" id="safehomeLandHeading2"></input>
|
||||
<input id="safehomeLandHeading2Excl" type="checkbox" value="0" class="togglemedium" required>
|
||||
<span data-i18n="missionExclusive"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="spacer" id="safehomeLegend">
|
||||
<span><b data-i18n="SafehomeLegend"></b></span>
|
||||
<div class="legendItem">
|
||||
<span class="fill" style="border-bottom-color:#900C3F"></span>
|
||||
<span class="fill" style="border-bottom:5px dotted #900C3F;"></span>
|
||||
<span class="textLegend" data-i18n="SafehomeMaxDistance"></span>
|
||||
<span id="safeHomeMaxDistance" class="valueLegend"></span>
|
||||
<span id="safeHomeMaxDistance"></span>
|
||||
</div>
|
||||
<div class="legendItem">
|
||||
<span class="fill"></span>
|
||||
<span class="fill" style="border-bottom:5px dotted #88CC3E;"></span>
|
||||
<span class="textLegend" data-i18n="SafehomeSafeRadius"></span>
|
||||
<span id="SafeHomeSafeDistance" class="valueLegend"></span>
|
||||
<span id="SafeHomeSafeDistance"></span>
|
||||
</div>
|
||||
<div class="legendItem">
|
||||
<span class="fill" style="border-bottom:5px solid #f78a05;border-top:5px solid #0025a1;"></span>
|
||||
<span class="textLegend" data-i18n="SafehomeFwAppraoch"></span>
|
||||
<span id="SafeHomeSafeDistance"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -234,7 +299,7 @@
|
|||
<div class="spacer" id="WPeditContent">
|
||||
<input type="hidden" name="pointNumber" value="">
|
||||
<div class="point">
|
||||
<label class="point-label" for="pointType">Type: </label>
|
||||
<label class="point-label" for="pointType" data-i18n="missionWpType"></label>
|
||||
<select name="type" id="pointType">
|
||||
<!--<option value="1">Home</option>-->
|
||||
<option value="1">Waypoint</option>
|
||||
|
@ -248,39 +313,39 @@
|
|||
</select>
|
||||
</div>
|
||||
<div class="point">
|
||||
<label class="point-label" for="pointLat">Lat: </label>
|
||||
<label class="point-label" for="pointLat" data-i18n="missionWpLat"></label>
|
||||
<input id="pointLat" type="text" value="0.0" required>
|
||||
</div>
|
||||
<div class="point">
|
||||
<label class="point-label" for="pointLon">Lon: </label>
|
||||
<label class="point-label" for="pointLon" data-i18n="missionWpLon"></label>
|
||||
<input id="pointLon" type="text" value="0.0" required>
|
||||
</div>
|
||||
<div class="point">
|
||||
<label class="point-label" for="pointAlt">Alt (cm): </label>
|
||||
<label class="point-label" for="pointAlt" data-i18n="missionDefaultPointAlt"></label>
|
||||
<input id="pointAlt" type="text" value="0" required><span id="altitudeInMeters"></span>
|
||||
</div>
|
||||
<div class="point" id="pointP3class" style="display: none">
|
||||
<label class="point-label" for="pointP3Alt">Sea level Ref: </label>
|
||||
<label class="point-label" for="pointP3Alt" data-i18n="missionSeaLevelRef"></label>
|
||||
<input id="pointP3Alt" type="checkbox" value="0" class="togglemedium" checked required>
|
||||
</div>
|
||||
<div class="point" id="elevationAtWP" style="display: none">
|
||||
<label class="point-label">Elevation (m): </label>
|
||||
<span id="elevationValueAtWP">N/A</span>
|
||||
<label class="point-label" data-i18n="missionElevation"></label>
|
||||
<span id="elevationValueAtWP" data-i18n="missionNA"></span>
|
||||
</div>
|
||||
<div class="point" id="groundClearanceAtWP" style="display: none">
|
||||
<label class="point-label">Grd Dist (m): </label>
|
||||
<span id="groundClearanceValueAtWP">N/A</span>
|
||||
<label class="point-label" data-i18n="missionGroundDist"></label>
|
||||
<span id="groundClearanceValueAtWP" data-i18n="missionNA"></span>
|
||||
</div>
|
||||
<div class="point" id="pointP1class" style="display: none">
|
||||
<label class="point-label" for="pointP1">Parameter 1: </label>
|
||||
<label class="point-label" for="pointP1" data-i18n="missionParameter1"></label>
|
||||
<input id="pointP1" type="text" value="0" required>
|
||||
</div>
|
||||
<div class="point" id="pointP2class" style="display: none">
|
||||
<label class="point-label" for="pointP2">Parameter 2: </label>
|
||||
<label class="point-label" for="pointP2" data-i18n="missionParameter1"></label>
|
||||
<input id="pointP2" type="text" value="0" required>
|
||||
</div>
|
||||
<div class="point" id="pointP3UserActionClass" style="display: none">
|
||||
<label class="point-label" for="pointP3UserAction">User Actions: </label>
|
||||
<label class="point-label" for="pointP3UserAction" data-i18n="missionUserActions"></label>
|
||||
<div class="userActionContainer">1 <input id="pointP3UserAction1" type="checkbox" value="0" class="togglemedium" checked required></div>
|
||||
<div class="userActionContainer">2 <input id="pointP3UserAction2" type="checkbox" value="0" class="togglemedium" checked required></div>
|
||||
<div class="userActionContainer">3 <input id="pointP3UserAction3" type="checkbox" value="0" class="togglemedium" checked required></div>
|
||||
|
@ -305,7 +370,74 @@
|
|||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="wpFwLanding" style="display: none;">
|
||||
<div class="point">
|
||||
<span style="font-weight: bold" data-i18n="missionFwLandingSettings"></span>
|
||||
</div>
|
||||
<div class="point">
|
||||
<label class="point-label-safehome" for="wpApproachAlt" data-i18n="missionFwApproachAlt"></label>
|
||||
<input type="number" id="wpApproachAlt"></input>
|
||||
<span id="wpApproachAltM"></span>
|
||||
</div>
|
||||
<div class="point">
|
||||
<label class="point-label-safehome" for="wpLandAlt" data-i18n="missionFwLandAlt"></label>
|
||||
<input type="number" id="wpLandAlt"></input>
|
||||
<span id="wpLandAltM"></span>
|
||||
</div>
|
||||
<div class="point">
|
||||
<label class="point-label-safehome" for="wpApproachDirection" data-i18n="missionFwApproachDir"></label>
|
||||
<select name="wpApproachDirection" id="wpApproachDirection">
|
||||
<option value="0">Left</option>
|
||||
<option value="1">Right</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="point">
|
||||
<label class="point-label-safehome" for="wpLandHeading1" data-i18n="missionFwLandHeading1"></label>
|
||||
<input type="number" id="wpLandHeading1"></input>
|
||||
<input id="wpLandHeading1Excl" type="checkbox" value="0" class="togglemedium" checked required>
|
||||
<span data-i18n="missionExclusive"></span>
|
||||
</div>
|
||||
<div class="point">
|
||||
<label class="point-label-safehome" for="wpLandHeading2" data-i18n="missionFwLandHeading1"></label>
|
||||
<input type="number" id="wpLandHeading2"></input>
|
||||
<input id="wpLandHeading2Excl" type="checkbox" value="0" class="togglemedium" checked required>
|
||||
<span data-i18n="missionExclusive"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="wpFwLanding" style="display: none;">
|
||||
<div class="point">
|
||||
<span style="font-weight: bold" data-i18n="missionFwLandingSettings"></span>
|
||||
</div>
|
||||
<div class="point">
|
||||
<label class="point-label-safehome" for="wpApproachAlt" data-i18n="missionFwApproachAlt"></label>
|
||||
<input type="number" id="wpApproachAlt"></input>
|
||||
<span id="wpApproachAltM"></span>
|
||||
</div>
|
||||
<div class="point">
|
||||
<label class="point-label-safehome" for="wpLandAlt" data-i18n="missionFwLandAlt"></label>
|
||||
<input type="number" id="wpLandAlt"></input>
|
||||
<span id="wpLandAltM"></span>
|
||||
</div>
|
||||
<div class="point">
|
||||
<label class="point-label-safehome" for="wpApproachDirection" data-i18n="missionFwApproachDir"></label>
|
||||
<select name="wpApproachDirection" id="wpApproachDirection">
|
||||
<option value="0">Left</option>
|
||||
<option value="1">Right</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="point">
|
||||
<label class="point-label-safehome" for="wpLandHeading1" data-i18n="missionFwLandHeading1"></label>
|
||||
<input type="number" id="wpLandHeading1"></input>
|
||||
<input id="wpLandHeading1Excl" type="checkbox" value="0" class="togglemedium" checked required>
|
||||
<span data-i18n="missionExclusive"></span>
|
||||
</div>
|
||||
<div class="point">
|
||||
<label class="point-label-safehome" for="wpLandHeading2" data-i18n="missionFwLandHeading1"></label>
|
||||
<input type="number" id="wpLandHeading2"></input>
|
||||
<input id="wpLandHeading2Excl" type="checkbox" value="0" class="togglemedium" checked required>
|
||||
<span data-i18n="missionExclusive"></span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="point-radio" id="pointOptionclass" style="display: none">
|
||||
<div class="radio-line">
|
||||
<input type="radio" id="Options_None" name="Options" value="None" checked>
|
||||
|
@ -332,7 +464,6 @@
|
|||
<input id="Options_HeadingHead" type="text" value="-1" required><br>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -15,11 +15,26 @@
|
|||
<span data-i18n="platformType"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<input id="motor_direction_inverted" type="checkbox" class="toggle" data-setting="motor_direction_inverted" />
|
||||
<label for="motor_direction_inverted"><span data-i18n="motor_direction_inverted"></span></label>
|
||||
<div class="radio">
|
||||
<fieldset>
|
||||
<legend>Motor direction</legend>
|
||||
<label for="motor_direction_normal">
|
||||
<input id="motor_direction_normal" name="motor_direction_inverted" type="radio"
|
||||
value="0" data-setting="motor_direction_inverted" class="left" />
|
||||
<span data-i18n="motor_direction_inverted"></span>
|
||||
</label><br class="clear-both"/>
|
||||
|
||||
<label class="checkbox-inline">
|
||||
<input id="motor_direction_inverted" name="motor_direction_inverted" type="radio"
|
||||
value="1" data-setting="motor_direction_inverted" class="left"/>
|
||||
<span data-i18n="motor_direction_isInverted"></span>
|
||||
</span></label>
|
||||
|
||||
<div class="helpicon cf_tip" data-i18n_title="motor_direction_inverted_hint"></div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="checkbox">
|
||||
<input id="mixer_pid_profile_linking" type="checkbox" class="toggle" data-setting="mixer_pid_profile_linking" />
|
||||
<label for="mixer_pid_profile_linking"><span data-i18n="mixer_pid_profile_linking"></span></label>
|
||||
|
|
|
@ -645,21 +645,13 @@ TABS.mixer.initialize = function (callback, scrollPosition) {
|
|||
});
|
||||
|
||||
const updateMotorDirection = function () {
|
||||
let motorDirectionCheckbox = $("#motor_direction_inverted");
|
||||
const isReversed = motorDirectionCheckbox.is(":checked") && (FC.MIXER_CONFIG.platformType == PLATFORM.MULTIROTOR || FC.MIXER_CONFIG.platformType == PLATFORM.TRICOPTER);
|
||||
let motorDirectionCheckbox = $('input[name=motor_direction_inverted]:checked');
|
||||
const isReversed = motorDirectionCheckbox.val() == 1 && (MIXER_CONFIG.platformType == PLATFORM_MULTIROTOR || MIXER_CONFIG.platformType == PLATFORM_TRICOPTER);
|
||||
|
||||
const path = './resources/motor_order/'
|
||||
+ currentMixerPreset.image + (isReversed ? "_reverse" : "") + '.svg';
|
||||
$('.mixerPreview img').attr('src', path);
|
||||
|
||||
if (FC.MIXER_CONFIG.platformType == PLATFORM.MULTIROTOR || FC.MIXER_CONFIG.platformType == PLATFORM.TRICOPTER) {
|
||||
if (isReversed) {
|
||||
motorDirectionCheckbox.parent().find("label span").html(i18n.getMessage("motor_direction_isInverted"));
|
||||
} else {
|
||||
motorDirectionCheckbox.parent().find("label span").html(i18n.getMessage("motor_direction_inverted"));
|
||||
}
|
||||
}
|
||||
|
||||
renderServoOutputImage();
|
||||
};
|
||||
|
||||
|
|
|
@ -326,6 +326,16 @@
|
|||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="gui_box grey custom-element-container">
|
||||
<div class="gui_box_titlebar">
|
||||
<div class="spacer_box_title" data-i18n="osd_custom_element_settings"></div>
|
||||
</div>
|
||||
<div class="spacer_box settings" id="osdCustomElements"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="gui_box grey pan-servo-container">
|
||||
<div class="gui_box_titlebar">
|
||||
<div for="osd_pan_servo_settings" class="helpicon cf_tip" data-i18n_title="osd_pan_servo_settings_HELP"></div>
|
||||
|
@ -435,6 +445,12 @@
|
|||
<a class="flash_font active" data-i18n="osd_font_upload"></a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="fonttypeselectorcontent" style="display:none; width:712px;">
|
||||
<div class="font-picker" style="margin-bottom: 10px;">
|
||||
<h1 class="tab_title">Font:</h1>
|
||||
<div class="content_wrapper font-preview"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
288
tabs/osd.js
288
tabs/osd.js
|
@ -355,7 +355,7 @@ FONT.preview = function ($el) {
|
|||
$el.empty();
|
||||
for (var i = 1; i <= SYM.LAST_CHAR; i++) {
|
||||
var url = FONT.data.character_image_urls[i];
|
||||
$el.append('<img src="' + url + '" title="0x' + i.toString(16) + '"></img> ');
|
||||
$el.append('<img src="' + url + '" title="0x' + i.toString(16) + ' (' + i.toString(10) + ') "></img> ');
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1879,7 +1879,28 @@ OSD.constants = {
|
|||
id: 116,
|
||||
positionable: true,
|
||||
preview: 'G3:30126'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'CUSTOM ELEMENT 1',
|
||||
id: 147,
|
||||
min_version: '7.1.0',
|
||||
positionable: true,
|
||||
preview: "CE_1",
|
||||
},
|
||||
{
|
||||
name: 'CUSTOM ELEMENT 2',
|
||||
id: 148,
|
||||
min_version: '7.1.0',
|
||||
positionable: true,
|
||||
preview: "CE_2",
|
||||
},
|
||||
{
|
||||
name: 'CUSTOM ELEMENT 3',
|
||||
id: 149,
|
||||
min_version: '7.1.0',
|
||||
positionable: true,
|
||||
preview: "CE_3",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -2172,6 +2193,11 @@ OSD.reload = function(callback) {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
if(semver.gte(CONFIG.flightControllerVersion, '7.1.0'))
|
||||
{
|
||||
MSP.send_message(MSPCodes.MSP2_INAV_CUSTOM_OSD_ELEMENTS);
|
||||
}
|
||||
};
|
||||
|
||||
OSD.updateSelectedLayout = function(new_layout) {
|
||||
|
@ -3356,9 +3382,265 @@ TABS.osd.initialize = function (callback) {
|
|||
usePitot = (SENSOR_CONFIG.pitot != 0);
|
||||
GUI.content_ready(callback);
|
||||
});
|
||||
|
||||
if(semver.gte(CONFIG.flightControllerVersion, '7.1.0')) {
|
||||
mspHelper.loadOsdCustomElements(createCustomElements);
|
||||
}
|
||||
}));
|
||||
};
|
||||
|
||||
function createCustomElements(){
|
||||
if(OSD_CUSTOM_ELEMENTS.settings.customElementsCount == 0){
|
||||
$('.custom-element-container').remove();
|
||||
return;
|
||||
}
|
||||
|
||||
var customElementsContainer = $('#osdCustomElements');
|
||||
|
||||
for(var i = 0; i < OSD_CUSTOM_ELEMENTS.settings.customElementsCount; i++){
|
||||
var label = $('<label>');
|
||||
|
||||
var customElementTable = $('<table>').addClass('osdCustomElement_main_table');
|
||||
var customElementRowType = $('<tr>').data('row', i);
|
||||
var customElementRowValue = $('<tr>').data('row', i);
|
||||
var customElementLabel = $('<tr>');
|
||||
|
||||
for(var ii = 0; ii < 3; ii++){
|
||||
|
||||
var select = $('<select>').addClass('osdCustomElement-' + i + '-part-' + ii + '-type').data('valueCellClass', 'osdCustomElement-' + i + '-part-' + ii + '-value').html(`
|
||||
<option value="0">none</option>
|
||||
<option data-value="text" value="1">Text</option>
|
||||
<option data-value="ico" value="2">Icon Static</option>
|
||||
<option data-value="ico_gv" value="3">Icon Global Variable</option>
|
||||
<option data-value="gv" value="4">Global Variable 00000</option>
|
||||
<option data-value="gv" value="5">Global Variable 000.00</option>
|
||||
<option data-value="gv" value="6">Global Variable 000</option>
|
||||
<option data-value="gv" value="7">Global Variable 0.0</option>
|
||||
`);
|
||||
|
||||
customElementRowType.append($('<td>').append(select));
|
||||
customElementRowValue.append($('<td>').addClass('osdCustomElement-' + i + '-part-' + ii + '-value').append(
|
||||
$('<input>').addClass('value').addClass('text').attr('type', 'text').attr('maxlength', OSD_CUSTOM_ELEMENTS.settings.customElementTextSize).hide()
|
||||
).append(
|
||||
$('<input>').addClass('value').addClass('ico').attr('min', 1).attr('max', 255).hide()
|
||||
).append(
|
||||
$('<select>').addClass('value').addClass('ico_gv').html(getGVoptions()).hide()
|
||||
).append(
|
||||
$('<select>').addClass('value').addClass('gv').html(getGVoptions()).hide()
|
||||
));
|
||||
|
||||
select.change(function(){
|
||||
var dataValue = $(this).find(':selected').data('value');
|
||||
var valueBlock = $('.' + $(this).data('valueCellClass'))
|
||||
valueBlock.find('.value').hide();
|
||||
valueBlock.find('.' + dataValue).show();
|
||||
});
|
||||
}
|
||||
|
||||
var selectVisibility = $('<select>').addClass('osdCustomElement-' + i + '-visibility-type').data('valueCellClass', 'osdCustomElement-' + i + '-visibility-value').html(`
|
||||
<option value="0">always</option>
|
||||
<option data-value="gv" value="1">Global Variable</option>
|
||||
<option data-value="lc" value="2">Logic Condition</option>
|
||||
`);
|
||||
customElementRowType.append($('<td>').append(selectVisibility));
|
||||
customElementRowValue.append($('<td>').addClass('osdCustomElement-' + i + '-visibility-value').append(
|
||||
$('<select>').addClass('value').addClass('gv').html(getGVoptions()).hide()
|
||||
).append(
|
||||
$('<select>').addClass('value').addClass('lc').html(getLCoptions()).hide()
|
||||
));
|
||||
|
||||
selectVisibility.change(function(){
|
||||
var dataValue = $(this).find(':selected').data('value');
|
||||
var valueBlock = $('.' + $(this).data('valueCellClass'))
|
||||
valueBlock.find('.value').hide();
|
||||
valueBlock.find('.' + dataValue).show();
|
||||
});
|
||||
|
||||
customElementLabel.append($('<td>').attr('colspan', 2).append($('<span>').html(chrome.i18n.getMessage("custom_element") + ' ' + (i + 1))));
|
||||
|
||||
customElementTable.append(customElementRowType).append(customElementRowValue).append(customElementLabel);
|
||||
label.append(customElementTable);
|
||||
customElementsContainer.append(label);
|
||||
}
|
||||
|
||||
fillCustomElementsValues();
|
||||
customElementsInitCallback();
|
||||
}
|
||||
|
||||
function fillCustomElementsValues() {
|
||||
for (var i = 0; i < OSD_CUSTOM_ELEMENTS.settings.customElementsCount; i++) {
|
||||
for (var ii = 0; ii < 3; ii++) {
|
||||
$('.osdCustomElement-' + i + '-part-' + ii + '-type').val(OSD_CUSTOM_ELEMENTS.items[i].customElementItems[ii].type).trigger('change');
|
||||
|
||||
var valueCell = $('.osdCustomElement-' + i + '-part-' + ii + '-value');
|
||||
switch (OSD_CUSTOM_ELEMENTS.items[i].customElementItems[ii].type){
|
||||
case 1:
|
||||
valueCell.find('.text').val(OSD_CUSTOM_ELEMENTS.items[i].customElementText).trigger('change');
|
||||
break;
|
||||
case 2:
|
||||
valueCell.find('.ico').val(OSD_CUSTOM_ELEMENTS.items[i].customElementItems[ii].value).trigger('change');
|
||||
break;
|
||||
case 3:
|
||||
valueCell.find('.ico_gv').val(OSD_CUSTOM_ELEMENTS.items[i].customElementItems[ii].value).trigger('change');
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
valueCell.find('.gv').val(OSD_CUSTOM_ELEMENTS.items[i].customElementItems[ii].value).trigger('change');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$('.osdCustomElement-' + i + '-visibility-type').val(OSD_CUSTOM_ELEMENTS.items[i].customElementVisibility.type).trigger('change');
|
||||
var valueVisibilityCell = $('.osdCustomElement-' + i + '-visibility-value');
|
||||
switch (OSD_CUSTOM_ELEMENTS.items[i].customElementVisibility.type){
|
||||
case 1:
|
||||
valueVisibilityCell.find('.gv').val(OSD_CUSTOM_ELEMENTS.items[i].customElementVisibility.value).trigger('change');
|
||||
break;
|
||||
case 2:
|
||||
valueVisibilityCell.find('.lc').val(OSD_CUSTOM_ELEMENTS.items[i].customElementVisibility.value).trigger('change');
|
||||
break;
|
||||
}
|
||||
|
||||
customElementNormaliseRow(i);
|
||||
customElementDisableNonValidOptionsRow(i);
|
||||
}
|
||||
}
|
||||
|
||||
function customElementsInitCallback() {
|
||||
|
||||
var callback = function(){
|
||||
var row = $(this).closest('tr').data('row');
|
||||
|
||||
customElementNormaliseRow(row);
|
||||
customElementDisableNonValidOptionsRow(row);
|
||||
|
||||
MSP.promise(MSPCodes.MSP2_INAV_SET_CUSTOM_OSD_ELEMENTS, customElementGetDataForRow(row));
|
||||
};
|
||||
|
||||
var customElements = $('#osdCustomElements')
|
||||
customElements.find('input, select').change(callback);
|
||||
customElements.find('input').keyup(callback);
|
||||
}
|
||||
|
||||
function customElementNormaliseRow(row){
|
||||
for(var i = 0; i < 3; i++){
|
||||
var elementType = $('.osdCustomElement-' + row + '-part-' + i + '-type');
|
||||
var valueCell = $('.' + elementType.data('valueCellClass'));
|
||||
|
||||
switch (parseInt(elementType.val())){
|
||||
case 1:
|
||||
valueCell.find('.text').val(valueCell.find('.text').val().toUpperCase());
|
||||
valueCell.find('.text').val(valueCell.find('.text').val().replace(/[^A-Z0-9!.\* ]/g, ""));
|
||||
break;
|
||||
case 2:
|
||||
valueCell.find('.ico').val(valueCell.find('.ico').val() > 255 ? 255 : valueCell.find('.ico').val());
|
||||
valueCell.find('.ico').val(valueCell.find('.ico').val() < 1 ? 1 : valueCell.find('.ico').val());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function customElementDisableNonValidOptionsRow(row){
|
||||
|
||||
var selectedTextIndex = false;
|
||||
for(let i = 0; i < 3; i++){
|
||||
let elementType = $('.osdCustomElement-' + row + '-part-' + i + '-type');
|
||||
|
||||
if(parseInt(elementType.val()) === 1)
|
||||
{
|
||||
selectedTextIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(let i = 0; i < 3; i++){
|
||||
let elementType = $('.osdCustomElement-' + row + '-part-' + i + '-type');
|
||||
if(i !== selectedTextIndex && selectedTextIndex !== false){
|
||||
elementType.find('option[value="1"]').attr('disabled', 'disabled');
|
||||
}else{
|
||||
elementType.find('option[value="1"]').removeAttr('disabled');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function customElementGetDataForRow(row){
|
||||
|
||||
var data = [];
|
||||
data.push8(row);
|
||||
|
||||
var text = "";
|
||||
|
||||
for(var ii = 0; ii < 3; ii++){
|
||||
var elementType = $('.osdCustomElement-' + row + '-part-' + ii + '-type');
|
||||
var valueCell = $('.' + elementType.data('valueCellClass'));
|
||||
var partValue = 0;
|
||||
|
||||
switch (parseInt(elementType.val())){
|
||||
case 1:
|
||||
text = valueCell.find('.text').val();
|
||||
break;
|
||||
case 2:
|
||||
partValue = parseInt(valueCell.find('.ico').val());
|
||||
break;
|
||||
case 3:
|
||||
partValue = parseInt(valueCell.find('.ico_gv').find(':selected').val());
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
partValue = parseInt(valueCell.find('.gv').find(':selected').val());
|
||||
break;
|
||||
}
|
||||
|
||||
data.push8(parseInt(elementType.val()));
|
||||
data.push16(partValue);
|
||||
}
|
||||
|
||||
var elementVisibilityType = $('.osdCustomElement-' + row + '-visibility-type');
|
||||
var valueVisibilityCell = $('.' + elementVisibilityType.data('valueCellClass'));
|
||||
var visibilityValue = null;
|
||||
switch (parseInt(elementVisibilityType.val())){
|
||||
case 1:
|
||||
visibilityValue = parseInt(valueVisibilityCell.find('.gv').find(':selected').val());
|
||||
break;
|
||||
case 2:
|
||||
visibilityValue = parseInt(valueVisibilityCell.find('.lc').find(':selected').val());
|
||||
break;
|
||||
}
|
||||
|
||||
data.push8(parseInt(elementVisibilityType.val()));
|
||||
data.push16(visibilityValue);
|
||||
|
||||
for(var i = 0; i < OSD_CUSTOM_ELEMENTS.settings.customElementTextSize; i++){
|
||||
if(i < text.length){
|
||||
data.push8(text.charCodeAt(i))
|
||||
}else{
|
||||
data.push8(0);
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
function getGVoptions(){
|
||||
var result = '';
|
||||
for(var i = 0; i < 8; i++){
|
||||
result += `<option value="` + i + `">GV `+i+`</option>`;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getLCoptions(){
|
||||
var result = '';
|
||||
for(var i = 0; i < 64; i++){
|
||||
result += `<option value="` + i + `">LC `+i+`</option>`;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
function refreshOSDSwitchIndicators() {
|
||||
let group = OSD.constants.ALL_DISPLAY_GROUPS.filter(function(e) {
|
||||
return e.name == "osdGroupSwitchIndicators";
|
||||
|
@ -3380,7 +3662,7 @@ function refreshOSDSwitchIndicators() {
|
|||
}
|
||||
|
||||
OSD.GUI.updatePreviews();
|
||||
};
|
||||
}
|
||||
|
||||
function updatePilotAndCraftNames() {
|
||||
let foundPilotName = ($('#pilot_name').val() == undefined);
|
||||
|
|
|
@ -46,7 +46,6 @@ TABS.outputs.initialize = function (callback) {
|
|||
mspHelper.loadMotorMixRules,
|
||||
mspHelper.loadServoMixRules,
|
||||
mspHelper.loadMixerConfig,
|
||||
mspHelper.loadServoMixRules,
|
||||
mspHelper.loadServoConfiguration,
|
||||
mspHelper.loadOutputMapping,
|
||||
mspHelper.loadRcData,
|
||||
|
|
266
tabs/ports.js
266
tabs/ports.js
|
@ -4,222 +4,43 @@ const path = require('path');
|
|||
|
||||
TABS.ports = {};
|
||||
|
||||
var portFunctionRules;
|
||||
|
||||
TABS.ports.initialize = function (callback) {
|
||||
|
||||
/* ** portFunctionRules Notes **
|
||||
Do not set a defaultBaud for functions in the telemetry group.
|
||||
These should default to AUTO, which is handled in the onchange function. The baud rate is then set by the firmware.
|
||||
*/
|
||||
portFunctionRules = [
|
||||
{name: 'MSP', groups: ['data', 'msp'], maxPorts: 2},
|
||||
{name: 'GPS', groups: ['sensors'], maxPorts: 1, defaultBaud: 115200},
|
||||
{name: 'TELEMETRY_FRSKY', groups: ['telemetry'], sharableWith: ['msp'], notSharableWith: ['blackbox'], maxPorts: 1},
|
||||
{name: 'TELEMETRY_HOTT', groups: ['telemetry'], sharableWith: ['msp'], notSharableWith: ['blackbox'], maxPorts: 1},
|
||||
{name: 'TELEMETRY_SMARTPORT', groups: ['telemetry'], maxPorts: 1},
|
||||
{name: 'TELEMETRY_LTM', groups: ['telemetry'], sharableWith: ['msp'], notSharableWith: ['blackbox'], maxPorts: 1},
|
||||
{name: 'RX_SERIAL', groups: ['rx'], maxPorts: 1},
|
||||
{name: 'BLACKBOX', groups: ['peripherals'], sharableWith: ['msp'], notSharableWith: ['telemetry'], maxPorts: 1}
|
||||
];
|
||||
|
||||
portFunctionRules.push({
|
||||
name: 'TELEMETRY_MAVLINK',
|
||||
groups: ['telemetry'],
|
||||
sharableWith: ['msp'],
|
||||
notSharableWith: ['blackbox'],
|
||||
maxPorts: 1
|
||||
});
|
||||
|
||||
/*
|
||||
* Support for FlySky iBus Telemetry
|
||||
*/
|
||||
portFunctionRules.push({
|
||||
name: 'TELEMETRY_IBUS',
|
||||
groups: ['telemetry'],
|
||||
sharableWith: ['msp'],
|
||||
notSharableWith: ['blackbox'],
|
||||
maxPorts: 1
|
||||
});
|
||||
|
||||
portFunctionRules.push({
|
||||
name: 'RANGEFINDER',
|
||||
groups: ['sensors'],
|
||||
maxPorts: 1 }
|
||||
);
|
||||
|
||||
portFunctionRules.push({
|
||||
name: 'GSM_SMS',
|
||||
groups: ['telemetry'],
|
||||
maxPorts: 1 }
|
||||
);
|
||||
|
||||
// support configure RunCam Device
|
||||
portFunctionRules.push({
|
||||
name: 'RUNCAM_DEVICE_CONTROL',
|
||||
groups: ['peripherals'],
|
||||
maxPorts: 1 }
|
||||
);
|
||||
|
||||
portFunctionRules.push({
|
||||
name: 'TBS_SMARTAUDIO',
|
||||
groups: ['peripherals'],
|
||||
maxPorts: 1 }
|
||||
);
|
||||
portFunctionRules.push({
|
||||
name: 'IRC_TRAMP',
|
||||
groups: ['peripherals'],
|
||||
maxPorts: 1 }
|
||||
);
|
||||
portFunctionRules.push({
|
||||
name: 'VTX_FFPV',
|
||||
groups: ['peripherals'],
|
||||
maxPorts: 1 }
|
||||
);
|
||||
|
||||
portFunctionRules.push({
|
||||
name: 'OPFLOW',
|
||||
groups: ['sensors'],
|
||||
maxPorts: 1 }
|
||||
);
|
||||
|
||||
portFunctionRules.push({
|
||||
name: 'ESC',
|
||||
groups: ['peripherals'],
|
||||
maxPorts: 1,
|
||||
defaultBaud: 115200 }
|
||||
);
|
||||
|
||||
portFunctionRules.push({
|
||||
name: 'FRSKY_OSD',
|
||||
groups: ['peripherals'],
|
||||
maxPorts: 1,
|
||||
defaultBaud: 250000 }
|
||||
);
|
||||
|
||||
portFunctionRules.push({
|
||||
name: 'DJI_FPV',
|
||||
groups: ['peripherals'],
|
||||
maxPorts: 1,
|
||||
defaultBaud: 115200 }
|
||||
);
|
||||
|
||||
portFunctionRules.push({
|
||||
name: 'MSP_DISPLAYPORT',
|
||||
groups: ['peripherals'],
|
||||
maxPorts: 1 }
|
||||
);
|
||||
|
||||
portFunctionRules.push({
|
||||
name: 'SMARTPORT_MASTER',
|
||||
groups: ['peripherals'],
|
||||
maxPorts: 1,
|
||||
defaultBaud: 57600 }
|
||||
);
|
||||
portFunctionRules.push({
|
||||
name: 'SBUS_OUTPUT',
|
||||
groups: ['peripherals'],
|
||||
maxPorts: 1,
|
||||
defaultBaud: 115200 }
|
||||
);
|
||||
|
||||
for (var i = 0; i < portFunctionRules.length; i++) {
|
||||
portFunctionRules[i].displayName = i18n.getMessage('portsFunction_' + portFunctionRules[i].name);
|
||||
}
|
||||
|
||||
var mspBaudRates = [
|
||||
'9600',
|
||||
'19200',
|
||||
'38400',
|
||||
'57600',
|
||||
'115200'
|
||||
];
|
||||
|
||||
var gpsBaudRates = [
|
||||
'9600',
|
||||
'19200',
|
||||
'38400',
|
||||
'57600',
|
||||
'115200',
|
||||
'230400'
|
||||
];
|
||||
|
||||
var telemetryBaudRates_post1_6_3 = [
|
||||
'AUTO',
|
||||
'1200',
|
||||
'2400',
|
||||
'4800',
|
||||
'9600',
|
||||
'19200',
|
||||
'38400',
|
||||
'57600',
|
||||
'115200'
|
||||
];
|
||||
|
||||
var peripheralsBaudRates = [
|
||||
'19200',
|
||||
'38400',
|
||||
'57600',
|
||||
'115200',
|
||||
'230400',
|
||||
'250000'
|
||||
];
|
||||
|
||||
var columns = ['data', 'logging', 'sensors', 'telemetry', 'rx', 'peripherals'];
|
||||
|
||||
if (GUI.active_tab != 'ports') {
|
||||
GUI.active_tab = 'ports';
|
||||
}
|
||||
|
||||
load_configuration_from_fc();
|
||||
|
||||
function load_configuration_from_fc() {
|
||||
MSP.send_message(MSPCodes.MSP2_CF_SERIAL_CONFIG, false, false, on_configuration_loaded_handler);
|
||||
|
||||
function on_configuration_loaded_handler() {
|
||||
GUI.load(path.join(__dirname, "tabs/ports.html"), on_tab_loaded_handler);
|
||||
}
|
||||
}
|
||||
mspHelper.loadSerialPorts(function () {
|
||||
GUI.load("./tabs/ports.html", on_tab_loaded_handler)
|
||||
});
|
||||
|
||||
function update_ui() {
|
||||
|
||||
$(".tab-ports").addClass("supported");
|
||||
|
||||
var portIdentifierToNameMapping = {
|
||||
0: 'UART1',
|
||||
1: 'UART2',
|
||||
2: 'UART3',
|
||||
3: 'UART4',
|
||||
4: 'UART5',
|
||||
5: 'UART6',
|
||||
6: 'UART7',
|
||||
7: 'UART8',
|
||||
20: 'USB VCP',
|
||||
30: 'SOFTSERIAL1',
|
||||
31: 'SOFTSERIAL2'
|
||||
};
|
||||
|
||||
var i,
|
||||
$elements;
|
||||
|
||||
$elements = $('select.sensors_baudrate');
|
||||
for (let i = 0; i < gpsBaudRates.length; i++) {
|
||||
$elements.append('<option value="' + gpsBaudRates[i] + '">' + gpsBaudRates[i] + '</option>');
|
||||
for (i = 0; i < helper.serialPortHelper.getBauds('SENSOR').length; i++) {
|
||||
$elements.append('<option value="' + helper.serialPortHelper.getBauds('SENSOR')[i] + '">' + helper.serialPortHelper.getBauds('SENSOR')[i] + '</option>');
|
||||
}
|
||||
|
||||
$elements = $('select.msp_baudrate');
|
||||
for (let i = 0; i < mspBaudRates.length; i++) {
|
||||
$elements.append('<option value="' + mspBaudRates[i] + '">' + mspBaudRates[i] + '</option>');
|
||||
for (i = 0; i < helper.serialPortHelper.getBauds('MSP').length; i++) {
|
||||
$elements.append('<option value="' + helper.serialPortHelper.getBauds('MSP')[i] + '">' + helper.serialPortHelper.getBauds('MSP')[i] + '</option>');
|
||||
}
|
||||
|
||||
$elements = $('select.telemetry_baudrate');
|
||||
for (let i = 0; i < telemetryBaudRates_post1_6_3.length; i++) {
|
||||
$elements.append('<option value="' + telemetryBaudRates_post1_6_3[i] + '">' + telemetryBaudRates_post1_6_3[i] + '</option>');
|
||||
for (i = 0; i < helper.serialPortHelper.getBauds('TELEMETRY').length; i++) {
|
||||
$elements.append('<option value="' + helper.serialPortHelper.getBauds('TELEMETRY')[i] + '">' + helper.serialPortHelper.getBauds('TELEMETRY')[i] + '</option>');
|
||||
}
|
||||
|
||||
$elements = $('select.peripherals_baudrate');
|
||||
for (let i = 0; i < peripheralsBaudRates.length; i++) {
|
||||
$elements.append('<option value="' + peripheralsBaudRates[i] + '">' + peripheralsBaudRates[i] + '</option>');
|
||||
for (i = 0; i < helper.serialPortHelper.getBauds('PERIPHERAL').length; i++) {
|
||||
$elements.append('<option value="' + helper.serialPortHelper.getBauds('PERIPHERAL')[i] + '">' + helper.serialPortHelper.getBauds('PERIPHERAL')[i] + '</option>');
|
||||
}
|
||||
|
||||
var ports_e = $('.tab-ports .ports');
|
||||
|
@ -239,7 +60,7 @@ TABS.ports.initialize = function (callback) {
|
|||
port_configuration_e.find('select.sensors_baudrate').val(serialPort.sensors_baudrate);
|
||||
port_configuration_e.find('select.peripherals_baudrate').val(serialPort.peripherals_baudrate);
|
||||
|
||||
port_configuration_e.find('.identifier').text(portIdentifierToNameMapping[serialPort.identifier]);
|
||||
port_configuration_e.find('.identifier').text(helper.serialPortHelper.getPortName(serialPort.identifier));
|
||||
if (serialPort.identifier >= 30) {
|
||||
port_configuration_e.find('.softSerialWarning').css("display", "inline")
|
||||
} else {
|
||||
|
@ -256,8 +77,8 @@ TABS.ports.initialize = function (callback) {
|
|||
let functions_e_id = "portFunc-" + column + "-" + portIndex;
|
||||
functions_e.attr("id", functions_e_id);
|
||||
|
||||
for (let i = 0; i < portFunctionRules.length; i++) {
|
||||
var functionRule = portFunctionRules[i];
|
||||
for (i = 0; i < helper.serialPortHelper.getRules().length; i++) {
|
||||
var functionRule = helper.serialPortHelper.getRules()[i];
|
||||
var functionName = functionRule.name;
|
||||
|
||||
if (functionRule.groups.indexOf(column) == -1) {
|
||||
|
@ -281,9 +102,9 @@ TABS.ports.initialize = function (callback) {
|
|||
select_e = functions_e.find(selectElementSelector);
|
||||
|
||||
if (select_e.length == 0) {
|
||||
functions_e.prepend('<span class="function"><select name="' + selectElementName + '" class="' + selectElementName + '" onchange="updateDefaultBaud(\'' + functions_e_id + '\', \'' + column + '\')" /></span>');
|
||||
functions_e.prepend('<span class="function"><select name="' + selectElementName + '" class="function-select ' + selectElementName + '" onchange="updateDefaultBaud(\'' + functions_e_id + '\', \'' + column + '\')" /></span>');
|
||||
select_e = functions_e.find(selectElementSelector);
|
||||
var disabledText = i18n.getMessage('portsTelemetryDisabled');
|
||||
var disabledText = chrome.i18n.getMessage('portsTelemetryDisabled');
|
||||
select_e.append('<option value="">' + disabledText + '</option>');
|
||||
}
|
||||
select_e.append('<option value="' + functionName + '">' + functionRule.displayName + '</option>');
|
||||
|
@ -298,6 +119,48 @@ TABS.ports.initialize = function (callback) {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
$('table.ports tbody').on('change', 'select', onSwitchChange);
|
||||
$('table.ports tbody').on('change', 'input', onSwitchChange);
|
||||
}
|
||||
|
||||
function onSwitchChange(e) {
|
||||
let $cT = $(e.currentTarget);
|
||||
|
||||
let functionName = $cT.val();
|
||||
let rule = helper.serialPortHelper.getRuleByName($cT.val());
|
||||
|
||||
//if type is checkbox then process only if selected
|
||||
if ($cT.is('input[type="checkbox"]') && !$cT.is(':checked')) {
|
||||
return;
|
||||
}
|
||||
//if type select then process only if selected
|
||||
if ($cT.is('select') && !functionName) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rule && rule.isUnique) {
|
||||
let $selects = $cT.closest('tr').find('.function-select');
|
||||
$selects.each(function (index, element) {
|
||||
|
||||
let $element = $(element);
|
||||
|
||||
if ($element.val() != functionName) {
|
||||
$element.val('');
|
||||
}
|
||||
});
|
||||
|
||||
let $checkboxes = $cT.closest('tr').find('input[type="checkbox"]');
|
||||
$checkboxes.each(function (index, element) {
|
||||
let $element = $(element);
|
||||
|
||||
if ($element.val() != functionName) {
|
||||
$element.prop('checked', false);
|
||||
$element.trigger('change');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function on_tab_loaded_handler() {
|
||||
|
@ -356,7 +219,7 @@ TABS.ports.initialize = function (callback) {
|
|||
SERIAL_CONFIG.ports.push(serialPort);
|
||||
});
|
||||
|
||||
MSP.send_message(MSPCodes.MSP2_SET_CF_SERIAL_CONFIG, mspHelper.crunch(MSPCodes.MSP2_SET_CF_SERIAL_CONFIG), false, save_to_eeprom);
|
||||
mspHelper.saveSerialPorts(save_to_eeprom);
|
||||
|
||||
function save_to_eeprom() {
|
||||
MSP.send_message(MSPCodes.MSP_EEPROM_WRITE, false, false, on_saved_handler);
|
||||
|
@ -382,13 +245,10 @@ function updateDefaultBaud(baudSelect, column) {
|
|||
let portName = section.find('.function-' + column).val();
|
||||
let baudRate = (column === 'telemetry') ? "AUTO" : 115200;;
|
||||
|
||||
for (let i = 0; i < portFunctionRules.length; i++) {
|
||||
if (portFunctionRules[i].name === portName) {
|
||||
if (typeof portFunctionRules[i].defaultBaud !== 'undefined') {
|
||||
baudRate = portFunctionRules[i].defaultBaud;
|
||||
}
|
||||
break;
|
||||
}
|
||||
let rule = helper.serialPortHelper.getRuleByName(portName);
|
||||
|
||||
if (rule && typeof rule.defaultBaud !== 'undefined') {
|
||||
baudRate = rule.defaultBaud;
|
||||
}
|
||||
|
||||
section.find("." + column + "_baudrate").children('[value=' + baudRate + ']').prop('selected', true);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue