1
0
Fork 0
mirror of https://github.com/iNavFlight/inav-configurator.git synced 2025-07-20 14:55:14 +03:00

Offline missions (with FC disconnected) on file (#720)

* Offline missions (with FC disconnected) are now available for load and save to file.
Supports XML file format, should be compatible enough with other software

* removed default file name

* removed code in early stage of future developments

* code style and fc buttons

* map resize handling
This commit is contained in:
mirko-it 2019-04-29 17:23:32 +02:00 committed by giacomo892
parent cec7997bfc
commit 3dcffdd292
6 changed files with 349 additions and 74 deletions

View file

@ -2719,6 +2719,18 @@
"saveEepromMissionButton": { "saveEepromMissionButton": {
"message": "Save Eeprom mission" "message": "Save Eeprom mission"
}, },
"loadFileMissionButton": {
"message": "Load file"
},
"saveFileMissionButton": {
"message": "Save file"
},
"missionSettingsSave": {
"message": "Save"
},
"missionSettingsCancel": {
"message": "Cancel"
},
"editPointHead": { "editPointHead": {
"message": "Edit point" "message": "Edit point"
}, },

View file

@ -13,6 +13,7 @@ var GUI_control = function () {
this.defaultAllowedTabsWhenDisconnected = [ this.defaultAllowedTabsWhenDisconnected = [
'landing', 'landing',
'firmware_flasher', 'firmware_flasher',
'mission_control',
'help' 'help'
]; ];
this.defaultAllowedTabsWhenConnected = [ this.defaultAllowedTabsWhenConnected = [

View file

@ -165,6 +165,7 @@
title="Welcome"></a></li> title="Welcome"></a></li>
<li class="tab_help"><a href="https://github.com/iNavFlight/inav/wiki" target="_blank" data-i18n="tabHelp" class="tabicon ic_help" <li class="tab_help"><a href="https://github.com/iNavFlight/inav/wiki" target="_blank" data-i18n="tabHelp" class="tabicon ic_help"
title="Documentation &amp; Support"></a></li> title="Documentation &amp; Support"></a></li>
<li class="tab_mission_control"><a href="#" data-i18n="tabMissionControl" class="tabicon ic_mission" title="Mission Control"></a></li>
<li class="tab_firmware_flasher"><a href="#" data-i18n="tabFirmwareFlasher" class="tabicon ic_flasher" <li class="tab_firmware_flasher"><a href="#" data-i18n="tabFirmwareFlasher" class="tabicon ic_flasher"
title="Firmware Flasher"></a></li> title="Firmware Flasher"></a></li>
</ul> </ul>

View file

@ -34,8 +34,10 @@
"minimist": "^1.2.0", "minimist": "^1.2.0",
"nw": "^0.36.1-sdk", "nw": "^0.36.1-sdk",
"nw-builder": "^3.5.7", "nw-builder": "^3.5.7",
"nw-dialog": "^1.0.7",
"openlayers": "^4.6.5", "openlayers": "^4.6.5",
"temp": "^0.8.3", "temp": "^0.8.3",
"three": "0.72.0" "three": "0.72.0",
"xml2js": "^0.4.19"
} }
} }

View file

