Files
MARTe-Integrated-Components/Test/E2E/datasources/gen_test_data.py
T
2026-06-25 00:45:45 +02:00

80 lines
2.7 KiB
Python

#!/usr/bin/env python3
"""
Generate a multi-signal binary test file for MARTe2 FileReader.
Format (per signal descriptor):
- 2B TypeDescriptor.all (uint16 LE)
- 32B signal name (null-padded)
- 4B numElements (uint32 LE)
Header: [4B numSigs] [signal desc...] [raw float32 data rows]
Three signals with different sizes to verify no data scrambling:
Signal_100: 100 float32 values per row
Signal_1K: 1000 float32 values per row
Signal_5K: 5000 float32 values per row
"""
import struct
import os
OUTPUT = "/tmp/udpstreamer_test_input.bin"
NUM_ROWS = 100
TYPE_FLOAT32 = 2056 # MARTe2 TypeDescriptor.all for Float32Bit
SIGNALS = [
("Signal_100", 100, lambda r, c: float(r * 1000 + c) / 100.0),
("Signal_1K", 1000, lambda r, c: float(r * 500 + c) / 50.0),
("Signal_5K", 5000, lambda r, c: float(r * 200 + c) / 20.0),
]
def generate():
with open(OUTPUT, "wb") as f:
# Header: numSigs
f.write(struct.pack("<I", len(SIGNALS)))
# Signal descriptors
for name, nelems, _ in SIGNALS:
f.write(struct.pack("<H", TYPE_FLOAT32))
padded = (name + "\0").encode() + b"\0" * 32
f.write(padded[:32])
f.write(struct.pack("<I", nelems))
# Data rows
total_floats = sum(n for _, n, _ in SIGNALS)
for row in range(NUM_ROWS):
values = []
for _, nelems, func in SIGNALS:
for col in range(nelems):
values.append(func(row, col))
f.write(struct.pack(f"<{total_floats}f", *values))
size = os.path.getsize(OUTPUT)
header_size = 4 + len(SIGNALS) * (2 + 32 + 4)
data_size = NUM_ROWS * total_floats * 4
print(f"Generated {OUTPUT}: {size} bytes")
print(f" Header: {header_size} B, Data: {data_size} B")
print(f" {NUM_ROWS} rows x {total_floats} floats ({', '.join(f'{n}' for _, n, _ in SIGNALS)} per signal)")
print(f" Total: {size} bytes")
# Verify
with open(OUTPUT, "rb") as f:
ns = struct.unpack("<I", f.read(4))[0]
print(f" Verified: {ns} signals")
for i in range(ns):
tc = struct.unpack("<H", f.read(2))[0]
nm = f.read(32).rstrip(b"\0").decode()
ne = struct.unpack("<I", f.read(4))[0]
print(f" {nm}: type={tc}, elems={ne}")
# Verify first row first few values of each signal
data = f.read()
offsets = [0]
for _, ne, _ in SIGNALS:
offsets.append(offsets[-1] + ne * 4)
for i, (name, ne, _) in enumerate(SIGNALS):
off = offsets[i]
vals = struct.unpack(f"<{min(5, ne)}f", data[off:off + min(5, ne) * 4])
print(f" {name} row 0 (first 5): {[round(v, 4) for v in vals]}")
if __name__ == "__main__":
generate()