Astro~/0.4
** Protocols / Time, payload, database / CDM * PAGE 31 / 35
** CCSDS 508.0-B-1 * Conjunction Data Message
** pkg/cdm

Conjunction Data Message

CCSDS 508.0-B-1, a warning that two objects will pass close.

CCSDS 508.0-B-1 | Blue Book | pkg/cdm

Overview

A CDM is a warning. It says two objects in orbit are going to pass close to each other, when, how close, and how well each object's position is known.

It is the only navigation message that describes a risk rather than a spacecraft, and the only one whose reader has a decision to make: whether to spend propellant getting out of the way. One message covers one conjunction between exactly two objects.

Scope

Implemented. Reading and writing, in key-value notation. All the keywords of tables 3-1 through 3-8.

Implemented: the XML form of section 4, with the structure of CCSDS 505.0-B-3. EncodeXML and DecodeXML sit beside Encode and Decode, and the two forms carry the same values.

Deliberately absent: conjunction analysis. Nothing here propagates either object, recomputes a miss distance, or calculates a collision probability. Clause 1.1 makes the message a report of the originator's analysis rather than an input to yours.

Both objects, or neither

There are no block delimiters. What separates the three sections is the OBJECT keyword: everything before the first one is relative metadata and data, everything after OBJECT = OBJECT1 belongs to the first object, and everything after OBJECT = OBJECT2 to the second.

A message with one object section is not a conjunction and is refused. So is a state vector written before any OBJECT — read loosely it would become a property of the conjunction rather than of an object, and the message would look complete. That case gets its own error, ErrObjectOutOfOrder, rather than "unknown keyword", because it is a real keyword in the wrong place.

The two objects are not symmetric

One is usually the operator's spacecraft; the other is usually debris, and its covariance will be far larger. Nothing in the format says which is which. MESSAGE_FOR names the spacecraft the warning was sent to and is optional.

What does mark the asymmetry is MANEUVERABLE, and it is the first thing an operator looks at: a conjunction with an unmanoeuvrable object is one only one side can resolve.

for i := range message.Objects {
    canMove, stated := message.Objects[i].Maneuverable()
    fmt.Println(i+1, message.Objects[i].Name(), canMove, stated)
}

The covariance is nine by nine

The obligatory part is the 21 lower triangular elements of a 6×6 in the RTN frame. Three optional rows extend it to 9×9, adding the uncertainties in drag, solar radiation pressure and thrust.

Covariance returns the full 9×9 with absent rows left at zero. Use CovarianceOrder to find how many rows were really there — a zero row and an absent one look identical in the matrix, and they mean different things to anyone computing a probability from it.

Note the units are metres here, not the kilometres the orbit messages use.

A probability without its method is unusable

Table 3-2 makes COLLISION_PROBABILITY_METHOD obligatory whenever COLLISION_PROBABILITY is given, and this package enforces it. The reason is that the number is not comparable between methods: the same conjunction gives different probabilities under Foster-1992 and Alfano-2005, and a bare figure cannot be acted on or compared with yesterday's.

CollisionProbability returns both, or nothing.

Re-encoding reproduces the values exactly

Unlike pkg/odm, a decoded CDM re-encodes to the same values it came in with, spelling included. A Section keeps the raw string each keyword arrived with and writes it out again.

That is deliberate. An orbit message is data a caller assembles and edits; a conjunction warning is a report a caller reads, forwards and archives, and re-emitting it unchanged is worth more than a tidy number format.

The XML form is not a reformatting

Three things genuinely differ, and none is cosmetic.

Units move. The key-value form puts them in the value, in brackets. XML puts them in an attribute:

MISS_DISTANCE = 715 [m]
<MISS_DISTANCE units="m">715</MISS_DISTANCE>

XML nests what KVN leaves flat. A CDM's object data is one run of keywords in the key-value form and four elements in XML — odParameters, additionalParameters, stateVector, covarianceMatrix. The relative section gains a relativeStateVector. Converting means knowing which keyword belongs to which block.

OBJECT stops being the boundary. In the key-value form it is what separates the two object sections. In XML the <segment> elements do that, and OBJECT becomes an ordinary element that could disagree with the segment it sits in. That disagreement would flip which object an operator thinks can manoeuvre, so it is refused.

The metadata and data split is another thing the key-value form does not have: an object section there runs from OBJECT to the last covariance element with no divider. The split comes from the tables — 3-3 is metadata, 3-5 through 3-8 are data.

Two header keywords are unique to this message

KeywordHereElsewhere
MESSAGE_IDobligatoryoptional
MESSAGE_FORoptionaldoes not exist
CLASSIFICATIONdoes not existoptional in ODM and ADM

MESSAGE_ID is obligatory because a conjunction warning has to be referable when someone asks about it a week later.

Using the package

// Either form, same values.
message, err := cdm.Decode(data)     // keyword = value
message, err = cdm.DecodeXML(data)   // XML

tca, _ := message.TCA()
miss, _ := message.MissDistance()
fmt.Printf("%.0f m at %s\n", miss, tca)

if p, method, ok := message.CollisionProbability(); ok {
    fmt.Printf("%.2e by %s\n", p, method)
}

for i := range message.Objects {
    o := message.Objects[i]
    fmt.Println(o.Name(), o.CovarianceOrder(), "rows of covariance")
}

Errors

ErrorMeans
ErrMissingObjectThe message does not describe both objects.
ErrObjectValueAn OBJECT value other than OBJECT1 or OBJECT2.
ErrObjectRepeatedThe same object named twice.
ErrObjectOutOfOrderAn object keyword before any OBJECT says which object it belongs to.
ErrMissingKeywordAn obligatory keyword is absent — including a probability with no method.
ErrUnknownKeywordA keyword none of the tables lists, or a relative keyword inside an object section.

Reference