Skip to content

* add ADSB areas to GPS map#2569

Open
error414 wants to merge 3 commits intoiNavFlight:maintenance-10.xfrom
error414:error414/feature/adsb-intercept-calc
Open

* add ADSB areas to GPS map#2569
error414 wants to merge 3 commits intoiNavFlight:maintenance-10.xfrom
error414:error414/feature/adsb-intercept-calc

Conversation

@error414
Copy link
Copy Markdown
Contributor

@error414 error414 commented Feb 18, 2026

#PR related to iNavFlight/inav#11346

New:

  1. map in GPS tab is spread to whole visible screen
  2. new table for adsb contacts
  3. marked plane warning or alert is coloured
image

@error414 error414 force-pushed the error414/feature/adsb-intercept-calc branch from 101344e to ce1c791 Compare February 20, 2026 07:15
@error414 error414 changed the base branch from maintenance-9.x to maintenance-10.x March 7, 2026 07:12
@error414 error414 changed the base branch from maintenance-10.x to maintenance-9.x March 7, 2026 08:03
@error414 error414 force-pushed the error414/feature/adsb-intercept-calc branch 3 times, most recently from b118ba2 to f870324 Compare March 21, 2026 18:41
@error414 error414 force-pushed the error414/feature/adsb-intercept-calc branch from f870324 to 49de051 Compare April 12, 2026 18:14
@error414 error414 force-pushed the error414/feature/adsb-intercept-calc branch from a7cf4ea to 1bf80b2 Compare April 12, 2026 18:23
@error414 error414 changed the base branch from maintenance-9.x to maintenance-10.x April 12, 2026 18:25
@error414 error414 marked this pull request as ready for review April 13, 2026 18:45
@qodo-code-review
Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Add ADSB warning system and vehicle table to GPS map

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Add ADSB warning/alert system with distance-based circular zones
• Implement ADSB vehicle table displaying all tracked aircraft details
• Expand GPS map to full screen with improved layout and styling
• Add MSP protocol support for ADSB limits and warning vehicle data
• Color-code ADSB table rows for alert/warning/normal/stale states
Diagram
flowchart LR
  A["MSP Protocol<br/>New Codes"] -->|MSP2_ADSB_LIMITS| B["ADSB Limits<br/>Distance Config"]
  A -->|MSP2_ADSB_WARNING_VEHICLE_ICAO| C["Warning Vehicle<br/>ICAO Data"]
  B --> D["GPS Map<br/>Alert/Warning Circles"]
  C --> E["ADSB Vehicle Table<br/>Color-coded Rows"]
  D --> F["Enhanced GPS Tab<br/>Full Screen Display"]
  E --> F
Loading

Grey Divider

File Changes

1. js/fc.js ✨ Enhancement +13/-0

Add ADSB limits and warning ICAO data structures

• Added ADSB_LIMITS object to store distance alert/warning thresholds
• Added ADSB_WARNING_ICAO object to track current warning vehicle ICAO and alert status
• Extended FC data model to support new ADSB warning features

js/fc.js


2. js/msp/MSPCodes.js ✨ Enhancement +2/-0

Define new MSP protocol codes for ADSB

• Added MSP2_ADSB_LIMITS code (0x2091) for distance configuration
• Added MSP2_ADSB_WARNING_VEHICLE_ICAO code (0x2092) for warning vehicle data

js/msp/MSPCodes.js


3. js/msp/MSPHelper.js ✨ Enhancement +18/-1

Implement ADSB MSP message parsing and loading

• Added parser for MSP2_ADSB_LIMITS to extract distance thresholds
• Added parser for MSP2_ADSB_WARNING_VEHICLE_ICAO to extract warning vehicle ICAO and alert flag
• Added loadADSBLimits() function to request ADSB limits from FC
• Added loadADSBWarningIcao() function to request warning vehicle data from FC

js/msp/MSPHelper.js


View more (4)
4. tabs/gps.js ✨ Enhancement +170/-10

Add ADSB table rendering and warning zone visualization

• Added renderAdsbListTable() function to dynamically render ADSB vehicle table with color-coded
 rows
• Added circular warning and alert zones around aircraft position based on distance limits
• Modified get_raw_adsb_data() to fetch warning vehicle data after vehicle list
• Updated tooltip to display ICAO code and use i18n for localization
• Added logic to show/hide warning rows and vehicle table based on vehicle count
• Imported Stroke and circular polygon utilities for map visualization

tabs/gps.js


5. tabs/gps.html ✨ Enhancement +12/-0

