diff --git a/js/msp/MSPHelper.js b/js/msp/MSPHelper.js index 2cc00953d..cb03e98db 100644 --- a/js/msp/MSPHelper.js +++ b/js/msp/MSPHelper.js @@ -198,6 +198,12 @@ var mspHelper = (function () { FC.GPS_DATA.hdop = data.getUint16(14, true); FC.GPS_DATA.eph = data.getUint16(16, true); FC.GPS_DATA.epv = data.getUint16(18, true); + // Check if hwVersion field exists (firmware with extended MSP_GPSSTATISTICS) + if (data.byteLength >= 24) { + FC.GPS_DATA.hwVersion = data.getUint32(20, true); + } else { + FC.GPS_DATA.hwVersion = 0; // Unknown for older firmware + } break; case MSPCodes.MSP2_ADSB_VEHICLE_LIST: var byteOffsetCounter = 0; diff --git a/locale/en/messages.json b/locale/en/messages.json index c16540af6..d1e7a2f8e 100644 --- a/locale/en/messages.json +++ b/locale/en/messages.json @@ -1209,6 +1209,24 @@ "configurationGPSUseGlonass": { "message": "Gps use Glonass Satellites (RU)" }, + "gpsPresetMode": { + "message": "GPS Configuration Preset" + }, + "gpsPresetModeHelp": { + "message": "Choose a preset optimized for your GPS module, or use Manual for custom configuration. Auto-detect will identify your GPS module if connected." + }, + "gpsUpdateRate": { + "message": "GPS Update Rate (Hz)" + }, + "gpsUpdateRateHelp": { + "message": "How often the GPS module sends position updates. Higher rates provide lower latency but may reduce accuracy with multiple constellations on M10 modules." + }, + "gpsAutoDetectFailed": { + "message": "Could not auto-detect GPS module. Please connect flight controller or select manual preset." + }, + "gpsAutoDetectSuccess": { + "message": "GPS module detected:" + }, "tzOffset": { "message": "Timezone Offset" }, diff --git a/tabs/gps.html b/tabs/gps.html index b74cfca21..aa5025adb 100644 --- a/tabs/gps.html +++ b/tabs/gps.html @@ -38,16 +38,45 @@ + +
+ + +
+
+ + + +
+ + +
+
- +
- +
- +
diff --git a/tabs/gps.js b/tabs/gps.js index c882e3737..c148db1db 100644 --- a/tabs/gps.js +++ b/tabs/gps.js @@ -200,6 +200,148 @@ TABS.gps.initialize = function (callback) { gps_ubx_sbas_e.val(FC.MISC.gps_ubx_sbas); + // GPS Preset Configuration + const GPS_PRESETS = { + m8: { + name: "u-blox M8", + galileo: true, + glonass: true, + beidou: true, + rate: 8, + description: [ + "4 GNSS constellations for maximum accuracy", + "8Hz update rate (conservative for M8)", + "Best for: Navigation, position hold, slower aircraft" + ] + }, + 'm9-precision': { + name: "u-blox M9 (Precision Mode)", + galileo: true, + glonass: false, + beidou: true, + rate: 5, + description: [ + "3 GNSS constellations (GPS+Galileo+Beidou) → 32 satellites", + "5Hz update rate, HDOP ~1.0-1.3", + "Best for: Long-range cruise, position hold, navigation missions" + ] + }, + 'm9-sport': { + name: "u-blox M9 (Sport Mode)", + galileo: true, + glonass: false, + beidou: true, + rate: 10, + description: [ + "3 GNSS constellations (GPS+Galileo+Beidou) → 16 satellites", + "10Hz update rate (hardware limit), HDOP ~2.0-2.5", + "Best for: Fast flying, racing, acrobatics, quick response" + ] + }, + m10: { + name: "u-blox M10", + galileo: true, + glonass: false, + beidou: true, + rate: 8, + description: [ + "3 GNSS constellations (GPS+Galileo+Beidou)", + "8Hz update rate (safe for M10 default CPU clock)", + "Best for: General use, balanced performance" + ] + }, + 'm10-highperf': { + name: "u-blox M10 (High-Performance)", + galileo: true, + glonass: true, + beidou: true, + rate: 10, + description: [ + "4 GNSS constellations for maximum satellites", + "10Hz update rate (requires high-performance CPU clock)", + "Only use if you KNOW your M10 has high-performance clock enabled" + ] + }, + manual: { + name: "Manual Settings", + description: [ + "Full control over constellation selection and update rate", + "For advanced users and special requirements" + ] + } + }; + + function detectGPSPreset(hwVersion) { + switch(hwVersion) { + case 800: return 'm8'; + case 900: return 'm9-precision'; // Default to precision mode for better accuracy + case 1000: return 'm10'; + default: return 'manual'; + } + } + + function applyGPSPreset(presetId) { + // Handle special cases first (before checking GPS_PRESETS) + if (presetId === 'manual') { + // Enable all controls + $('.preset-controlled').prop('disabled', false); + $('#gps_ublox_nav_hz').prop('disabled', false); + $('#preset_info').hide(); + return; + } + + if (presetId === 'auto') { + // Try to auto-detect from FC + if (FC.GPS_DATA && FC.GPS_DATA.hwVersion) { + const detectedPreset = detectGPSPreset(FC.GPS_DATA.hwVersion); + applyGPSPreset(detectedPreset); + $('#gps_preset_mode').val(detectedPreset); + GUI.log(i18n.getMessage('gpsAutoDetectSuccess') + ' ' + GPS_PRESETS[detectedPreset].name); + } else { + // Fall back to manual if can't detect + applyGPSPreset('manual'); + $('#gps_preset_mode').val('manual'); + GUI.log(i18n.getMessage('gpsAutoDetectFailed')); + } + return; + } + + // Normal preset application + const preset = GPS_PRESETS[presetId]; + if (!preset) return; + + // Apply preset values (trigger change for state consistency) + $('#gps_use_galileo').prop('checked', preset.galileo).trigger('change'); + $('#gps_use_glonass').prop('checked', preset.glonass).trigger('change'); + $('#gps_use_beidou').prop('checked', preset.beidou).trigger('change'); + $('#gps_ublox_nav_hz').val(preset.rate).trigger('change'); + + // Disable controls (user can see but not edit) + $('.preset-controlled').prop('disabled', true); + $('#gps_ublox_nav_hz').prop('disabled', true); + + // Show preset info + $('#preset_name').text(preset.name); + $('#preset_details').html(preset.description.map(d => `
  • ${d}
  • `).join('')); + $('#preset_info').show(); + } + + // Set up preset mode handler + $('#gps_preset_mode').on('change', function() { + applyGPSPreset($(this).val()); + }); + + // Initialize - try auto-detect if GPS data available, otherwise manual + if (FC.GPS_DATA && FC.GPS_DATA.hwVersion && FC.GPS_DATA.hwVersion > 0) { + // GPS data already available (e.g., from previous tab load) + const detectedPreset = detectGPSPreset(FC.GPS_DATA.hwVersion); + applyGPSPreset(detectedPreset); + $('#gps_preset_mode').val(detectedPreset); + } else { + // GPS data not yet available, default to manual + applyGPSPreset('manual'); + } + let mapView = new View({ center: [0, 0], zoom: 15