-
dbc에서 m_id들을 찾기application 2025. 1. 26. 00:16
dbc에서 m_id들을 찾기
- 목적: 차량 형상 관리 관점에서 설계 사양 (dbc)과 실차의 형상(m_info)을 비교한다.
- m_id_info는 blf 파일에서 m_id, dlc, d_ts 추출하기 :: hsl's tsmaster 사용기에서 측정한 CAN 통신 데이터를 분석한 결과이다. 메시지 아이디(m_id)별로 메시지 길이(dlc), 메지지 전송 주기(d_ts) 정보를 갖고 있다.
- dbc 파일에서 m_info의 m_id들을 찾는다.
- 찾아야할 m_id들은 ~mid_info.xlsx에 저장되어 있다.
- cantools라는 Python 모듈을 이용하여 dbc의 내용을 읽는다.
- 찾기와 비교를 쉽게 하기 위해서 pandas라는 Python 모듈을 이용한다.
- xlsx의 내용을 df_car라는 dataframe(df)으로 만든다.
- dbc의 내용을 df_dbc라는 df로 만든다.
- 두 df를 합친다.
- 양쪽 df 모두에 포함되어 있고, dlc(data length code)가 동일하면 ok
- 양쪽 df 모두에 포함되어 있는데, dlc가 다르면 nok
- df_dbc에는 있는데 df_car에 없으면 missing
- df_car에 있는데 df_dbc에 없으면 unidentified
- 로 분류한다.

