Rename kamil_adc to rph_radar and fix its data path

This commit is contained in:
Ayzen
2026-10-06 18:15:18 +03:00
parent aef549ea76
commit a185e61495
94 changed files with 2851 additions and 9485 deletions
@@ -0,0 +1,69 @@
"""Collector packets preserve whole sweeps, source windows and pair identity."""
import struct
import unittest
import numpy as np
from python_app.hardware_full.rph_radar.protocol import RphRadarStreamParser
def packet(*, source_id=1, cycle_id=1, start=100, end=200, combo=(1, 2), dirty=0, points=None):
if points is None:
points = [(0xA, 1, 10, -1), (0xA8, 1, 100, 5)]
payload = b"".join(struct.pack("<HHhh", *point) for point in points)
return struct.pack("<4sIQQQQHHI", b"RPH1", len(payload), source_id, cycle_id,
start, end, *combo, dirty) + payload
class RphRadarStreamParserTest(unittest.TestCase):
def test_fragmented_packets_keep_source_window_and_identity(self):
parser = RphRadarStreamParser()
sweeps = []
for byte in b"preroll" + packet(source_id=73, cycle_id=9):
sweeps.extend(parser.feed(bytes([byte])))
self.assertEqual(len(sweeps), 1)
sweep = sweeps[0]
self.assertEqual((sweep.source_id, sweep.cycle_id, sweep.capture_start_ns, sweep.capture_end_ns),
(73, 9, 100, 200))
self.assertEqual(sweep.combo, (1, 2))
self.assertEqual(sweep.main.tolist(), [10-1j])
self.assertEqual(sweep.reference.tolist(), [100+5j])
self.assertEqual(sweep.main.dtype, np.complex64)
def test_whole_packet_loss_does_not_merge_pairs(self):
parser = RphRadarStreamParser()
first, last = parser.feed(packet(source_id=1) + packet(source_id=3, combo=(2, 3),
points=[(0xA, 2, 20, 0), (0xA8, 2, 200, 0)]))
self.assertEqual((first.combo, first.steps.tolist()), ((1, 2), [1]))
self.assertEqual((last.combo, last.steps.tolist()), ((2, 3), [2]))
self.assertEqual(last.source_id, 3)
def test_aligns_both_channels_and_keeps_only_shared_steps(self):
parser = RphRadarStreamParser()
(sweep,) = parser.feed(packet(points=[(0xA, 3, 3, 0), (0xA8, 3, 30, 0),
(0xA, 1, 1, 0), (0xA8, 1, 10, 0), (0xA, 2, 2, 0)]))
self.assertEqual(sweep.steps.tolist(), [1, 3])
self.assertEqual(sweep.main.real.tolist(), [1, 3])
self.assertEqual(sweep.reference.real.tolist(), [10, 30])
def test_bad_window_size_flags_and_point_marker_fail_fast(self):
for encoded in (packet(start=0), packet(start=200, end=100), packet(dirty=2),
packet(source_id=0), packet(cycle_id=0),
packet(points=[(0x1A, 1, 1, 1)]),
b"RPH1" + struct.pack("<I", 0xFFFFFFFF) + bytes(40)):
with self.subTest(encoded=encoded), self.assertRaisesRegex(ValueError, "protocol"):
RphRadarStreamParser().feed(encoded)
def test_reset_discards_partial_packet(self):
parser = RphRadarStreamParser()
self.assertEqual(parser.feed(packet()[:53]), [])
parser.reset()
(sweep,) = parser.feed(packet(source_id=2, dirty=1, combo=(65535, 65535)))
self.assertEqual(sweep.source_id, 2)
self.assertIsNone(sweep.combo)
self.assertTrue(sweep.dirty)
if __name__ == "__main__":
unittest.main()