orbitforge link
Synopsis
orbitforge link --constellation <PATH> --station <SPEC> [OPTIONS]Description
Computes a link budget across every contact in the window and reports the margin and the availability actually achieved, against the availability you asked for.
Unlike coverage, which is pure geometry, this asks
whether enough signal survives the path: free-space loss over the true slant
range, plus the ITU-R atmosphere at the exceedance probability your availability
target implies.
Options
| Parameter | Type | Unit | Default | Required | Description |
|---|---|---|---|---|---|
--constellation | path | n/a | — | Yes | Path to a constellation JSON file. |
--station | string | n/a | — | Yes | Ground station as `Name,lat_deg,lon_deg,alt_km`. Repeatable. |
--frequency-ghz | float | GHz | — | Yes | Carrier frequency. Drives both free-space loss and atmospheric attenuation. |
--availability | float | percent | — | No | Availability target, for example `99.9`. Sets the rain exceedance the margin is quoted at. |
--climate-zone | string | n/a | — | No | ITU-R rain climate zone, for example `K`. |
--r001 | float | mm/h | — | No | Rain rate exceeded 0.01 percent of an average year. Overrides the climate zone. |
--rain-rate | float | mm/h | — | No | Explicit rain rate, bypassing the statistical model. |
--modcod-thresholds | path | n/a | — | No | Threshold artifact from `waveform thresholds`, so margin is quoted against a measured decoder. |
--modcod | string | n/a | — | No | MODCOD to evaluate against, for example `qpsk-1/2`. |
--start | string | RFC 3339 UTC | 2026-01-01T00:00:00Z | No | Analysis start epoch. |
--duration-hours | float | h | 6 | No | Analysis window length. |
--step-seconds | float | s | 60 | No | Time step. |
--output | path | n/a | — | No | Write the full link report. |
Worked examples
The same constellation and station at two frequencies. Nothing else changes.
20 GHz
orbitforge link \
--constellation demo.json \
--station "Madrid,40.43,-3.7,0.6" \
--frequency-ghz 20 --availability 99.9 --climate-zone KLink analysis: 60 satellites, 1 stations, 6.0 h at 60 s (20.0 GHz).
madrid: coverage 100.0%, 92 contacts, best margin 4.6 dB
Madrid link availability: does not close at 95%12 GHz
orbitforge link \
--constellation demo.json \
--station "Madrid,40.43,-3.7,0.6" \
--frequency-ghz 12 --availability 99.9 --climate-zone KLink analysis: 60 satellites, 1 stations, 6.0 h at 60 s (12.0 GHz).
madrid: coverage 100.0%, 92 contacts, best margin 14.1 dB
Madrid link availability: 99.822%What that comparison shows
| Figure | 20 GHz | 12 GHz |
|---|---|---|
| Coverage | 100 percent | 100 percent |
| Contacts | 92 | 92 |
| Best margin | 4.6 dB | 14.1 dB |
| Availability | Does not close at 95 percent | 99.822 percent |
Geometry is identical: same coverage, same contact count. The frequency change alone moved the link from failing a 95 percent target to nearly meeting a 99.9 percent one, worth 9.5 dB of margin.
Free-space loss accounts for only about 4.4 dB of that, from the term. The remainder is atmospheric, and most of it is rain. Rain attenuation rises steeply with frequency: at 20 GHz in a wet climate zone it dominates the budget, while at 12 GHz it is a manageable term.
Coverage and link closure are different questions, and they disagree routinely. 100 percent coverage with a failing link is not a contradiction. It means the constraint is RF, not geometry, and adding satellites will not fix it. Lower frequency, more power, a bigger antenna, a higher elevation mask, or a relaxed availability target might.
Availability, not weather
Rain attenuation is a statistical distribution, so the meaningful question is not “how much rain loss” but “how much loss is exceeded for no more than percent of an average year”.
| Target | Permitted outage per year | Consequence |
|---|---|---|
| 99.0 percent | About 88 hours | Modest margin required |
| 99.9 percent | About 8.8 hours | Substantially more at Ka band |
| 99.99 percent | About 53 minutes | Often unreachable at Ka band without diversity |
The reported availability is what the design achieves. The 12 GHz run achieves 99.822 percent against a 99.9 percent request, so it very nearly meets the target and is short by a small amount of margin.
Closing the loop with a measured threshold
By default, margin is quoted against a nominal threshold. Supplying a threshold
artifact from
waveform thresholds quotes it against a
decoder that was actually measured:
orbitforge waveform thresholds --modcods qpsk-1/2 --output thr.json
orbitforge link \
--constellation demo.json \
--station "Madrid,40.43,-3.7,0.6" \
--frequency-ghz 12 --availability 99.9 --climate-zone K \
--modcod-thresholds thr.json --modcod qpsk-1/2That is the difference between margin against an assumption and margin against a demonstration.
Choosing the rain input
| Flag | Use |
|---|---|
--climate-zone | Standard ITU-R zone. The usual choice |
--r001 | A site-specific rain rate exceeded 0.01 percent of the year, from local statistics. Preferred where available |
--rain-rate | A fixed rate, bypassing the statistical model. For sensitivity studies, not for a quoted availability |
--rain-rate produces a deterministic answer that cannot be interpreted as an
availability, because it discards the distribution the availability is defined
against.
See also
- Link budgets for the underlying arithmetic.
coveragefor the geometric question.waveform thresholdsfor measured decoder thresholds.
main (pre-release)