Skip to content

Instantly share code, notes, and snippets.

@ymkim92
Created December 21, 2020 00:20
Show Gist options
  • Save ymkim92/1ff9e06b359e37227972297bb458ace8 to your computer and use it in GitHub Desktop.
Save ymkim92/1ff9e06b359e37227972297bb458ace8 to your computer and use it in GitHub Desktop.
Analysis the candump of canopen with vscode and matplotlib
# 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