ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • CAN 메시지 전송 주기 분포 분석
    카테고리 없음 2025. 1. 4. 14:59

    메시지 전송 주기 분포 분석

    • m_id 별로 메시지 전송 주기의 분포를 확인한다.
    import pandas as pd
    from pathlib import Path
    import plotly.express as px
    import plotly.graph_objects as go
    # data 디렉토리에 있는 모든 .asc 파일들
    
    dir_data = Path('.').absolute()/'asc_per_id'
    ascs = list(dir_data.glob('*.asc'))
    print(f'{len(ascs) = :,}')
    # for asc in ascs:
    #     print(asc.name)
    
    len(ascs) = 59

    한 asc를 대상으로 방법을 개발한다.

    def read_asc_to_df(asc):
        '''
        .asc 파일을 읽어서 DataFrame으로 반환한다.
        asc 파일은 m_id 별로 분리된 파일이어야 한다.
        '''
    
        # 파일을 읽어서 DataFrame으로 변환한다.
        df = pd.read_csv(asc, sep=' ', skiprows=4, header=None, dtype=str)
    
        # 빈 컬럼은 제거한다.
        df = df.dropna(axis=1)
    
        # 컬럼의 개수를 확인한다.
        n_cols = df.shape[1]
    
        # 처음 6개 컬럼은 고정이고, 나머지는 d01, d02, ... 이런 식으로 이름을 붙인다.
        n_data_byte = n_cols - 6
        col_ds = [f'd{i + 1:02}' for i in range(n_data_byte)]
        cols = ['ts', 'ch', 'm_id', 'trx', 'd', 'dlc'] + col_ds
        df.columns = cols
    
        # 컬럼별 dtype을 변경한다.
        df['ts'] = df['ts'].astype(float)
        df['ch'] = df['ch'].astype(int)
        df['dlc'] = df['dlc'].astype(int)
        for col in col_ds:
            df[col] = df[col].apply(lambda x: int(x, 16))
    
        return df
    # 임의로 파일을 선택하여 df로 만든다.
    asc = ascs[10]
    df = read_asc_to_df(asc)
    print(df.head())
              ts  ch m_id trx  d  dlc  d01  d02  d03  d04
    0  72.378126   1  164  Rx  d    4    0    8   16  102
    1  72.388119   1  164  Rx  d    4    0    8   18   92
    2  72.398848   1  164  Rx  d    4    0    8   20   18
    3  72.408127   1  164  Rx  d    4    0    8   22   40
    4  72.418854   1  164  Rx  d    4    0    8   24  142
    # 메시지 전송 주기는 인접한 메시지들의 ts(timestamp)들 사이의 차이다.
    df['d_ts'] = df['ts'].diff()
    
    # 맨 처음 메시지는 인접한 메시지가 없어 d_ts가 na이다. 이를 d_ts의 평균으로 채운다.
    df['d_ts'] = df['d_ts'].fillna(df['d_ts'].mean())
    
    # d_ts의 통계를 본다.
    print(df['d_ts'].describe())
    count    38393.000000
    mean         0.010000
    std          0.000257
    min          0.008302
    25%          0.009892
    50%          0.010002
    75%          0.010109
    max          0.011694
    Name: d_ts, dtype: float64

    0x164 메시지의 전송 주기 통계치 점검

    • mean이 전송 주기의 평균이다. 10msec이다.
    • 전송 주기의 최소는 8.3msec이다.
    • 전송 주기의 표준 편차는 0.3msec이다.
    # d_ts의 히스토그램을 그려본다. 
    # 전송 주기에 따라 그래프의 d_ts 범위를 조정한다. 
    # 그렇지 않으면 d_ts의 범위가 너무 넓다.
    d_ts_mean = df['d_ts'].mean()
    if d_ts_mean < 0.010:
        d_ts_min = d_ts_mean - 0.005
        d_ts_max = d_ts_mean + 0.005
        n_bins = 10
    elif d_ts_mean < 0.050:
        d_ts_min = d_ts_mean - 0.010
        d_ts_max = d_ts_mean + 0.010
        n_bins = 20
    elif d_ts_mean < 0.100:
        d_ts_min = d_ts_mean - 0.010
        d_ts_max = d_ts_mean + 0.010
        n_bins = 40
    elif d_ts_mean < 0.500:
        d_ts_min = d_ts_mean - 0.010
        d_ts_max = d_ts_mean + 0.010
        n_bins = 80
    else:
        d_ts_min = d_ts_mean - 0.010
        d_ts_max = d_ts_mean + 0.010
        n_bins = 160
    
    fig = go.Figure()
    fig.add_trace(go.Histogram(x=df['d_ts'], nbinsx=n_bins))
    fig.update_layout(
        title=f'd_ts histogram: 0x{asc.name} mean={df["d_ts"].mean():.3f}sec',
        # width=1200,
        # height=600
    )
    fig.update_xaxes(range=[d_ts_min, d_ts_max])
    fig.show()
    

    # 히스토그램을 파일에 저장한다.
    fig.write_image(f'0x{asc.name}_d_ts_histogram.png', engine='kaleido')

    전체 asc를 대상으로 d_ts의 분포를 계산한다.

    • m_id별 계산 결과를 모아서 한 xlsx에 저장한다.
    dfs_to_concat = []
    ascs_to_draw = ascs[:]
    for asc in ascs_to_draw:
        df = read_asc_to_df(asc)
        df['d_ts'] = df['ts'].diff()
        df['d_ts'] = df['d_ts'].fillna(df['d_ts'].mean())
        dfs_to_concat.append(df['d_ts'].describe().to_frame().T)
    
        # fig = draw_histogram(df)
        # fig.show()
    
    df_desc = pd.concat(dfs_to_concat)
    df_desc.index = [asc.name for asc in ascs_to_draw]
    print(df_desc)
               count      mean       std       min       25%       50%       75%  \
    042.asc    384.0  0.999332  0.000104  0.999062  0.999282  0.999332  0.999387   
    043.asc    384.0  0.999332  0.000104  0.999062  0.999282  0.999332  0.999387   
    044.asc    387.0  0.991565  0.083612  0.040136  0.999277  0.999332  0.999386   
    080.asc  38394.0  0.010000  0.000368  0.008272  0.009863  0.010006  0.010153   
    081.asc  38394.0  0.010000  0.000369  0.008275  0.009863  0.010006  0.010153   
    111.asc  38393.0  0.010000  0.000093  0.009095  0.009957  0.009999  0.010043   
    112.asc  38393.0  0.010000  0.000095  0.009096  0.009957  0.009999  0.010044   
    113.asc  38393.0  0.010000  0.000096  0.009072  0.009957  0.009999  0.010044   
    124.asc  38394.0  0.010000  0.000371  0.008273  0.009863  0.010006  0.010154   
    153.asc  38393.0  0.010000  0.000164  0.008872  0.009981  0.010001  0.010020   
    164.asc  38393.0  0.010000  0.000257  0.008302  0.009892  0.010002  0.010109   
    18F.asc  38394.0  0.010000  0.000369  0.008127  0.009873  0.010005  0.010141   
    200.asc  38393.0  0.010000  0.000365  0.008291  0.009875  0.010005  0.010138   
    220.asc  38392.0  0.010000  0.000219  0.007867  0.009983  0.010001  0.010019   
    251.asc  38394.0  0.010000  0.000138  0.008312  0.009983  0.010001  0.010017   
    260.asc  38393.0  0.010000  0.000367  0.008293  0.009877  0.010005  0.010137   
    280.asc  38393.0  0.010000  0.000369  0.008293  0.009876  0.010005  0.010138   
    2B0.asc  38394.0  0.010000  0.000136  0.007685  0.009983  0.010001  0.010015   
    316.asc  38393.0  0.010000  0.000381  0.007673  0.009875  0.010005  0.010139   
    329.asc  38393.0  0.010000  0.000408  0.007904  0.009873  0.010005  0.010141   
    340.asc  38375.0  0.010005  0.000384  0.005954  0.009983  0.010003  0.010027   
    346.asc  38393.0  0.010000  0.000138  0.008452  0.009957  0.009999  0.010044   
    34C.asc  38393.0  0.010000  0.000139  0.008504  0.009957  0.009999  0.010044   
    374.asc  38393.0  0.010000  0.000148  0.008502  0.009956  0.009999  0.010045   
    381.asc  19197.0  0.020000  0.000284  0.017230  0.019991  0.020001  0.020010   
    383.asc  19210.0  0.019987  0.000526  0.014295  0.019966  0.019990  0.020020   
    386.asc  19196.0  0.020001  0.000425  0.017361  0.019937  0.020001  0.020060   
    387.asc  19197.0  0.020001  0.000343  0.016671  0.019959  0.020001  0.020039   
    38D.asc  19188.0  0.020010  0.000495  0.014686  0.019987  0.020005  0.020022   
    394.asc  19197.0  0.020001  0.000538  0.016500  0.019959  0.020001  0.020038   
    417.asc   1919.0  0.200007  0.000587  0.196472  0.199914  0.200008  0.200089   
    436.asc   7678.0  0.050000  0.000663  0.046183  0.049723  0.050000  0.050279   
    483.asc   1919.0  0.200103  0.000594  0.194965  0.200002  0.200057  0.200074   
    492.asc   7678.0  0.050002  0.000752  0.045929  0.049759  0.050006  0.050254   
    4A7.asc    768.0  0.500258  0.000734  0.497171  0.500010  0.500147  0.500268   
    4E5.asc   3840.0  0.100003  0.000983  0.096180  0.099814  0.100008  0.100194   
    4E6.asc   3840.0  0.100003  0.001014  0.096178  0.099844  0.100008  0.100169   
    4E7.asc   3840.0  0.100003  0.001118  0.096178  0.099840  0.100007  0.100177   
    4F1.asc  19197.0  0.020000  0.000626  0.016281  0.019969  0.020002  0.020048   
    500.asc   3840.0  0.099983  0.000646  0.094257  0.099979  0.099984  0.100027   
    502.asc   3840.0  0.100003  0.000151  0.097623  0.099979  0.100003  0.100026   
    507.asc   3839.0  0.100005  0.000765  0.094490  0.099991  0.100005  0.100018   
    50C.asc   3839.0  0.100001  0.000518  0.096297  0.099983  0.100002  0.100023   
    50E.asc   1921.0  0.199773  0.005853  0.039997  0.199987  0.200005  0.200021   
    52A.asc   3204.0  0.119789  0.075249  0.036903  0.040091  0.119791  0.199999   
    53E.asc   3838.0  0.100052  0.000644  0.095217  0.099988  0.100028  0.100052   
    541.asc   4112.0  0.093375  0.017887  0.037633  0.099838  0.099996  0.100021   
    545.asc   3840.0  0.100004  0.001497  0.095077  0.099771  0.100006  0.100234   
    547.asc   3840.0  0.100004  0.001161  0.095070  0.099800  0.100008  0.100212   
    549.asc   3840.0  0.100004  0.001794  0.094866  0.099712  0.100011  0.100309   
    553.asc   1923.0  0.199669  0.007302  0.039843  0.199985  0.200005  0.200024   
    556.asc   3840.0  0.100004  0.000924  0.096036  0.099801  0.100011  0.100221   
    557.asc   3840.0  0.100004  0.000708  0.096538  0.099807  0.100011  0.100208   
    593.asc   1920.0  0.200000  0.000412  0.196663  0.199981  0.199999  0.200025   
    5A0.asc    384.0  0.999825  0.000886  0.994424  0.999810  0.999896  1.000041   
    5B0.asc    384.0  1.000009  0.000577  0.996280  0.999989  1.000017  1.000063   
    5CE.asc   3840.0  0.100003  0.000583  0.097103  0.099805  0.100010  0.100214   
    5CF.asc   3840.0  0.100003  0.000571  0.096861  0.099799  0.100010  0.100225   
    5FA.asc    384.0  1.000835  0.001151  0.996349  1.000083  1.000736  1.000854   
    
                  max  
    042.asc  0.999562  
    043.asc  0.999561  
    044.asc  0.999561  
    080.asc  0.011640  
    081.asc  0.011640  
    111.asc  0.010893  
    112.asc  0.010894  
    113.asc  0.010911  
    124.asc  0.011641  
    153.asc  0.011131  
    164.asc  0.011694  
    18F.asc  0.011695  
    200.asc  0.011691  
    220.asc  0.012148  
    251.asc  0.011692  
    260.asc  0.011691  
    280.asc  0.011689  
    2B0.asc  0.012318  
    316.asc  0.012495  
    329.asc  0.012496  
    340.asc  0.014079  
    346.asc  0.011556  
    34C.asc  0.011510  
    374.asc  0.011510  
    381.asc  0.022744  
    383.asc  0.025658  
    386.asc  0.022872  
    387.asc  0.022752  
    38D.asc  0.025327  
    394.asc  0.023352  
    417.asc  0.203601  
    436.asc  0.053847  
    483.asc  0.206470  
    492.asc  0.054093  
    4A7.asc  0.506141  
    4E5.asc  0.103506  
    4E6.asc  0.103640  
    4E7.asc  0.103774  
    4F1.asc  0.023714  
    500.asc  0.105708  
    502.asc  0.102375  
    507.asc  0.105515  
    50C.asc  0.103706  
    50E.asc  0.202726  
    52A.asc  0.204175  
    53E.asc  0.105255  
    541.asc  0.104125  
    545.asc  0.104939  
    547.asc  0.104984  
    549.asc  0.105168  
    553.asc  0.203569  
    556.asc  0.104081  
    557.asc  0.104078  
    593.asc  0.203304  
    5A0.asc  1.005045  
    5B0.asc  1.003779  
    5CE.asc  0.102899  
    5CF.asc  0.103144  
    5FA.asc  1.006901  

    d_ts 분포 계산 결과를 xlsx로 저장한다.

    df_desc.to_excel('d_ts_distribution.xlsx', index=True)

    히스토그램을 png로 저장한다.

    def draw_histogram(df, asc):
        '''
        DataFrame을 받아서 d_ts의 히스토그램을 그린다.
        '''
        d_ts_mean = df['d_ts'].mean()
        if d_ts_mean < 0.010:
            d_ts_min = d_ts_mean - 0.005
            d_ts_max = d_ts_mean + 0.005
            n_bins = 10
        elif d_ts_mean < 0.050:
            d_ts_min = d_ts_mean - 0.010
            d_ts_max = d_ts_mean + 0.010
            n_bins = 20
        elif d_ts_mean < 0.100:
            d_ts_min = d_ts_mean - 0.010
            d_ts_max = d_ts_mean + 0.010
            n_bins = 40
        else:
            d_ts_min = d_ts_mean - 0.010
            d_ts_max = d_ts_mean + 0.010
            n_bins = 80
    
        fig = px.histogram(df, x='d_ts', nbins=n_bins, title=f'0x{asc.stem} d_ts histogram (mean={df["d_ts"].mean():.3f}sec)')
        # fig.update_layout(
        #     width=1200,
        #     height=600
        # )    
        fig.update_xaxes(range=[d_ts_min, d_ts_max])
    
        return fig
    ascs_to_draw = ascs[:]
    for asc in ascs_to_draw:
        path_to_output_png = dir_data/f'{asc.stem}.png'
        print(f'saving histogram of {asc.name} to {path_to_output_png.name}')
        df = read_asc_to_df(asc)
        df['d_ts'] = df['ts'].diff()
        df['d_ts'] = df['d_ts'].fillna(df['d_ts'].mean())
    
        fig = draw_histogram(df, asc)
    
        # fig.show()
        fig.write_image(path_to_output_png, format='png', engine='kaleido')
    
    
    saving histogram of 042.asc to 042.png
    saving histogram of 043.asc to 043.png
    saving histogram of 044.asc to 044.png
    saving histogram of 080.asc to 080.png
    saving histogram of 081.asc to 081.png
    saving histogram of 111.asc to 111.png
    saving histogram of 112.asc to 112.png
    saving histogram of 113.asc to 113.png
    saving histogram of 124.asc to 124.png
    saving histogram of 153.asc to 153.png
    saving histogram of 164.asc to 164.png
    saving histogram of 18F.asc to 18F.png
    saving histogram of 200.asc to 200.png
    saving histogram of 220.asc to 220.png
    saving histogram of 251.asc to 251.png
    saving histogram of 260.asc to 260.png
    saving histogram of 280.asc to 280.png
    saving histogram of 2B0.asc to 2B0.png
    saving histogram of 316.asc to 316.png
    saving histogram of 329.asc to 329.png
    saving histogram of 340.asc to 340.png
    saving histogram of 346.asc to 346.png
    saving histogram of 34C.asc to 34C.png
    saving histogram of 374.asc to 374.png
    saving histogram of 381.asc to 381.png
    saving histogram of 383.asc to 383.png
    saving histogram of 386.asc to 386.png
    saving histogram of 387.asc to 387.png
    saving histogram of 38D.asc to 38D.png
    saving histogram of 394.asc to 394.png
    saving histogram of 417.asc to 417.png
    saving histogram of 436.asc to 436.png
    saving histogram of 483.asc to 483.png
    saving histogram of 492.asc to 492.png
    saving histogram of 4A7.asc to 4A7.png
    saving histogram of 4E5.asc to 4E5.png
    saving histogram of 4E6.asc to 4E6.png
    saving histogram of 4E7.asc to 4E7.png
    saving histogram of 4F1.asc to 4F1.png
    saving histogram of 500.asc to 500.png
    saving histogram of 502.asc to 502.png
    saving histogram of 507.asc to 507.png
    saving histogram of 50C.asc to 50C.png
    saving histogram of 50E.asc to 50E.png
    saving histogram of 52A.asc to 52A.png
    saving histogram of 53E.asc to 53E.png
    saving histogram of 541.asc to 541.png
    saving histogram of 545.asc to 545.png
    saving histogram of 547.asc to 547.png
    saving histogram of 549.asc to 549.png
    saving histogram of 553.asc to 553.png
    saving histogram of 556.asc to 556.png
    saving histogram of 557.asc to 557.png
    saving histogram of 593.asc to 593.png
    saving histogram of 5A0.asc to 5A0.png
    saving histogram of 5B0.asc to 5B0.png
    saving histogram of 5CE.asc to 5CE.png
    saving histogram of 5CF.asc to 5CF.png
    saving histogram of 5FA.asc to 5FA.png
    # 마지막인 m_id = 0x5FA의 메시지 전송 주기 히스토그램을 살펴본다.
    fig.show()

    0x5FA 메시지의 전송 주기 히스토그램 점검

    • 전송 주기는 1sec로 보인다.
    • 예상대로 전송 주기를 중심으로 매우 집중된 분포를 보인다.
    • 다른 메시지들에 비해서 상대적으로 전송 주기가 들쭉날쭉한 편이다.
    • IDS 관점에서 중요한 값은 최소 전송 주기이다. 0.996sec이다.
    • 칩입 감지를 위한 전송 주기 기준을 0.9sec 혹은 0.95sec로 하면 될 것 같다. 넉넉하게 0.8sec 하면 민감 감지되는 일을 없을 것 같다.