sensord: test fixups (#25935)

* sensord: test fixups

* fix linter

* check freq

* fp seems reliable

* clean that up

* update refs

Co-authored-by: Comma Device <device@comma.ai>
Co-authored-by: Bruce Wayne <batman@z840-provisioning.internal>
old-commit-hash: 80c40048cb
taco
Adeeb Shihadeh 3 years ago committed by GitHub
parent d3d79ad145
commit 1ade0ce47d
  1. 124
      selfdrive/sensord/tests/test_sensord.py
  2. 2
      selfdrive/test/process_replay/process_replay.py
  3. 2
      selfdrive/test/process_replay/ref_commit

@ -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()

@ -328,7 +328,7 @@ CONFIGS = [
proc_name="locationd",
pub_sub={
"cameraOdometry": ["liveLocationKalman"],
"accelerometer": [], "gyroscope": [], "magnetometer": [],
"accelerometer": [], "gyroscope": [],
"gpsLocationExternal": [], "liveCalibration": [], "carState": [],
},
ignore=["logMonoTime", "valid"],

@ -1 +1 @@
761eada809a0eaa67989e6e435042633f965d1fe
5d33199905cbf9d9b45ef722a40530b08d5cecf4
Loading…
Cancel
Save