|  |  |  | from collections import defaultdict
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from cereal import messaging
 | 
					
						
							|  |  |  | from openpilot.selfdrive.test.process_replay.vision_meta import meta_from_encode_index
 | 
					
						
							|  |  |  | from openpilot.selfdrive.car.toyota.values import EPS_SCALE
 | 
					
						
							|  |  |  | from openpilot.selfdrive.manager.process_config import managed_processes
 | 
					
						
							|  |  |  | from panda import Panda
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def migrate_all(lr, old_logtime=False, manager_states=False, panda_states=False, camera_states=False):
 | 
					
						
							|  |  |  |   msgs = migrate_sensorEvents(lr, old_logtime)
 | 
					
						
							|  |  |  |   msgs = migrate_carParams(msgs, old_logtime)
 | 
					
						
							|  |  |  |   if manager_states:
 | 
					
						
							|  |  |  |     msgs = migrate_managerState(msgs)
 | 
					
						
							|  |  |  |   if panda_states:
 | 
					
						
							|  |  |  |     msgs = migrate_pandaStates(msgs)
 | 
					
						
							|  |  |  |     msgs = migrate_peripheralState(msgs)
 | 
					
						
							|  |  |  |   if camera_states:
 | 
					
						
							|  |  |  |     msgs = migrate_cameraStates(msgs)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return msgs
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def migrate_managerState(lr):
 | 
					
						
							|  |  |  |   all_msgs = []
 | 
					
						
							|  |  |  |   for msg in lr:
 | 
					
						
							|  |  |  |     if msg.which() != "managerState":
 | 
					
						
							|  |  |  |       all_msgs.append(msg)
 | 
					
						
							|  |  |  |       continue
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     new_msg = msg.as_builder()
 | 
					
						
							|  |  |  |     new_msg.managerState.processes = [{'name': name, 'running': True} for name in managed_processes]
 | 
					
						
							|  |  |  |     all_msgs.append(new_msg.as_reader())
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return all_msgs
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def migrate_pandaStates(lr):
 | 
					
						
							|  |  |  |   all_msgs = []
 | 
					
						
							|  |  |  |   # TODO: safety param migration should be handled automatically
 | 
					
						
							|  |  |  |   safety_param_migration = {
 | 
					
						
							|  |  |  |     "TOYOTA PRIUS 2017": EPS_SCALE["TOYOTA PRIUS 2017"] | Panda.FLAG_TOYOTA_STOCK_LONGITUDINAL,
 | 
					
						
							|  |  |  |     "TOYOTA RAV4 2017": EPS_SCALE["TOYOTA RAV4 2017"] | Panda.FLAG_TOYOTA_ALT_BRAKE | Panda.FLAG_TOYOTA_GAS_INTERCEPTOR,
 | 
					
						
							|  |  |  |     "KIA EV6 2022": Panda.FLAG_HYUNDAI_EV_GAS | Panda.FLAG_HYUNDAI_CANFD_HDA2,
 | 
					
						
							|  |  |  |   }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # Migrate safety param base on carState
 | 
					
						
							|  |  |  |   CP = next((m.carParams for m in lr if m.which() == 'carParams'), None)
 | 
					
						
							|  |  |  |   assert CP is not None, "carParams message not found"
 | 
					
						
							|  |  |  |   if CP.carFingerprint in safety_param_migration:
 | 
					
						
							|  |  |  |     safety_param = safety_param_migration[CP.carFingerprint]
 | 
					
						
							|  |  |  |   elif len(CP.safetyConfigs):
 | 
					
						
							|  |  |  |     safety_param = CP.safetyConfigs[0].safetyParam
 | 
					
						
							|  |  |  |     if CP.safetyConfigs[0].safetyParamDEPRECATED != 0:
 | 
					
						
							|  |  |  |       safety_param = CP.safetyConfigs[0].safetyParamDEPRECATED
 | 
					
						
							|  |  |  |   else:
 | 
					
						
							|  |  |  |     safety_param = CP.safetyParamDEPRECATED
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for msg in lr:
 | 
					
						
							|  |  |  |     if msg.which() == 'pandaStateDEPRECATED':
 | 
					
						
							|  |  |  |       new_msg = messaging.new_message('pandaStates', 1)
 | 
					
						
							|  |  |  |       new_msg.valid = msg.valid
 | 
					
						
							|  |  |  |       new_msg.logMonoTime = msg.logMonoTime
 | 
					
						
							|  |  |  |       new_msg.pandaStates[0] = msg.pandaStateDEPRECATED
 | 
					
						
							|  |  |  |       new_msg.pandaStates[0].safetyParam = safety_param
 | 
					
						
							|  |  |  |       all_msgs.append(new_msg.as_reader())
 | 
					
						
							|  |  |  |     elif msg.which() == 'pandaStates':
 | 
					
						
							|  |  |  |       new_msg = msg.as_builder()
 | 
					
						
							|  |  |  |       new_msg.pandaStates[-1].safetyParam = safety_param
 | 
					
						
							|  |  |  |       all_msgs.append(new_msg.as_reader())
 | 
					
						
							|  |  |  |     else:
 | 
					
						
							|  |  |  |       all_msgs.append(msg)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return all_msgs
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def migrate_peripheralState(lr):
 | 
					
						
							|  |  |  |   if any(msg.which() == "peripheralState" for msg in lr):
 | 
					
						
							|  |  |  |     return lr
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   all_msg = []
 | 
					
						
							|  |  |  |   for msg in lr:
 | 
					
						
							|  |  |  |     all_msg.append(msg)
 | 
					
						
							|  |  |  |     if msg.which() not in ["pandaStates", "pandaStateDEPRECATED"]:
 | 
					
						
							|  |  |  |       continue
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     new_msg = messaging.new_message("peripheralState")
 | 
					
						
							|  |  |  |     new_msg.valid = msg.valid
 | 
					
						
							|  |  |  |     new_msg.logMonoTime = msg.logMonoTime
 | 
					
						
							|  |  |  |     all_msg.append(new_msg.as_reader())
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return all_msg
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def migrate_cameraStates(lr):
 | 
					
						
							|  |  |  |   all_msgs = []
 | 
					
						
							|  |  |  |   frame_to_encode_id = defaultdict(dict)
 | 
					
						
							|  |  |  |   # just for encodeId fallback mechanism
 | 
					
						
							|  |  |  |   min_frame_id = defaultdict(lambda: float('inf'))
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for msg in lr:
 | 
					
						
							|  |  |  |     if msg.which() not in ["roadEncodeIdx", "wideRoadEncodeIdx", "driverEncodeIdx"]:
 | 
					
						
							|  |  |  |       continue
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     encode_index = getattr(msg, msg.which())
 | 
					
						
							|  |  |  |     meta = meta_from_encode_index(msg.which())
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert encode_index.segmentId < 1200, f"Encoder index segmentId greater that 1200: {msg.which()} {encode_index.segmentId}"
 | 
					
						
							|  |  |  |     frame_to_encode_id[meta.camera_state][encode_index.frameId] = encode_index.segmentId
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for msg in lr:
 | 
					
						
							|  |  |  |     if msg.which() not in ["roadCameraState", "wideRoadCameraState", "driverCameraState"]:
 | 
					
						
							|  |  |  |       all_msgs.append(msg)
 | 
					
						
							|  |  |  |       continue
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     camera_state = getattr(msg, msg.which())
 | 
					
						
							|  |  |  |     min_frame_id[msg.which()] = min(min_frame_id[msg.which()], camera_state.frameId)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     encode_id = frame_to_encode_id[msg.which()].get(camera_state.frameId)
 | 
					
						
							|  |  |  |     if encode_id is None:
 | 
					
						
							|  |  |  |       print(f"Missing encoded frame for camera feed {msg.which()} with frameId: {camera_state.frameId}")
 | 
					
						
							|  |  |  |       if len(frame_to_encode_id[msg.which()]) != 0:
 | 
					
						
							|  |  |  |         continue
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       # fallback mechanism for logs without encodeIdx (e.g. logs from before 2022 with dcamera recording disabled)
 | 
					
						
							|  |  |  |       # try to fake encode_id by subtracting lowest frameId
 | 
					
						
							|  |  |  |       encode_id = camera_state.frameId - min_frame_id[msg.which()]
 | 
					
						
							|  |  |  |       print(f"Faking encodeId to {encode_id} for camera feed {msg.which()} with frameId: {camera_state.frameId}")
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     new_msg = messaging.new_message(msg.which())
 | 
					
						
							|  |  |  |     new_camera_state = getattr(new_msg, new_msg.which())
 | 
					
						
							|  |  |  |     new_camera_state.frameId = encode_id
 | 
					
						
							|  |  |  |     new_camera_state.encodeId = encode_id
 | 
					
						
							|  |  |  |     # timestampSof was added later so it might be missing on some old segments
 | 
					
						
							|  |  |  |     if camera_state.timestampSof == 0 and camera_state.timestampEof > 25000000:
 | 
					
						
							|  |  |  |       new_camera_state.timestampSof = camera_state.timestampEof - 18000000
 | 
					
						
							|  |  |  |     else:
 | 
					
						
							|  |  |  |       new_camera_state.timestampSof = camera_state.timestampSof
 | 
					
						
							|  |  |  |     new_camera_state.timestampEof = camera_state.timestampEof
 | 
					
						
							|  |  |  |     new_msg.logMonoTime = msg.logMonoTime
 | 
					
						
							|  |  |  |     new_msg.valid = msg.valid
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     all_msgs.append(new_msg.as_reader())
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return all_msgs
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def migrate_carParams(lr, old_logtime=False):
 | 
					
						
							|  |  |  |   all_msgs = []
 | 
					
						
							|  |  |  |   for msg in lr:
 | 
					
						
							|  |  |  |     if msg.which() == 'carParams':
 | 
					
						
							|  |  |  |       CP = messaging.new_message('carParams')
 | 
					
						
							|  |  |  |       CP.valid = True
 | 
					
						
							|  |  |  |       CP.carParams = msg.carParams.as_builder()
 | 
					
						
							|  |  |  |       for car_fw in CP.carParams.carFw:
 | 
					
						
							|  |  |  |         car_fw.brand = CP.carParams.carName
 | 
					
						
							|  |  |  |       if old_logtime:
 | 
					
						
							|  |  |  |         CP.logMonoTime = msg.logMonoTime
 | 
					
						
							|  |  |  |       msg = CP.as_reader()
 | 
					
						
							|  |  |  |     all_msgs.append(msg)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return all_msgs
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def migrate_sensorEvents(lr, old_logtime=False):
 | 
					
						
							|  |  |  |   all_msgs = []
 | 
					
						
							|  |  |  |   for msg in lr:
 | 
					
						
							|  |  |  |     if msg.which() != 'sensorEventsDEPRECATED':
 | 
					
						
							|  |  |  |       all_msgs.append(msg)
 | 
					
						
							|  |  |  |       continue
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # migrate to split sensor events
 | 
					
						
							|  |  |  |     for evt in msg.sensorEventsDEPRECATED:
 | 
					
						
							|  |  |  |       # build new message for each sensor type
 | 
					
						
							|  |  |  |       sensor_service = ''
 | 
					
						
							|  |  |  |       if evt.which() == 'acceleration':
 | 
					
						
							|  |  |  |         sensor_service = 'accelerometer'
 | 
					
						
							|  |  |  |       elif evt.which() == 'gyro' or evt.which() == 'gyroUncalibrated':
 | 
					
						
							|  |  |  |         sensor_service = 'gyroscope'
 | 
					
						
							|  |  |  |       elif evt.which() == 'light' or evt.which() == 'proximity':
 | 
					
						
							|  |  |  |         sensor_service = 'lightSensor'
 | 
					
						
							|  |  |  |       elif evt.which() == 'magnetic' or evt.which() == 'magneticUncalibrated':
 | 
					
						
							|  |  |  |         sensor_service = 'magnetometer'
 | 
					
						
							|  |  |  |       elif evt.which() == 'temperature':
 | 
					
						
							|  |  |  |         sensor_service = 'temperatureSensor'
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       m = messaging.new_message(sensor_service)
 | 
					
						
							|  |  |  |       m.valid = True
 | 
					
						
							|  |  |  |       if old_logtime:
 | 
					
						
							|  |  |  |         m.logMonoTime = msg.logMonoTime
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       m_dat = getattr(m, sensor_service)
 | 
					
						
							|  |  |  |       m_dat.version = evt.version
 | 
					
						
							|  |  |  |       m_dat.sensor = evt.sensor
 | 
					
						
							|  |  |  |       m_dat.type = evt.type
 | 
					
						
							|  |  |  |       m_dat.source = evt.source
 | 
					
						
							|  |  |  |       if old_logtime:
 | 
					
						
							|  |  |  |         m_dat.timestamp = evt.timestamp
 | 
					
						
							|  |  |  |       setattr(m_dat, evt.which(), getattr(evt, evt.which()))
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       all_msgs.append(m.as_reader())
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return all_msgs
 |