@ -14,16 +14,17 @@
</div> </div>
<div class="spacer"> <div class="spacer">
<div class="point"> <div class="point">
<label class="point-label" for="pointAlt">Alt (cm): </label> <label class="point-label" for="MPdefaultPointAlt">Alt (cm): </label>
<input id="MPdefaultPointAlt" type="text" value="0" required> <input id="MPdefaultPointAlt" type="text" value="0" required>
</div> </div>
<div class="point"> <div class="point">
<label class="point-label" for="pointSpeed">Speed (cm/s): </label> <label class="point-label" for="MPdefaultPointSpeed">Speed (cm/s): </label>
<input id="MPdefaultPointSpeed" type="text" value="0" required> <input id="MPdefaultPointSpeed" type="text" value="0" required>
</div> </div>
<div> <div>
<div id="saveSettings" class="btn save_btn" style="padding-top: 10px; display: inline-block"> <div class="btn save_btn" style="padding-top: 10px;">
<a class="save" href="#" data-i18n="editPointButtonSave" style="float: left">Save</a> <a id="saveSettings" class="save" href="#" data-i18n="missionSettingsSave" style="float: left">Save</a>
<a id="cancelSettings" class="save" href="#" data-i18n="missionSettingsCancel" style="float: right">Cancel</a>
</div> </div>
</div> </div>
</div> </div>
@ -33,30 +34,34 @@
<div class="spacer_box_title i18n-replaced" data-i18n="missionTotalInformationHead">Total information</div> <div class="spacer_box_title i18n-replaced" data-i18n="missionTotalInformationHead">Total information</div>
</div> </div>
<div class="spacer"> <div class="spacer">
<div style="padding-bottom: 2px;"> <div id="infoMissionDistance" style="padding-bottom: 2px;">
<span>Distance (m):</span> <span>Distance (m):</span>
<span id="missionDistance"></span> <span id="missionDistance"></span>
</div> </div>
<div style="padding-bottom: 2px;"> <div id="infoAvailablePoints" style="padding-bottom: 2px;">
<span>Available Points</span> <span>Available Points</span>
<span id="availablePoints">0/0</span> <span id="availablePoints">0/0</span>
</div> </div>
<div style="padding-bottom: 2px;"> <div id="infoMissionValid" style="padding-bottom: 2px;">
<span>Mission valid</span> <span>Mission valid</span>
<div id="missionValid" style="display: inline-block"></div> <div id="missionValid" style="display: inline-block"></div>
</div> </div>
<br> <br>
<div style="display: flex;"> <div style="display: flex;">
<input type="checkbox" style="width: 18px;margin-left: 5px;" id="rthEndMission"> <input type="checkbox" style="width: 18px; margin-left: 5px;" id="rthEndMission">
<label for="rthEndMission" style="padding: 2px;">RTH at the end of the mission</label> <label for="rthEndMission" style="padding: 2px;">RTH at the end of the mission</label>
</div> </div>
<div id="rthSettings" style="display: none"> <div id="rthSettings" style="display: none">
<div style="display: flex"> <div style="display: flex">
<input type="checkbox" id="rthLanding" style="width: 18px;margin-left: 5px;"> <input type="checkbox" id="rthLanding" style="width: 18px; margin-left: 5px;">
<label for="rthLanding" style="padding: 2px">Landing</label> <label for="rthLanding" style="padding: 2px">Landing</label>
</div> </div>
</div> </div>
<hr> <hr>
<div class="btn save_btn">
<a id="loadFileMissionButton" class="save" href="#" data-i18n="loadFileMissionButton">Load file mission</a>
<a id="saveFileMissionButton" class="save" href="#" data-i18n="saveFileMissionButton">Save file mission</a>
</div>
<div class="btn save_btn"> <div class="btn save_btn">
<a id="loadMissionButton" class="save" href="#" data-i18n="loadMissionButton">Load mission from FC</a> <a id="loadMissionButton" class="save" href="#" data-i18n="loadMissionButton">Load mission from FC</a>
<a id="saveMissionButton" class="save" href="#" data-i18n="saveMissionButton">Save mission to FC</a> <a id="saveMissionButton" class="save" href="#" data-i18n="saveMissionButton">Save mission to FC</a>

View file

