# `Sidereon.CCSDS.CDM`
[🔗](https://github.com/neilberkman/sidereon-ex/blob/main/lib/sidereon/ccsds/cdm.ex#L1)

Parse and encode CCSDS Conjunction Data Messages (CDM).

Supports both the **KVN** (Keyword=Value Notation) and **XML** formats
per CCSDS 508.0-B-1. CDMs describe a predicted close approach between
two space objects, including states, covariances, and collision
probability.

`parse/1` auto-detects the format based on the first non-whitespace
character: a leading `<` is treated as XML, anything else as KVN.

## Examples

    {:ok, cdm} = Sidereon.CCSDS.CDM.parse(kvn_string)
    cdm.tca                    # ~U[2010-03-13 22:37:52.618Z]
    cdm.miss_distance_m        # 715.0
    cdm.collision_probability  # 4.835e-05

    # KVN output (default)
    kvn = Sidereon.CCSDS.CDM.encode(cdm)

    # XML output
    xml = Sidereon.CCSDS.CDM.encode(cdm, format: :xml)

    # Round-trip through XML
    {:ok, cdm2} = Sidereon.CCSDS.CDM.parse(xml)

# `t`

```elixir
@type t() :: %Sidereon.CCSDS.CDM{
  collision_probability: float() | nil,
  collision_probability_method: String.t() | nil,
  creation_date: DateTime.t() | nil,
  hard_body_radius_m: float() | nil,
  message_id: String.t() | nil,
  miss_distance_m: float() | nil,
  object1: Sidereon.CCSDS.CDM.ObjectData.t() | nil,
  object2: Sidereon.CCSDS.CDM.ObjectData.t() | nil,
  originator: String.t() | nil,
  relative_speed_m_s: float() | nil,
  tca: DateTime.t() | nil
}
```

# `encode`

```elixir
@spec encode(
  t(),
  keyword()
) :: String.t()
```

Encode a CDM.

## Options
  * `:format` - `:kvn` (default) or `:xml`

# `encode_kvn`

```elixir
@spec encode_kvn(t()) :: String.t()
```

Encode a CDM to KVN format explicitly.

# `encode_xml`

```elixir
@spec encode_xml(t()) :: String.t()
```

Encode a CDM to XML format explicitly.

Produces a document matching the CCSDS 508.0-B-1 CDM XML schema's
top-level shape (cdm > header/body > segment > metadata/data). This
is the canonical XML form used for inter-system exchange alongside KVN.

# `parse`

```elixir
@spec parse(String.t()) :: {:ok, t()} | {:error, String.t()}
```

Parse a CDM in either KVN or XML format.

Format is auto-detected from the first non-whitespace character: `<`
routes to the XML parser, anything else to the KVN parser.

Returns `{:ok, %CDM{}}` or `{:error, reason}`.

# `parse_kvn`

```elixir
@spec parse_kvn(String.t()) :: {:ok, t()} | {:error, String.t()}
```

Parse a CDM in KVN format explicitly. Skips format auto-detection.

# `parse_xml`

```elixir
@spec parse_xml(String.t()) :: {:ok, t()} | {:error, String.t()}
```

Parse a CDM in XML format explicitly. Skips format auto-detection.

# `to_collision_params`

```elixir
@spec to_collision_params(t()) :: map()
```

Convert a parsed CDM to inputs for `Sidereon.Collision.probability/1`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
