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 extendContainerMeta, which holds a flatcontainerslist and provideslookup_container,concrete_containers, andresolve_entries.resolve_entrieswalks a container’sbase_containerchain 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", withvalue/bits), or an argument reference ("E", TC only). TM containers also carry arestriction: 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 optionalCalibrator, optionalenumerations, and absolute-time fields for CUC-encoded parameters. ACalibratoris a polynomial:engineering = sum(coefficient * raw ** exponent).enumerationsmap 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: fixedargument_assignments(e.g. a command that pins its own APID/service/subtype),verifiers(which TM containers confirm which stage), andverification(the stage → status map seeded when the command is built). When a parameter’sheaderfield 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 sameContainertype — soContainerMeta’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
headerwith the sentinelHEADER_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.