CCSDS Synchronization and Channel Coding (131.0-B, 231.0-B)
0
fork

Configure Feed

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

Remove self-test interop (LDPC, Turbo); extend SCC dariol83

LDPC and Turbo interop tests reimplemented the CCSDS encoder in
Python ("we implement the full CCSDS H-matrix construction",
"we implement the full CCSDS turbo encoder here"). Not interop.

SCC dariol83 interop extended with Reed-Solomon traces using
dariol83's RS codec.

+189 -2
+85
test/interop/dariol83/scripts/generate.java
··· 9 9 10 10 import eu.dariolucia.ccsds.tmtc.algorithm.BchCltuAlgorithm; 11 11 import eu.dariolucia.ccsds.tmtc.algorithm.RandomizerAlgorithm; 12 + import eu.dariolucia.ccsds.tmtc.algorithm.ReedSolomonAlgorithm; 12 13 13 14 import java.io.FileWriter; 14 15 import java.io.PrintWriter; ··· 205 206 } 206 207 207 208 // ----------------------------------------------------------------------- 209 + // Reed-Solomon traces 210 + // ----------------------------------------------------------------------- 211 + 212 + record RsVector(String name, byte[] data) {} 213 + 214 + static void generateReedSolomonTraces(Path traceDir) throws Exception { 215 + // RS(255,223): 223 data bytes -> 255 codeword bytes (32 parity) 216 + ReedSolomonAlgorithm rs = ReedSolomonAlgorithm.TM_255_223; 217 + 218 + RsVector[] vectors = { 219 + // All zeros 220 + new RsVector("rs_zeros", filled(223, 0x00)), 221 + // All ones 222 + new RsVector("rs_ff", filled(223, 0xFF)), 223 + // Alternating 0xAA/0x55 224 + new RsVector("rs_alt", alternating(223)), 225 + // Counting bytes 226 + new RsVector("rs_count", counting(223)), 227 + // Single non-zero byte at start 228 + new RsVector("rs_one_at_start", oneAt(223, 0)), 229 + // Single non-zero byte at end 230 + new RsVector("rs_one_at_end", oneAt(223, 222)), 231 + // Single non-zero byte in middle 232 + new RsVector("rs_one_at_mid", oneAt(223, 111)), 233 + // Random-looking data via pseudo-random seed 234 + new RsVector("rs_prbs", prbs(223, 0x42)), 235 + // All 0x01 236 + new RsVector("rs_01", filled(223, 0x01)), 237 + // All 0x80 238 + new RsVector("rs_80", filled(223, 0x80)), 239 + }; 240 + 241 + try (PrintWriter pw = new PrintWriter(new FileWriter( 242 + traceDir.resolve("reed_solomon.csv").toFile()))) { 243 + pw.println("name,data_hex,codeword_hex"); 244 + 245 + for (RsVector v : vectors) { 246 + byte[] codeword = rs.encodeCodeword(v.data()); 247 + 248 + // Verify data is a prefix of codeword (systematic encoding) 249 + boolean systematic = true; 250 + for (int i = 0; i < v.data().length; i++) { 251 + if (codeword[i] != v.data()[i]) { 252 + systematic = false; 253 + break; 254 + } 255 + } 256 + assert systematic 257 + : v.name() + ": encodeCodeword not systematic"; 258 + assert codeword.length == 255 259 + : v.name() + ": codeword length != 255"; 260 + 261 + String dataHex = bytesToHex(v.data()); 262 + String codewordHex = bytesToHex(codeword); 263 + 264 + pw.printf("%s,%s,%s%n", v.name(), dataHex, codewordHex); 265 + } 266 + } 267 + System.out.println("Wrote " + traceDir.resolve("reed_solomon.csv")); 268 + } 269 + 270 + /** Byte array with a single 0xFF at position [pos], rest zeros. */ 271 + static byte[] oneAt(int len, int pos) { 272 + byte[] out = new byte[len]; 273 + out[pos] = (byte) 0xFF; 274 + return out; 275 + } 276 + 277 + /** Simple PRBS-like data: XOR-shift from a seed. */ 278 + static byte[] prbs(int len, int seed) { 279 + byte[] out = new byte[len]; 280 + int state = seed; 281 + for (int i = 0; i < len; i++) { 282 + state ^= (state << 13) & 0xFFFF; 283 + state ^= (state >>> 17); 284 + state ^= (state << 5) & 0xFFFF; 285 + out[i] = (byte) (state & 0xFF); 286 + state = (state & 0xFFFF) | ((out[i] & 0xFF) << 16); 287 + } 288 + return out; 289 + } 290 + 291 + // ----------------------------------------------------------------------- 208 292 // Main 209 293 // ----------------------------------------------------------------------- 210 294 ··· 218 302 219 303 generateCltuTraces(traceDir); 220 304 generateRandomizerTraces(traceDir); 305 + generateReedSolomonTraces(traceDir); 221 306 } 222 307 }
+93 -2
test/interop/dariol83/test.ml
··· 1 1 (** Java interop tests for ocaml-scc. 2 2 3 - Tests CLTU encoding (BCH codeblocks) and CCSDS TM randomizer against 4 - dariol83/ccsds (Java), an independent CCSDS library. 3 + Tests CLTU encoding (BCH codeblocks), CCSDS TM randomizer, and 4 + Reed-Solomon RS(255,223) encoding against dariol83/ccsds (Java), an 5 + independent CCSDS library. 5 6 6 7 Traces generated by: dariol83/ccsds 1.0.6 via jbang 7 8 Regenerate: REGEN_TRACES=1 dune build @regen-traces *) ··· 145 146 r.name r.randomized_hex got_hex 146 147 147 148 (* ----------------------------------------------------------------------- 149 + Reed-Solomon traces 150 + ----------------------------------------------------------------------- *) 151 + 152 + type rs_row = { name : string; data_hex : string; codeword_hex : string } 153 + 154 + let rs_codec = 155 + Csvt.( 156 + Row.( 157 + obj (fun name data_hex codeword_hex -> { name; data_hex; codeword_hex }) 158 + |> col "name" string ~enc:(fun r -> r.name) 159 + |> col "data_hex" string ~enc:(fun r -> r.data_hex) 160 + |> col "codeword_hex" string ~enc:(fun r -> r.codeword_hex) 161 + |> finish)) 162 + 163 + let parse_rs_rows () = 164 + match Csvt.decode_file rs_codec (trace "reed_solomon.csv") with 165 + | Ok rows -> rows 166 + | Error e -> 167 + Alcotest.failf "failed to parse reed_solomon.csv: %a" Csvt.pp_error e 168 + 169 + let test_rs_encode (r : rs_row) () = 170 + let data = bytes_of_hex r.data_hex in 171 + let codeword = Scc.Coding.Reed_solomon.encode data in 172 + let got_hex = hex_of_bytes codeword in 173 + if got_hex <> r.codeword_hex then 174 + Alcotest.failf "%s: RS encode mismatch\n expected: %s\n got: %s" 175 + r.name r.codeword_hex got_hex 176 + 177 + let test_rs_decode (r : rs_row) () = 178 + let codeword = bytes_of_hex r.codeword_hex in 179 + match Scc.Coding.Reed_solomon.decode codeword with 180 + | Error e -> Alcotest.failf "%s: RS decode failed: %s" r.name e 181 + | Ok data -> 182 + let got_hex = hex_of_bytes data in 183 + if got_hex <> r.data_hex then 184 + Alcotest.failf "%s: RS decode mismatch\n expected: %s\n got: %s" 185 + r.name r.data_hex got_hex 186 + 187 + let test_rs_roundtrip (r : rs_row) () = 188 + let data = bytes_of_hex r.data_hex in 189 + let codeword = Scc.Coding.Reed_solomon.encode data in 190 + match Scc.Coding.Reed_solomon.decode codeword with 191 + | Error e -> Alcotest.failf "%s: RS roundtrip decode failed: %s" r.name e 192 + | Ok decoded -> 193 + let got_hex = hex_of_bytes decoded in 194 + if got_hex <> r.data_hex then 195 + Alcotest.failf 196 + "%s: RS roundtrip mismatch\n expected: %s\n got: %s" r.name 197 + r.data_hex got_hex 198 + 199 + let test_rs_error_correction (r : rs_row) () = 200 + let codeword = bytes_of_hex r.codeword_hex in 201 + (* Inject 8 symbol errors (well within t=16 correction capability) *) 202 + for i = 0 to 7 do 203 + let pos = i * 30 in 204 + let orig = Char.code (Bytes.get codeword pos) in 205 + Bytes.set codeword pos (Char.chr (orig lxor 0xFF)) 206 + done; 207 + match Scc.Coding.Reed_solomon.decode codeword with 208 + | Error e -> 209 + Alcotest.failf "%s: RS decode failed with 8 errors (t=16): %s" r.name e 210 + | Ok data -> 211 + let got_hex = hex_of_bytes data in 212 + if got_hex <> r.data_hex then 213 + Alcotest.failf 214 + "%s: RS error-correction mismatch\n expected: %s\n got: %s" 215 + r.name r.data_hex got_hex 216 + 217 + (* ----------------------------------------------------------------------- 148 218 Test runner 149 219 ----------------------------------------------------------------------- *) 150 220 151 221 let () = 152 222 let cltu_rows = parse_cltu_rows () in 153 223 let rand_rows = parse_rand_rows () in 224 + let rs_rows = parse_rs_rows () in 154 225 Alcotest.run "scc-interop" 155 226 [ 156 227 ( "cltu-encode", ··· 183 254 (fun (r : rand_row) -> 184 255 Alcotest.test_case r.name `Quick (test_randomize_string r)) 185 256 rand_rows ); 257 + ( "rs-encode", 258 + List.map 259 + (fun (r : rs_row) -> 260 + Alcotest.test_case r.name `Quick (test_rs_encode r)) 261 + rs_rows ); 262 + ( "rs-decode", 263 + List.map 264 + (fun (r : rs_row) -> 265 + Alcotest.test_case r.name `Quick (test_rs_decode r)) 266 + rs_rows ); 267 + ( "rs-roundtrip", 268 + List.map 269 + (fun (r : rs_row) -> 270 + Alcotest.test_case r.name `Quick (test_rs_roundtrip r)) 271 + rs_rows ); 272 + ( "rs-error-correction", 273 + List.map 274 + (fun (r : rs_row) -> 275 + Alcotest.test_case r.name `Quick (test_rs_error_correction r)) 276 + rs_rows ); 186 277 ]
+11
test/interop/dariol83/traces/reed_solomon.csv
··· 1 + name,data_hex,codeword_hex 2 + rs_zeros,00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 3 + rs_ff,ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff,ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 4 + rs_alt,aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa,aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aa55aae834d202bee417b8fbc5c7e435e53db4b43de535e4c7c5fbb817e4be02d234e8 5 + rs_count,000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcddde,000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcddde4ffb92dd557ec67f27fb8982cf58f8fd028ad117fcef6b2793d0418826578651 6 + rs_one_at_start,ff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,ff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ff22071d51813ff686e75df5641d37b8d7b8371d64f55de786f63f81511d0722 7 + rs_one_at_end,000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ff,000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ff22071d51813ff686e75df5641d37b8d7b8371d64f55de786f63f81511d0722ff 8 + rs_one_at_mid,000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002eb0a05ba37d4a329285ff313613bcf5f5bc133631ff8592324a7da35ba0b02e 9 + rs_prbs,0263127b8665b76c1af70c4a8fc82c7aa7748ee93d4322533ac724f62d5bb64d0bce896d3be635cfa87c0263127b8665b76c1af70c4a8fc82c7aa7748ee93d4322533ac724f62d5bb64d0bce896d3be635cfa87c0263127b8665b76c1af70c4a8fc82c7aa7748ee93d4322533ac724f62d5bb64d0bce896d3be635cfa87c0263127b8665b76c1af70c4a8fc82c7aa7748ee93d4322533ac724f62d5bb64d0bce896d3be635cfa87c0263127b8665b76c1af70c4a8fc82c7aa7748ee93d4322533ac724f62d5bb64d0bce896d3be635cfa87c0263127b8665b76c1af70c4a8f,0263127b8665b76c1af70c4a8fc82c7aa7748ee93d4322533ac724f62d5bb64d0bce896d3be635cfa87c0263127b8665b76c1af70c4a8fc82c7aa7748ee93d4322533ac724f62d5bb64d0bce896d3be635cfa87c0263127b8665b76c1af70c4a8fc82c7aa7748ee93d4322533ac724f62d5bb64d0bce896d3be635cfa87c0263127b8665b76c1af70c4a8fc82c7aa7748ee93d4322533ac724f62d5bb64d0bce896d3be635cfa87c0263127b8665b76c1af70c4a8fc82c7aa7748ee93d4322533ac724f62d5bb64d0bce896d3be635cfa87c0263127b8665b76c1af70c4a8ff08d02e67ed9e22fada8d5d3cbeec3bbcd790f47bc83f09a728c68a3e7320c55 10 + rs_01,01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101,010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101 11 + rs_80,80808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080,808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080