23
23
from openpilot .system .hardware import HARDWARE
24
24
from openpilot .system .hardware .hw import Paths
25
25
from openpilot .tools .lib .logreader import LogReader
26
- from openpilot .tools .lib .log_time_series import msgs_to_time_series
27
26
28
27
"""
29
28
CPU usage budget
@@ -120,8 +119,7 @@ def setup_class(cls):
120
119
if "DEBUG" in os .environ :
121
120
segs = filter (lambda x : os .path .exists (os .path .join (x , "rlog.zst" )), Path (Paths .log_root ()).iterdir ())
122
121
segs = sorted (segs , key = lambda x : x .stat ().st_mtime )
123
- cls .lr = list (LogReader (os .path .join (segs [- 1 ], "rlog.zst" )))
124
- cls .ts = msgs_to_time_series (cls .lr )
122
+ cls .lr = list (LogReader (os .path .join (segs [- 3 ], "rlog.zst" )))
125
123
return
126
124
127
125
# setup env
@@ -175,8 +173,7 @@ def setup_class(cls):
175
173
176
174
cls .lrs = [list (LogReader (os .path .join (str (s ), "rlog.zst" ))) for s in cls .segments ]
177
175
178
- cls .lr = cls .lrs [0 ]
179
- cls .ts = msgs_to_time_series (cls .lr )
176
+ cls .lr = list (LogReader (os .path .join (str (cls .segments [0 ]), "rlog.zst" )))
180
177
cls .log_path = cls .segments [0 ]
181
178
182
179
cls .log_sizes = {}
@@ -201,7 +198,7 @@ def test_service_frequencies(self, subtests):
201
198
assert len (msgs ) >= math .floor (SERVICE_LIST [s ].frequency * int (TEST_DURATION * 0.8 ))
202
199
203
200
def test_manager_starting_time (self ):
204
- st = self .ts ['managerState' ]['t' ][ 0 ]
201
+ st = self .msgs ['managerState' ][0 ]. logMonoTime / 1e9
205
202
assert (st - self .manager_st ) < 10 , f"manager.py took { st - self .manager_st } s to publish the first 'managerState' msg"
206
203
207
204
def test_cloudlog_size (self ):
@@ -229,7 +226,7 @@ def test_ui_timings(self):
229
226
result += "-------------- UI Draw Timing ------------------\n "
230
227
result += "------------------------------------------------\n "
231
228
232
- ts = self .ts ['uiDebug' ][ 'drawTimeMillis' ]
229
+ ts = [ m . uiDebug . drawTimeMillis for m in self .msgs ['uiDebug' ]]
233
230
result += f"min { min (ts ):.2f} ms\n "
234
231
result += f"max { max (ts ):.2f} ms\n "
235
232
result += f"std { np .std (ts ):.2f} ms\n "
@@ -322,7 +319,7 @@ def test_camera_frame_timings(self, subtests):
322
319
result += "----------------- SOF Timing ------------------\n "
323
320
result += "------------------------------------------------\n "
324
321
for name in ['roadCameraState' , 'wideRoadCameraState' , 'driverCameraState' ]:
325
- ts = self .ts [ name ][ 'timestampSof' ]
322
+ ts = [ getattr ( m , m . which ()). timestampSof for m in self .lr if name in m . which () ]
326
323
d_ms = np .diff (ts ) / 1e6
327
324
d50 = np .abs (d_ms - 50 )
328
325
result += f"{ name } sof delta vs 50ms: min { min (d50 ):.2f} ms\n "
@@ -341,30 +338,33 @@ def test_camera_sync(self, subtests):
341
338
# sanity checks within a single cam
342
339
for cam in cams :
343
340
with subtests .test (test = "frame_skips" , camera = cam ):
344
- assert set (np .diff (self .ts [cam ]['frameId' ])) == {1 , }, "Frame ID skips"
341
+ cam_log = [getattr (x , x .which ()) for x in self .msgs [cam ]]
342
+ assert set (np .diff ([x .frameId for x in cam_log ])) == {1 , }, "Frame ID skips"
345
343
346
344
# EOF > SOF
347
- eof_sof_diff = self . ts [ cam ][ ' timestampEof' ] - self . ts [ cam ][ ' timestampSof' ]
345
+ eof_sof_diff = np . array ([ x . timestampEof - x . timestampSof for x in cam_log ])
348
346
assert np .all (eof_sof_diff > 0 )
349
347
assert np .all (eof_sof_diff < 50 * 1e6 )
350
348
351
- first_fid = {c : min (self .ts [c ]['frameId' ]) for c in cams }
349
+ fid = {c : [getattr (m , m .which ()).frameId for m in self .msgs [c ]] for c in cams }
350
+ first_fid = [min (x ) for x in fid .values ()]
352
351
if cam .endswith ('CameraState' ):
353
352
# camerad guarantees that all cams start on frame ID 0
354
353
# (note loggerd also needs to start up fast enough to catch it)
355
- assert set (first_fid . values () ) == {0 , }, "Cameras don't start on frame ID 0"
354
+ assert set (first_fid ) == {0 , }, "Cameras don't start on frame ID 0"
356
355
else :
357
356
# encoder guarantees all cams start on the same frame ID
358
- assert len (set (first_fid . values () )) == 1 , "Cameras don't start on same frame ID"
357
+ assert len (set (first_fid )) == 1 , "Cameras don't start on same frame ID"
359
358
360
359
# we don't do a full segment rotation, so these might not match exactly
361
- last_fid = { c : max (self . ts [ c ][ 'frameId' ] ) for c in cams }
362
- assert max (last_fid . values ()) - min (last_fid . values () ) < 10
360
+ last_fid = [ max (x ) for x in fid . values ()]
361
+ assert max (last_fid ) - min (last_fid ) < 10
363
362
364
- start , end = min (first_fid .values ()), min (last_fid .values ())
363
+ start , end = min (first_fid ), min (last_fid )
364
+ all_ts = [[getattr (m , m .which ()).timestampSof for m in self .msgs [c ]] for c in cams ]
365
365
for i in range (end - start ):
366
- ts = { c : round (self . ts [ c ][ 'timestampSof' ][ i ]/ 1e6 , 1 ) for c in cams }
367
- diff = ( max (ts . values ()) - min (ts . values ()) )
366
+ ts = [ round (x [ i ]/ 1e6 , 1 ) for x in all_ts ]
367
+ diff = max (ts ) - min (ts )
368
368
assert diff < 2 , f"Cameras not synced properly: frame_id={ start + i } , { diff = :.1f} ms, { ts = } "
369
369
370
370
def test_mpc_execution_timings (self ):
@@ -438,7 +438,12 @@ def test_timings(self):
438
438
439
439
@release_only
440
440
def test_startup (self ):
441
- startup_alert = self .ts ['selfdriveState' ]['alertText1' ][0 ]
441
+ startup_alert = None
442
+ for msg in self .lrs [0 ]:
443
+ # can't use onroadEvents because the first msg can be dropped while loggerd is starting up
444
+ if msg .which () == "selfdriveState" :
445
+ startup_alert = msg .selfdriveState .alertText1
446
+ break
442
447
expected = EVENTS [log .OnroadEvent .EventName .startup ][ET .PERMANENT ].alert_text_1
443
448
assert startup_alert == expected , "wrong startup alert"
444
449
0 commit comments