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