22import os
33import sys
44import time
5- from typing import Any
6-
5+ from collections import defaultdict
76from tqdm import tqdm
7+ from typing import Any
88
99import cereal .messaging as messaging
1010from cereal .visionipc .visionipc_pyx import VisionIpcServer , VisionStreamType # pylint: disable=no-name-in-module, import-error
1111from common .spinner import Spinner
1212from common .timeout import Timeout
1313from common .transformations .camera import get_view_frame_from_road_frame , eon_f_frame_size , tici_f_frame_size , \
14- eon_d_frame_size , tici_d_frame_size
14+ eon_d_frame_size , tici_d_frame_size
1515from selfdrive .hardware import PC , TICI
1616from selfdrive .manager .process_config import managed_processes
1717from selfdrive .test .openpilotci import BASE_URL , get_url
2525 TEST_ROUTE = "4cf7a6ad03080c90|2021-09-29--13-46-36"
2626else :
2727 TEST_ROUTE = "303055c0002aefd1|2021-11-22--18-36-32"
28+ SEGMENT = 0
2829
29- CACHE_DIR = os .getenv ("CACHE_DIR " , None )
30+ SEND_EXTRA_INPUTS = bool ( os .getenv ("SEND_EXTRA_INPUTS " , "0" ) )
3031
31- packet_from_camera = {"roadCameraState" :"modelV2" , "driverCameraState" :"driverState" }
3232
3333def get_log_fn (ref_commit ):
3434 return "%s_%s_%s.bz2" % (TEST_ROUTE , "model_tici" if TICI else "model" , ref_commit )
3535
36+
3637def replace_calib (msg , calib ):
3738 msg = msg .as_builder ()
3839 if calib is not None :
3940 msg .liveCalibration .extrinsicMatrix = get_view_frame_from_road_frame (* calib , 1.22 ).flatten ().tolist ()
4041 return msg
4142
42- def process_frame (msg , pm , sm , log_msgs , vipc_server , spinner , frs , frame_idxs , last_desire ):
43- if msg .which () == "roadCameraState" and last_desire is not None :
44- dat = messaging .new_message ('lateralPlan' )
45- dat .lateralPlan .desire = last_desire
46- pm .send ('lateralPlan' , dat )
47-
48- f = msg .as_builder ()
49- pm .send (msg .which (), f )
50-
51- img = frs [msg .which ()].get (frame_idxs [msg .which ()], pix_fmt = "yuv420p" )[0 ]
52- if msg .which == "roadCameraState" :
53- vipc_server .send (VisionStreamType .VISION_STREAM_ROAD , img .flatten ().tobytes (), f .roadCameraState .frameId ,
54- f .roadCameraState .timestampSof , f .roadCameraState .timestampEof )
55- else :
56- vipc_server .send (VisionStreamType .VISION_STREAM_DRIVER , img .flatten ().tobytes (), f .driverCameraState .frameId ,
57- f .driverCameraState .timestampSof , f .driverCameraState .timestampEof )
58- with Timeout (seconds = 15 ):
59- log_msgs .append (messaging .recv_one (sm .sock [packet_from_camera [msg .which ()]]))
60-
61- frame_idxs [msg .which ()] += 1
62- if frame_idxs [msg .which ()] >= frs [msg .which ()].frame_count :
63- return None
64- update_spinner (spinner , frame_idxs ['roadCameraState' ], frs ['roadCameraState' ].frame_count ,
65- frame_idxs ['driverCameraState' ], frs ['driverCameraState' ].frame_count )
66- return 0
67-
68- def update_spinner (s , fidx , fcnt , didx , dcnt ):
69- s .update ("replaying models: road %d/%d, driver %d/%d" % (fidx , fcnt , didx , dcnt ))
70-
71- def model_replay (lr_list , frs ):
43+
44+ def model_replay (lr , frs ):
7245 spinner = Spinner ()
7346 spinner .update ("starting model replay" )
7447
@@ -77,93 +50,110 @@ def model_replay(lr_list, frs):
7750 vipc_server .create_buffers (VisionStreamType .VISION_STREAM_DRIVER , 40 , False , * (tici_d_frame_size if TICI else eon_d_frame_size ))
7851 vipc_server .start_listener ()
7952
80- pm = messaging .PubMaster (['roadCameraState' , 'driverCameraState' , 'liveCalibration' , 'lateralPlan' ])
8153 sm = messaging .SubMaster (['modelV2' , 'driverState' ])
54+ pm = messaging .PubMaster (['roadCameraState' , 'driverCameraState' , 'liveCalibration' , 'lateralPlan' ])
8255
8356 try :
8457 managed_processes ['modeld' ].start ()
8558 managed_processes ['dmonitoringmodeld' ].start ()
86- time .sleep (5 )
59+ time .sleep (2 )
8760 sm .update (1000 )
8861
89- last_desire = None
9062 log_msgs = []
91- frame_idxs = dict .fromkeys (['roadCameraState' ,'driverCameraState' ], 0 )
92-
93- cal = [msg for msg in lr if msg .which () == "liveCalibration" ]
94- for msg in cal [:5 ]:
95- pm .send (msg .which (), replace_calib (msg , None ))
96-
97- for msg in tqdm (lr_list ):
98- if msg .which () == "liveCalibration" :
99- last_calib = list (msg .liveCalibration .rpyCalib )
100- pm .send (msg .which (), replace_calib (msg , last_calib ))
101- elif msg .which () == "lateralPlan" :
102- last_desire = msg .lateralPlan .desire
103- elif msg .which () in ["roadCameraState" , "driverCameraState" ]:
104- ret = process_frame (msg , pm , sm , log_msgs , vipc_server , spinner , frs , frame_idxs , last_desire )
105- if ret is None :
63+ last_desire = None
64+ frame_idxs = defaultdict (lambda : 0 )
65+
66+ # init modeld with valid calibration
67+ cal_msgs = [msg for msg in lr if msg .which () == "liveCalibration" ]
68+ for _ in range (5 ):
69+ pm .send (cal_msgs [0 ].which (), cal_msgs [0 ].as_builder ())
70+ time .sleep (0.1 )
71+
72+ for msg in tqdm (lr ):
73+ if SEND_EXTRA_INPUTS :
74+ if msg .which () == "liveCalibration" :
75+ last_calib = list (msg .liveCalibration .rpyCalib )
76+ pm .send (msg .which (), replace_calib (msg , last_calib ))
77+ elif msg .which () == "lateralPlan" :
78+ last_desire = msg .lateralPlan .desire
79+ dat = messaging .new_message ('lateralPlan' )
80+ dat .lateralPlan .desire = last_desire
81+ pm .send ('lateralPlan' , dat )
82+
83+ if msg .which () in ["roadCameraState" , "driverCameraState" ]:
84+ camera_state = getattr (msg , msg .which ())
85+ stream = VisionStreamType .VISION_STREAM_ROAD if msg .which () == "roadCameraState" else VisionStreamType .VISION_STREAM_DRIVER
86+ img = frs [msg .which ()].get (frame_idxs [msg .which ()], pix_fmt = "yuv420p" )[0 ]
87+
88+ # send camera state and frame
89+ pm .send (msg .which (), msg .as_builder ())
90+ vipc_server .send (stream , img .flatten ().tobytes (), camera_state .frameId ,
91+ camera_state .timestampSof , camera_state .timestampEof )
92+
93+ # wait for a response
94+ with Timeout (seconds = 15 ):
95+ packet_from_camera = {"roadCameraState" : "modelV2" , "driverCameraState" : "driverState" }
96+ log_msgs .append (messaging .recv_one (sm .sock [packet_from_camera [msg .which ()]]))
97+
98+ frame_idxs [msg .which ()] += 1
99+ if frame_idxs [msg .which ()] >= frs [msg .which ()].frame_count :
106100 break
107101
108- except KeyboardInterrupt :
109- pass
102+ spinner .update ("replaying models: road %d/%d, driver %d/%d" % (frame_idxs ['roadCameraState' ],
103+ frs ['roadCameraState' ].frame_count , frame_idxs ['driverCameraState' ], frs ['driverCameraState' ].frame_count ))
104+
110105 finally :
111106 spinner .close ()
112107 managed_processes ['modeld' ].stop ()
113108 managed_processes ['dmonitoringmodeld' ].stop ()
114109
110+
115111 return log_msgs
116112
113+
117114if __name__ == "__main__" :
118115
119116 update = "--update" in sys .argv
120-
121- if TICI :
122- os .system ('sudo mount -o remount,size=200M /tmp' ) # c3 hevcs are 75M each
123-
124117 replay_dir = os .path .dirname (os .path .abspath (__file__ ))
125118 ref_commit_fn = os .path .join (replay_dir , "model_replay_ref_commit" )
126119
127- segnum = 0
128- frs = {}
129- if CACHE_DIR :
130- lr = LogReader (os .path .join (CACHE_DIR , '%s--%d--rlog.bz2' % (TEST_ROUTE .replace ('|' , '_' ), segnum )))
131- frs ['roadCameraState' ] = FrameReader (os .path .join (CACHE_DIR , '%s--%d--fcamera.hevc' % (TEST_ROUTE .replace ('|' , '_' ), segnum )))
132- frs ['driverCameraState' ] = FrameReader (os .path .join (CACHE_DIR , '%s--%d--dcamera.hevc' % (TEST_ROUTE .replace ('|' , '_' ), segnum )))
133- else :
134- lr = LogReader (get_url (TEST_ROUTE , segnum ))
135- frs ['roadCameraState' ] = FrameReader (get_url (TEST_ROUTE , segnum , log_type = "fcamera" ))
136- frs ['driverCameraState' ] = FrameReader (get_url (TEST_ROUTE , segnum , log_type = "dcamera" ))
120+ # load logs
121+ lr = list (LogReader (get_url (TEST_ROUTE , SEGMENT )))
122+ frs = {
123+ 'roadCameraState' : FrameReader (get_url (TEST_ROUTE , SEGMENT , log_type = "fcamera" )),
124+ 'driverCameraState' : FrameReader (get_url (TEST_ROUTE , SEGMENT , log_type = "dcamera" )),
125+ }
137126
138- lr_list = list ( lr )
139- log_msgs = model_replay (lr_list , frs )
127+ # run replay
128+ log_msgs = model_replay (lr , frs )
140129
130+ # get diff
141131 failed = False
142132 if not update :
143- ref_commit = open (ref_commit_fn ).read ().strip ()
133+ with open (ref_commit_fn ) as f :
134+ ref_commit = f .read ().strip ()
144135 log_fn = get_log_fn (ref_commit )
145136 cmp_log = LogReader (BASE_URL + log_fn )
146137
147- ignore = ['logMonoTime' , 'valid' ,
148- 'modelV2.frameDropPerc' ,
149- 'modelV2.modelExecutionTime' ,
150- 'driverState.modelExecutionTime' ,
151- 'driverState.dspExecutionTime' ]
138+ ignore = [
139+ 'logMonoTime' ,
140+ 'modelV2.frameDropPerc' ,
141+ 'modelV2.modelExecutionTime' ,
142+ 'driverState.modelExecutionTime' ,
143+ 'driverState.dspExecutionTime'
144+ ]
152145 tolerance = None if not PC else 1e-3
153146 results : Any = {TEST_ROUTE : {}}
154147 results [TEST_ROUTE ]["models" ] = compare_logs (cmp_log , log_msgs , tolerance = tolerance , ignore_fields = ignore )
155148 diff1 , diff2 , failed = format_diff (results , ref_commit )
156149
157150 print (diff2 )
158- print ('-------------' )
159- print ('-------------' )
160- print ('-------------' )
161- print ('-------------' )
162- print ('-------------' )
151+ print ('-------------\n ' * 5 )
163152 print (diff1 )
164153 with open ("model_diff.txt" , "w" ) as f :
165154 f .write (diff2 )
166155
156+ # upload new refs
167157 if update or failed :
168158 from selfdrive .test .openpilotci import upload_file
169159
0 commit comments