@ -1,5 +1,21 @@
'use strict'; 'use strict';
// MultiWii NAV Protocol
var MWNP = MWNP || {};
// WayPoint type
MWNP.WPTYPE = {
WAYPOINT: 1,
PH_UNLIM: 2,
PH_TIME: 3,
RTH: 4,
SET_POI: 5,
JUMP: 6,
SET_HEAD: 7,
LAND: 8
};
TABS.mission_control = {}; TABS.mission_control = {};
TABS.mission_control.isYmapLoad = false; TABS.mission_control.isYmapLoad = false;
TABS.mission_control.initialize = function (callback) { TABS.mission_control.initialize = function (callback) {
@ -9,37 +25,46 @@ TABS.mission_control.initialize = function (callback) {
googleAnalytics.sendAppView('Mission Control'); googleAnalytics.sendAppView('Mission Control');
} }
if (CONFIGURATOR.connectionValid) {
var loadChainer = new MSPChainerClass(); var loadChainer = new MSPChainerClass();
loadChainer.setChain([ loadChainer.setChain([
mspHelper.getMissionInfo mspHelper.getMissionInfo
]); ]);
loadChainer.setExitPoint(loadHtml); loadChainer.setExitPoint(loadHtml);
loadChainer.execute(); loadChainer.execute();
} else {
// FC not connected, load page anyway
loadHtml();
}
function updateTotalInfo() { function updateTotalInfo() {
if (CONFIGURATOR.connectionValid) {
$('#availablePoints').text(MISSION_PLANER.countBusyPoints + '/' + MISSION_PLANER.maxWaypoints); $('#availablePoints').text(MISSION_PLANER.countBusyPoints + '/' + MISSION_PLANER.maxWaypoints);
$('#missionValid').html(MISSION_PLANER.isValidMission ? chrome.i18n.getMessage('armingCheckPass') : chrome.i18n.getMessage('armingCheckFail')); $('#missionValid').html(MISSION_PLANER.isValidMission ? chrome.i18n.getMessage('armingCheckPass') : chrome.i18n.getMessage('armingCheckFail'));
} }
}
function loadHtml() { function loadHtml() {
$('#content').load("./tabs/mission_control.html", process_html); $('#content').load("./tabs/mission_control.html", process_html);
} }
function process_html() { function process_html() {
if (typeof require !== "undefined") {
chrome.storage.local.get('missionPlanerSettings', function (result) { // set GUI for offline operations
if (result.missionPlanerSettings) { if (!CONFIGURATOR.connectionValid) {
$('#MPdefaultPointAlt').val(result.missionPlanerSettings.alt); $('#infoAvailablePoints').hide();
$('#MPdefaultPointSpeed').val(result.missionPlanerSettings.speed); $('#infoMissionValid').hide();
} else { $('#loadMissionButton').hide();
chrome.storage.local.set({'missionPlanerSettings': {speed: 0, alt: 5000}}); $('#saveMissionButton').hide();
$('#MPdefaultPointAlt').val(5000); $('#loadEepromMissionButton').hide();
$('#MPdefaultPointSpeed').val(0); $('#saveEepromMissionButton').hide();
} }
});
if (typeof require !== "undefined") {
initMap(); loadSettings();
// let the dom load finish, avoiding the resizing of the map
setTimeout(initMap, 200);
} else { } else {
$('#missionMap, #missionControls').hide(); $('#missionMap, #missionControls').hide();
$('#notLoadMap').show(); $('#notLoadMap').show();
@ -54,6 +79,7 @@ TABS.mission_control.initialize = function (callback) {
var map; var map;
var selectedMarker = null; var selectedMarker = null;
var pointForSend = 0; var pointForSend = 0;
var settings = { speed: 0, alt: 5000 };
function clearEditForm() { function clearEditForm() {
$('#pointLat').val(''); $('#pointLat').val('');
@ -64,6 +90,25 @@ TABS.mission_control.initialize = function (callback) {
$('#MPeditPoint').fadeOut(300); $('#MPeditPoint').fadeOut(300);
} }
function loadSettings() {
chrome.storage.local.get('missionPlanerSettings', function (result) {
if (result.missionPlanerSettings) {
settings = result.missionPlanerSettings;
}
refreshSettings();
});
}
function saveSettings() {
chrome.storage.local.set({'missionPlanerSettings': settings});
}
function refreshSettings() {
$('#MPdefaultPointAlt').val(settings.alt);
$('#MPdefaultPointSpeed').val(settings.speed);
}
function repaint() { function repaint() {
var oldPos; var oldPos;
for (var i in lines) { for (var i in lines) {
@ -122,16 +167,16 @@ TABS.mission_control.initialize = function (callback) {
scale: 0.5, scale: 0.5,
src: '../images/icons/cf_icon_position' + (isEdit ? '_edit' : '') + '.png' src: '../images/icons/cf_icon_position' + (isEdit ? '_edit' : '') + '.png'
})) }))
// text: new ol.style.Text({ /*
// text: '10', text: new ol.style.Text({
// offsetX: -1, text: '10',
// offsetY: -30, offsetX: -1,
// overflow: true, offsetY: -30,
// scale: 2, overflow: true,
// fill: new ol.style.Fill({ scale: 2,
// color: 'black' fill: new ol.style.Fill({ color: 'black' })
// }) })
// }) */
}); });
} }
@ -315,8 +360,8 @@ TABS.mission_control.initialize = function (callback) {
return false; return false;
}; };
var lat = GPS_DATA.lat / 10000000; var lat = (GPS_DATA ? (GPS_DATA.lat / 10000000) : 0);
var lon = GPS_DATA.lon / 10000000; var lon = (GPS_DATA ? (GPS_DATA.lon / 10000000) : 0);
let mapLayer; let mapLayer;
@ -358,15 +403,26 @@ TABS.mission_control.initialize = function (callback) {
// Set the attribute link to open on an external browser window, so // Set the attribute link to open on an external browser window, so
// it doesn't interfere with the configurator. // it doesn't interfere with the configurator.
var interval; setTimeout(function() {
interval = setInterval(function() { $('.ol-attribution a').attr('target', '_blank');
var anchor = $('.ol-attribution a');
if (anchor.length) {
anchor.attr('target', '_blank');
clearInterval(interval);
}
}, 100); }, 100);
// save map view settings when user moves it
map.on('moveend', function (evt) {
chrome.storage.local.set({'missionPlanerLastValues': {
center: ol.proj.toLonLat(map.getView().getCenter()),
zoom: map.getView().getZoom()
}});
});
// load map view settings on startup
chrome.storage.local.get('missionPlanerLastValues', function (result) {
if (result.missionPlanerLastValues && result.missionPlanerLastValues.center) {
map.getView().setCenter(ol.proj.fromLonLat(result.missionPlanerLastValues.center));
map.getView().setZoom(result.missionPlanerLastValues.zoom);
}
});
map.on('click', function (evt) { map.on('click', function (evt) {
if (selectedMarker != null) { if (selectedMarker != null) {
try { try {
@ -392,14 +448,14 @@ TABS.mission_control.initialize = function (callback) {
selectedFeature.setStyle(getPointIcon(true)); selectedFeature.setStyle(getPointIcon(true));
$('#pointLon').val(coord[0]); $('#pointLon').val(Math.round(coord[0] * 10000000) / 10000000);
$('#pointLat').val(coord[1]); $('#pointLat').val(Math.round(coord[1] * 10000000) / 10000000);
$('#pointAlt').val(selectedMarker.alt); $('#pointAlt').val(selectedMarker.alt);
$('#pointType').val(selectedMarker.action); $('#pointType').val(selectedMarker.action);
$('#pointSpeed').val(selectedMarker.speedValue); $('#pointSpeed').val(selectedMarker.speedValue);
$('#MPeditPoint').fadeIn(300); $('#MPeditPoint').fadeIn(300);
} else { } else {
map.addLayer(addMarker(evt.coordinate, $('#MPdefaultPointAlt').val(), 1, $('#MPdefaultPointSpeed').val())); map.addLayer(addMarker(evt.coordinate, settings.alt, MWNP.WPTYPE.WAYPOINT, settings.speed));
repaint(); repaint();
} }
}); });
@ -417,8 +473,15 @@ TABS.mission_control.initialize = function (callback) {
} }
}); });
// handle map size on container resize
setInterval(function () {
let width = $("#missionMap canvas").width(), height = $("#missionMap canvas").height();
if ((map.width_ != width) || (map.height_ != height)) map.updateSize();
map.width_ = width; map.height_ = height;
}, 200);
$('#removeAllPoints').on('click', function () { $('#removeAllPoints').on('click', function () {
if (confirm(chrome.i18n.getMessage('confirm_delete_all_points'))) { if (markers.length && confirm(chrome.i18n.getMessage('confirm_delete_all_points'))) {
removeAllPoints(); removeAllPoints();
} }
}); });
@ -460,13 +523,28 @@ TABS.mission_control.initialize = function (callback) {
} }
}); });
$('#loadMissionButton').on('click', function () { $('#loadFileMissionButton').on('click', function () {
if (markers.length) { if (markers.length && !confirm(chrome.i18n.getMessage('confirm_delete_all_points'))) return;
if (!confirm(chrome.i18n.getMessage('confirm_delete_all_points'))) { removeAllPoints();
return; var dialog = require('nw-dialog');
} dialog.setContext(document);
dialog.openFileDialog(function(result) {
loadMissionFile(result);
})
});
$('#saveFileMissionButton').on('click', function () {
//if (!markers.length) return;
var dialog = require('nw-dialog');
dialog.setContext(document);
dialog.saveFileDialog('', '.mission', function(result) {
saveMissionFile(result);
})
});
$('#loadMissionButton').on('click', function () {
if (markers.length && !confirm(chrome.i18n.getMessage('confirm_delete_all_points'))) return;
removeAllPoints(); removeAllPoints();
}
$(this).addClass('disabled'); $(this).addClass('disabled');
GUI.log('Start get point'); GUI.log('Start get point');
@ -483,12 +561,8 @@ TABS.mission_control.initialize = function (callback) {
}); });
$('#loadEepromMissionButton').on('click', function () { $('#loadEepromMissionButton').on('click', function () {
if (markers.length) { if (markers.length && !confirm(chrome.i18n.getMessage('confirm_delete_all_points'))) return;
if (!confirm(chrome.i18n.getMessage('confirm_delete_all_points'))) {
return;
}
removeAllPoints(); removeAllPoints();
}
GUI.log(chrome.i18n.getMessage('eeprom_load_ok')); GUI.log(chrome.i18n.getMessage('eeprom_load_ok'));
MSP.send_message(MSPCodes.MSP_WP_MISSION_LOAD, [0], getPointsFromEprom); MSP.send_message(MSPCodes.MSP_WP_MISSION_LOAD, [0], getPointsFromEprom);
@ -507,15 +581,25 @@ TABS.mission_control.initialize = function (callback) {
}); });
$('#saveSettings').on('click', function () { $('#saveSettings').on('click', function () {
chrome.storage.local.set({'missionPlanerSettings': {speed: $('#MPdefaultPointSpeed').val(), alt: $('#MPdefaultPointAlt').val()}}); settings = { speed: $('#MPdefaultPointSpeed').val(), alt: $('#MPdefaultPointAlt').val() };
saveSettings();
closeSettingsPanel();
});
$('#cancelSettings').on('click', function () {
loadSettings();
closeSettingsPanel();
});
updateTotalInfo();
}
function closeSettingsPanel() {
$('#missionPlanerSettings').hide(); $('#missionPlanerSettings').hide();
$('#missionPalnerTotalInfo').fadeIn(300); $('#missionPalnerTotalInfo').fadeIn(300);
if (selectedMarker !== null) { if (selectedMarker !== null) {
$('#MPeditPoint').fadeIn(300); $('#MPeditPoint').fadeIn(300);
} }
});
updateTotalInfo();
} }
function removeAllPoints() { function removeAllPoints() {
@ -524,9 +608,179 @@ TABS.mission_control.initialize = function (callback) {
} }
markers = []; markers = [];
clearEditForm(); clearEditForm();
updateTotalInfo();
$('#rthEndMission').prop('checked', false);
$('#rthSettings').fadeOut(300);
$('#rthLanding').prop('checked', false);
repaint(); repaint();
} }
function loadMissionFile(filename) {
const fs = require('fs-extra');
const xml2js = require('xml2js');
fs.readFile(filename, (err, data) => {
if (err) {
GUI.log('<span style="color: red">Error reading file</span>');
return console.error(err);
}
xml2js.Parser({ 'explicitChildren': true, 'preserveChildrenOrder': true }).parseString(data, (err, result) => {
if (err) {
GUI.log('<span style="color: red">Error parsing file</span>');
return console.error(err);
}
// parse mission file
var mission = { points: [] };
var node = null;
var nodemission = null;
for (var noderoot in result) {
if (!nodemission && noderoot.match(/mission/i)) {
nodemission = result[noderoot];
if (nodemission.$$ && nodemission.$$.length) {
for (var i = 0; i < nodemission.$$.length; i++) {
node = nodemission.$$[i];
if (node['#name'].match(/version/i) && node.$) {
for (var attr in node.$) {
if (attr.match(/value/i)) {
mission.version = node.$[attr]
}
}
} else if (node['#name'].match(/mwp/i) && node.$) {
mission.center = {};
for (var attr in node.$) {
if (attr.match(/zoom/i)) {
mission.center.zoom = parseInt(node.$[attr]);
} else if (attr.match(/cx/i)) {
mission.center.lon = parseFloat(node.$[attr]);
} else if (attr.match(/cy/i)) {
mission.center.lat = parseFloat(node.$[attr]);
}
}
} else if (node['#name'].match(/missionitem/i) && node.$) {
var point = {};
for (var attr in node.$) {
if (attr.match(/no/i)) {
point.index = parseInt(node.$[attr]);
} else if (attr.match(/action/i)) {
if (node.$[attr].match(/WAYPOINT/i)) {
point.action = MWNP.WPTYPE.WAYPOINT;
} else if (node.$[attr].match(/PH_UNLIM/i) || node.$[attr].match(/POSHOLD_UNLIM/i)) {
point.action = MWNP.WPTYPE.PH_UNLIM;
} else if (node.$[attr].match(/PH_TIME/i) || node.$[attr].match(/POSHOLD_TIME/i)) {
point.action = MWNP.WPTYPE.PH_TIME;
} else if (node.$[attr].match(/RTH/i)) {
point.action = MWNP.WPTYPE.RTH;
} else if (node.$[attr].match(/SET_POI/i)) {
point.action = MWNP.WPTYPE.SET_POI;
} else if (node.$[attr].match(/JUMP/i)) {
point.action = MWNP.WPTYPE.JUMP;
} else if (node.$[attr].match(/SET_HEAD/i)) {
point.action = MWNP.WPTYPE.SET_HEAD;
} else if (node.$[attr].match(/LAND/i)) {
point.action = MWNP.WPTYPE.LAND;
} else {
point.action = 0;
}
} else if (attr.match(/lat/i)) {
point.lat = parseFloat(node.$[attr]);
} else if (attr.match(/lon/i)) {
point.lon = parseFloat(node.$[attr]);
} else if (attr.match(/alt/i)) {
point.alt = (parseInt(node.$[attr]) * 100);
} else if (attr.match(/parameter1/i)) {
point.p1 = parseInt(node.$[attr]);
} else if (attr.match(/parameter2/i)) {
point.p2 = parseInt(node.$[attr]);
} else if (attr.match(/parameter3/i)) {
point.p3 = parseInt(node.$[attr]);
}
}
mission.points.push(point);
}
}
}
}
}
// draw actual mission
removeAllPoints();
for (var i = 0; i < mission.points.length; i++) {
//if ([MWNP.WPTYPE.WAYPOINT,MWNP.WPTYPE.PH_UNLIM,MWNP.WPTYPE.PH_TIME,MWNP.WPTYPE.LAND].includes(mission.points[i].action)) {
if (mission.points[i].action == MWNP.WPTYPE.WAYPOINT) {
var coord = ol.proj.fromLonLat([mission.points[i].lon, mission.points[i].lat]);
map.addLayer(addMarker(coord, mission.points[i].alt, mission.points[i].action, mission.points[i].p1));
if (i == 0) {
map.getView().setCenter(coord);
map.getView().setZoom(16);
}
} else if (mission.points[i].action == MWNP.WPTYPE.RTH) {
$('#rthEndMission').prop('checked', true);
$('#rthSettings').fadeIn(300);
if (mission.points[i].p1 > 0) {
$('#rthLanding').prop('checked', true);
}
}
}
if (mission.center) {
var coord = ol.proj.fromLonLat([mission.center.lon, mission.center.lat]);
map.getView().setCenter(coord);
if (mission.center.zoom) map.getView().setZoom(mission.center.zoom);
}
repaint();
updateTotalInfo();
});
});
}
function saveMissionFile(filename) {
const fs = require('fs-extra');
const xml2js = require('xml2js');
var center = ol.proj.toLonLat(map.getView().getCenter());
var zoom = map.getView().getZoom();
var data = {
'version': { $: { 'value': '2.3-pre8' } },
'mwp': { $: { 'cx': (Math.round(center[0] * 10000000) / 10000000), 'cy': (Math.round(center[1] * 10000000) / 10000000), 'zoom': zoom } },
'missionitem': []
};
for (var i = 0; i < markers.length; i++) {
var geometry = markers[i].getSource().getFeatures()[0].getGeometry();
var coordinate = ol.proj.toLonLat(geometry.getCoordinates());
var point = { $: {
'no': (i + 1),
'action': ((markers[i].action == MWNP.WPTYPE.WAYPOINT) ? 'WAYPOINT' : markers[i].action),
'lon': (Math.round(coordinate[0] * 10000000) / 10000000),
'lat': (Math.round(coordinate[1] * 10000000) / 10000000),
'alt': (markers[i].alt / 100)
} };
if ((markers[i].action == MWNP.WPTYPE.WAYPOINT) && (markers[i].speedValue > 0)) point.$['parameter1'] = markers[i].speedValue;
data.missionitem.push(point);
}
// add last RTH point
if ($('#rthEndMission').is(':checked')) {
data.missionitem.push({ $: { 'no': (markers.length + 1), 'action': 'RTH', 'lon': 0, 'lat': 0, 'alt': (settings.alt / 100), 'parameter1': ($('#rthLanding').is(':checked') ? 1 : 0) } });
}
var builder = new xml2js.Builder({ 'rootName': 'mission', 'renderOpts': { 'pretty': true, 'indent': '\t', 'newline': '\n' } });
var xml = builder.buildObject(data);
fs.writeFile(filename, xml, (err) => {
if (err) {
GUI.log('<span style="color: red">Error writing file</span>');
return console.error(err);
}
GUI.log('File saved');
});
}
function getPointsFromEprom() { function getPointsFromEprom() {
pointForSend = 0; pointForSend = 0;
MSP.send_message(MSPCodes.MSP_WP_GETINFO, false, false, getNextPoint); MSP.send_message(MSPCodes.MSP_WP_GETINFO, false, false, getNextPoint);
@ -551,10 +805,10 @@ TABS.mission_control.initialize = function (callback) {
// console.log(MISSION_PLANER.bufferPoint.alt); // console.log(MISSION_PLANER.bufferPoint.alt);
// console.log(MISSION_PLANER.bufferPoint.action); // console.log(MISSION_PLANER.bufferPoint.action);
if (MISSION_PLANER.bufferPoint.action == 4) { if (MISSION_PLANER.bufferPoint.action == 4) {
$('#rthEndMission').attr('checked', true); $('#rthEndMission').prop('checked', true);
$('#rthSettings').fadeIn(300); $('#rthSettings').fadeIn(300);
if (MISSION_PLANER.bufferPoint.p1 > 0) { if (MISSION_PLANER.bufferPoint.p1 > 0) {
$('#rthLanding').attr('checked', true); $('#rthLanding').prop('checked', true);
} }
} else { } else {
var coord = ol.proj.fromLonLat([MISSION_PLANER.bufferPoint.lon, MISSION_PLANER.bufferPoint.lat]); var coord = ol.proj.fromLonLat([MISSION_PLANER.bufferPoint.lon, MISSION_PLANER.bufferPoint.lat]);