CAN 통신에서 메시지 아이디(m_id)들을 찾고 그 아이디들을 dbc에서 찾는 것은 차량 형상 점검의 기본이자 시작점이다. from pathlib import Path import cantools import pandas as pdldf is not supported xls is not supported xlsx is not supported찾아야 할 m_id
- blf 파일에서 m_id, dlc, d_ts 추출하기 :: hsl's tsmaster 사용기에서 추출하여 xlsx에 저장한 정보를 이용한다.
- df_car를 만든다.
xlsx_m_info = Path(r'C:/data/tosun/projects/uds_vehicle_config/Logging/Bus/uds_vehicle_config_2025_01_19_10_34_14_m_info.xlsx') df_car = pd.read_excel(xlsx_m_info, sheet_name='Sheet1') df_car[['m_id', 'm_id_int', 'dlc', 'd_ts']].sample(3)m_id m_id_int dlc d_ts 29 394 916 8 0.02 44 52A 1322 8 0.20 36 4E6 1254 8 0.10 m_id를 찾을 dbc
# dbc 파일 dbc = Path(r'C:\data\tosun\reference\dbc\20240809_venue\venue_esc.dbc') db = cantools.database.load_file(dbc, strict=False) db.messages[message('calc', 0x222, False, 8, {None: '[P] Periodic'}), message('ESP12', 0x220, False, 8, {None: '[P] Periodic'}), message('SAS11', 0x2b0, False, 5, {None: '[P] Periodic'}), message('WHL_SPD11', 0x386, False, 8, {None: '[P] Periodic'})]df_dbc를 만든다.
messages = [(message.name, hex(message.frame_id), message.frame_id, message.length) for message in db.messages] df_dbc = pd.DataFrame(messages, columns=['name', 'm_id', 'm_id_int', 'dlc']) df_dbcname m_id m_id_int dlc 0 calc 0x222 546 8 1 ESP12 0x220 544 8 2 SAS11 0x2b0 688 5 3 WHL_SPD11 0x386 902 8 df_dbc와 df_m_info를 합친다.
df = pd.merge(df_dbc, df_car[['m_id_int', 'dlc', 'd_ts']], on='m_id_int', how='outer', suffixes=['_dbc', '_car'], indicator=True) df['m_id'] = df['m_id_int'].apply(lambda x: f'0x{x:03X}') df['dlc_check'] = df['dlc_dbc'] == df['dlc_car'] df.sample(3)name m_id m_id_int dlc_dbc dlc_car d_ts _merge dlc_check 58 NaN 0x5CF 1487 NaN 8.0 0.10 right_only False 20 NaN 0x329 809 NaN 8.0 0.01 right_only False 10 NaN 0x164 356 NaN 4.0 0.01 right_only False # columns of interest coi = ['m_id', 'name', 'dlc_dbc', 'dlc_car', 'dlc_check'] # df_dbc와 df_car에 모두 있고 dlc가 같은 것 df_ok = df.loc[(df['_merge'] == 'both') & (df['dlc_check'] == True), coi] # 메시지를 송신하는 제어기를 찾는다. df_ok['ecu_tx'] = df_ok['m_id'].apply(lambda x: db.get_message_by_frame_id(int(x, 16)).senders) # 메시지를 수신하는 제어기를 찾는다. df_ok['ecu_rx'] = df_ok['m_id'].apply(lambda x: db.get_message_by_frame_id(int(x, 16)).receivers) # df_dbc와 df_car에 모두 있는데 dlc가 다른 것 df_nok = df.loc[(df['_merge'] == 'both') & (df['dlc_check'] == False), coi] df_nok['ecu_tx'] = df_nok['m_id'].apply(lambda x: db.get_message_by_frame_id(int(x, 16)).senders) df_nok['ecu_rx'] = df_nok['m_id'].apply(lambda x: db.get_message_by_frame_id(int(x, 16)).receivers) # df_dbc에 있는데 df_car에 없는 것 df_missing = df.loc[df['_merge'] == 'left_only', coi] df_missing['ecu_tx'] = df_missing['m_id'].apply(lambda x: db.get_message_by_frame_id(int(x, 16)).senders) df_missing['ecu_rx'] = df_missing['m_id'].apply(lambda x: db.get_message_by_frame_id(int(x, 16)).receivers) # df_car에 있는데 df_dbc에 없는 것 df_unidentified = df.loc[df['_merge'] == 'right_only', coi]print(f'{len(df_ok)} messages are found in both dbc and m_info with the same dlc') df_ok2 messages are found in both dbc and m_info with the same dlcm_id name dlc_dbc dlc_car dlc_check ecu_tx ecu_rx 13 0x220 ESP12 8.0 8.0 True [ESC] {GST, EMS, SAS} 27 0x386 WHL_SPD11 8.0 8.0 True [ESC] {GST, EMS, SAS} print(f'{len(df_nok)} messages are found in both dbc and m_info with different dlc') df_nok1 messages are found in both dbc and m_info with different dlcm_id name dlc_dbc dlc_car dlc_check ecu_tx ecu_rx 18 0x2B0 SAS11 5.0 6.0 False [SAS] {ESC} print(f'{len(df_missing)} messages are found in car but not in dbc') df_missing1 messages are found in car but not in dbcm_id name dlc_dbc dlc_car dlc_check ecu_tx ecu_rx 14 0x222 calc 8.0 NaN False [ESC] {GST, EMS, SAS} - 0x222는 미니프로그램에서 CAN 메시지 전송하는 방법을 설명하기 위해 정의해둔 메시지이다.
- 미니프로그램에서 CAN 신호와 시스템 변수 다루기 :: hsl's tsmaster 사용기
print(f'{len(df_unidentified)} messages are found in car but not in dbc') df_unidentified.sample(3) # 많아서 3개만 출력한다.56 messages are found in car but not in dbcm_id name dlc_dbc dlc_car dlc_check 41 0x502 NaN NaN 4.0 False 51 0x553 NaN NaN 8.0 False 46 0x53E NaN NaN 6.0 False 결론
- "blf 파일에서 m_id, dlc, d_ts 추출하기"에서 CAN 버스에 있는 메시지들을 찾았다.
- 이 메시지들이 dbc 파일에 있는 지 확인하였다.
- dbc에도 있고 차에도 있고 사양(예제에서는 dlc만 확인하였다.)도 같은 경우, 문제 없다. (case OK)
- dbc에도 있고 차에도 있는데 사양이 다른 경우, 문제이다. 점검이 필요하다. (case NOK)
- dbc에는 있는데 차에는 없는 경우, 문제이다. 용도가 있어서 dbc에 포함하였거나, dbc에 오류가 있거나, 제어기에 오류가 있다. (case Missing)
- dbc에는 없는데 차에는 있는 경우, 문제이다. dbc에 오류가 있거나, 제어기에 오류가 있다. (case Unidentified)
- dbc와 제어기를 점검하고 필요에 따라 수정하고 이 스크립트를 실행하여 결과를 확인하는 절차를 반복하는 방식으로 설계 형상과 실제 형상을 맞춰나갈 수 있다.
- dbc를 최신 상태로 유지하는 것은 차량 형상 관리를 위해서 중요하다.
- 툴 없이 차량 형상 관리를 한다는 것은 무모한 일이라고 생각한다.
차량 형상 점검 :: hsl's tsmaster 사용기
'application' 카테고리의 다른 글
진단 요청과 응답 m_id 짝 찾기 (0) 2025.01.26 진단 통신으로 제어기 확인하기 (0) 2025.01.26 차량 형상 점검 (1) 2025.01.19 주행 중인 도로의 경사도 구하기 1/t.b.d. (2) 2025.01.15 침입 감지 시스템 (IDS) - 타임스탬프 보완 (0) 2025.01.05 - 목적: 차량 형상 관리 관점에서 설계 사양 (dbc)과 실차의 형상(m_info)을 비교한다.