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 @@

+
+ +
+
diff --git a/tabs/osd.js b/tabs/osd.js index 95393953d..f3dbc8d4b 100644 --- a/tabs/osd.js +++ b/tabs/osd.js @@ -114,6 +114,7 @@ SYM.FLIGHT_DIST_REMAINING = 0x167; SYM.GROUND_COURSE = 0xDC; SYM.ALERT = 0xDD; SYM.CROSS_TRACK_ERROR = 0xFC; +SYM.ADSB = 0xFD; SYM.PAN_SERVO_IS_OFFSET_L = 0x1C7; SYM.ODOMETER = 0X168; SYM.PILOT_LOGO_SML_L = 0x1D5; @@ -480,6 +481,8 @@ OSD.initData = function () { imu_temp_alarm_max: null, baro_temp_alarm_min: null, baro_temp_alarm_max: null, + adsb_distance_warning: null, + adsb_distance_alert: null, }, layouts: [], layout_count: 1, // This needs to be 1 for compatibility with < 2.0 @@ -781,6 +784,24 @@ OSD.constants = { min: -55, max: 125 }, + { + name: 'ADSB_MAX_DISTANCE_WARNING', + field: 'adsb_distance_warning', + step: 1, + unit: "meters", + min: 1, + max: 64000, + min_version: '7.1.0', + }, + { + name: 'ADSB_MAX_DISTANCE_ALERT', + field: 'adsb_distance_alert', + step: 1, + unit: "meters", + min: 1, + max: 64000, + min_version: '7.1.0', + }, ], // All display fields, from every version, do not remove elements, only add! @@ -1654,6 +1675,18 @@ OSD.constants = { min_version: '6.0.0', preview: FONT.symbol(SYM.GROUND_COURSE) + '245' + FONT.symbol(SYM.DEGREES) }, + { + name: 'ADSB_WARNING_MESSAGE', + id: 147, + min_version: '7.1.0', + preview: FONT.symbol(SYM.ADSB) + '19.25' + FONT.symbol(SYM.DIR_TO_HOME+1) + '2.75', + }, + { + name: 'ADSB_INFO', + id: 148, + min_version: '7.1.0', + preview: FONT.symbol(SYM.ADSB) + '2', + }, { name: 'CROSS TRACK ERROR', id: 141, @@ -2264,6 +2297,8 @@ OSD.msp = { result.push16(OSD.data.alarms.imu_temp_alarm_max); result.push16(OSD.data.alarms.baro_temp_alarm_min); result.push16(OSD.data.alarms.baro_temp_alarm_max); + result.push16(OSD.data.alarms.adsb_distance_warning); + result.push16(OSD.data.alarms.adsb_distance_alert); return result; }, @@ -2283,6 +2318,8 @@ OSD.msp = { OSD.data.alarms.imu_temp_alarm_max = alarms.read16(); OSD.data.alarms.baro_temp_alarm_min = alarms.read16(); OSD.data.alarms.baro_temp_alarm_max = alarms.read16(); + OSD.data.alarms.adsb_distance_warning = alarms.read16(); + OSD.data.alarms.adsb_distance_alert = alarms.read16(); }, encodePreferences: function() {