Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Terrain Referenced Navigation

ASecurity

Use when you must aid an unaided inertial navigation solution from terrain with no GNSS available: correlate a measured radar-altimeter terrain profile (INS altitude minus radar clearance) along the INS indicated track against a stored digital elevation model strip, form the TERCOM correlation surface over the candidate along-track and cross-track offsets, and take the best-match offset as the coarse position correction. Then run the point-mass SITAN fine stage, per-mass terrain-height likeli...

2 stars
0 votes
0 copies
0 views
Added 9/27/2026
ai-agentspythonrustnodegitdatabase

Works with

claude code

Security Analysis

A100/100

Scanned 9/27/2026

Install to Claude Code

$npx -y skills add ashfordeOU/aero-agent-skills --skill terrain-referenced-navigation --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Terrain Referenced Navigation?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Terrain Referenced Navigation
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/ashfordeou-terrain-referenced-navigation/badge)](https://www.skillsdirectory.com/skills/ashfordeou-terrain-referenced-navigation)

More formats (shields.io, HTML) on the badges page.

Download with Pro
Files
SKILL.md
---
name: terrain-referenced-navigation
description: "Use when you must aid an unaided inertial navigation solution from terrain with no GNSS available: correlate a measured radar-altimeter terrain profile (INS altitude minus radar clearance) along the INS indicated track against a stored digital elevation model strip, form the TERCOM correlation surface over the candidate along-track and cross-track offsets, and take the best-match offset as the coarse position correction. Then run the point-mass SITAN fine stage, per-mass terrain-height likelihood updates and the linearized terrain-slope measurement update that refine the inertial correction epoch by epoch. Produces the correlation surface and best-match offset, the corrected inertial position with per-axis 1-sigma, the recovered vertical bias, and each slope update's innovation, variance and gain. Trigger: terrain referenced navigation, tercom correlation, digital elevation model matching, terrain slope update, radar altimeter profile, point mass sitan, ins position correction."
license: Apache-2.0
compliance: STANDARDS-REF
standards:
  - id: arp4754a
    reference-only: true
gated: false
domain: gnc-autonomy
pack: navigation
compatibility: "agentskills.io SKILL.md; any SKILL.md host (Claude Code, Hermes, OpenClaw)"
metadata:
  domain: gnc-autonomy
  subdomain: navigation
  tags: [terrain-referenced-navigation, tercom-correlation, radar-altimeter-profile, digital-elevation-model-matching, terrain-slope-update, sitan-point-mass, ins-position-correction]
  version: 0.1.0
  author: AeroSkills
---

# Terrain-Referenced Navigation (gnc-autonomy/navigation/terrain-referenced-navigation)

Use when you must aid an unaided inertial navigation solution from
terrain with no GNSS available. This leaf implements the classic
terrain-referenced navigation pair: a TERCOM-style grid correlation of
a measured radar-altimeter terrain profile against a stored digital
elevation model (DEM) strip that estimates the INS horizontal position
error to one grid step, followed by a SITAN point-mass fine stage with a
linearized terrain-slope measurement update that refines the correction
epoch by epoch and recovers the vertical INS altitude bias. The radar
altimeter measures geometric clearance; the INS indicated track is a
GIVEN input (never mechanized, never re-integrated), and no GNSS
observable of any kind appears in the loop. Deterministic offline: pure
stdlib math, no RNG. It pairs with inertial-navigation (the INS error
growth this leaf consumes as an input), tightly-coupled-ins-gnss and
ins-gnss-integrated-filter (the GNSS-aided alternatives this leaf
replaces when no GNSS is available), and kalman-filter-design (the
single-state recursions reused per mass).

## Domain quick reference

- Stored DEM strip: analytic rolling terrain sampled on a 25 m grid,
  origin east 3800 m, north -600 m, grid 293 x 113 nodes (east 3800..
  11100 m, north -600..2200 m). Surface h(x, y) = 420.0 + 62.0 sin(2 pi
  x / 2100.0 + 0.55) + 47.0 sin(2 pi y / 1500.0 + 1.25) + 30.0 sin(2 pi
  (0.75 x + 0.66 y) / 2900.0 + 0.15) + 16.0 sin(2 pi (0.50 x - 0.87 y) /
  760.0 + 0.90), east x and north y in metres. The analytic formula
  exists only to BUILD the strip (terrain_height, build_dem_strip); the
  correlator reads ONLY the stored grid through dem_height (bilinear)
  and dem_gradient (centered differences (f[j + 1] - f[j - 1]) / (2 *
  25) at the cell nodes, bilinearly interpolated).
- Measurement: radar clearance c_i = A_true - h_true_i + eta_i with the
  deterministic mismatch offsets eta_i = 1.7 sin(0.4 + 2 pi i / 11) +
  0.9 sin(1.3 + 2 pi i / 6) + 0.55 sin(2.0 + 2 pi i / 4) (RMS 1.451 m,
  radar-altimeter plus DEM error lumped, no RNG). The measured terrain
  profile is z_i = A_ins - c_i (clearance_profile_to_terrain), with
  A_ins the INS indicated barometric altitude carrying the hidden
  vertical error dA.
- INS error convention: e = p_ind - p_true is constant over the profile
  window. The TERCOM best-match offset (dx_best, dy_best) estimates e;
  the coarse correction is dr0 = (-dx_best, -dy_best).
- Correction convention: dr is ADDED to the INS indicated position,
  p_corrected = p_ind + dr; the true correction is dr_true = -e. A
  hypothesis at dr_k evaluates the DEM at (x_ind_i + dr_k_e, y_ind_i +
  dr_k_n). In the worked example e = (450.0, 180.0) m and dr_true =
  (-450.0, -180.0) m.
- TERCOM stage: for candidate (dx, dy) the DEM profile along the
  corrected track is d_i = h_strip(x_ind_i - dx_c, y_ind_i - dy_c).
  Pearson r = covariance(z, d) / (sigma_z * sigma_d) and MSD =
  mean((z_i - d_i)^2) come from profile_metrics; the best match is the
  argmax r over the candidate grid (mean-centered r is immune to the
  constant vertical bias; MSD is reported at the best but never selects
  it).
- SITAN point-mass stage (filter defaults R_MEAS = 2.25 m^2, Q_BIAS =
  0.02 m^2, P0_BIAS = 100.0 m^2): a bank of (2 * half + 1)^2 candidate
  corrections at spacing around dr0 (13 by 13 at 10 m, dr0 +/- 60 m)
  covers the one-grid-step coarse residual. Each mass k carries a scalar
  vertical-bias Kalman state (dA_k init 0, P_k init P0_BIAS). Per epoch:
  P_k += Q_BIAS, innovation y_k = z_i - h_strip(pos_k) - dA_k with S_k =
  P_k + R_MEAS and gain k_k = P_k / S_k, dA_k += k_k * y_k, P_k = (1 -
  k_k) * P_k, log weight += -0.5 * (y_k^2 / S_k + ln(2 pi S_k)); weights
  normalize from log space (subtract the max before exp).
- Linearized terrain-slope update at the weighted centroid: H = [dh/dx,
  dh/dy, 1.0] (slope row from dem_gradient plus the unit vertical-bias
  column), innovation y_c = z_i - h(pos_c) - dA_c, S = H P_c H^T +
  R_MEAS, gain K = P_c H^T / S on the 3 by 3 centroid covariance of
  (east correction, north correction, vertical bias), then P_c = (I - K
  H) P_c. With the DEM rising toward +x, a centroid east of the truth
  gives a negative innovation y_c ~ H * delta and dr_c += K * y_c moves
  the correction back toward dr_true, contracting the state error epoch
  by epoch.

## Workflow

1. Build the DEM strip on the 25 m grid with build_dem_strip; the strip
   statistics (elevation min 266.69 m, max 568.98 m, mean 426.51 m;
   slope magnitude RMS 0.2220) confirm the stored grid carries the
   texture the correlation needs.
2. Convert the radar-altimeter profile to the measured terrain profile
   z_i = A_ins - c_i with clearance_profile_to_terrain (scalar INS
   barometric altitude broadcast, or a per-sample altitude sequence).
3. Run the TERCOM grid correlation with tercom_match over the INS
   indicated track (x_ind_i, y_ind_i): resample the stored DEM along
   each candidate-corrected track, correlate with the measured profile
   through profile_metrics, and read the correlation surface rows plus
   the best-match offset (dx_best, dy_best) that estimates the INS
   horizontal position error. The coarse correction is dr0 =
   (-dx_best, -dy_best).
4. Run the fine SITAN point-mass stage with sitan_point_mass from dr0
   over the epoch sample indices: the per-mass terrain-height likelihood
   updates concentrate the bank, the weighted centroid feeds the
   linearized terrain-slope measurement update each epoch, and the
   per-epoch states (dr, bias, per-axis 1-sigma, slope row, innovation,
   innovation variance, gain) plus the final correction and recovered
   vertical bias gate the map-aided navigation output.
5. Sanity-check the result against the deterministic checks (the
   corrected position p_ind + dr recovers the true track, the final
   horizontal error, the recovered vertical bias) and run the contract
   test.

## Worked example

Demo aircraft flying due east over the stored strip at north 600.0 m,
true track east 5000.0..9800.0 m, sample spacing 200.0 m, 25 samples.
True altitude 700.0 m; the INS indicates 715.0 m (hidden vertical error
15.0 m). INS horizontal error e = (450.0, 180.0) m, so the indicated
track runs 450 m east and 180 m north of the truth. Radar clearance
carries the deterministic mismatch above (RMS 1.451 m). All values are
REAL outputs of this module, matching the wave-44 spec anchors.

- Measured terrain profile z_0..z_24 (m): 410.435, 369.515, 344.917,
  338.265, 347.204, 366.645, 390.313, 413.563, 433.052, 443.588,
  439.197, 419.466, 392.686, 371.474, 366.708, 384.193, 421.515,
  465.407, 495.856, 497.128, 466.217, 412.889, 355.267, 314.301,
  305.266.
- TERCOM stage over the INS indicated track, candidate grid dx -800..
  800 m step 100 (17 values), dy -400..400 m step 100 (9 values): best
  match r = 0.989515 at offset (dx = 400 m, dy = 200 m) with MSD at the
  best 206.4905 m^2 (the 15 m bias dominates the MSD floor). TERCOM
  estimates the INS error at (400, 200) against the truth (450, 180);
  the peak sits one grid step from the truth because the true error is
  off the 100 m candidate grid. Coarse residual after applying dr0 =
  (-400, -200): 50.0 m east, -20.0 m north, horizontal 53.85 m.
- Identity arm (clean profile, no bias, no mismatch, INS error exactly
  on the grid at (500, 200)): argmax (500, 200), r = 1.000000000, MSD
  0.000000 m^2. Bias-immunity arm (15 m bias stripped from the profile):
  argmax stays (400, 200) (identical = True) and the MSD at the best
  drops to 61.7653 m^2.
- SITAN fine stage from dr0 = (-400.0, -200.0), 169 hypotheses at 10 m
  spacing (coverage dr0 +/- 60 m), replaying samples 6..17 (200 m of
  travel per epoch). Epoch-0 slope-update detail (sample 6): centroid
  position east 6261.3 m, north 574.6 m, DEM height 383.482 m, slope
  row H = [0.1232, -0.0742, 1.00], innovation y = 0.8256 m, innovation
  variance S = 2.6432 m^2, gain K = (0.4334, -1.8335, -0.0406).
- Final SITAN correction: east -447.084 m, north -188.925 m (truth
  -450.000, -180.000 m); final error 2.916 m east, -8.925 m north,
  horizontal 9.389 m. Final vertical-bias estimate 13.487 m (truth 15.0
  m). Fine-stage reduction: coarse horizontal residual 53.85 m to 9.389
  m, factor 5.7.

Read-off: with a 1.45 m-RMS radar-altimeter and DEM mismatch on a
267-569 m rolling strip, a 100 m TERCOM grid resolves a 450/180 m INS
error to one grid step (r = 0.9895, 53.85 m residual), and the SITAN
point-mass fine stage with the linearized terrain-slope update pulls the
correction to about 3-9 m per axis (per-axis 1-sigma about 5 m) while
recovering 13.5 m of the 15 m vertical error, all from radar clearance
against the stored grid, with no GNSS in the loop.

## Verification

- Confirm build_dem_strip statistics (min 266.69, max 568.98, mean
  426.51 m within 0.1 m; slope magnitude RMS 0.2220 within 0.001).
- Confirm tercom_match on the worked set returns the argmax at exactly
  (400, 200) with r = 0.989515 (within 1e-4) and MSD at the best
  206.4905 m^2 (within 1.0 m^2); the clean-profile identity returns
  (500, 200) with r = 1.0 (within 1e-9) and MSD 0.0 (within 1e-6); the
  bias-immunity arm keeps (400, 200) with MSD 61.7653 m^2 (within 1.0).
- Confirm the five correlation-surface rows (dy 0..400 m over dx 100..
  700 m) match the anchors within 5e-4 per cell.
- Confirm sitan_point_mass from dr0 = (-400.0, -200.0) over samples
  6..17 gives the epoch-0 slope row H = [0.1232, -0.0742, 1.00] within
  1e-3, innovation 0.8256 m within 0.01, innovation variance 2.6432 m^2
  within 0.01, gain (0.4334, -1.8335, -0.0406) within 0.005, the final
  correction (-447.084, -188.925) within 0.5 m per axis (final
  horizontal error 9.389 m within 1.0 m) and the final bias 13.487 m
  within 0.5 m, with the per-epoch 1-sigma sequence within 1.0 m of the
  anchor values.
- Confirm the correction convention: p_corrected = p_ind + dr recovers
  the true track to within the final error, and dr_true = -e.
- Confirm ValueError rejection of non-physical inputs across the module
  (off-strip and non-finite sampling, malformed grid, empty profiles
  and candidate grids, length mismatches, empty epoch indices,
  non-positive spacing / r_meas / p0_bias, negative half / q_bias).
- Run the contract test offline: python3
  scripts/test_terrain_referenced_navigation.py (deterministic, exits
  0). The same test passes under the pre-push hook interpreter
  (~/.pyenv/versions/3.13.12/bin/python3).

## Related leaves

- gnc-autonomy/navigation/inertial-navigation: the INS error growth this
  leaf consumes as a given, unaided input.
- gnc-autonomy/navigation/tightly-coupled-ins-gnss: the raw-GNSS
  measurement update alternative when GNSS observables exist.
- gnc-autonomy/navigation/ins-gnss-integrated-filter: the GNSS
  position-update alternative for aided inertial filtering.
- gnc-autonomy/navigation/gnss-pseudorange-positioning: the GNSS
  position solution this leaf replaces when no GNSS is available.
- gnc-autonomy/navigation/kalman-filter-design: the single-state Kalman
  recursion reused per mass in the point-mass bank.
- gnc-autonomy/navigation/navigation-frames: frame conventions for the
  east/north grid coordinates.
- gnc-autonomy/guidance/coverage-path-planning: survey path planning
  over (assumed flat) terrain, the planning-side neighbor.

## Contract test

Run the deterministic contract test (stdlib unittest, offline):

    python3 scripts/test_terrain_referenced_navigation.py

The test covers the DEM strip statistics, node-exact bilinear
reconstruction, the radar-altimeter to terrain conversion, the TERCOM
worked match and its correlation-surface rows, the exact-match and
bias-immunity identities, the SITAN epoch-0 slope-update detail, the
final correction and vertical-bias recovery, the per-epoch 1-sigma
sequence, the correction-convention round trip, determinism, and
ValueError rejection of every non-physical input class listed above.

## Pitfalls

- Feeding the INS indicated altitude error into the DEM correlation: the
  measured profile z_i = A_ins - c_i carries the constant vertical bias
  dA, but mean-centered Pearson r is immune to it, so the TERCOM argmax
  is unbiased; the bias square only lifts the MSD floor (206.4905 m^2
  with the 15 m bias versus 61.7653 m^2 without). Never let MSD select
  the offset, and never strip a bias you cannot prove is constant over
  the window.
- Trusting the coarse TERCOM offset as the final correction: the true
  INS error (450, 180) m is off the 100 m candidate grid, so the argmax
  lands one grid step away at (400, 200) and leaves a 53.85 m residual.
  The fine SITAN stage exists exactly to remove that residual; report
  the coarse offset only as dr0 for the point-mass bank.
- Treating the terrain height as a direct measurement of position: the
  height residual only constrains position through the local slope row
  H = [dh/dx, dh/dy, 1.0], so epochs over flat strip regions (slope near
  zero) barely move the east/north correction. The bank coverage (dr0
  +/- 60 m at 10 m spacing) must always cover the residual from the
  coarse stage or the filter locks onto a false height match.
- Confusing the sign conventions: dr is ADDED to the INS indicated
  position (p_corrected = p_ind + dr, dr_true = -e), while the TERCOM
  offset (dx_best, dy_best) is the estimated INS error e in
  indicated-minus-true form. The coarse correction is dr0 =
  (-dx_best, -dy_best); a sign slip here doubles the error instead of
  removing it.
- Forgetting the vertical bias state: without the per-mass dA_k Kalman
  state and the unit vertical-bias column in H, the constant INS
  altitude error aliases directly into the height innovations and biases
  the position estimate by the slope-to-bias ratio; the recovered bias
  (13.487 m of the 15.0 m truth in the worked example) is a required
  output, not a side effect.
- Sampling the analytic terrain instead of the stored grid: the DEM is a
  given stored strip and the correlator reads only the stored grid
  through bilinear dem_height / centered-difference dem_gradient. The
  analytic TERMS formula exists only inside the strip builder.
- This leaf does NOT do: raw-pseudorange or carrier measurement updates
  with clock states (tightly-coupled-ins-gnss), GNSS position-fix
  updates or the psi-angle error model (ins-gnss-integrated-filter),
  GNSS doppler velocity fixes (gnss-doppler-velocity-positioning),
  code-carrier smoothing (gnss-carrier-smoothing), RAIM fault detection
  (gnss-raim-fde), DOP geometry (dilution-of-precision), INS error
  growth, mechanization, Schuler tuning, alignment or INS/GPS
  integration scoping (inertial-navigation), angle-only bearing
  localization (bearing-only-localization), frame-conversion utilities
  (navigation-frames), single-state Kalman design rules
  (kalman-filter-design), boustrophedon survey swath planning
  (coverage-path-planning), or terrain-following/terrain-avoidance
  guidance. No DEM creation, georeferencing or terrain database
  management: the strip is a given input.

## Behavior contract (gate 3)

Run the deterministic contract test (stdlib unittest, offline):

    python3 scripts/test_terrain_referenced_navigation.py

The test exercises the full workflow of this SKILL.md: building the DEM
strip (step 1), converting the radar-altimeter profile (step 2), the
TERCOM grid correlation surface and best-match offset over the INS
indicated track (step 3), and the SITAN point-mass fine stage with the
linearized terrain-slope measurement update, per-epoch states and
recovered vertical bias (step 4). It must pass under /usr/bin/python3
and under the pre-push hook interpreter; both exits 0, offline, in well
under 20 s.

## Compliance

- Standards referenced, not reproduced: arp4754a (SAE, proprietary-sold)
  frames the airborne-system development assurance context for the
  navigation function; name and paraphrase only, per standards-map.yaml.
- The TERCOM and SITAN relations above are standard published
  navigation methodology (terrain contour matching and point-mass
  terrain-referenced navigation), summary-only.
- compliance: STANDARDS-REF, gated: false.

Attribution

ashfordeOUashfordeOU
View sourceMore from ashfordeOU →
SSkills DirectorySkills Directory

Know which skills are safe — weekly.

Best new skills + every skill we flagged as malicious. From the team that scanned 103,619.

Join free

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Know which skills are safe — weekly.

Best new skills + every skill we flagged as malicious. From the team that scanned 103,619.

Join free

Related Skills

Caveman

Ultra-compressed communication mode that cuts output tokens while keeping technical accuracy. Levels: lite, full, ultra and the wenyan variants. Use for /caveman, "caveman mode", "talk like caveman", "be brief" or "less tokens".

1074701 votes

Hyperplan

Adversarial multi-agent planning skill. Self-orchestrates 5 hostile category members (unspecified-low, unspecified-high, deep, ultrabrain, artistry) via team-mode for ruthless cross-critique debate, distills only the defensible insights, then MANDATORILY hands the distilled insight bundle to the `plan` agent for executable plan formalization. Use when planning needs maximum rigor and surfacing of weak assumptions, blind spots, and over-engineering. Triggers: 'hyperplan', 'hpp', '/hyperplan', ...

694821 votes

Mcp Code Execution

Routes multi-tool workflows through MCP servers for large datasets and pipelines. Use when Bash tool overhead is limiting throughput on data-heavy tasks.

3351 votes

catchup

Recovers the conversation and failed tool calls of a previous Codex, Claude Code, Antigravity, Cline, Copilot CLI, Cursor, DeepSeek Harness, Kimi, OpenCode, Pi Agent, or ZCode session. Use when the user says "catch up", "what did the last session do", "get me up to speed", "I switched agents", asks to recover/summarize a previous session before continuing, or asks to diagnose or report a catchup failure. Do NOT use for the current conversation, git history, or any non-agent log.

691 votes

math-skill

A comprehensive mathematical reasoning skill for AI assistants — handles arithmetic to research-level problems with rigorous step-by-step reasoning, systematic verification, and transparent uncertainty handling

381 votes
View all in ai-agents →