Add ADSB warning and vehicle list HTML elements

• Added table rows for warning ICAO display and warning type indicator
• Added container row for ADSB vehicle list table
• Rows are initially hidden and shown dynamically when vehicles are detected

tabs/gps.html


6. src/css/tabs/gps.css ✨ Enhancement +70/-13

Style GPS map and ADSB vehicle table layout

• Added flexbox layout for full-screen GPS map display
• Changed map height from fixed 400px to calc(100vh - 305px) for responsive sizing
• Added styling for ADSB vehicle table with color-coded rows (alert red, warning orange, normal
 white)
• Added table wrapper with horizontal scrolling support
• Added stale vehicle row styling with reduced opacity

src/css/tabs/gps.css


7. locale/en/messages.json 📝 Documentation +33/-0

Add ADSB localization strings

• Added i18n messages for ADSB table columns: adsbCallsign, adsbAlt, adsbHeading, adsbType,
 adsbEmitter
• Added i18n messages for warning display: adsbAlert, adsbWarning, adsbNoWarning,
 adsbWarningIcao, adsbWarningType

locale/en/messages.json


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown
Contributor

qodo-code-review bot commented Apr 13, 2026

Code Review by Qodo

🐞 Bugs (5)   📘 Rule violations (2)   📎 Requirement gaps (0)
🐞\ ≡ Correctness (2) ☼ Reliability (2) ⛨ Security (1)
📘\ ☼ Reliability (1) ⚙ Maintainability (1)

Grey Divider


Action required

1. ICAO/TSLC headers hardcoded 📘
Description
The ADSB vehicle table UI introduces multiple user-facing strings as hardcoded literals (e.g.,
ICAO, TSLC, TTL, No vehicles, , unit suffixes), bypassing i18next translation keys. This
breaks internationalization coverage and violates the project requirement to avoid hardcoded UI
text.
Code

tabs/gps.js[R142-170]

