python调用simulink_使用Python从dbc文件中提取simulink建模数据定义
使用dbc文件建模完成CAN通訊是一種比較高效的開發模式,不過在建模的過程中dbc文件中描述的數據需要自己去定義。使用文本編輯工具打開dbc文件可以看到,實際上dbc文件是一個可以進行語義解析的文本。這樣,通過腳本語言便可以輕松的實現simulink建模所需要的數據定義。
以下面的dbc文件為例,簡單做一下嘗試。首先定義dbc文件中定義兩個消息幀,以及消息幀相關的部分變量。出于示例的簡單,只定義了8位和16位的數據。具體的dbc文件文本如下:
VERSION
""
NS_ :
NS_DESC_
CM_
BA_DEF_
BA_
VAL_
CAT_DEF_
CAT_
FILTER
BA_DEF_DEF_
EV_DATA_
ENVVAR_DATA_
SGTYPE_
SGTYPE_VAL_
BA_DEF_SGTYPE_
BA_SGTYPE_
SIG_TYPE_REF_
VAL_TABLE_
SIG_GROUP_
SIG_VALTYPE_
SIGTYPE_VALTYPE_
BO_TX_BU_
BA_DEF_REL_
BA_REL_
BA_DEF_DEF_REL_
BU_SG_REL_
BU_EV_REL_
BU_BO_REL_
SG_MUL_VAL_
BS_:
BU_:
BO_ 2147486754 Message2: 8 Vector__XXX
BO_ 2147486753 Message1: 8 Vector__XXX
SG_ message_var3_16bit : 55|16@0+ (1,0) [0|0]
"" Vector__XXX
SG_ message_var2_16bit : 39|16@0+ (1,0) [0|0]
"" Vector__XXX
SG_ message_var2_8bit : 31|8@0+ (1,0) [0|0]
"" Vector__XXX
SG_ message_var1_16bit : 15|16@0+ (1,0) [0|0]
"" Vector__XXX
SG_ test_flag : 7|8@0+ (1,0) [0|0]
"" Vector__XXX
BA_DEF_ SG_
"SigType" ENUM
"Default","Range","RangeSigned","ASCII","Discrete","Control","ReferencePGN","DTC","StringDelimiter","StringLength","StringLengthControl";
BA_DEF_ SG_
"GenSigEVName" STRING
;
BA_DEF_ SG_
"GenSigILSupport"
ENUM
"No","Yes";
BA_DEF_ SG_
"GenSigSendType"
ENUM
"Cyclic","OnWrite","OnWriteWithRepetition","OnChange","OnChangeWithRepetition","IfActive","IfActiveWithRepetition","NoSigSendType";
BA_DEF_ BO_
"GenMsgFastOnStart" INT 0
100000;
BA_DEF_ SG_
"GenSigInactiveValue" INT 0
0;
BA_DEF_ BO_
"GenMsgCycleTimeFast" INT 0
3600000;
BA_DEF_ BO_
"GenMsgNrOfRepetition" INT 0
1000000;
BA_DEF_ SG_
"GenSigStartValue" INT 0
10000;
BA_DEF_ BO_
"GenMsgDelayTime" INT 0
1000;
BA_DEF_ BO_
"GenMsgILSupport"
ENUM
"No","Yes";
BA_DEF_ BO_
"GenMsgStartDelayTime" INT 0
100000;
BA_DEF_ BU_
"NodeLayerModules" STRING
;
BA_DEF_ BU_
"ECU" STRING ;
BA_DEF_ BU_
"NmJ1939SystemInstance" INT 0
15;
BA_DEF_ BU_
"NmJ1939System" INT 0
127;
BA_DEF_ BU_
"NmJ1939ManufacturerCode" INT 0
2047;
BA_DEF_ BU_
"NmJ1939IndustryGroup" INT 0
7;
BA_DEF_ BU_
"NmJ1939IdentityNumber" INT 0
2097151;
BA_DEF_ BU_
"NmJ1939FunctionInstance" INT 0
7;
BA_DEF_ BU_
"NmJ1939Function" INT 0
255;
BA_DEF_ BU_
"NmJ1939ECUInstance" INT 0
3;
BA_DEF_ BU_
"NmJ1939AAC" INT 0 1;
BA_DEF_ BU_
"NmStationAddress" INT 0
255;
BA_DEF_ BO_
"GenMsgSendType"
ENUM
"cyclic","NotUsed","IfActive","NotUsed","NotUsed","NotUsed","NotUsed","NotUsed","noMsgSendType";
BA_DEF_ BO_
"GenMsgRequestable" INT 0
1;
BA_DEF_ BO_
"GenMsgCycleTime" INT 0
3600000;
BA_DEF_ SG_
"SPN" INT 0 524287;
BA_DEF_
"DBName" STRING ;
BA_DEF_
"BusType" STRING ;
BA_DEF_
"ProtocolType" STRING
;
BA_DEF_ BO_
"VFrameFormat"
ENUM
"StandardCAN","ExtendedCAN","reserved","J1939PG";
BA_DEF_DEF_
"SigType"
"Default";
BA_DEF_DEF_
"GenSigEVName"
"Env@Nodename_@Signame";
BA_DEF_DEF_
"GenSigILSupport"
"Yes";
BA_DEF_DEF_
"GenSigSendType"
"NoSigSendType";
BA_DEF_DEF_
"GenMsgFastOnStart" 0;
BA_DEF_DEF_
"GenSigInactiveValue"
0;
BA_DEF_DEF_
"GenMsgCycleTimeFast"
0;
BA_DEF_DEF_
"GenMsgNrOfRepetition"
0;
BA_DEF_DEF_
"GenSigStartValue" 0;
BA_DEF_DEF_
"GenMsgDelayTime" 0;
BA_DEF_DEF_
"GenMsgILSupport"
"Yes";
BA_DEF_DEF_
"GenMsgStartDelayTime"
0;
BA_DEF_DEF_
"NodeLayerModules"
"";
BA_DEF_DEF_
"ECU"
"";
BA_DEF_DEF_
"NmJ1939SystemInstance"
0;
BA_DEF_DEF_
"NmJ1939System" 0;
BA_DEF_DEF_
"NmJ1939ManufacturerCode"
0;
BA_DEF_DEF_
"NmJ1939IndustryGroup"
0;
BA_DEF_DEF_
"NmJ1939IdentityNumber"
0;
BA_DEF_DEF_
"NmJ1939FunctionInstance"
0;
BA_DEF_DEF_
"NmJ1939Function" 0;
BA_DEF_DEF_
"NmJ1939ECUInstance"
0;
BA_DEF_DEF_
"NmJ1939AAC" 0;
BA_DEF_DEF_
"NmStationAddress"
254;
BA_DEF_DEF_
"GenMsgSendType"
"noMsgSendType";
BA_DEF_DEF_
"GenMsgRequestable" 1;
BA_DEF_DEF_
"GenMsgCycleTime" 0;
BA_DEF_DEF_
"SPN" 0;
BA_DEF_DEF_
"DBName"
"";
BA_DEF_DEF_
"BusType"
"CAN";
BA_DEF_DEF_
"ProtocolType"
"J1939";
BA_DEF_DEF_
"VFrameFormat"
"J1939PG";
BA_ "DBName"
"ECUTstInf";
BA_
"VFrameFormat" BO_ 2147486754
3;
BA_
"VFrameFormat" BO_ 2147486753
3;
編寫Python腳本,首先數據的解析。完成一個M腳本,腳本會通過對MATLAB
Workspace中的數據模板進行拷貝修改完成數據定義。
腳本如下(其中Excel寫入變量信息表的功能可以去掉):
#!/usr/bin/python
################################################################################
# Grey 2016.03.02
# Update : add the function to gnerate M script
for data import.
# Grey? 2016.03.01
# generate variables list according to dbc
file.
# Inupt : dbc file name as a string, excel file
name as a string.
# Output : An excel file : variables list
file
#
import re
from xlwt import Workbook
def
GetVarList(dbc_file,var_list,model_name):
data_c_file
= model_name + '_Data.c'
data_head_file
= model_name + '_Data.h'
fid
= open('var_import.m','w')
book
= Workbook()
sheet_result
= book.add_sheet('variables')
data_type_dict
= {2:'uint8',8:'uint8',12:'uint16',16:'uint16'}
text_lines
= open(dbc_file,'r')
regexp_var
= re.compile(r'SG_\s+(\w+)\s+.*\|(\w+)@')
var_detail
=
re.compile(r'SG_.*\((\S+),(\S+)\).*\[(\S+)\|(\S+)\].*\"(\S*)\"')
index_col_num
= 0
var_name_col_num? = 1
data_type_col_num = 2
raw_num
= 0
sheet_result.write(raw_num,index_col_num,'index')
sheet_result.write(raw_num,var_name_col_num,'variable
name')
sheet_result.write(raw_num,data_type_col_num,'data
type')
for each_line in text_lines:
line_info? =
each_line.strip()
if line_info.startswith('SG_ '):
search_result
= regexp_var.search(line_info)
var_detail_result =
var_detail.search(line_info)
try:
raw_num += 1
var_name
= search_result.group(1)
data_index
= int(search_result.group(2))
data_type
= data_type_dict[data_index]
factor_value? =
var_detail_result.group(1)
bias_value
= var_detail_result.group(2)
min_value
= var_detail_result.group(3)
max_value
= var_detail_result.group(4)
unit_str
= var_detail_result.group(5)
sheet_result.write(raw_num,index_col_num,raw_num)
sheet_result.write(raw_num,var_name_col_num,var_name)
sheet_result.write(raw_num,data_type_col_num,data_type)
if data_type
== 'uint8':
fid.write("%s =
copy(base_8bit);\n" % var_name)
fid.write("%s.DataType =
\'fixdt(0,8,%s,%s)\';\n"
%(var_name,factor_value,bias_value))
fid.write("%s.Min =
%s;\n" % (var_name,0))
fid.write("%s.Max =
%s;\n" % (var_name,255))
fid.write("%s.DocUnits =
\'%s\';\n" % (var_name,unit_str))
fid.write("%s.RTWInfo.CustomAttributes.DefinitionFile
= '%s';\n" % (var_name,data_c_file))
fid.write("%s.RTWInfo.CustomAttributes.HeaderFile
= '%s';\n" % (var_name,data_head_file))
elif data_type == 'uint16':
fid.write("%s =
copy(base_16bit);\n" % var_name)
fid.write("%s.DataType =
\'fixdt(0,16,%s,%s)\';\n"
%(var_name,factor_value,bias_value))
fid.write("%s.Min =
%s;\n" % (var_name,0))
fid.write("%s.Max =
%s;\n" % (var_name,65535))
fid.write("%s.DocUnits =
\'%s\';\n" % (var_name,unit_str))
fid.write("%s.RTWInfo.CustomAttributes.DefinitionFile
= '%s';\n" % (var_name,data_c_file))
fid.write("%s.RTWInfo.CustomAttributes.HeaderFile
= '%s';\n" % (var_name,data_head_file))
#print("%s factor : %s\t bias :
%s\tMin : %s\tMax : %s\tUnit : %s" % \
#(var_name,factor_value,bias_value,min_value,max_value,unit_str))
except:
print("ERROR:%s" %
line_info)
book.save(var_list)
fid.close()
print("Process Done! Please
refer to excel file %s" % var_list)
GetVarList('test.dbc','temp.xls','DbcTst')
運行腳本,生成如下內容的M文件:
message_var3_16bit = copy(base_16bit);
message_var3_16bit.DataType =
'fixdt(0,16,1,0)';
message_var3_16bit.Min = 0;
message_var3_16bit.Max = 65535;
message_var3_16bit.DocUnits = '';
message_var3_16bit.RTWInfo.CustomAttributes.DefinitionFile =
'DbcTst_Data.c';
message_var3_16bit.RTWInfo.CustomAttributes.HeaderFile =
'DbcTst_Data.h';
message_var2_16bit = copy(base_16bit);
message_var2_16bit.DataType =
'fixdt(0,16,1,0)';
message_var2_16bit.Min = 0;
message_var2_16bit.Max = 65535;
message_var2_16bit.DocUnits = '';
message_var2_16bit.RTWInfo.CustomAttributes.DefinitionFile =
'DbcTst_Data.c';
message_var2_16bit.RTWInfo.CustomAttributes.HeaderFile =
'DbcTst_Data.h';
message_var2_8bit = copy(base_8bit);
message_var2_8bit.DataType =
'fixdt(0,8,1,0)';
message_var2_8bit.Min = 0;
message_var2_8bit.Max = 255;
message_var2_8bit.DocUnits = '';
message_var2_8bit.RTWInfo.CustomAttributes.DefinitionFile =
'DbcTst_Data.c';
message_var2_8bit.RTWInfo.CustomAttributes.HeaderFile =
'DbcTst_Data.h';
message_var1_16bit = copy(base_16bit);
message_var1_16bit.DataType =
'fixdt(0,16,1,0)';
message_var1_16bit.Min = 0;
message_var1_16bit.Max = 65535;
message_var1_16bit.DocUnits = '';
message_var1_16bit.RTWInfo.CustomAttributes.DefinitionFile =
'DbcTst_Data.c';
message_var1_16bit.RTWInfo.CustomAttributes.HeaderFile =
'DbcTst_Data.h';
test_flag = copy(base_8bit);
test_flag.DataType = 'fixdt(0,8,1,0)';
test_flag.Min = 0;
test_flag.Max = 255;
test_flag.DocUnits = '';
test_flag.RTWInfo.CustomAttributes.DefinitionFile
= 'DbcTst_Data.c';
test_flag.RTWInfo.CustomAttributes.HeaderFile =
'DbcTst_Data.h';
在MATLAB的Workspace中定義8位以及16位的數據定義模板,然后執行M文件。
數據定義模板:
運行后,Workspace中已經生成dbc中的數據定義,只需要把這些數據保存成mat文件即可保存使用。
后續,提供使用這個示例中的dbc文件進行建模的方法。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的python调用simulink_使用Python从dbc文件中提取simulink建模数据定义的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 三支香的含义 三支香的含义是什么
- 下一篇: 博主称拍到小米汽车实车新疆路试谍照 雷军