My own corner of monopam
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

README.md

flexacm#

CCSDS Flexible Advanced Coding and Modulation for OCaml.

flexacm provides types and helpers for adaptive coding and modulation on space links per CCSDS 131.2-B-1: combinations of modulation (QPSK, 8-PSK, 16-APSK, 32-APSK) with coding rates from 1/4 to 9/10, and a Physical Layer Operations Control (PLOP) header that signals the active ACM mode to the receiver.

Installation#

Install with opam:

$ opam install flexacm

If opam cannot find the package, it may not yet be released in the public opam-repository. Add the overlay repository, then install it:

$ opam repo add samoht https://tangled.org/gazagnaire.org/opam-overlay.git
$ opam update
$ opam install flexacm

Usage#

Several presets from CCSDS 131.2-B Table 5-1 are built in. Spectral efficiency is derived from the modulation order and coding rate:

# let m = Flexacm.thirty_two_apsk_5_6 in
  Fmt.str "%a %.2f bits/symbol"
    Flexacm.pp_modulation m.modulation m.spectral_efficiency
- : string = "32-APSK 4.17 bits/symbol"

Custom modes can be constructed directly:

# let m =
    Flexacm.acm_mode ~mode_id:42
      ~modulation:Flexacm.Sixteen_APSK ~code_rate:Flexacm.Rate_3_4 in
  (m.mode_id, m.spectral_efficiency)
- : int * float = (42, 3.)

PLOP frame#

Wrap a coded data unit with a PLOP header so the receiver can demodulate:

# let plop =
    { Flexacm.plop_type = Flexacm.Plop_2;
      acm_mode_id = Flexacm.qpsk_1_2.mode_id;
      frame_len = 2048 } in
  let frame = Flexacm.frame ~plop (Bytes.of_string "coded bytes") in
  Fmt.str "%a" Flexacm.pp_frame frame
- : string = "{ plop={ plop=PLOP-2; mode=2; frame_len=2048 }; data_len=11 }"

Adaptive mode selection#

Given a table of modes sorted by ascending efficiency, mode_for_snr returns the highest-throughput mode whose threshold is below the current SNR:

# let table = [
    Flexacm.qpsk_1_4; Flexacm.qpsk_1_2; Flexacm.qpsk_3_4;
    Flexacm.eight_psk_2_3; Flexacm.sixteen_apsk_3_4;
    Flexacm.thirty_two_apsk_5_6 ] in
  match Flexacm.mode_for_snr table 8.0 with
  | Some m -> Fmt.str "%a" Flexacm.pp_modulation m.modulation
  | None -> "link budget too low"
- : string = "16-APSK"

The built-in threshold uses spectral efficiency as a proxy; a production implementation should use mode-specific Eb/N0 thresholds from the actual link budget.

Licence#

ISC