15 releases

0.1.0-beta.23 Feb 5, 2025
0.1.0-beta.21 Dec 17, 2024
0.1.0-beta.19 Nov 26, 2024
0.1.0-beta.10 Jul 1, 2024
0.1.0-beta.1 Mar 30, 2024

#76 in Science

Download history 6/week @ 2024-11-01 3/week @ 2024-11-08 126/week @ 2024-11-22 58/week @ 2024-11-29 116/week @ 2024-12-06 163/week @ 2024-12-13 42/week @ 2024-12-20 24/week @ 2024-12-27 45/week @ 2025-01-03 30/week @ 2025-01-10 108/week @ 2025-01-17 26/week @ 2025-01-24 142/week @ 2025-01-31 45/week @ 2025-02-07 15/week @ 2025-02-14

263 downloads per month
Used in rdr

MIT/Apache

9MB
2.5K SLoC

CCSDS Spacecraft Data Stream Decoding

WARNING: This project is very much in development, and the API is very likely to change in ways that will break things. If you have comments or suggestions regarding the API feel free to file an issue.

The project provides tools for decoding spacecraft downlink telemetry streams conforming to the CCSDS recommended specifications (Blue Books) TM Synchronization and Channel Coding and Space Packet Protocol.

Supports:

  • Framing
    • Stream synchronization
    • Deransomization (pseudo-noise removal)
    • Integrity checking/correcting
      • Reed-Solomon FEC
      • CRC
  • Spacepacket decoding
    • Telemetry packets
    • Sequencing
    • Packet groups
  • Limited support for secondary header timecodes
    • CCSDS Day Segmented timecodes
    • NASA EOS timecodes for Aqua and Terra spacecrafts
    • Provided but not directly used

Much of the functionality is wrapped around [Iterator]s, and as such most of the public API returns an [Iterator] of some sort.

Examples

The following example shows how to decode an unsynchronized byte stream of CADUs for the Suomi-NPP spacecraft. This example code should work for any spacecraft data stream that conforms to CCSDS TM Synchronization and Channel Coding and Space Packet Protocol documents, where the input data is a stream containing pseudo-randomized CADUs with Reed-Solomon FEC (including parity bytes).

use std::fs::File;
use std::io::BufReader;
use ccsds::framing::*;

// Framing configuration
let block_len = 1020; // CADU length - ASM length
let interleave: u8 = 4;
let izone_len = 0;
let trailer_len = 0;

// 1. Synchronize stream and extract blocks
let file = BufReader::new(File::open("snpp.dat").unwrap());
let cadus = Synchronizer::new(file, block_len)
     .into_iter()
     .filter_map(Result::ok);

// 2. Decode (PN & RS) those blocks into Frames, ignoring frames with errors
let frames = decode_frames(
    cadus,
    Some(Box::new(DefaultReedSolomon::new(interleave))),
    Some(Box::new(DefaultDerandomizer)),
).filter_map(Result::ok);

// 3. Extract packets from Frames
let packets = decode_framed_packets(frames, izone_len, trailer_len, None);

It is also possible to have more control over the decode process for cases that do not conform to the standard CCSDS specifications.

For example, this will decode a stream of frames that are not pseudo-randomized and does not use Reed-Solomon FEC.

use std::fs::File;
use std::io::BufReader;
use ccsds::framing::*;

let block_len = 892; // Frame length
let interleave: u8 = 4;
let izone_len = 0;
let trailer_len = 0;

// 1. Synchronize stream and extract blocks
let file = BufReader::new(File::open("frames.dat").unwrap());
let cadus = Synchronizer::new(file, block_len)
    .into_iter()
    .filter_map(Result::ok);

// 2. Decode blocks into Frames
let frames = decode_frames(cadus, None, None).filter_map(|z| z.ok());

// 3. Extract packets from Frames
let packets = decode_framed_packets(frames, izone_len, trailer_len, None);

References:

License

Licensed under either of

at your option.

Dependencies

~6–20MB
~222K SLoC