From 1ade0ce47d8fec4e23370a548ca5bf6f19b78a1d Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Fri, 30 Sep 2022 12:25:11 -0700 Subject: [PATCH] sensord: test fixups (#25935) * sensord: test fixups * fix linter * check freq * fp seems reliable * clean that up * update refs Co-authored-by: Comma Device Co-authored-by: Bruce Wayne old-commit-hash: 80c40048cb62fff15a8e884cb05fba8ddfb11809 --- selfdrive/sensord/tests/test_sensord.py | 124 ++++++++---------- .../test/process_replay/process_replay.py | 2 +- selfdrive/test/process_replay/ref_commit | 2 +- 3 files changed, 57 insertions(+), 71 deletions(-) mode change 100644 => 100755 selfdrive/sensord/tests/test_sensord.py diff --git a/selfdrive/sensord/tests/test_sensord.py b/selfdrive/sensord/tests/test_sensord.py old mode 100644 new mode 100755 index 1af76c8384..82bd28446b --- a/selfdrive/sensord/tests/test_sensord.py +++ b/selfdrive/sensord/tests/test_sensord.py @@ -10,41 +10,33 @@ from cereal import log from system.hardware import TICI, HARDWARE from selfdrive.manager.process_config import managed_processes +BMX = { + ('bmx055', 'acceleration'), + ('bmx055', 'gyroUncalibrated'), + ('bmx055', 'magneticUncalibrated'), + ('bmx055', 'temperature'), +} + +LSM = { + ('lsm6ds3', 'acceleration'), + ('lsm6ds3', 'gyroUncalibrated'), + ('lsm6ds3', 'temperature'), +} +LSM_C = {(x[0]+'trc', x[1]) for x in LSM} + +MMC = { + ('mmc5603nj', 'magneticUncalibrated'), +} + +RPR = { + ('rpr0521', 'light'), +} + SENSOR_CONFIGURATIONS = ( - { - ('bmx055', 'acceleration'), - ('bmx055', 'gyroUncalibrated'), - ('bmx055', 'magneticUncalibrated'), - ('bmx055', 'temperature'), - ('lsm6ds3', 'acceleration'), - ('lsm6ds3', 'gyroUncalibrated'), - ('lsm6ds3', 'temperature'), - ('rpr0521', 'light'), - }, - { - ('lsm6ds3', 'acceleration'), - ('lsm6ds3', 'gyroUncalibrated'), - ('lsm6ds3', 'temperature'), - ('mmc5603nj', 'magneticUncalibrated'), - ('rpr0521', 'light'), - }, - { - ('bmx055', 'acceleration'), - ('bmx055', 'gyroUncalibrated'), - ('bmx055', 'magneticUncalibrated'), - ('bmx055', 'temperature'), - ('lsm6ds3trc', 'acceleration'), - ('lsm6ds3trc', 'gyroUncalibrated'), - ('lsm6ds3trc', 'temperature'), - ('rpr0521', 'light'), - }, - { - ('lsm6ds3trc', 'acceleration'), - ('lsm6ds3trc', 'gyroUncalibrated'), - ('lsm6ds3trc', 'temperature'), - ('mmc5603nj', 'magneticUncalibrated'), - ('rpr0521', 'light'), - }, + (BMX | LSM | RPR), + (MMC | LSM | RPR), + (BMX | LSM_C | RPR), + (MMC| LSM_C | RPR), ) Sensor = log.SensorEventData.SensorSource @@ -78,19 +70,14 @@ ALL_SENSORS = { } } -LSM_INT_GPIO = 84 - -def get_proc_interrupts(int_pin): - with open("/proc/interrupts") as f: - lines = f.read().split("\n") +LSM_IRQ = 336 - for line in lines: - if f" {int_pin} " in line: - return ''.join(list(filter(lambda e: e != '', line.split(' ')))[1:6]) - return "" +def get_irq_count(irq: int): + with open(f"/sys/kernel/irq/{irq}/per_cpu_count") as f: + per_cpu = map(int, f.read().split(",")) + return sum(per_cpu) def read_sensor_events(duration_sec): - sensor_types = ['accelerometer', 'gyroscope', 'magnetometer', 'accelerometer2', 'gyroscope2', 'lightSensor', 'temperatureSensor'] esocks = {} @@ -104,8 +91,7 @@ def read_sensor_events(duration_sec): events[esock] += messaging.drain_sock(esocks[esock]) time.sleep(0.1) - for etype in events: - assert len(events[etype]) != 0, f"No {etype} events collected" + assert sum(map(len, events.values())) != 0, "No sensor events collected!" return events @@ -120,11 +106,14 @@ class TestSensord(unittest.TestCase): # read initial sensor values every test case can use os.system("pkill -f ./_sensord") - managed_processes["sensord"].start() - time.sleep(3) - cls.sample_secs = 10 - cls.events = read_sensor_events(cls.sample_secs) - managed_processes["sensord"].stop() + try: + managed_processes["sensord"].start() + time.sleep(3) + cls.sample_secs = 10 + cls.events = read_sensor_events(cls.sample_secs) + finally: + # teardown won't run if this doesn't succeed + managed_processes["sensord"].stop() @classmethod def tearDownClass(cls): @@ -168,9 +157,9 @@ class TestSensord(unittest.TestCase): high_delay_diffs = list(filter(lambda d: d >= 20., tdiffs)) assert len(high_delay_diffs) < 15, f"Too many large diffs: {high_delay_diffs}" - # 100-108Hz, expected 104Hz avg_diff = sum(tdiffs)/len(tdiffs) - assert 9.3 < avg_diff < 10., f"avg difference {avg_diff}, below threshold" + avg_freq = 1. / (avg_diff * 1e-3) + assert 92. < avg_freq < 114., f"avg freq {avg_freq}Hz wrong, expected 104Hz" stddev = np.std(tdiffs) assert stddev < 2.0, f"Standard-dev to big {stddev}" @@ -201,26 +190,24 @@ class TestSensord(unittest.TestCase): m = getattr(measurement, measurement.which()) # check if gyro and accel timestamps are before logMonoTime - if str(m.source).startswith("lsm6ds3"): - if m.which() != 'temperature': - err_msg = f"Timestamp after logMonoTime: {m.timestamp} > {measurement.logMonoTime}" - assert m.timestamp < measurement.logMonoTime, err_msg + if str(m.source).startswith("lsm6ds3") and m.which() != 'temperature': + err_msg = f"Timestamp after logMonoTime: {m.timestamp} > {measurement.logMonoTime}" + assert m.timestamp < measurement.logMonoTime, err_msg # negative values might occur, as non interrupt packages created # before the sensor is read - tdiffs.append(abs(measurement.logMonoTime - m.timestamp)) + tdiffs.append(abs(measurement.logMonoTime - m.timestamp) / 1e6) - high_delay_diffs = set(filter(lambda d: d >= 10*10**6, tdiffs)) - assert len(high_delay_diffs) < 15, f"Too many high delay packages: {high_delay_diffs}" + high_delay_diffs = set(filter(lambda d: d >= 15., tdiffs)) + assert len(high_delay_diffs) < 20, f"Too many measurements published : {high_delay_diffs}" avg_diff = round(sum(tdiffs)/len(tdiffs), 4) - assert avg_diff < 4*10**6, f"Avg packet diff: {avg_diff:.1f}ns" + assert avg_diff < 4, f"Avg packet diff: {avg_diff:.1f}ms" stddev = np.std(tdiffs) - assert stddev < 2*10**6, f"Timing diffs have to high stddev: {stddev}" + assert stddev < 2, f"Timing diffs have too high stddev: {stddev}" def test_sensor_values_sanity_check(self): - sensor_values = dict() for etype in self.events: for measurement in self.events[etype]: @@ -239,7 +226,6 @@ class TestSensord(unittest.TestCase): # Sanity check sensor values and counts for sensor, stype in sensor_values: - for s in ALL_SENSORS[sensor]: if s.type != stype: continue @@ -255,14 +241,13 @@ class TestSensord(unittest.TestCase): assert s.sanity_min <= mean_norm <= s.sanity_max, err_msg def test_sensor_verify_no_interrupts_after_stop(self): - managed_processes["sensord"].start() time.sleep(3) # read /proc/interrupts to verify interrupts are received - state_one = get_proc_interrupts(LSM_INT_GPIO) + state_one = get_irq_count(LSM_IRQ) time.sleep(1) - state_two = get_proc_interrupts(LSM_INT_GPIO) + state_two = get_irq_count(LSM_IRQ) error_msg = f"no interrupts received after sensord start!\n{state_one} {state_two}" assert state_one != state_two, error_msg @@ -271,10 +256,11 @@ class TestSensord(unittest.TestCase): time.sleep(1) # read /proc/interrupts to verify no more interrupts are received - state_one = get_proc_interrupts(LSM_INT_GPIO) + state_one = get_irq_count(LSM_IRQ) time.sleep(1) - state_two = get_proc_interrupts(LSM_INT_GPIO) + state_two = get_irq_count(LSM_IRQ) assert state_one == state_two, "Interrupts received after sensord stop!" + if __name__ == "__main__": unittest.main() diff --git a/selfdrive/test/process_replay/process_replay.py b/selfdrive/test/process_replay/process_replay.py index c8389bb71c..10084bff9f 100755 --- a/selfdrive/test/process_replay/process_replay.py +++ b/selfdrive/test/process_replay/process_replay.py @@ -328,7 +328,7 @@ CONFIGS = [ proc_name="locationd", pub_sub={ "cameraOdometry": ["liveLocationKalman"], - "accelerometer": [], "gyroscope": [], "magnetometer": [], + "accelerometer": [], "gyroscope": [], "gpsLocationExternal": [], "liveCalibration": [], "carState": [], }, ignore=["logMonoTime", "valid"], diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index e308d2dff4..7485942244 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -761eada809a0eaa67989e6e435042633f965d1fe \ No newline at end of file +5d33199905cbf9d9b45ef722a40530b08d5cecf4 \ No newline at end of file