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