diff --git a/can_converter_gui.py b/can_converter_gui.py index 4167b9d..e872232 100644 --- a/can_converter_gui.py +++ b/can_converter_gui.py @@ -363,6 +363,10 @@ class CANBinToCSV: # MDF 변환기 # ============================================================================ +# ============================================================================ +# MDF 변환기 (수정된 버전) +# ============================================================================ + class CANBinToMDF: """CAN bin 파일을 MDF4로 변환하는 클래스""" @@ -399,10 +403,17 @@ class CANBinToMDF: return messages - def decode_messages(self, messages: List[CANMessage]) -> Dict[str, Dict[str, List]]: - """CAN 메시지를 DBC를 사용하여 디코딩""" + def decode_messages(self, messages: List[CANMessage]) -> tuple: + """ + CAN 메시지를 DBC를 사용하여 디코딩 + Returns: + (decoded_data, start_time): 디코딩된 데이터와 시작 시간 + """ decoded_data = {} + # 시작 시간 계산 (첫 번째 메시지의 타임스탬프) + start_time = messages[0].timestamp_us / 1e6 if messages else 0 + # 각 메시지별로 초기화 for msg_def in self.db.messages: msg_name = msg_def.name @@ -418,8 +429,9 @@ class CANBinToMDF: decoded = msg_def.decode(msg.data) - # 타임스탬프 저장 (마이크로초 -> 초) - decoded_data[msg_name]['timestamps'].append(msg.timestamp_us / 1e6) + # 타임스탬프를 상대 시간으로 변환 (시작 시간을 0으로) + relative_time = (msg.timestamp_us / 1e6) - start_time + decoded_data[msg_name]['timestamps'].append(relative_time) # 각 시그널 값 저장 for signal in msg_def.signals: @@ -435,18 +447,30 @@ class CANBinToMDF: continue print(f"✓ 메시지 디코딩 완료: {decode_count}/{len(messages)} 개") + print(f" - 시작 시간: {datetime.fromtimestamp(start_time)}") + print(f" - 상대 시간으로 변환: 0.000초 부터 시작") # 빈 메시지 제거 decoded_data = {k: v for k, v in decoded_data.items() if len(v['timestamps']) > 0} - return decoded_data + return decoded_data, start_time def to_mdf(self, decoded_data: Dict[str, Dict[str, List]], output_path: str, - compression: int = 0): - """MDF4 파일 생성""" + compression: int = 0, + start_time: float = 0): + """ + MDF4 파일 생성 + Args: + start_time: 원본 시작 시간 (메타데이터 저장용) + """ mdf = MDF(version='4.10') + # 메타데이터에 원본 시작 시간 기록 + if start_time > 0: + mdf.header.start_time = datetime.fromtimestamp(start_time) + print(f" - 원본 시작 시간을 메타데이터에 저장: {mdf.header.start_time}") + signal_count = 0 for msg_name, msg_data in decoded_data.items(): timestamps = np.array(msg_data['timestamps']) @@ -501,6 +525,7 @@ class CANBinToMDF: print(f"✓ MDF4 파일 생성 완료: {output_path}") print(f" - 시그널 수: {signal_count}") + print(f" - 시간 범위: 0.000초 ~ {timestamps[-1]:.3f}초") # 파일 크기 출력 file_size = Path(output_path).stat().st_size @@ -520,24 +545,24 @@ class CANBinToMDF: print("✗ 메시지가 없습니다.") return - # 시간 범위 출력 + # 시간 범위 출력 (절대 시간) start_time = messages[0].timestamp_us / 1e6 end_time = messages[-1].timestamp_us / 1e6 duration = end_time - start_time - print(f" - 시작 시간: {datetime.fromtimestamp(start_time)}") - print(f" - 종료 시간: {datetime.fromtimestamp(end_time)}") + print(f" - 절대 시작 시간: {datetime.fromtimestamp(start_time)}") + print(f" - 절대 종료 시간: {datetime.fromtimestamp(end_time)}") print(f" - 기간: {duration:.2f} 초") - # 2. 메시지 디코딩 - decoded_data = self.decode_messages(messages) + # 2. 메시지 디코딩 (상대 시간으로 변환) + decoded_data, abs_start_time = self.decode_messages(messages) if not decoded_data: print("✗ 디코딩된 데이터가 없습니다.") return - # 3. MDF 파일 생성 - self.to_mdf(decoded_data, output_path, compression) + # 3. MDF 파일 생성 (상대 시간 사용) + self.to_mdf(decoded_data, output_path, compression, abs_start_time) print(f"{'='*60}") print(f"✓ 변환 완료!")