Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Decode LTM telemetry protocol #1988

Merged
merged 14 commits into from
Mar 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions _locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -5603,5 +5603,38 @@
},
"ezTuneNote": {
"message": "<strong>Important</strong> Ez Tune is enabled. All settings on this tab are set and controlled by the Ez Tune. To use PID Tuning tab you have to disable Ez Tune. To do it, uncheck the <strong>Enabled</strong> checkbox on the Ez Tune tab."
},
"gsActivated": {
"message": "Ground station mode activated"
},
"gsDeactivated": {
"message": "Ground station mode deactivated"
},
"gsTelemetry": {
"message": "Telemetry"
},
"gsTelemetryLatitude": {
"message": "Latitude"
},
"gsTelemetryLongitude": {
"message": "Longitude"
},
"gsTelemetryAltitude": {
"message": "Altitude"
},
"gsTelemetryAltitudeShort": {
"message": "Alt"
},
"gsTelemetryVoltageShort": {
"message": "Vbat"
},
"gsTelemetrySats": {
"message": "Sats"
},
"gsTelemetryFix": {
"message": "Fix"
},
"gsTelemetrySpeed": {
"message": "Speed"
}
}
5 changes: 4 additions & 1 deletion gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ sources.css = [
'./node_modules/openlayers/dist/ol.css',
'./src/css/logic.css',
'./src/css/defaults_dialog.css',
'./src/css/groundstation.css',
];

sources.js = [
Expand Down Expand Up @@ -139,7 +140,9 @@ sources.js = [
'./js/libraries/plotly-latest.min.js',
'./js/sitl.js',
'./js/CliAutoComplete.js',
'./node_modules/jquery-textcomplete/dist/jquery.textcomplete.js'
'./node_modules/jquery-textcomplete/dist/jquery.textcomplete.js',
'./js/ltmDecoder.js',
'./js/groundstation.js'
];

sources.receiverCss = [
Expand Down
194 changes: 194 additions & 0 deletions js/groundstation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
'use strict';

var helper = helper || {};

helper.groundstation = (function () {

let publicScope = {},
privateScope = {};

privateScope.activated = false;
privateScope.$viewport = null;
privateScope.$gsViewport = null;
privateScope.mapHandler = null;
privateScope.mapLayer = null;
privateScope.mapView = null;

privateScope.cursorStyle = null;
privateScope.cursorPosition = null;
privateScope.cursorFeature = null;
privateScope.cursorVector = null;
privateScope.cursorLayer = null;

privateScope.textGeometry = null;
privateScope.textFeature = null;
privateScope.textVector = null;
privateScope.textSource = null;

privateScope.mapInitiated = false;

publicScope.isActivated = function () {
return privateScope.activated;
};

publicScope.activate = function ($viewport) {

if (privateScope.activated) {
return;
}

helper.interval.add('gsUpdateGui', privateScope.updateGui, 200);

privateScope.$viewport = $viewport;

privateScope.$viewport.find(".tab_container").hide();
privateScope.$viewport.find('#content').hide();
privateScope.$viewport.find('#status-bar').hide();
privateScope.$viewport.find('#connectbutton a.connect_state').text(chrome.i18n.getMessage('disconnect')).addClass('active');

privateScope.$gsViewport = $viewport.find('#view-groundstation');
privateScope.$gsViewport.show();
privateScope.mapInitiated = false;

setTimeout(privateScope.initMap, 100);

privateScope.activated = true;
GUI.log(chrome.i18n.getMessage('gsActivated'));
}

privateScope.initMap = function () {

//initialte layers
if (globalSettings.mapProviderType == 'bing') {
privateScope.mapLayer = new ol.source.BingMaps({
key: globalSettings.mapApiKey,
imagerySet: 'AerialWithLabels',
maxZoom: 19
});
} else if (globalSettings.mapProviderType == 'mapproxy') {
privateScope.mapLayer = new ol.source.TileWMS({
url: globalSettings.proxyURL,
params: { 'LAYERS': globalSettings.proxyLayer }
})
} else {
privateScope.mapLayer = new ol.source.OSM();
}

//initiate view
privateScope.mapView = new ol.View({
center: ol.proj.fromLonLat([0, 0]),
zoom: 3
});

//initiate map handler
privateScope.mapHandler = new ol.Map({
target: document.getElementById('groundstation-map'),
layers: [
new ol.layer.Tile({
source: privateScope.mapLayer
})
],
view: privateScope.mapView
});
};

publicScope.deactivate = function () {

if (!privateScope.activated) {
return;
}

helper.interval.remove('gsUpdateGui');

if (privateScope.$viewport !== null) {
privateScope.$viewport.find(".tab_container").show();
privateScope.$viewport.find('#content').show();
privateScope.$viewport.find('#status-bar').show();
}

if (privateScope.$gsViewport !== null) {
privateScope.$gsViewport.hide();
}

privateScope.activated = false;
GUI.log(chrome.i18n.getMessage('gsDeactivated'));
}

privateScope.updateGui = function () {

let telemetry = helper.ltmDecoder.get();

if (telemetry.gpsFix && telemetry.gpsFix > 1) {

let lat = telemetry.latitude / 10000000;
let lon = telemetry.longitude / 10000000;

//On first initiation, set zoom to 15
if (!privateScope.mapInitiated) {

//Place UAV on the map
privateScope.cursorStyle = new ol.style.Style({
image: new ol.style.Icon(({
anchor: [0.5, 0.5],
opacity: 1,
scale: 0.6,
src: '../images/icons/icon_mission_airplane.png'
}))
});
privateScope.cursorPosition = new ol.geom.Point(ol.proj.fromLonLat([lon, lat]));

privateScope.cursorFeature = new ol.Feature({
geometry: privateScope.cursorPosition
});

privateScope.cursorFeature.setStyle(privateScope.cursorStyle);

privateScope.cursorVector = new ol.source.Vector({
features: [privateScope.cursorFeature]
});
privateScope.cursorLayer = new ol.layer.Vector({
source: privateScope.cursorVector
});

privateScope.mapHandler.addLayer(privateScope.cursorLayer);

privateScope.mapView.setZoom(17);

privateScope.mapInitiated = true;
}

//Update map center
let position = ol.proj.fromLonLat([lon, lat]);
privateScope.mapView.setCenter(position);

//Update position of cursor
privateScope.cursorPosition.setCoordinates(position);
//Update orientation of cursor
privateScope.cursorStyle.getImage().setRotation((telemetry.heading / 360.0) * 6.28318);



//Update text
privateScope.$viewport.find("#gs-telemetry-latitude").html(lat);
privateScope.$viewport.find("#gs-telemetry-longitude").html(lon);
}

privateScope.$viewport.find("#gs-telemetry-altitude").html(telemetry.altitude / 100.0 + 'm');
privateScope.$viewport.find("#gs-telemetry-voltage").html(telemetry.voltage / 100.0 + 'V');
privateScope.$viewport.find("#gs-telemetry-sats").html(telemetry.gpsSats);
privateScope.$viewport.find("#gs-telemetry-speed").html(telemetry.groundSpeed * 100 + 'm/s');

let fixText = '';
if (telemetry.gpsFix == 3) {
fixText = '3D';
} else if (telemetry.gpsFix == 2) {
fixText = '2D';
} else {
fixText = 'No fix';
}

privateScope.$viewport.find("#gs-telemetry-fix").html(fixText);
};

return publicScope;
})();
Loading