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