1
0
Fork 0
mirror of https://github.com/iNavFlight/inav-configurator.git synced 2025-07-14 20:10:11 +03:00
This commit is contained in:
Andi Kanzler 2023-11-17 10:55:50 -03:00
parent 23a6a01143
commit 4df66d0fc5
10 changed files with 473 additions and 197 deletions

View file

@ -139,7 +139,9 @@ sources.js = [
'./js/libraries/plotly-latest.min.js', './js/libraries/plotly-latest.min.js',
'./js/sitl.js', './js/sitl.js',
'./js/CliAutoComplete.js', './js/CliAutoComplete.js',
'./node_modules/jquery-textcomplete/dist/jquery.textcomplete.js' './node_modules/jquery-textcomplete/dist/jquery.textcomplete.js',
'./js/fwApproach.js',
'./js/fwApproachCollection.js'
]; ];
sources.receiverCss = [ sources.receiverCss = [

View file

@ -65,7 +65,8 @@ var CONFIG,
BOARD_ALIGNMENT, BOARD_ALIGNMENT,
CURRENT_METER_CONFIG, CURRENT_METER_CONFIG,
FEATURES, FEATURES,
RATE_DYNAMICS; RATE_DYNAMICS,
FW_APPROACH;
var FC = { var FC = {
restartRequired: false, restartRequired: false,
@ -543,27 +544,6 @@ var FC = {
SETTINGS = {}; SETTINGS = {};
SAFEHOMES = new SafehomeCollection(); SAFEHOMES = new SafehomeCollection();
RATE_DYNAMICS = {
sensitivityCenter: null,
sensitivityEnd: null,
correctionCenter: null,
correctionEnd: null,
weightCenter: null,
weightEnd: null
};
EZ_TUNE = {
enabled: null,
filterHz: null,
axisRatio: null,
response: null,
damping: null,
stability: null,
aggressiveness: null,
rate: null,
expo: null
};
}, },
getOutputUsages: function() { getOutputUsages: function() {
return { return {

108
js/fwApproach.js Normal file
View file

@ -0,0 +1,108 @@
/*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 () {
number = 0;
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") ? "sealevel" : "ellipsoid";
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;
};

View 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;
};

View file

@ -239,6 +239,9 @@ var MSPCodes = {
MSP2_INAV_LED_STRIP_CONFIG_EX: 0x2048, MSP2_INAV_LED_STRIP_CONFIG_EX: 0x2048,
MSP2_INAV_SET_LED_STRIP_CONFIG_EX: 0x2049, 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_RATE_DYNAMICS: 0x2060,
MSP2_INAV_SET_RATE_DYNAMICS: 0x2061, MSP2_INAV_SET_RATE_DYNAMICS: 0x2061,

View file

@ -1568,24 +1568,13 @@ var mspHelper = (function (gui) {
break; break;
case MSPCodes.MSP2_INAV_SAFEHOME: case MSPCodes.MSP2_INAV_SAFEHOME:
let safehome = new Safehome( let safehome = new Safehome(
data.getUint8(0),
data.getUint8(1), data.getUint8(1),
data.getInt32(2, true), data.getInt32(2, true),
data.getInt32(6, true), data.getInt32(6, true),
data.getInt32(10, true),
data.getInt32(14, true),
data.getUint8(18, true),
data.getInt16(19, true),
data.getInt16(21, true),
data.getUint8(23, true),
data.getUint8(0, true),
); );
if (safehome.getEnabled()) { if (safehome.getEnabled()) {
(async () => { SAFEHOMES.put(safehome);
const elevation = await safehome.getElevationFromServer(globalSettings) * 100;
safehome.setElevation(elevation);
SAFEHOMES.put(safehome);
})();
} }
break; break;
@ -1593,6 +1582,22 @@ var mspHelper = (function (gui) {
console.log('Safehome points saved'); console.log('Safehome points saved');
break; 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: case MSPCodes.MSP2_INAV_RATE_DYNAMICS:
RATE_DYNAMICS.sensitivityCenter = data.getUint8(0); RATE_DYNAMICS.sensitivityCenter = data.getUint8(0);
RATE_DYNAMICS.sensitivityEnd = data.getUint8(1); RATE_DYNAMICS.sensitivityEnd = data.getUint8(1);
@ -3217,6 +3222,37 @@ var mspHelper = (function (gui) {
}; };
}; };
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) { self._getSetting = function (name) {
if (SETTINGS[name]) { if (SETTINGS[name]) {
return Promise.resolve(SETTINGS[name]); return Promise.resolve(SETTINGS[name]);

View file

@ -1,12 +1,8 @@
/*global $*/ /*global $*/
'use strict'; 'use strict';
const ApproachDirection = Object.freeze({
LEFT: 0,
RIGHT: 1,
})
let Safehome = function (enabled, lat, lon, approachAltAsl = 0, landAltAsl = 0, approachDirection = 0, landHeading1 = 0, landHeading2 = 0, isSeaLevelRef = 0, elevation = 0, number = 0) { let Safehome = function (number, enabled, lat, lon) {
var self = {}; var self = {};
@ -53,63 +49,7 @@ let Safehome = function (enabled, lat, lon, approachAltAsl = 0, landAltAsl = 0,
self.setEnabled = function (data) { self.setEnabled = function (data) {
enabled = data; enabled = 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 () { self.cleanup = function () {
number = 0; number = 0;
enabled = 0; enabled = 0;
@ -117,24 +57,5 @@ let Safehome = function (enabled, lat, lon, approachAltAsl = 0, landAltAsl = 0,
lat = 0; lat = 0;
}; };
self.getElevationFromServer = async function (globalSettings) {
let elevation = "N/A";
if (globalSettings.mapProviderType == 'bing') {
let elevationEarthModel = $('#elevationEarthModel').prop("checked") ? "sealevel" : "ellipsoid";
const response = await fetch('http://dev.virtualearth.net/REST/v1/Elevation/List?points='+self.getLatMap()+','+self.getLonMap()+'&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='+self.getLatMap()+','+self.getLonMap());
const myJson = await response.json();
if (myJson.status == "OK" && myJson.results[0].elevation != null) {
elevation = myJson.results[0].elevation;
}
}
return elevation;
}
return self; return self;
}; };

View file

@ -75,20 +75,6 @@ let SafehomeCollection = function () {
buffer.push(specificByte(safehome.getLon(), 1)); buffer.push(specificByte(safehome.getLon(), 1));
buffer.push(specificByte(safehome.getLon(), 2)); buffer.push(specificByte(safehome.getLon(), 2));
buffer.push(specificByte(safehome.getLon(), 3)); buffer.push(specificByte(safehome.getLon(), 3));
buffer.push(specificByte(safehome.getApproachAltAsl(), 0));
buffer.push(specificByte(safehome.getApproachAltAsl(), 1));
buffer.push(specificByte(safehome.getApproachAltAsl(), 2));
buffer.push(specificByte(safehome.getApproachAltAsl(), 3));
buffer.push(specificByte(safehome.getLandAltAsl(), 0));
buffer.push(specificByte(safehome.getLandAltAsl(), 1));
buffer.push(specificByte(safehome.getLandAltAsl(), 2));
buffer.push(specificByte(safehome.getLandAltAsl(), 3));
buffer.push(safehome.getApproachDirection());
buffer.push(specificByte(safehome.getLandHeading1(), 0));
buffer.push(specificByte(safehome.getLandHeading1(), 1));
buffer.push(specificByte(safehome.getLandHeading2(), 0));
buffer.push(specificByte(safehome.getLandHeading2(), 1));
buffer.push(safehome.getIsSeaLevelRef());
} else { } else {
buffer = Array(24).fill(0); buffer = Array(24).fill(0);
buffer[0] = safehomeId; buffer[0] = safehomeId;

View file

@ -303,6 +303,38 @@
<tbody id="waypointOptionsTableBody"> <tbody id="waypointOptionsTableBody">
</tbody> </tbody>
</table> </table>
<div id="wpFwLanding" style="display: none;">
<div class="point">
<span style="font-weight: bold">Fixed Wing landing settings:</span>
</div>
<div class="point">
<label class="point-label-safehome" for="wpApproachAlt">Approach Alt: (cm):</label>
<input type="number" id="wpApproachAlt"></input>
<span id="wpApproachAltM"></span>
</div>
<div class="point">
<label class="point-label-safehome" for="wpLandAlt">Land Alt: (cm):</label>
<input type="number" id="wpLandAlt"></input>
<span id="wpLandAltM"></span>
</div>
<div class="point">
<label class="point-label-safehome" for="wpApproachDirection">Approach direction:</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">Heading 1: (deg):</label>
<input type="number" id="wpLandHeading1"></input>
<input id="wpLandHeading1Excl" type="checkbox" value="0" class="togglemedium" required> Excl.
</div>
<div class="point">
<label class="point-label-safehome" for="wpLandHeading2">Heading 2: (deg):</label>
<input type="number" id="wpLandHeading2"></input>
<input id="wpLandHeading2Excl" type="checkbox" value="0" class="togglemedium" required> Excl.
</div>
</div>
</div> </div>
<!-- <div class="point-radio" id="pointOptionclass" style="display: none"> <!-- <div class="point-radio" id="pointOptionclass" style="display: none">

View file

@ -1,5 +1,7 @@
'use strict'; 'use strict';
const { event } = require('jquery');
//////////////////////////////////// ////////////////////////////////////
// //
// global Parameters definition // global Parameters definition
@ -93,6 +95,7 @@ TABS.mission_control.initialize = function (callback) {
mspHelper.getMissionInfo, mspHelper.getMissionInfo,
//mspHelper.loadWaypoints, //mspHelper.loadWaypoints,
mspHelper.loadSafehomes, mspHelper.loadSafehomes,
mspHelper.loadFwApproach,
function (callback) { function (callback) {
mspHelper.getSetting("nav_fw_land_approach_length").then((data) => { mspHelper.getSetting("nav_fw_land_approach_length").then((data) => {
settings.fwApproachLength = parseInt(data.value); settings.fwApproachLength = parseInt(data.value);
@ -371,7 +374,8 @@ TABS.mission_control.initialize = function (callback) {
////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////
var markers = []; // Layer for Waypoints var markers = []; // Layer for Waypoints
var lines = []; // Layer for lines between waypoints var lines = []; // Layer for lines between waypoints
var safehomeMarkers = []; // layer for Safehome points var safehomeMarkers = []; // layer for Safehome points
var approachLayers = [] // Layers for FW approach
var map; var map;
@ -382,6 +386,7 @@ TABS.mission_control.initialize = function (callback) {
var selectedFeature = null; var selectedFeature = null;
var tempMarker = null; var tempMarker = null;
var disableMarkerEdit = false; var disableMarkerEdit = false;
var selectedFwApproachWp = null;
////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////
// define & init parameters for default Settings // define & init parameters for default Settings
@ -488,6 +493,7 @@ TABS.mission_control.initialize = function (callback) {
} }
const safehome = SAFEHOMES.get()[selectedSafehome]; const safehome = SAFEHOMES.get()[selectedSafehome];
const fwApproach = FW_APPROACH.get()[selectedSafehome];
$safehomeContentBox.append('\ $safehomeContentBox.append('\
<div class="gui_box grey missionPlannerSafehomeBox"> \ <div class="gui_box grey missionPlannerSafehomeBox"> \
@ -550,11 +556,21 @@ TABS.mission_control.initialize = function (callback) {
</div> \ </div> \
'); ');
if (fwApproach.getElevation() == 0) {
(async () => {
const elevation = await fwApproach.getElevationFromServer(safehome.getLonMap(), safehome.getLatMap(), globalSettings) * 100;
fwApproach.setElevation(elevation);
$('#safehomeElevation').text(fwApproach.getElevation() / 100 + " m");
})();
}
const $safehomeBox = $safehomeContentBox.find('.missionPlannerSafehomeBox:last-child'); const $safehomeBox = $safehomeContentBox.find('.missionPlannerSafehomeBox:last-child');
$safehomeBox.find('.spacer_box_title').append(safehome.getNumber() + 1); $safehomeBox.find('.spacer_box_title').append(safehome.getNumber() + 1);
$safehomeBox.find('#deleteSafehome').on('click', () => { $safehomeBox.find('#deleteSafehome').on('click', () => {
SAFEHOMES.drop(safehome.getNumber()); var shNum = safehome.getNumber();
SAFEHOMES.drop(shNum);
FW_APPROACH.clean(shNum);
selectedSafehome = SAFEHOMES.safehomeCount() - 1; selectedSafehome = SAFEHOMES.safehomeCount() - 1;
cleanSafehomeLayers(); cleanSafehomeLayers();
renderSafehomesOnMap(); renderSafehomesOnMap();
@ -575,79 +591,78 @@ TABS.mission_control.initialize = function (callback) {
renderSafehomesOnMap(); renderSafehomesOnMap();
}); });
$safehomeBox.find($('#safehomeSeaLevelRef')).prop('checked', safehome.getIsSeaLevelRef()).change(event => { $safehomeBox.find($('#safehomeSeaLevelRef')).prop('checked', fwApproach.getIsSeaLevelRef()).change(event => {
let isChecked = $(event.currentTarget).prop('checked') ? 1 : 0; let isChecked = $(event.currentTarget).prop('checked') ? 1 : 0;
safehome.setIsSeaLevelRef(isChecked); fwApproach.setIsSeaLevelRef(isChecked);
(async () => { (async () => {
const elevation = await safehome.getElevationFromServer(globalSettings) * 100; const elevation = await fwApproach.getElevationFromServer(safehome.getLonMap(), safehome.getLatMap(), globalSettings) * 100;
safehome.setElevation(elevation); fwApproach.setElevation(elevation);
$('#safehomeElevation').text(elevation / 100); $('#safehomeElevation').text(elevation / 100);
$approachAlt = $safehomeBox.find('#safehomeApproachAlt'); $approachAlt = $safehomeBox.find('#safehomeApproachAlt');
$landAlt = $safehomeBox.find('#safehomeLandAlt'); $landAlt = $safehomeBox.find('#safehomeLandAlt');
if (isChecked) { if (isChecked) {
safehome.setApproachAltAsl(safehome.getApproachAltAsl() + elevation) fwApproach.setApproachAltAsl(fwApproach.getApproachAltAsl() + elevation);
$approachAlt.val(safehome.getApproachAltAsl()); fwApproach.setLandAltAsl(fwApproach.getLandAltAsl() + elevation);
safehome.setLandAltAsl(safehome.getLandAltAsl() + elevation)
$landAlt.val(safehome.getLandAltAsl());
} else { } else {
safehome.setApproachAltAsl(safehome.getApproachAltAsl() - elevation) fwApproach.setApproachAltAsl(fwApproach.getApproachAltAsl() - elevation);
$approachAlt.val(safehome.getApproachAltAsl()); fwApproach.setLandAltAsl(fwApproach.getLandAltAsl() - elevation);
safehome.setLandAltAsl(safehome.getLandAltAsl() - elevation)
$landAlt.val(safehome.getLandAltAsl());
} }
$approachAlt.val(fwApproach.getApproachAltAsl());
$landAlt.val(fwApproach.getLandAltAsl());
$('#safehomeLandAltM').text(safehome.getLandAltAsl() / 100 + " m"); $('#safehomeLandAltM').text(fwApproach.getLandAltAsl() / 100 + " m");
$('#safehomeApproachAltM').text( safehome.getApproachAltAsl() / 100 + " m"); $('#safehomeApproachAltM').text( fwApproach.getApproachAltAsl() / 100 + " m");
})(); })();
}); });
$safehomeBox.find('#safehomeApproachAlt').val(safehome.getApproachAltAsl()).on('change', event => { $safehomeBox.find('#safehomeApproachAlt').val(fwApproach.getApproachAltAsl()).on('change', event => {
let altitude = Number($(event.currentTarget).val()); let altitude = Number($(event.currentTarget).val());
if (checkSafhomeAltitude(altitude, $safehomeBox.find('#safehomeSeaLevelRef').prop('checked'), Number($('#safehomeElevation').text()))) { if (checkLandingAltitude(altitude, $safehomeBox.find('#safehomeSeaLevelRef').prop('checked'), Number($('#safehomeElevation').text()))) {
safehome.setApproachAltAsl(Number($(event.currentTarget).val())); fwApproach.setApproachAltAsl(Number($(event.currentTarget).val()));
$('#safehomeApproachAltM').text( safehome.getApproachAltAsl() / 100 + " m"); $('#safehomeApproachAltM').text( fwApproach.getApproachAltAsl() / 100 + " m");
cleanSafehomeLayers(); cleanSafehomeLayers();
renderSafehomesOnMap(); renderSafehomesOnMap();
renderHomeTable(); renderHomeTable();
} }
$safehomeBox.find('#safehomeApproachAlt').val(safehome.getApproachAltAsl()); $safehomeBox.find('#safehomeApproachAlt').val(fwApproach.getApproachAltAsl());
}); });
$safehomeBox.find('#safehomeLandAlt').val(safehome.getLandAltAsl()).on('change', event => { $safehomeBox.find('#safehomeLandAlt').val(fwApproach.getLandAltAsl()).on('change', event => {
let altitude = Number($(event.currentTarget).val()); let altitude = Number($(event.currentTarget).val());
if (checkSafhomeAltitude(altitude, $safehomeBox.find('#safehomeSeaLevelRef').prop('checked'), Number($('#safehomeElevation').text()))) { if (checkLandingAltitude(altitude, $safehomeBox.find('#safehomeSeaLevelRef').prop('checked'), Number($('#safehomeElevation').text()))) {
safehome.setLandAltAsl(altitude); fwApproach.setLandAltAsl(altitude);
$('#safehomeLandAltM').text(safehome.getLandAltAsl() / 100 + " m"); $('#safehomeLandAltM').text(fwApproach.getLandAltAsl() / 100 + " m");
cleanSafehomeLayers(); cleanSafehomeLayers();
renderSafehomesOnMap(); renderSafehomesOnMap();
renderHomeTable(); renderHomeTable();
} else { } else {
$safehomeBox.find('#safehomeLandAlt').val(safehome.getLandAltAsl()); $safehomeBox.find('#safehomeLandAlt').val(fwApproach.getLandAltAsl());
} }
}); });
$safehomeBox.find('#geozoneApproachDirection').val(safehome.getApproachDirection()).on('change', event => { $safehomeBox.find('#geozoneApproachDirection').val(fwApproach.getApproachDirection()).on('change', event => {
safehome.setApproachDirection($(event.currentTarget).val()); fwApproach.setApproachDirection($(event.currentTarget).val());
cleanSafehomeLayers(); cleanSafehomeLayers();
renderSafehomesOnMap(); renderSafehomesOnMap();
}); });
$safehomeBox.find('#safehomeLandHeading1Excl').prop('checked', safehome.getLandHeading1() < 0).change(event => { $safehomeBox.find('#safehomeLandHeading1Excl').prop('checked', fwApproach.getLandHeading1() < 0).change(event => {
safehome.setLandHeading1(safehome.getLandHeading1() * -1); fwApproach.setLandHeading1(fwApproach.getLandHeading1() * -1);
cleanSafehomeLayers(); cleanSafehomeLayers();
renderSafehomesOnMap(); renderSafehomesOnMap();
}); });
$safehomeBox.find('#safehomeLandHeading1').val(Math.abs(safehome.getLandHeading1())).on('change', event => { $safehomeBox.find('#safehomeLandHeading1').val(Math.abs(fwApproach.getLandHeading1())).on('change', event => {
let val = Number($(event.currentTarget).val()); let val = Number($(event.currentTarget).val());
if (val < 0) { if (val < 0) {
val = 360; val = 360;
@ -662,18 +677,18 @@ TABS.mission_control.initialize = function (callback) {
val *= -1; val *= -1;
} }
safehome.setLandHeading1(val); fwApproach.setLandHeading1(val);
cleanSafehomeLayers(); cleanSafehomeLayers();
renderSafehomesOnMap(); renderSafehomesOnMap();
}); });
$safehomeBox.find('#safehomeLandHeading2Excl').prop('checked', safehome.getLandHeading2() < 0).change(event => { $safehomeBox.find('#safehomeLandHeading2Excl').prop('checked', fwApproach.getLandHeading2() < 0).change(event => {
safehome.setLandHeading2(safehome.getLandHeading2() * -1); fwApproach.setLandHeading2(fwApproach.getLandHeading2() * -1);
cleanSafehomeLayers(); cleanSafehomeLayers();
renderSafehomesOnMap(); renderSafehomesOnMap();
}); });
$safehomeBox.find('#safehomeLandHeading2').val(Math.abs(safehome.getLandHeading2())).on('change', event => { $safehomeBox.find('#safehomeLandHeading2').val(Math.abs(fwApproach.getLandHeading2())).on('change', event => {
let val = Number($(event.currentTarget).val()); let val = Number($(event.currentTarget).val());
if (val < 0) { if (val < 0) {
val = 360; val = 360;
@ -688,22 +703,22 @@ TABS.mission_control.initialize = function (callback) {
val *= -1; val *= -1;
} }
safehome.setLandHeading2(val); fwApproach.setLandHeading2(val);
cleanSafehomeLayers(); cleanSafehomeLayers();
renderSafehomesOnMap(); renderSafehomesOnMap();
}); });
$('#safehomeLandAltM').text(safehome.getLandAltAsl() / 100 + " m"); $('#safehomeLandAltM').text(fwApproach.getLandAltAsl() / 100 + " m");
$('#safehomeApproachAltM').text(safehome.getApproachAltAsl() / 100 + " m"); $('#safehomeApproachAltM').text(fwApproach.getApproachAltAsl() / 100 + " m");
if (safehome.getElevation() != NaN) if (fwApproach.getElevation() != NaN)
$('#safehomeElevation').text(safehome.getElevation() / 100 + " m"); $('#safehomeElevation').text(fwApproach.getElevation() / 100 + " m");
GUI.switchery(); GUI.switchery();
localize(); localize();
} }
function checkSafhomeAltitude(altitude, isSeaLevelRef, sealevel) { function checkLandingAltitude(altitude, isSeaLevelRef, sealevel) {
if (isSeaLevelRef && altitude - sealevel < 0) { if (isSeaLevelRef && altitude - sealevel < 0) {
alert(chrome.i18n.getMessage('MissionPlannerAltitudeChangeReset')); alert(chrome.i18n.getMessage('MissionPlannerAltitudeChangeReset'));
@ -726,11 +741,8 @@ TABS.mission_control.initialize = function (callback) {
let mapCenter = map.getView().getCenter(); let mapCenter = map.getView().getCenter();
let midLon = Math.round(ol.proj.toLonLat(mapCenter)[0] * 1e7); let midLon = Math.round(ol.proj.toLonLat(mapCenter)[0] * 1e7);
let midLat = Math.round(ol.proj.toLonLat(mapCenter)[1] * 1e7); let midLat = Math.round(ol.proj.toLonLat(mapCenter)[1] * 1e7);
var safehome = new Safehome(1, midLat, midLon); SAFEHOMES.put(new Safehome(SAFEHOMES.safehomeCount(), 1, midLat, midLon));
safehome.setNumber(SAFEHOMES.safehomeCount()); selectedSafehome = SAFEHOMES.safehomeCount() - 1;
SAFEHOMES.put(safehome);
selectedSafehome = SAFEHOMES.safehomeCount() - 1;
cleanSafehomeLayers(); cleanSafehomeLayers();
renderSafehomesOnMap(); renderSafehomesOnMap();
@ -749,15 +761,24 @@ TABS.mission_control.initialize = function (callback) {
addSafeHomeMarker(safehome); addSafeHomeMarker(safehome);
}); });
SAFEHOMES.get().forEach(safehome => { SAFEHOMES.get().forEach(safehome => {
addFwApproach(safehome); addFwApproach(safehome.getLonMap(), safehome.getLatMap(), FW_APPROACH.get()[safehome.getNumber()]);
}); });
} }
function cleanApproachLayers()
{
for (var i in approachLayers) {
map.removeLayer(approachLayers[i]);
}
approachLayers = [];
}
function cleanSafehomeLayers() { function cleanSafehomeLayers() {
for (var i in safehomeMarkers) { for (var i in safehomeMarkers) {
map.removeLayer(safehomeMarkers[i]); map.removeLayer(safehomeMarkers[i]);
} }
safehomeMarkers = []; safehomeMarkers = [];
cleanApproachLayers();
} }
function getSafehomeIcon(safehome) { function getSafehomeIcon(safehome) {
@ -836,7 +857,7 @@ TABS.mission_control.initialize = function (callback) {
vectorLayer.kind = "approachline"; vectorLayer.kind = "approachline";
vectorLayer.selection = false; vectorLayer.selection = false;
safehomeMarkers.push(vectorLayer); approachLayers.push(vectorLayer);
map.addLayer(vectorLayer); map.addLayer(vectorLayer);
} }
@ -856,26 +877,26 @@ TABS.mission_control.initialize = function (callback) {
paintApproachLine(pos1, landCoord, '#f78a05'); paintApproachLine(pos1, landCoord, '#f78a05');
} }
function addFwApproach(safehome) function addFwApproach(lon, lat, fwApproach)
{ {
if (safehome.getLandHeading1() != 0) { if (fwApproach.getLandHeading1() != 0) {
let bearing = wrap_360(Math.abs(safehome.getLandHeading1()) + 180); let bearing = wrap_360(Math.abs(fwApproach.getLandHeading1()) + 180);
paintApproach({lat: safehome.getLatMap(), lon: safehome.getLonMap()}, settings.fwApproachLength, bearing, safehome.getApproachDirection()); paintApproach({lat: lat, lon: lon}, settings.fwApproachLength, bearing, fwApproach.getApproachDirection());
} }
if (safehome.getLandHeading1() > 0) { if (fwApproach.getLandHeading1() > 0) {
let direction = safehome.getApproachDirection() == ApproachDirection.LEFT ? ApproachDirection.RIGHT : ApproachDirection.LEFT; let direction = fwApproach.getApproachDirection() == ApproachDirection.LEFT ? ApproachDirection.RIGHT : ApproachDirection.LEFT;
paintApproach({lat: safehome.getLatMap(), lon: safehome.getLonMap()}, settings.fwApproachLength, safehome.getLandHeading1(), direction); paintApproach({lat: lat, lon: lon}, settings.fwApproachLength, fwApproach.getLandHeading1(), direction);
} }
if (safehome.getLandHeading2() != 0) { if (fwApproach.getLandHeading2() != 0) {
let bearing = wrap_360(Math.abs(safehome.getLandHeading2()) + 180); let bearing = wrap_360(Math.abs(fwApproach.getLandHeading2()) + 180);
paintApproach({lat: safehome.getLatMap(), lon: safehome.getLonMap()}, settings.fwApproachLength, bearing, safehome.getApproachDirection()); paintApproach({lat: lat, lon: lon}, settings.fwApproachLength, bearing, fwApproach.getApproachDirection());
} }
if (safehome.getLandHeading2() > 0) { if (fwApproach.getLandHeading2() > 0) {
let direction = safehome.getApproachDirection() == ApproachDirection.LEFT ? ApproachDirection.RIGHT : ApproachDirection.LEFT; let direction = fwApproach.getApproachDirection() == ApproachDirection.LEFT ? ApproachDirection.RIGHT : ApproachDirection.LEFT;
paintApproach({lat: safehome.getLatMap(), lon: safehome.getLonMap()}, settings.fwApproachLength, safehome.getLandHeading2(), direction); paintApproach({lat: lat, lon: lon}, settings.fwApproachLength, fwApproach.getLandHeading2(), direction);
} }
} }
@ -2028,6 +2049,20 @@ TABS.mission_control.initialize = function (callback) {
$('#elevationValueAtWP').text(elevationAtWP); $('#elevationValueAtWP').text(elevationAtWP);
const returnAltitude = checkAltElevSanity(false, mission.getWaypoint(tempMarker.number).getAlt(), elevationAtWP, mission.getWaypoint(tempMarker.number).getP3()); const returnAltitude = checkAltElevSanity(false, mission.getWaypoint(tempMarker.number).getAlt(), elevationAtWP, mission.getWaypoint(tempMarker.number).getP3());
mission.getWaypoint(tempMarker.number).setAlt(returnAltitude); mission.getWaypoint(tempMarker.number).setAlt(returnAltitude);
let approach = FW_APPROACH.get()[SAFEHOMES.getMaxSafehomeCount() + tempMarker.number];
if (approach.getIsSeaLevelRef()) {
if (approach.getElevation() != 0) {
approach.setApproachAltAsl(approach.getApproachAltAsl() - approach.getElevation() + elevationAtWP * 100);
approach.setLandAltAsl(approach.getLandAltAsl() - approach.getElevation() + elevationAtWP * 100);
}
approach.setElevation(elevationAtWP * 100);
$('#wpApproachAlt').val(approach.getApproachAltAsl());
$('#wpLandAlt').val(approach.getLandAltAsl);
$('#wpLandAltM').text(approach.getLandAltAsl() / 100 + " m");
$('#wpApproachAltM').text(approach.getApproachAltAsl() / 100 + " m");
}
plotElevation(); plotElevation();
})() })()
} }
@ -2042,15 +2077,16 @@ TABS.mission_control.initialize = function (callback) {
} }
else if (tempMarker.kind == "safehome") { else if (tempMarker.kind == "safehome") {
(async () => { (async () => {
let approach = FW_APPROACH.get()[tempMarker.number];
let safehome = SAFEHOMES.get()[tempMarker.number]; let safehome = SAFEHOMES.get()[tempMarker.number];
const elevation = await safehome.getElevationFromServer(globalSettings) * 100; const elevation = await approach.getElevationFromServer(safehome.getLonMap(), safehome.getLatMap(), globalSettings) * 100;
$('#safehomeElevation').text(elevation / 100 + " m"); $('#safehomeElevation').text(elevation / 100 + " m");
if (safehome.getIsSeaLevelRef()) { if (approach.getIsSeaLevelRef()) {
if ( safehome.getElevation() != 0) { if (approach.getElevation() != 0) {
safehome.setApproachAltAsl(safehome.getApproachAltAsl() - safehome.getElevation() + elevation); approach.setApproachAltAsl(approach.getApproachAltAsl() - approach.getElevation() + elevation);
safehome.setLandAltAsl(safehome.getLandAltAsl() - safehome.getElevation() + elevation); approach.setLandAltAsl(approach.getLandAltAsl() - approach.getElevation() + elevation);
} }
safehome.setElevation(elevation); approach.setElevation(elevation);
renderSafehomesTable(); renderSafehomesTable();
} }
})() })()
@ -2174,6 +2210,7 @@ TABS.mission_control.initialize = function (callback) {
if (selectedFeature && tempMarker.kind == "waypoint") { if (selectedFeature && tempMarker.kind == "waypoint") {
$("#editMission").hide(); $("#editMission").hide();
selectedMarker = mission.getWaypoint(tempMarker.number); selectedMarker = mission.getWaypoint(tempMarker.number);
selectedFwApproachWp = FW_APPROACH.get()[SAFEHOMES.getMaxSafehomeCount() + selectedMarker.getNumber()];
var geometry = selectedFeature.getGeometry(); var geometry = selectedFeature.getGeometry();
var coord = ol.proj.toLonLat(geometry.getCoordinates()); var coord = ol.proj.toLonLat(geometry.getCoordinates());
@ -2210,6 +2247,15 @@ TABS.mission_control.initialize = function (callback) {
$('#pointP1').val(selectedMarker.getP1()); $('#pointP1').val(selectedMarker.getP1());
$('#pointP2').val(selectedMarker.getP2()); $('#pointP2').val(selectedMarker.getP2());
$('#wpApproachAlt').val(selectedFwApproachWp.getApproachAltAsl());
$('#wpLandAlt').val(selectedFwApproachWp.getLandAltAsl);
$('#wpLandAltM').text(selectedFwApproachWp.getLandAltAsl() / 100 + " m");
$('#wpApproachAltM').text(selectedFwApproachWp.getApproachAltAsl() / 100 + " m");
$('#wpApproachDirection').val(selectedFwApproachWp.getApproachDirection());
$('#wpLandHeading1').val(selectedFwApproachWp.getLandHeading1());
$('#wpLandHeading1Excl1').prop('checked', selectedFwApproachWp.getLandHeading1() < 0);
$('#wpLandHeading2').val(selectedFwApproachWp.getLandHeading2());
$('#wpLandHeading1Excl2').prop('checked', selectedFwApproachWp.getLandHeading2() < 0);
// Selection box update depending on choice of type of waypoint // Selection box update depending on choice of type of waypoint
for (var j in dictOfLabelParameterPoint[selectedMarker.getAction()]) { for (var j in dictOfLabelParameterPoint[selectedMarker.getAction()]) {
@ -2403,6 +2449,13 @@ TABS.mission_control.initialize = function (callback) {
$('#pointType').change(function () { $('#pointType').change(function () {
if (selectedMarker) { if (selectedMarker) {
selectedMarker.setAction(Number($('#pointType').val())); selectedMarker.setAction(Number($('#pointType').val()));
if (selectedMarker.getAction() == MWNP.WPTYPE.LAND) {
$('#wpFwLanding').fadeIn(300);
} else {
$('#wpFwLanding').fadeOut(300);
}
if ([MWNP.WPTYPE.SET_POI,MWNP.WPTYPE.POSHOLD_TIME,MWNP.WPTYPE.LAND].includes(selectedMarker.getAction())) { if ([MWNP.WPTYPE.SET_POI,MWNP.WPTYPE.POSHOLD_TIME,MWNP.WPTYPE.LAND].includes(selectedMarker.getAction())) {
selectedMarker.setP1(0.0); selectedMarker.setP1(0.0);
selectedMarker.setP2(0.0); selectedMarker.setP2(0.0);
@ -2513,6 +2566,24 @@ TABS.mission_control.initialize = function (callback) {
altitudeMeters = app.ConvertCentimetersToMeters(selectedMarker.getAlt()); altitudeMeters = app.ConvertCentimetersToMeters(selectedMarker.getAlt());
$('#altitudeInMeters').text(` ${altitudeMeters}m`); $('#altitudeInMeters').text(` ${altitudeMeters}m`);
if (selectedFwApproachWp && selectedFwApproachWp.getIsSeaLevelRef() != $('#pointP3Alt').prop("checked")) {
selectedFwApproachWp.setIsSeaLevelRef($('#pointP3Alt').prop("checked"));
selectedFwApproachWp.setElevation(elevationAtWP * 100);
if ($('#pointP3Alt').prop("checked")) {
selectedFwApproachWp.setApproachAltAsl(selectedFwApproachWp.getApproachAltAsl() + elevationAtWP * 100);
selectedFwApproachWp.setLandAltAsl(selectedFwApproachWp.getLandAltAsl() + elevationAtWP * 100);
} else {
selectedFwApproachWp.setApproachAltAsl(selectedFwApproachWp.getApproachAltAsl() - elevationAtWP * 100);
selectedFwApproachWp.setLandAltAsl(selectedFwApproachWp.getLandAltAsl() - elevationAtWP * 100);
}
$('#wpApproachAlt').val(selectedFwApproachWp.getApproachAltAsl());
$('#wpLandAlt').val(selectedFwApproachWp.getLandAltAsl());
}
$('#wpLandAltM').text(selectedFwApproachWp.getLandAltAsl() / 100 + " m");
$('#wpApproachAltM').text(selectedFwApproachWp.getApproachAltAsl() / 100 + " m");
mission.updateWaypoint(selectedMarker); mission.updateWaypoint(selectedMarker);
mission.update(singleMissionActive()); mission.update(singleMissionActive());
redrawLayer(); redrawLayer();
@ -2581,6 +2652,49 @@ TABS.mission_control.initialize = function (callback) {
} }
}); });
$('#wpApproachAlt').on('change', (event) => {
if (selectedMarker && selectedFwApproachWp) {
let altitude = Number($(event.currentTarget).val());
if (checkLandingAltitude(altitude, $('#pointP3Alt').prop('checked'), Number($('#elevationValueAtWP').text()))) {
selectedFwApproachWp.setApproachAltAsl(Number($(event.currentTarget).val()));
$('#wpApproachAltM').text(selectedFwApproachWp.getApproachAltAsl() / 100 + " m");
redrawLayer();
}
}
});
$('#wpLandAlt').on('change', (event) => {
if (selectedMarker && selectedFwApproachWp) {
let altitude = Number($(event.currentTarget).val());
if (checkLandingAltitude(altitude, $('#pointP3Alt').prop('checked'), Number($('#elevationValueAtWP').text()))) {
selectedFwApproachWp.setLandAltAsl(Number($(event.currentTarget).val()));
$('#wpLandAltM').text(selectedFwApproachWp.getApproachAltAsl() / 100 + " m");
redrawLayer();
}
}
});
$('#wpApproachDirection').on('change', (event) => {
});
$('#wpLandHeading1').on('change', (event) => {
});
$('#wpLandHeading1Excl1').on('change', (event) => {
});
$('#wpLandHeading2').on('change', (event) => {
});
$('#wpLandHeading1Excl2').on('change', (event) => {
});
///////////////////////////////////////////// /////////////////////////////////////////////
// Callback for Waypoint Options Table // Callback for Waypoint Options Table
///////////////////////////////////////////// /////////////////////////////////////////////
@ -2638,6 +2752,7 @@ TABS.mission_control.initialize = function (callback) {
$(this).addClass('disabled'); $(this).addClass('disabled');
GUI.log(chrome.i18n.getMessage('startGettingSafehomePoints')); GUI.log(chrome.i18n.getMessage('startGettingSafehomePoints'));
mspHelper.loadSafehomes(); mspHelper.loadSafehomes();
mspHelper.loadFwApproach();
setTimeout(function(){ setTimeout(function(){
renderSafehomesTable(); renderSafehomesTable();
cleanSafehomeLayers(); cleanSafehomeLayers();
@ -2653,6 +2768,7 @@ TABS.mission_control.initialize = function (callback) {
$(this).addClass('disabled'); $(this).addClass('disabled');
GUI.log(chrome.i18n.getMessage('startSendingSafehomePoints')); GUI.log(chrome.i18n.getMessage('startSendingSafehomePoints'));
mspHelper.saveSafehomes(); mspHelper.saveSafehomes();
mspHelper.saveFwApproach();
setTimeout(function(){ setTimeout(function(){
mspHelper.saveToEeprom(); mspHelper.saveToEeprom();
GUI.log(chrome.i18n.getMessage('endSendingSafehomePoints')); GUI.log(chrome.i18n.getMessage('endSendingSafehomePoints'));