Created
December 21, 2020 00:20
-
-
Save ymkim92/1ff9e06b359e37227972297bb458ace8 to your computer and use it in GitHub Desktop.
Analysis the candump of canopen with vscode and matplotlib
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # candump can0 -ta | |
| # data analysis | |
| ''' | |
| (1541915735.968732) can0 000 [2] 81 74 | |
| (1541915735.978482) can0 774 [1] 00 | |
| (1541915735.978591) can0 774 [1] 7F | |
| (1541915735.983890) can0 674 [8] 2B 17 10 00 90 01 00 00 | |
| (1541915735.984228) can0 5F4 [8] 60 17 10 00 00 00 00 00 | |
| time dev canid size data | |
| ''' | |
| import pandas as pd | |
| import numpy as np | |
| import matplotlib.pyplot as plt | |
| import argparse | |
| import sys | |
| import mplcursors | |
| import subprocess | |
| picker_value = 4 | |
| def get_arguments(): | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument('input', help='Input log file') | |
| return parser.parse_args(sys.argv[1:]) | |
| def get_items(line): | |
| items = line.split() | |
| if len(items) >= 4: | |
| items[0] = float(items[0][1:-1]) | |
| items[2] = int(items[2], 16) | |
| items[3] = int(items[3][1:-1]) | |
| size = items[3] | |
| items = items[:4+size] | |
| for i in range(8): | |
| if i<size: | |
| items[4+i] = int(items[4+i], 16) | |
| else: | |
| items.append(0) | |
| return items | |
| return None | |
| def gen_data_frame(log_file): | |
| log_list = [] | |
| with open(log_file, 'r') as f: | |
| for line in f: | |
| items = get_items(line) | |
| if items != None: | |
| log_list.append(items) | |
| df = pd.DataFrame(log_list, columns=['time(s)', | |
| 'dev','canid','size', 'd0', 'd1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', ]) | |
| return df | |
| def onpick(event): | |
| thisline = event.artist | |
| xdata = thisline.get_xdata() | |
| ydata = thisline.get_ydata() | |
| ind = event.ind | |
| # print(ind) | |
| points = tuple(zip(xdata[ind], ydata[ind])) | |
| # print('onpick points:', points[0]) | |
| line_number = df.index[df['time(s)'] == points[0][0]].tolist()[0] + 1 | |
| # print(line_number) | |
| open_editor(line_number) | |
| def open_editor(line_number): | |
| editor_command = f'code -g {file_name}:{line_number}' | |
| subprocess.call(editor_command.split(), shell=False) | |
| def draw_heartbeat(df, ax): | |
| df_bootup = df[(df['canid']&0x700 == 0x700) & (df['canid']&0x80 == 0) & (df['d0'] == 0)] | |
| df_heartbeat = df[(df['canid']&0x700 == 0x700) & (df['canid']&0x80 == 0) & (df['d0'] != 0)] | |
| df_bootup.plot(x='time(s)', y='d0', ax=ax, style='.', label='bootup', picker=picker_value) | |
| df_heartbeat.plot(x='time(s)', y='d0', ax=ax, style='.', label='heartbeat', picker=picker_value) | |
| ax.set_ylabel("NMT state") | |
| def draw_nmt_control(df, ax): | |
| df_nmt_control = df[(df['canid'] == 0x000)] | |
| df_nmt_control.plot(x='time(s)', y='d0', ax=ax, style='.', label='data0', picker=picker_value) | |
| ax.set_ylabel("NMT control") | |
| def draw_emergency(df, ax): | |
| df_emergency = df[(df['canid'] != 0x80) & (df['canid']&0xf80 == 0x80)] | |
| df_emergency.plot(x='time(s)', y='d2', ax=ax, style='.', label='data2', picker=picker_value) | |
| ax.set_ylabel("Emergency") | |
| def draw_sdo(df, ax): | |
| df_sdo_req = df[df['canid']&0x780 == 0x600] | |
| df_sdo_rep = df[df['canid']&0x780 == 0x580] | |
| df_sdo_req.plot(x='time(s)', y='d0', ax=ax, style='.', label='SDO_REQ', picker=picker_value) | |
| df_sdo_rep.plot(x='time(s)', y='d0', ax=ax, style='.', label='SDO_REP', picker=picker_value) | |
| ax.set_ylabel("SDO") | |
| def draw_chart(df): | |
| fig, ax = plt.subplots(6,1, sharex=True, sharey=False, figsize=(20,6.5), gridspec_kw={'height_ratios': [2, 2, 2, 4, 1, 1]}) | |
| plt.subplots_adjust(left=0.1, right=0.95, bottom=0.1, top=0.94, wspace=0.02, hspace=0.07) | |
| df_sync = df[(df['canid'] == 0x80)] | |
| df_time = df[(df['canid'] == 0x100)] | |
| df_lss = df[(df['canid']&0x700 == 0x700) & (df['canid']&0x80 == 0x80)] | |
| draw_heartbeat(df, ax[0]) | |
| draw_nmt_control(df, ax[1]) | |
| draw_emergency(df, ax[2]) | |
| draw_sdo(df, ax[3]) | |
| fig.canvas.mpl_connect('pick_event', onpick) | |
| df = None | |
| file_name = '' | |
| def main(): | |
| global df, file_name | |
| args = get_arguments() | |
| file_name = args.input | |
| # print(args) | |
| df = gen_data_frame(args.input) | |
| print(df) | |
| draw_chart(df) | |
| plt.suptitle(args.input) | |
| # plt.savefig(args.input[0] +'.png') | |
| plt.show() | |
| if __name__ == '__main__': | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment