Skip to content

fix(Terrain): back off after failed tile fetches to stop warning spam#14414

Draft
dakejahl wants to merge 2 commits into
mavlink:masterfrom
dakejahl:fix/terrain-tile-failure-spam
Draft

fix(Terrain): back off after failed tile fetches to stop warning spam#14414
dakejahl wants to merge 2 commits into
mavlink:masterfrom
dakejahl:fix/terrain-tile-failure-spam

Conversation

@dakejahl
Copy link
Copy Markdown
Collaborator

Summary

Eliminate the warning spam (and unnecessary network traffic) when the elevation server cannot return data for a tile, by caching recent failures in TerrainTileManager and not looping on a known-failed tile in TerrainProtocolHandler.

Problem

When a vehicle sends TERRAIN_REQUEST with uninitialized lat=0/lon=0, the request maps to elevation tile (0, 0) — "Null Island". The Auterion terrain server returns HTTP 500 for that tile, but TerrainTileManager had no memory of recent failures, so every TerrainProtocolHandler timer tick (~12 Hz) dispatched a fresh HTTP request. Observed log shows continuous warnings from both QtLocationPlugin.QGeoTiledMapReplyQGC and Terrain.TerrainTileManager::_terrainDone at ~80–150 ms intervals:

Warning: 1 "Error transferring https://terrain-ce.suite.auterion.com/api/v1/carpet?points=0,0,0.01,0.01 - server replied with status code 500"
Warning: Elevation tile fetching returned error: "Error transferring https://terrain-ce.suite.auterion.com/api/v1/carpet?points=0,0,0.01,0.01 - server replied with status code 500"

The handler also intentionally never cleared the mask bit on a non-success result, so even with backoff added, it would just transfer the spam to its own log line.

Solution

src/Terrain/TerrainTileManager.{h,cc}

  • Add _failedTiles (tile hash → ms timestamp) with a 5 s backoff.
  • While a tile is in the failed set, getAltitudesForCoordinates returns NaN + error=true without dispatching a network request.
  • _terrainDone records the hash on failure, removes it on success, and rate-limits the warning (first failure at warning level; repeats inside the window at debug level).

src/Vehicle/TerrainProtocolHandler.cc

  • _sendTerrainData now clears the mask bit on error as well as on success, so the handler stops looping on a known-failed tile. The vehicle re-issues TERRAIN_REQUEST if it still needs the data, which then gets a fresh fetch once the backoff window expires.
  • Demote the per-call warning to debug since the underlying cause is already logged by TerrainTileManager.

When the elevation server returns 500 for an uncached tile (e.g. uninitialized
lat=0/lon=0 from a vehicle TERRAIN_REQUEST hitting Null Island), the prior
code re-issued the request on every TerrainProtocolHandler timer tick (~12 Hz),
producing continuous warning spam from QGeoTiledMapReplyQGC and
TerrainTileManager::_terrainDone.

- TerrainTileManager: remember failed tile hashes with a 5 s backoff. While
  a tile is in the failed set, getAltitudesForCoordinates returns NaN +
  error=true without dispatching a new network request. Demote repeat
  warnings to debug within the backoff window.
- TerrainProtocolHandler: clear the mask bit on error too. Looping on a
  known-failed tile just hammers the same request every tick; the vehicle
  re-issues TERRAIN_REQUEST if it still needs the data, allowing a fresh
  attempt once the backoff expires.
@dakejahl dakejahl marked this pull request as draft May 20, 2026 21:28
Autopilots can emit TERRAIN_REQUEST before GPS lock with uninitialized
(0, 0) coordinates. Bail out at the protocol entry point so we never
even start a fetch for that tile, complementing the failed-tile backoff
in TerrainTileManager.
@dakejahl
Copy link
Copy Markdown
Collaborator Author

Corresponding Ardupilot PR which fixes the root cause of the issue
ArduPilot/ardupilot#33135

@codecov
Copy link
Copy Markdown

codecov Bot commented May 20, 2026

Codecov Report

❌ Patch coverage is 9.67742% with 28 lines in your changes missing coverage. Please review.
✅ Project coverage is 26.44%. Comparing base (f29efd3) to head (076f4a6).
⚠️ Report is 25 commits behind head on master.

Files with missing lines Patch % Lines
src/Terrain/TerrainTileManager.cc 13.04% 18 Missing and 2 partials ⚠️
src/Vehicle/TerrainProtocolHandler.cc 0.00% 8 Missing ⚠️

❌ Your patch check has failed because the patch coverage (9.67%) is below the target coverage (30.00%). You can increase the patch coverage or adjust the target coverage.
❌ Your project check has failed because the head coverage (26.44%) is below the target coverage (30.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master   #14414      +/-   ##
==========================================
+ Coverage   25.47%   26.44%   +0.97%     
==========================================
  Files         769      767       -2     
  Lines       65912    66308     +396     
  Branches    30495    30682     +187     
==========================================
+ Hits        16788    17536     +748     
+ Misses      37285    36327     -958     
- Partials    11839    12445     +606     
Flag Coverage Δ
unittests 26.44% <9.67%> (+0.97%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/Vehicle/TerrainProtocolHandler.cc 8.91% <0.00%> (-0.28%) ⬇️
src/Terrain/TerrainTileManager.cc 13.52% <13.04%> (+0.11%) ⬆️

... and 104 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 483aae4...076f4a6. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link
Copy Markdown
Contributor

Build Results

Platform Status

Platform Status Details
Linux Passed View
Windows Passed View
MacOS Passed View
Android Passed View

All builds passed.

Pre-commit

Check Status Details
pre-commit Failed (non-blocking) View

Pre-commit hooks: 4 passed, 45 failed, 7 skipped.

Test Results

linux-coverage: 88 passed, 0 skipped
Total: 88 passed, 0 skipped

Code Coverage

Coverage: 60.4%

No baseline available for comparison

Artifact Sizes

Artifact Size
QGroundControl 216.77 MB
QGroundControl-aarch64 176.66 MB
QGroundControl-installer-AMD64 134.68 MB
QGroundControl-installer-AMD64-ARM64 77.30 MB
QGroundControl-installer-ARM64 106.01 MB
QGroundControl-linux 334.68 MB
QGroundControl-mac 186.86 MB
QGroundControl-windows 186.87 MB
QGroundControl-x86_64 171.87 MB
No baseline available for comparison

Updated: 2026-05-20 22:37:22 UTC • Triggered by: Android

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant