加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

[转载]使用Python从dbc文件中提取simulink建模数据定义

(2016-08-31 18:02:37)
标签:

转载

    使用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 : %st bias : %stMin : %stMax : %stUnit : %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文件。

    数据定义模板:

wps_clip_image-13459

运行后,Workspace中已经生成dbc中的数据定义,只需要把这些数据保存成mat文件即可保存使用。

http://s12/middle/001NO4wDzy6ZO6BJHUD8b&690

    后续,提供使用这个示例中的dbc文件进行建模的方法。

0

  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有