74 lines
3.5 KiB
Markdown
74 lines
3.5 KiB
Markdown
# odm
|
|
|
|
Orbit Data Messages: read, write and convert orbital element sets.
|
|
|
|
Everything ODMS knows about orbital *formats*, with nothing it knows about
|
|
Django, HTTP or a database. Dependencies are `sgp4` and the standard library.
|
|
|
|
## Why it is a library
|
|
|
|
The formats used to live in the service that happened to serve them first —
|
|
TLE rendering in a Django app's `formats.py`, the element-set catalogue in
|
|
another app, the OPM/OEM builders in a third, and the canonical record itself
|
|
implicit in a model row. That worked while one service read the data. It stops
|
|
working the moment a second one does: a format two services implement separately
|
|
is a format they will eventually disagree about, and the disagreement surfaces as
|
|
a satellite whose OMM and TLE describe slightly different orbits.
|
|
|
|
So: the OMM is the record. TLE text, OMM XML, OMM KVN and Celestrak GP CSV are
|
|
*renderings* of it, and the CCSDS SANA element sets are conversions of the state
|
|
it propagates to. One definition each, here.
|
|
|
|
## Use
|
|
|
|
```python
|
|
from odm import OmmRecord, parse_tle, registry
|
|
|
|
parsed = parse_tle(name, line1, line2)
|
|
record = OmmRecord(omm=parsed.omm, object_name=parsed.name, line1=line1, line2=line2)
|
|
|
|
xml = registry.get("omm_xml").write([record])
|
|
csv = registry.get("csv").write([record])
|
|
kep = registry.get("keplerian").write([record], backend=backend, at=when)
|
|
```
|
|
|
|
Every writer takes the same arguments — `write(records, *, backend=None,
|
|
at=None)` — so a caller never has to know which kind it got. `backend` and `at`
|
|
matter only to the element-set formats, which propagate before converting.
|
|
|
|
## Modules
|
|
|
|
| Module | What |
|
|
|---|---|
|
|
| `records` | `OmmRecord`, `ParsedTLE`, `StateVector` — what readers produce and writers consume. |
|
|
| `tle` | TLE text in and out. Lossy by construction; see the module docstring. |
|
|
| `omm` | CCSDS 502.0-B-3 OMM, XML and KVN. The authoritative rendering. |
|
|
| `gp` | Celestrak GP CSV, in their exact column order. |
|
|
| `norad` | Catalog-ID normalisation, ALPHA-5, and the temp-ID fallback. |
|
|
| `orbits` | Mean-element derivations: period, apogee, perigee, altitudes. |
|
|
| `conversions` | State vector → one SANA element set. |
|
|
| `element_sets` | The SANA catalogue, and computing a set for an OMM. |
|
|
| `messages` | CCSDS OPM/OEM: build and parse. |
|
|
| `registry` | Every output format in one table. |
|
|
| `propagator` | The seam a propagation backend implements. |
|
|
|
|
## The propagator seam
|
|
|
|
`odm` does no orbital mechanics beyond mean-element algebra. Anything needing a
|
|
propagated state takes a `PropagatorBackend` — `element_sets.compute_element_set`,
|
|
`messages.build_opm`, `messages.build_oem`, the element-set writers.
|
|
|
|
The backend is always **passed in**, never looked up. A library that reached for
|
|
a service's configured default would only work inside that service, which is the
|
|
thing this package exists not to be. Implementations live in the `yksa_orbital`
|
|
Django app (pure-Python SGP4, and an HTTP client to the Orekit sidecar).
|
|
|
|
## What is deliberately not here
|
|
|
|
- **Storage.** ODMS holds elements in Django, `track` holds them elsewhere, the
|
|
sidecar holds none. The format code works on records; the service adapts.
|
|
- **Serving.** Content types and filenames are in `registry` because they are
|
|
properties of the format, but nothing here builds a response.
|
|
- **The simulation model.** Force models, atmospheres and propagator settings
|
|
belong to the Orekit sidecar (`services/orekit/config.py`), which is their one
|
|
definition for the same reason this package is the formats' one definition.
|