RNP / ANP Containment (avionics/flight-management/rnp-anp-containment)
Use when the task is the navigation performance containment check of a
flight management system: compare the actual navigation performance
(ANP) of the position solution with the required navigation performance
(RNP) of the airspace or route segment and decide whether the aircraft
stays inside the containment bound. ANP is the 95th percentile lateral
position error, taken as two times the supplied 1-sigma lateral
position error or read directly from the navigation system, and a
required margin fraction of RNP can be applied before the comparison.
This leaf implements the standard RNP containment rule in pure Python,
stdlib only. It pairs with gnc-autonomy/navigation/dilution-of-precision
and gnc-autonomy/navigation/gnss-pseudorange-positioning, which produce
the position error inputs, and with lateral-navigation, the FMS lateral
function that consumes the containment verdict.
Domain quick reference
- RNP is a 95 percent containment bound: the position must stay within
the RNP distance for at least 95 percent of the flight time. RNP
values are distances: RNP 0.3 NM equals 0.3 * 1852 = 555.6 m.
- ANP from sigma: anp = 2 * sigma_lateral_m, the 95th percentile
lateral position error from a 1-sigma lateral position error
(anp_from_sigma).
- Required margin: margin = rnp_m * margin_fraction, zero by default,
set by operator or procedure policy (margin_m).
- Containment rule: pass when anp + margin <= rnp, boundary inclusive
(containment_pass).
- Available margin: margin_available = rnp - margin - anp, the reserve
left over after the required margin (margin_available_m).
- analyze() bundles the check: it takes sigma_lateral_m or anp_m,
rnp_m and margin_fraction, and returns the anp_m, rnp_m, pass bool,
margin_m and the PASS or FAIL verdict.
- The 1-sigma lateral position error is an input from the navigation
error analysis; deriving it from geometry or ranging residuals is out
of scope, as are obstacle clearance and route geometry.
- Units are meters for distances and fractions (0.05 means 5 percent)
for the margin.
Workflow
- Fix the segment: read the RNP for the airspace or route segment and
convert NM to meters (multiply by 1852) when the procedure gives NM.
- Get the position error input: the 1-sigma lateral position error
sigma_lateral_m from the navigation error estimate, or the ANP value
reported by the navigation system.
- Compute the ANP with anp_from_sigma when only sigma is available, or
pass the reported ANP directly as anp_m.
- Set the required margin fraction (default 0.0) and compute the
margin in meters with margin_m when the operator demands a reserve.
- Run containment_pass for the verdict and margin_available_m for the
remaining reserve.
- For the full record call analyze(sigma_lateral_m=..., anp_m=...,
rnp_m=..., margin_fraction=...) and use the returned dict with the
verdict.
- Confirm the deterministic checks with the contract test
scripts/test_rnp_anp_containment.py.
Worked example
RNP 0.3 NM = 555.6 m on the approach with a 1-sigma lateral position
error of 120 m.
- ANP: anp_from_sigma(120) = 2 * 120 = 240 m (95 percent bound).
- Default margin: margin_m(555.6, 0.0) = 0 m.
- Verdict: containment_pass(240, 555.6) is True because 240 <= 555.6.
- Available margin: margin_available_m(240, 555.6) = 555.6 - 240 =
315.6 m.
- Degraded case: sigma 300 m gives ANP 600 m; 600 > 555.6 so
containment_pass(600, 555.6) is False and analyze returns verdict
FAIL.
- Direct ANP case: analyze(anp_m=500, rnp_m=555.6,
margin_fraction=0.05) applies margin_m = 555.6 * 0.05 = 27.78 m,
checks 500 + 27.78 = 527.78 <= 555.6, passes with verdict PASS and
27.82 m of margin still available.
Verification
- Confirm anp_from_sigma(120) returns 240.0 m.
- Confirm containment_pass(240, 555.6) is True and
containment_pass(600, 555.6) is False.
- Confirm margin_available_m(240, 555.6) returns 315.6 m within 0.1.
- Confirm analyze(anp_m=500, rnp_m=555.6, margin_fraction=0.05)
returns pass True, margin_m 27.78 and verdict PASS.
- Confirm the boundary is inclusive: containment_pass(240, 240) is True.
- Confirm ValueError rejection of non-physical inputs: both sigma and
anp missing, rnp_m <= 0, sigma_lateral_m < 0, anp_m < 0 and
margin_fraction < 0.
- Run the contract test offline: python3
scripts/test_rnp_anp_containment.py (32 tests, deterministic).
Related leaves
- avionics/flight-management/lateral-navigation: the FMS lateral
guidance function that consumes the containment verdict and the
cross-track state.
- gnc-autonomy/navigation/dilution-of-precision: navigation geometry
based error analysis that can feed the lateral position error sigma.
- gnc-autonomy/navigation/gnss-pseudorange-positioning: the position
fix whose residuals bound the navigation error for the sigma input.
Pitfalls
- Feeding the 1-sigma error as the ANP: the ANP is the 95th
percentile bound anp = 2 * sigma_lateral_m, so a 120 m sigma is an
ANP of 240 m - comparing the raw sigma against the RNP halves the
effective containment and can pass a degraded navigation system.
- Mixing nautical miles into a meters check: RNP values arrive in NM
(RNP 0.3 NM = 555.6 m) and every comparison runs in meters - an
unconverted 0.3 against a 240 m ANP passes any degraded case.
- Comparing ANP against RNP without the required margin: the rule is
anp + margin <= rnp, so at RNP 555.6 m with a 5 percent margin
(27.78 m) an ANP of 500 m passes only because 527.78 <= 555.6, and
margin_available_m reports the reserve after the margin is reserved,
not the raw rnp - anp.
- Treating the boundary as exclusive: containment is inclusive - anp +
margin equal to rnp passes (containment_pass(240, 240) is True), so
an equality case must not be flagged as a violation.
- Reading RNP as an absolute limit: RNP is the 95 percent containment
bound that the position must satisfy for at least 95 percent of
flight time, and the ANP is the 95th percentile error - momentary
excursions beyond the bound are not automatically a containment
failure, and neither is the mean error the quantity to compare.
- Deriving the sigma inside this leaf: the 1-sigma lateral position
error is an input from the navigation error analysis (dilution-of-
precision and gnss-pseudorange-positioning leaves feed it); geometry
and ranging-residual estimation are out of scope here, and analyze
raises ValueError when both sigma and anp are missing.
Behavior contract (gate 3)
Run the deterministic contract test (stdlib unittest, offline):
python3 scripts/test_rnp_anp_containment.py
The test covers the worked-example contract (ANP 240 m from a 120 m
sigma, pass verdict and 315.6 m available margin at RNP 555.6 m; fail
verdict at a 300 m sigma; direct ANP 500 m pass with the 5 percent
margin), the margin helper, the inclusive boundary, sigma and ANP input
agreement round trip, verdict typing, and ValueError rejection of both
missing inputs, non-positive RNP, negative sigma, negative ANP and
negative margin fraction.
Compliance
- Standards referenced, not reproduced: DO-178C frames the flight
management software context for this containment function; the RNP
containment relations above are standard navigation methodology,
summary-only per standards-map.yaml.
- compliance: STANDARDS-REF, gated: false.
1---2name: rnp-anp-containment3description: Use when you must assess the RNP containment of a performance based navigation segment: compute the actual navigation performance (ANP) as the 95 percent containment bound from a lateral position error sigma or accept a directly supplied ANP, apply the required navigation performance (RNP) for the segment with an optional margin fraction, and decide whether the ANP stays inside the RNP. Produces the ANP, the containment margin and the pass or fail verdict that gate FMS navigation dispatch. Trigger: required navigation performance, actual navigation performance, RNP containment, ANP comparison, lateral position error sigma, 95 percent containment, performance based navigation.4license: Apache-2.05---67# RNP / ANP Containment (avionics/flight-management/rnp-anp-containment)89Use when the task is the navigation performance containment check of a10flight management system: compare the actual navigation performance11(ANP) of the position solution with the required navigation performance12(RNP) of the airspace or route segment and decide whether the aircraft13stays inside the containment bound. ANP is the 95th percentile lateral14position error, taken as two times the supplied 1-sigma lateral15position error or read directly from the navigation system, and a16required margin fraction of RNP can be applied before the comparison.17This leaf implements the standard RNP containment rule in pure Python,18stdlib only. It pairs with gnc-autonomy/navigation/dilution-of-precision19and gnc-autonomy/navigation/gnss-pseudorange-positioning, which produce20the position error inputs, and with lateral-navigation, the FMS lateral21function that consumes the containment verdict.2223## Domain quick reference2425- RNP is a 95 percent containment bound: the position must stay within26 the RNP distance for at least 95 percent of the flight time. RNP27 values are distances: RNP 0.3 NM equals 0.3 * 1852 = 555.6 m.28- ANP from sigma: anp = 2 * sigma_lateral_m, the 95th percentile29 lateral position error from a 1-sigma lateral position error30 (anp_from_sigma).31- Required margin: margin = rnp_m * margin_fraction, zero by default,32 set by operator or procedure policy (margin_m).33- Containment rule: pass when anp + margin <= rnp, boundary inclusive34 (containment_pass).35- Available margin: margin_available = rnp - margin - anp, the reserve36 left over after the required margin (margin_available_m).37- analyze() bundles the check: it takes sigma_lateral_m or anp_m,38 rnp_m and margin_fraction, and returns the anp_m, rnp_m, pass bool,39 margin_m and the PASS or FAIL verdict.40- The 1-sigma lateral position error is an input from the navigation41 error analysis; deriving it from geometry or ranging residuals is out42 of scope, as are obstacle clearance and route geometry.43- Units are meters for distances and fractions (0.05 means 5 percent)44 for the margin.4546## Workflow47481. Fix the segment: read the RNP for the airspace or route segment and49 convert NM to meters (multiply by 1852) when the procedure gives NM.502. Get the position error input: the 1-sigma lateral position error51 sigma_lateral_m from the navigation error estimate, or the ANP value52 reported by the navigation system.533. Compute the ANP with anp_from_sigma when only sigma is available, or54 pass the reported ANP directly as anp_m.554. Set the required margin fraction (default 0.0) and compute the56 margin in meters with margin_m when the operator demands a reserve.575. Run containment_pass for the verdict and margin_available_m for the58 remaining reserve.596. For the full record call analyze(sigma_lateral_m=..., anp_m=...,60 rnp_m=..., margin_fraction=...) and use the returned dict with the61 verdict.627. Confirm the deterministic checks with the contract test63 scripts/test_rnp_anp_containment.py.6465## Worked example6667RNP 0.3 NM = 555.6 m on the approach with a 1-sigma lateral position68error of 120 m.6970- ANP: anp_from_sigma(120) = 2 * 120 = 240 m (95 percent bound).71- Default margin: margin_m(555.6, 0.0) = 0 m.72- Verdict: containment_pass(240, 555.6) is True because 240 <= 555.6.73- Available margin: margin_available_m(240, 555.6) = 555.6 - 240 =74 315.6 m.75- Degraded case: sigma 300 m gives ANP 600 m; 600 > 555.6 so76 containment_pass(600, 555.6) is False and analyze returns verdict77 FAIL.78- Direct ANP case: analyze(anp_m=500, rnp_m=555.6,79 margin_fraction=0.05) applies margin_m = 555.6 * 0.05 = 27.78 m,80 checks 500 + 27.78 = 527.78 <= 555.6, passes with verdict PASS and81 27.82 m of margin still available.8283## Verification8485- Confirm anp_from_sigma(120) returns 240.0 m.86- Confirm containment_pass(240, 555.6) is True and87 containment_pass(600, 555.6) is False.88- Confirm margin_available_m(240, 555.6) returns 315.6 m within 0.1.89- Confirm analyze(anp_m=500, rnp_m=555.6, margin_fraction=0.05)90 returns pass True, margin_m 27.78 and verdict PASS.91- Confirm the boundary is inclusive: containment_pass(240, 240) is True.92- Confirm ValueError rejection of non-physical inputs: both sigma and93 anp missing, rnp_m <= 0, sigma_lateral_m < 0, anp_m < 0 and94 margin_fraction < 0.95- Run the contract test offline: python396 scripts/test_rnp_anp_containment.py (32 tests, deterministic).9798## Related leaves99100- avionics/flight-management/lateral-navigation: the FMS lateral101 guidance function that consumes the containment verdict and the102 cross-track state.103- gnc-autonomy/navigation/dilution-of-precision: navigation geometry104 based error analysis that can feed the lateral position error sigma.105- gnc-autonomy/navigation/gnss-pseudorange-positioning: the position106 fix whose residuals bound the navigation error for the sigma input.107108## Pitfalls109110- Feeding the 1-sigma error as the ANP: the ANP is the 95th111 percentile bound anp = 2 * sigma_lateral_m, so a 120 m sigma is an112 ANP of 240 m - comparing the raw sigma against the RNP halves the113 effective containment and can pass a degraded navigation system.114- Mixing nautical miles into a meters check: RNP values arrive in NM115 (RNP 0.3 NM = 555.6 m) and every comparison runs in meters - an116 unconverted 0.3 against a 240 m ANP passes any degraded case.117- Comparing ANP against RNP without the required margin: the rule is118 anp + margin <= rnp, so at RNP 555.6 m with a 5 percent margin119 (27.78 m) an ANP of 500 m passes only because 527.78 <= 555.6, and120 margin_available_m reports the reserve after the margin is reserved,121 not the raw rnp - anp.122- Treating the boundary as exclusive: containment is inclusive - anp +123 margin equal to rnp passes (containment_pass(240, 240) is True), so124 an equality case must not be flagged as a violation.125- Reading RNP as an absolute limit: RNP is the 95 percent containment126 bound that the position must satisfy for at least 95 percent of127 flight time, and the ANP is the 95th percentile error - momentary128 excursions beyond the bound are not automatically a containment129 failure, and neither is the mean error the quantity to compare.130- Deriving the sigma inside this leaf: the 1-sigma lateral position131 error is an input from the navigation error analysis (dilution-of-132 precision and gnss-pseudorange-positioning leaves feed it); geometry133 and ranging-residual estimation are out of scope here, and analyze134 raises ValueError when both sigma and anp are missing.135136## Behavior contract (gate 3)137138Run the deterministic contract test (stdlib unittest, offline):139140 python3 scripts/test_rnp_anp_containment.py141142The test covers the worked-example contract (ANP 240 m from a 120 m143sigma, pass verdict and 315.6 m available margin at RNP 555.6 m; fail144verdict at a 300 m sigma; direct ANP 500 m pass with the 5 percent145margin), the margin helper, the inclusive boundary, sigma and ANP input146agreement round trip, verdict typing, and ValueError rejection of both147missing inputs, non-positive RNP, negative sigma, negative ANP and148negative margin fraction.149150## Compliance151152- Standards referenced, not reproduced: DO-178C frames the flight153 management software context for this containment function; the RNP154 containment relations above are standard navigation methodology,155 summary-only per standards-map.yaml.156- compliance: STANDARDS-REF, gated: false.