diff --git a/_locales/en/messages.json b/_locales/en/messages.json
index 7e4a89009..fd8674443 100755
--- a/_locales/en/messages.json
+++ b/_locales/en/messages.json
@@ -3590,6 +3590,12 @@
"osdAlarmGFORCE_AXIS_MAX_HELP": {
"message": "The axes g force elements will start blinking when greater than this value"
},
+ "osdAlarmADSB_MAX_DISTANCE_WARNING": {
+ "message": "Distance in meters of ADSB aircraft that is displayed"
+ },
+ "osdAlarmADSB_MAX_DISTANCE_ALERT": {
+ "message": "Distance inside which ADSB data flashes for proximity warning"
+ },
"osd_current_alarm": {
"message": "Current (A)"
},
@@ -3629,6 +3635,12 @@
"osd_rssi_dbm_alarm": {
"message": "CRSF RSSI dBm Alarm"
},
+ "osd_adsb_distance_warning": {
+ "message": "ADSB distance warning"
+ },
+ "osd_adsb_distance_alert": {
+ "message": "ADSB distance alert"
+ },
"osd_rssi_dbm_alarm_HELP": {
"message": "RSSI indicator blinks below this value. Range: [-130,0]. Zero disables this alarm."
},
diff --git a/js/fc.js b/js/fc.js
index 447eb114a..cf47c58af 100644
--- a/js/fc.js
+++ b/js/fc.js
@@ -29,6 +29,7 @@ var CONFIG,
MOTOR_DATA,
SERVO_DATA,
GPS_DATA,
+ ADSB_VEHICLES,
MISSION_PLANNER,
ANALOG,
ARMING_CONFIG,
@@ -251,6 +252,12 @@ var FC = {
packetCount: 0
};
+ ADSB_VEHICLES = {
+ vehiclesCount: 0,
+ callsignLength: 0,
+ vehicles: []
+ };
+
MISSION_PLANNER = new WaypointCollection();
ANALOG = {
diff --git a/js/msp/MSPCodes.js b/js/msp/MSPCodes.js
index fe28c2a3c..c86be42c5 100644
--- a/js/msp/MSPCodes.js
+++ b/js/msp/MSPCodes.js
@@ -245,5 +245,7 @@ var MSPCodes = {
MSP2_INAV_EZ_TUNE: 0x2070,
MSP2_INAV_EZ_TUNE_SET: 0x2071,
- MSP2_INAV_SELECT_MIXER_PROFILE: 0x2080
+ MSP2_INAV_SELECT_MIXER_PROFILE: 0x2080,
+
+ MSP2_ADSB_VEHICLE_LIST: 0x2090,
};
diff --git a/js/msp/MSPHelper.js b/js/msp/MSPHelper.js
index f54f3ec37..48bba5026 100644
--- a/js/msp/MSPHelper.js
+++ b/js/msp/MSPHelper.js
@@ -186,6 +186,35 @@ var mspHelper = (function (gui) {
GPS_DATA.eph = data.getUint16(16, true);
GPS_DATA.epv = data.getUint16(18, true);
break;
+ case MSPCodes.MSP2_ADSB_VEHICLE_LIST:
+ var byteOffsetCounter = 0;
+ ADSB_VEHICLES.vehicles = [];
+ ADSB_VEHICLES.vehiclesCount = data.getUint8(byteOffsetCounter++);
+ ADSB_VEHICLES.callsignLength = data.getUint8(byteOffsetCounter++);
+
+ for(i = 0; i < ADSB_VEHICLES.vehiclesCount; i++){
+
+ var vehicle = {callSignByteArray: [], callsign: "", icao: 0, lat: 0, lon: 0, alt: 0, heading: 0, ttl: 0, tslc: 0, emitterType: 0};
+
+ for(ii = 0; ii < ADSB_VEHICLES.callsignLength; ii++){
+ vehicle.callSignByteArray.push(data.getUint8(byteOffsetCounter++));
+ }
+
+ vehicle.callsign = (String.fromCharCode(...vehicle.callSignByteArray)).replace(/[^\x20-\x7E]/g, '');
+ vehicle.icao = data.getUint32(byteOffsetCounter, true); byteOffsetCounter += 4;
+ vehicle.lat = data.getInt32(byteOffsetCounter, true); byteOffsetCounter += 4;
+ vehicle.lon = data.getInt32(byteOffsetCounter, true); byteOffsetCounter += 4;
+ vehicle.altCM = data.getInt32(byteOffsetCounter, true); byteOffsetCounter += 4;
+ vehicle.headingDegrees = data.getUint16(byteOffsetCounter, true); byteOffsetCounter += 2;
+ vehicle.tslc = data.getUint8(byteOffsetCounter++);
+ vehicle.emitterType = data.getUint8(byteOffsetCounter++);
+ vehicle.ttl = data.getUint8(byteOffsetCounter++);
+
+ ADSB_VEHICLES.vehicles.push(vehicle);
+ }
+
+ break;
+
case MSPCodes.MSP_ATTITUDE:
SENSOR_DATA.kinematics[0] = data.getInt16(0, true) / 10.0; // x
SENSOR_DATA.kinematics[1] = data.getInt16(2, true) / 10.0; // y
diff --git a/resources/adsb/adsb_1.png b/resources/adsb/adsb_1.png
new file mode 100644
index 000000000..838abaf31
Binary files /dev/null and b/resources/adsb/adsb_1.png differ
diff --git a/resources/adsb/adsb_10.png b/resources/adsb/adsb_10.png
new file mode 100644
index 000000000..b4bce66ad
Binary files /dev/null and b/resources/adsb/adsb_10.png differ
diff --git a/resources/adsb/adsb_11.png b/resources/adsb/adsb_11.png
new file mode 100644
index 000000000..f9fec1e66
Binary files /dev/null and b/resources/adsb/adsb_11.png differ
diff --git a/resources/adsb/adsb_12.png b/resources/adsb/adsb_12.png
new file mode 100644
index 000000000..5a5477d50
Binary files /dev/null and b/resources/adsb/adsb_12.png differ
diff --git a/resources/adsb/adsb_13.png b/resources/adsb/adsb_13.png
new file mode 100644
index 000000000..a6b2e3ffc
Binary files /dev/null and b/resources/adsb/adsb_13.png differ
diff --git a/resources/adsb/adsb_14.png b/resources/adsb/adsb_14.png
new file mode 100644
index 000000000..e8c915330
Binary files /dev/null and b/resources/adsb/adsb_14.png differ
diff --git a/resources/adsb/adsb_15.png b/resources/adsb/adsb_15.png
new file mode 100644
index 000000000..e2f54672a
Binary files /dev/null and b/resources/adsb/adsb_15.png differ
diff --git a/resources/adsb/adsb_2.png b/resources/adsb/adsb_2.png
new file mode 100644
index 000000000..a319bf54e
Binary files /dev/null and b/resources/adsb/adsb_2.png differ
diff --git a/resources/adsb/adsb_3.png b/resources/adsb/adsb_3.png
new file mode 100644
index 000000000..8e3134b03
Binary files /dev/null and b/resources/adsb/adsb_3.png differ
diff --git a/resources/adsb/adsb_4.png b/resources/adsb/adsb_4.png
new file mode 100644
index 000000000..69bdd0496
Binary files /dev/null and b/resources/adsb/adsb_4.png differ
diff --git a/resources/adsb/adsb_5.png b/resources/adsb/adsb_5.png
new file mode 100644
index 000000000..d04f39dda
Binary files /dev/null and b/resources/adsb/adsb_5.png differ
diff --git a/resources/adsb/adsb_6.png b/resources/adsb/adsb_6.png
new file mode 100644
index 000000000..55bb74d1c
Binary files /dev/null and b/resources/adsb/adsb_6.png differ
diff --git a/resources/adsb/adsb_7.png b/resources/adsb/adsb_7.png
new file mode 100644
index 000000000..76b24a71e
Binary files /dev/null and b/resources/adsb/adsb_7.png differ
diff --git a/resources/adsb/adsb_8.png b/resources/adsb/adsb_8.png
new file mode 100644
index 000000000..c302bcde7
Binary files /dev/null and b/resources/adsb/adsb_8.png differ
diff --git a/resources/adsb/adsb_9.png b/resources/adsb/adsb_9.png
new file mode 100644
index 000000000..3b6e77796
Binary files /dev/null and b/resources/adsb/adsb_9.png differ
diff --git a/tabs/gps.js b/tabs/gps.js
index 074eb9627..e0d9a65c1 100644
--- a/tabs/gps.js
+++ b/tabs/gps.js
@@ -9,6 +9,32 @@ TABS.gps.initialize = function (callback) {
googleAnalytics.sendAppView('GPS');
}
+ // mavlink ADSB_EMITTER_TYPE
+ const ADSB_VEHICLE_TYPE = {
+ 0: 'adsb_14.png', // ADSB_EMITTER_TYPE_NO_INFO
+ 1: 'adsb_1.png', // ADSB_EMITTER_TYPE_LIGHT
+ 2: 'adsb_1.png', // ADSB_EMITTER_TYPE_SMALL
+ 3: 'adsb_2.png', // ADSB_EMITTER_TYPE_LARGE
+ 4: 'adsb_14.png', // ADSB_EMITTER_TYPE_HIGH_VORTEX_LARGE
+ 5: 'adsb_5.png', // ADSB_EMITTER_TYPE_HEAVY
+ 6: 'adsb_14.png', // ADSB_EMITTER_TYPE_HIGHLY_MANUV
+ 7: 'adsb_13.png', // ADSB_EMITTER_TYPE_ROTOCRAFT
+ 8: 'adsb_14.png', // ADSB_EMITTER_TYPE_UNASSIGNED
+ 9: 'adsb_6.png', // ADSB_EMITTER_TYPE_GLIDER
+ 10: 'adsb_7.png', // ADSB_EMITTER_TYPE_LIGHTER_AIR
+ 11: 'adsb_15.png', // ADSB_EMITTER_TYPE_PARACHUTE
+ 12: 'adsb_1.png', // ADSB_EMITTER_TYPE_ULTRA_LIGHT
+ 13: 'adsb_14.png', // ADSB_EMITTER_TYPE_UNASSIGNED2
+ 14: 'adsb_8.png', // ADSB_EMITTER_TYPE_UAV
+ 15: 'adsb_14.png', // ADSB_EMITTER_TYPE_SPACE
+ 16: 'adsb_14.png', // ADSB_EMITTER_TYPE_UNASSGINED3
+ 17: 'adsb_9.png', // ADSB_EMITTER_TYPE_EMERGENCY_SURFACE
+ 18: 'adsb_10.png', // ADSB_EMITTER_TYPE_SERVICE_SURFACE
+ 19: 'adsb_12.png', // ADSB_EMITTER_TYPE_POINT_OBSTACLE
+ };
+
+
+
var loadChainer = new MSPChainerClass();
var loadChain = [
@@ -58,6 +84,10 @@ TABS.gps.initialize = function (callback) {
let iconGeometry;
let iconFeature;
+ let vehicleVectorSource;
+ let vehiclesCursorInitialized = false;
+
+
function process_html() {
localize();
@@ -131,6 +161,36 @@ TABS.gps.initialize = function (callback) {
view: mapView
});
+ TABS.gps.toolboxAdsbVehicle = new jBox('Mouse', {
+ position: {
+ x: "right",
+ y: "bottom"
+ },
+ offset: {
+ x: -5,
+ y: 20,
+ },
+ });
+
+ mapHandler.on('pointermove', function(evt) {
+ var feature = mapHandler.forEachFeatureAtPixel(mapHandler.getEventPixel(evt.originalEvent), function(feature, layer) {
+ return feature;
+ });
+
+ if (feature) {
+ TABS.gps.toolboxAdsbVehicle.setContent(
+ `icao: ` + feature.get('name') + `
`
+ + `lat: `+ (feature.get('data').lat / 10000000) + `
`
+ + `lon: `+ (feature.get('data').lon / 10000000) + `
`
+ + `ASL: `+ (feature.get('data').altCM ) / 100 + `m
`
+ + `heading: `+ feature.get('data').headingDegrees + `°
`
+ + `type: `+ feature.get('data').emitterType + ``
+ ).open();
+ }else{
+ TABS.gps.toolboxAdsbVehicle.close();
+ }
+ });
+
let center = ol.proj.fromLonLat([0, 0]);
mapView.setCenter(center);
mapView.setZoom(2);
@@ -221,6 +281,66 @@ TABS.gps.initialize = function (callback) {
iconGeometry.setCoordinates(center);
}
+
+ if (semver.gte(CONFIG.flightControllerVersion, "7.1.0")) {
+ MSP.send_message(MSPCodes.MSP2_ADSB_VEHICLE_LIST, false, false, function () {
+ //ADSB vehicles
+
+ if (vehiclesCursorInitialized) {
+ vehicleVectorSource.clear();
+ }
+
+ for (let key in ADSB_VEHICLES.vehicles) {
+ let vehicle = ADSB_VEHICLES.vehicles[key];
+
+ if (!vehiclesCursorInitialized) {
+ vehiclesCursorInitialized = true;
+
+ vehicleVectorSource = new ol.source.Vector({});
+
+ let vehicleLayer = new ol.layer.Vector({
+ source: vehicleVectorSource
+ });
+
+ mapHandler.addLayer(vehicleLayer);
+ }
+
+ if (vehicle.lat > 0 && vehicle.lon > 0 && vehicle.ttl > 0) {
+ let vehicleIconStyle = new ol.style.Style({
+ image: new ol.style.Icon(({
+ opacity: 1,
+ rotation: vehicle.headingDegrees * (Math.PI / 180),
+ scale: 0.8,
+ anchor: [0.5, 0.5],
+ src: '../resources/adsb/' + ADSB_VEHICLE_TYPE[vehicle.emitterType],
+ })),
+ text: new ol.style.Text(({
+ text: vehicle.callsign,
+ textAlign: 'center',
+ textBaseline: "bottom",
+ offsetY: +40,
+ padding: [2, 2, 2, 2],
+ backgroundFill: '#444444',
+ fill: new ol.style.Fill({color: '#ffffff'}),
+ })),
+ });
+
+
+ let iconGeometry = new ol.geom.Point(ol.proj.fromLonLat([vehicle.lon / 10000000, vehicle.lat / 10000000]));
+ let iconFeature = new ol.Feature({
+ geometry: iconGeometry,
+ name: vehicle.callsign,
+ type: 'adsb',
+ data: vehicle,
+ });
+
+ iconFeature.setStyle(vehicleIconStyle);
+ vehicleVectorSource.addFeature(iconFeature);
+ }
+ }
+ });
+ }
+
}
/*
@@ -271,4 +391,7 @@ TABS.gps.initialize = function (callback) {
TABS.gps.cleanup = function (callback) {
if (callback) callback();
+ if(TABS.gps.toolboxAdsbVehicle){
+ TABS.gps.toolboxAdsbVehicle.close();
+ }
};
diff --git a/tabs/osd.html b/tabs/osd.html
index 99d215b5e..f9489d713 100644
--- a/tabs/osd.html
+++ b/tabs/osd.html
@@ -242,6 +242,16 @@