+            [
+                i18n.getMessage('adsbCallsign'),
+                'ICAO',
+                i18n.getMessage('gpsLat'),
+                i18n.getMessage('gpsLon'),
+                i18n.getMessage('adsbAlt'),
+                i18n.getMessage('adsbHeading'),
+                'TSLC',
+                'TTL',
+                i18n.getMessage('adsbEmitter')
+            ].forEach(function(col) {
+                $headerRow.append($('<th>').addClass('adsb-table__header').text(col));
+            });
+            $thead.append($headerRow);
+            $table.append($thead);
+            $table.append($('<tbody>').addClass('adsb-table__body'));
+
+            var $wrapper = $('<div>').addClass('adsb-table__wrapper').append($table);
+            $('.adsbVehicleList').empty().append($wrapper);
+        }
+
+        var $tbody = $('.adsb-table__body');
+
+        if (FC.ADSB_VEHICLES.vehicles.length === 0) {
+            $tbody.empty();
+            $tbody.append(
+                $('<tr>').append(
+                    $('<td>').attr('colspan', 9).addClass('adsb-table__empty').text('No vehicles')
+                )
Evidence
PR Compliance ID 3 requires UI-visible text to be provided via i18next translation keys (e.g.,
data-i18n/i18n.getMessage) rather than hardcoded strings. The new ADSB table construction uses
multiple hardcoded literals that will not be translated.

CLAUDE.md
tabs/gps.js[142-170]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The ADSB list table renders user-facing strings as hardcoded literals (e.g., `ICAO`, `TSLC`, `TTL`, `No vehicles`, `—`, and unit suffixes like `m`, `°`, `s`) instead of using i18next translation keys.

## Issue Context
Per i18n compliance requirements, all UI-visible text must be localizable via i18next (commonly `data-i18n` in HTML or `i18n.getMessage()` in JS for dynamically created elements).

## Fix Focus Areas
- tabs/gps.js[142-170]
- locale/en/messages.json[6201-6236]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. GPS tab load hangs 🐞
Description
The GPS tab load chain now includes mspHelper.loadADSBLimits; if the FC doesn’t respond
(unsupported/disabled), the chainer callback is never invoked and load_html() never runs. This can
make the GPS tab fail to render indefinitely.
Code

tabs/gps.js[R73-78]

    var loadChain = [
        mspHelper.loadFeatures,
        mspHelper.loadSerialPorts,
-        mspHelper.loadMiscV2
+        mspHelper.loadMiscV2,
+        mspHelper.loadADSBLimits,
    ];
Evidence
MSPChainer only advances when the per-step callback is called; loadADSBLimits relies on an MSP
response to call that callback, and on timeout the serial queue removes the callback and retries
without invoking onFinish, so the chainer can stall forever.

tabs/gps.js[71-82]
js/msp/MSPchainer.js[20-32]
js/msp/MSPHelper.js[2946-2952]
js/serial_queue.js[137-166]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`mspHelper.loadADSBLimits` was added to the GPS tab `loadChain`. If the FC doesn’t respond to `MSP2_ADSB_LIMITS`, the MSP chainer never reaches `load_html()`, so the GPS tab can hang on load.

### Issue Context
`MSPChainerClass` requires each step to call `returnCallback` to proceed. MSP timeouts in `serial_queue.js` do not invoke the original request callback.

### Fix Focus Areas
- tabs/gps.js[73-82]
- js/msp/MSPHelper.js[2950-2952]

### Suggested fix
- Remove `mspHelper.loadADSBLimits` from the blocking `loadChain`.
- Trigger ADSB-limits loading after the tab has rendered and only when ADSB is actually enabled/visible (e.g., inside the existing `semver.gte(..., "8.0.0")` + MAVLink telemetry check).
- Ensure UI behavior is safe if limits never arrive (keep defaults and render accordingly).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. ADSB MSP parse can crash 🐞
Description
MSPHelper parses MSP2_ADSB_LIMITS and MSP2_ADSB_WARNING_VEHICLE_ICAO without checking payload length
or unsupported responses, which can throw RangeError on short payloads. An exception inside
MSP.processData prevents freeing the serial hard-lock, potentially breaking all subsequent MSP
traffic.
Code

js/msp/MSPHelper.js[R231-240]

+            case MSPCodes.MSP2_ADSB_LIMITS:
+                FC.ADSB_LIMITS.adsb_distance_warning = data.getUint16(0, true);
+                FC.ADSB_LIMITS.adsb_distance_alert = data.getUint16(2, true);
+                FC.ADSB_LIMITS.adsb_ignore_plane_above_me_limit = data.getUint16(4, true);
+                break;
+            case MSPCodes.MSP2_ADSB_WARNING_VEHICLE_ICAO:
+                FC.ADSB_WARNING_ICAO = {}
+                FC.ADSB_WARNING_ICAO.icao = data.getUint32(0, true);
+                FC.ADSB_WARNING_ICAO.isAlert = data.getUint8(4, true);
+                break;
Evidence
The new handlers read fixed offsets (0..4) unconditionally; MSP._dispatch_message doesn’t catch
processData exceptions and the hard-lock release is after processData in the try block, so a thrown
exception can leave the lock uncleared.

js/msp/MSPHelper.js[231-240]
js/msp.js[264-283]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
New MSP parsers for `MSP2_ADSB_LIMITS` and `MSP2_ADSB_WARNING_VEHICLE_ICAO` read DataView offsets without validating `data.byteLength` and without handling unsupported/empty replies. This can throw and also prevent releasing the MSP hard-lock.

### Issue Context
For robustness, other optional MSP2 handlers in `MSPHelper.processData` commonly guard on `data.byteLength` and/or `dataHandler.unsupported` before reading offsets.

### Fix Focus Areas
- js/msp/MSPHelper.js[231-240]
- js/msp.js[264-283]

### Suggested fix
- Add guards:
 - `MSP2_ADSB_LIMITS`: require `data.byteLength >= 6` (3x uint16)
 - `MSP2_ADSB_WARNING_VEHICLE_ICAO`: require `data.byteLength >= 5` (uint32 + uint8)
 - If insufficient/unsupported, keep defaults (don’t throw) and optionally log a warning.
- Avoid assigning `FC.ADSB_WARNING_ICAO = {}`; instead set fields on the existing object so defaults remain intact.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (1)
4. Callsign HTML injection 🐞
Description
The ADSB callsign is interpolated into an HTML tooltip string without escaping, and callsign
sanitization allows '<' and '>' characters. A crafted callsign can inject arbitrary markup into the
tooltip content.
Code

tabs/gps.js[R363-369]

+                    `ICAO: <strong>0x${(feature.get('data').icao >>> 0).toString(16).toUpperCase().padStart(6, '0')}</strong><br />
+                    ${i18n.getMessage('adsbCallsign')}: <strong>${feature.get('name')}</strong><br /> 
+                    ${i18n.getMessage('gpsLat')}: <strong>${feature.get('data').lat / 10000000}</strong><br /> 
+                    ${i18n.getMessage('gpsLon')}: <strong>${feature.get('data').lon / 10000000}</strong><br />
+                    ${i18n.getMessage('adsbAsl')}: <strong>${(feature.get('data').altCM) / 100}m</strong><br /> 
+                    ${i18n.getMessage('adsbHeading')}: <strong>${feature.get('data').headingDegrees}°</strong><br /> 
+                    ${i18n.getMessage('adsbType')}: <strong>${ADSB_VEHICLE_TYPE[feature.get('data').emitterType].name}</strong>`
Evidence
The callsign is only filtered to printable ASCII, which includes '<' and '>'; the tooltip content is
built as an HTML string containing <strong>${feature.get('name')}</strong>, so the callsign
becomes part of rendered HTML.

js/msp/MSPHelper.js[212-219]
tabs/gps.js[356-370]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The ADSB callsign is inserted into an HTML template string for the tooltip without escaping. Callsigns are sourced from external RF data and can contain characters like `<` and `>`.

### Issue Context
The code intentionally passes HTML tags (`<strong>`, `<br />`) into `setContent`, so the content is interpreted as HTML.

### Fix Focus Areas
- js/msp/MSPHelper.js[212-219]
- tabs/gps.js[356-370]

### Suggested fix
- Escape callsign before interpolation OR build the tooltip content via DOM nodes:
 - e.g., create a container element and append text nodes for values (`$('<span>').text(feature.get('name'))`).
- Keep the existing formatting, but ensure any externally-derived strings (callsign, possibly other fields) are inserted as text, not raw HTML.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

5. ADSB_VEHICLE_TYPE lookup unguarded 📘
Description
The new tooltip content dereferences ADSB_VEHICLE_TYPE[feature.get('data').emitterType].name
without validating that the lookup exists. If emitterType is missing or out of range, this can
throw at runtime and break the GPS tab UI.
Code

tabs/gps.js[369]

+                    ${i18n.getMessage('adsbType')}: <strong>${ADSB_VEHICLE_TYPE[feature.get('data').emitterType].name}</strong>`
Evidence
PR Compliance ID 5 requires defensive guards before accessing nested properties that may be
undefined. The added code indexes a map and immediately reads .name without a fallback when the
indexed entry is undefined.

tabs/gps.js[369-369]
Best Practice: Learned patterns

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The code reads `.name` from `ADSB_VEHICLE_TYPE[emitterType]` without checking that the entry exists.

## Issue Context
`emitterType` comes from incoming MSP data and may be missing/out-of-range depending on firmware/protocol versions or corrupt data.

## Fix Focus Areas
- tabs/gps.js[369-369]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. Stale ADSB warning displayed 🐞
Description
The warning ICAO is only fetched when vehiclesCount > 0, but the UI shows the warning rows based on
vehiclePacketCount and doesn’t clear FC.ADSB_WARNING_ICAO when vehicles disappear. This can keep
showing an old warning ICAO/type even when there are currently zero vehicles.
Code

tabs/gps.js[R488-499]

+            if(FC.ADSB_VEHICLES.vehiclePacketCount > 0){
+                $('.adsbWarningIcao').html('0x' + (FC.ADSB_WARNING_ICAO.icao >>> 0).toString(16).toUpperCase().padStart(6, '0'));
+                $('.adsbWarningType').html(FC.ADSB_WARNING_ICAO.icao != 0 ? (FC.ADSB_WARNING_ICAO.isAlert == 1 ? i18n.getMessage('adsbAlert') : i18n.getMessage('adsbWarning')) : i18n.getMessage('adsbNoWarning'));
+
+                $('.adsbWarningIcaoRow').show();
+                $('.adsbWarningTypeRow').show();
+                renderAdsbListTable();
+            }else{
+                $('.adsbWarningIcaoRow').hide();
+                $('.adsbWarningTypeRow').hide();
+                $('.adsbVehicleListRow').hide();
+            }
Evidence
The warning query is skipped when vehiclesCount==0, but the UI visibility uses vehiclePacketCount (a
cumulative counter from the MSP payload) and will remain >0 after the first packet, so the warning
rows can continue to show while FC.ADSB_WARNING_ICAO remains stale.

tabs/gps.js[392-402]
tabs/gps.js[485-499]
js/msp/MSPHelper.js[204-209]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
ADSB warning state can become stale because warning is only requested when `vehiclesCount > 0`, while the UI uses `vehiclePacketCount > 0` to decide whether to show warning rows.

### Issue Context
`vehiclePacketCount` is parsed from the vehicle-list message and is not tied to the current vehicle count; it may remain positive even when `vehiclesCount` becomes 0.

### Fix Focus Areas
- tabs/gps.js[392-402]
- tabs/gps.js[485-499]

### Suggested fix
- Change the UI show/hide condition to use `FC.ADSB_VEHICLES.vehiclesCount > 0` (or `FC.ADSB_VEHICLES.vehicles.length > 0`).
- When `vehiclesCount == 0`, explicitly reset `FC.ADSB_WARNING_ICAO.icao = 0` and `isAlert = 0` before rendering.
- Optionally: always request `MSP2_ADSB_WARNING_VEHICLE_ICAO` and treat 0 ICAO as “none”, but don’t block UI if unsupported.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


7. ADSB circles gated by vehicles 🐞
Description
Alert/warning distance circles are only rendered when vehiclesCursorInitialized is true, which is
only set inside the vehicle loop. With a valid GPS fix and ADSB limits but zero vehicles, the
circles won’t render at all.
Code

tabs/gps.js[R552-560]

+            if (FC.GPS_DATA.fix >= 2  && vehiclesCursorInitialized && FC.ADSB_LIMITS.adsb_distance_alert > 0 &&  FC.ADSB_LIMITS.adsb_distance_warning > 0){
+                let lat = FC.GPS_DATA.lat / 10000000;
+                let lon = FC.GPS_DATA.lon / 10000000;
+
+                let circleWarning = circular(
+                    [lon, lat],
+                    FC.ADSB_LIMITS.adsb_distance_warning,
+                    64
+                );
Evidence
vehiclesCursorInitialized becomes true only when iterating at least one vehicle; the
circle-rendering condition depends on that flag, so no circles are drawn until at least one vehicle
has been processed.

tabs/gps.js[502-516]
tabs/gps.js[551-596]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
ADSB warning/alert circles are gated on `vehiclesCursorInitialized`, preventing them from rendering when there are no vehicles.

### Issue Context
The circles represent configured ADSB safety distances around the current GPS position and are useful even when no vehicles are currently tracked.

### Fix Focus Areas
- tabs/gps.js[502-516]
- tabs/gps.js[551-596]

### Suggested fix
- Create the ADSB vector source/layer regardless of vehicle presence (e.g., initialize `vehicleVectorSource` and add the layer once during `process_html`).
- Remove `vehiclesCursorInitialized` from the circle condition, or replace it with a check that `vehicleVectorSource` exists.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment thread tabs/gps.js
Comment on lines +142 to +170
[
i18n.getMessage('adsbCallsign'),
'ICAO',
i18n.getMessage('gpsLat'),
i18n.getMessage('gpsLon'),
i18n.getMessage('adsbAlt'),
i18n.getMessage('adsbHeading'),
'TSLC',
'TTL',
i18n.getMessage('adsbEmitter')
].forEach(function(col) {
$headerRow.append($('<th>').addClass('adsb-table__header').text(col));
});
$thead.append($headerRow);
$table.append($thead);
$table.append($('<tbody>').addClass('adsb-table__body'));

var $wrapper = $('<div>').addClass('adsb-table__wrapper').append($table);
$('.adsbVehicleList').empty().append($wrapper);
}

var $tbody = $('.adsb-table__body');

if (FC.ADSB_VEHICLES.vehicles.length === 0) {
$tbody.empty();
$tbody.append(
$('<tr>').append(
$('<td>').attr('colspan', 9).addClass('adsb-table__empty').text('No vehicles')
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. icao/tslc headers hardcoded 📘 Rule violation ⚙ Maintainability

The ADSB vehicle table UI introduces multiple user-facing strings as hardcoded literals (e.g.,
ICAO, TSLC, TTL, No vehicles, , unit suffixes), bypassing i18next translation keys. This
breaks internationalization coverage and violates the project requirement to avoid hardcoded UI
text.
Agent Prompt
## Issue description
The ADSB list table renders user-facing strings as hardcoded literals (e.g., `ICAO`, `TSLC`, `TTL`, `No vehicles`, `—`, and unit suffixes like `m`, `°`, `s`) instead of using i18next translation keys.

## Issue Context
Per i18n compliance requirements, all UI-visible text must be localizable via i18next (commonly `data-i18n` in HTML or `i18n.getMessage()` in JS for dynamically created elements).

## Fix Focus Areas
- tabs/gps.js[142-170]
- locale/en/messages.json[6201-6236]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread tabs/gps.js
Comment thread js/msp/MSPHelper.js
Comment thread tabs/gps.js
@sonarqubecloud
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant