Skip to content

The spacecraft model

A Spacecraft is the in-memory domain model that everything else in minmcs-lib operates against — which parameters and telecommands exist, how they’re packed into packets, and how raw bytes decode to engineering values. It’s built once, at process start, from an XTCE 1.2 file. Nothing about the mission is hand-maintained in Python.

Model types

spacecraft_model.py defines the model as plain (table=False) SQLModel classes:

  • Spacecraft — the root object: telemetry_meta, telecommand_meta, systems.
  • TelemetryMeta / TelecommandMeta — both extend ContainerMeta, which holds a flat containers list and provides lookup_container, concrete_containers, and resolve_entries. resolve_entries walks a container’s base_container chain up to the full ordered entry list. TM and TC share this inheritance logic, even though XTCE encodes the inheritance differently for each side — see below.
  • Container / ContainerField — a container is an ordered list of fields. A field is one of three kinds: a parameter reference (eltype="P", TM only — its width comes from the parameter’s type), a literal written straight to the wire ("F", with value/bits), or an argument reference ("E", TC only). TM containers also carry a restriction: a list of (parameter_short, value) comparisons used to identify which container a raw packet belongs to.
  • TelemetryParameter — a type, a bit width/encoding, an optional Calibrator, optional enumerations, and absolute-time fields for CUC-encoded parameters. A Calibrator is a polynomial: engineering = sum(coefficient * raw ** exponent). enumerations map a raw value to a label. The time fields (epoch, time_scale) apply when the parameter encodes an absolute time.
  • Telecommand / TelecommandParameter — a command’s payload parameters, plus three other pieces: fixed argument_assignments (e.g. a command that pins its own APID/service/subtype), verifiers (which TM containers confirm which stage), and verification (the stage → status map seeded when the command is built). When a parameter’s header field is non-empty, it routes that argument to a packet-header slot instead of the payload — see Telecommand uplink.
  • System — one per APID, grouping the parameter shorts that belong to a subsystem. This is what backs the UI’s telemetry-by-subsystem view.

Importing from XTCE

importers.py::XTCEImporter is the sole model source. It parses parameter/argument types, parameters, containers, telecommands, and systems out of the XTCE tree, and returns a Spacecraft. Two points are worth knowing:

  • TM and TC containers come from different places in XTCE. TM containers are standalone (TelemetryMetaData/ContainerSet/SequenceContainer); TC containers are nested inside their command (MetaCommand/CommandContainer). The importer has a separate parsing pass for each, but both passes produce the same Container type — so ContainerMeta’s inheritance and lookup logic works identically on either side.
  • Unresolved header arguments. A command argument that XTCE routes into the container it inherits from — rather than into its own payload — is header-bound. But the importer has no packet-format knowledge to say which header field it belongs to, so it marks that parameter’s header with the sentinel HEADER_ARG_UNRESOLVED = "?". The mission layer (missions/xtce.py) resolves it against the concrete PUS-C header layout when the model is built — see Telecommand uplink.

Only the subset of XTCE that minscs.xtce actually uses is interpreted — ParameterType/Parameter/SequenceContainer and MetaCommand/Argument. Unknown constructs are skipped rather than raising an error.

Last updated on