本文研究如何通过Matlab脚本导入A2L文件,并将A2L文件的一些信息写入表格中。
做汽车控制器开发的同行肯定对A2L文件不会陌生,通过A2L文件可以进行数据采集和标定。A2L文件的格式符合ASAP2标准,格式可以参照ASAP2标准手册。
A2L文件也是文本文件,只要知道了其中的书写规则(ASAP2标准),就可以通过Matlab中的fopen之类的函数打开,并用正则表达式提取字符串信息。但是在实际工作中,这种“造轮子”的做法不但付出了时间成本,而且很容易出错。
实际上,Matlab软件已经很贴心地帮我们做好了封装,可以直接调用函数导入A2L文件信息。
博主通过Simulink生成了一个包含两个观测量(MEASUREMENT)的A2L文件untitled.a2l。
如果要获取这个A2L中的这两个观测量信息,首先在Matlab命令行输入xcpA2L函数:
>> a2lfile = xcpA2L('untitled.a2l')
a2lfile =
A2L - 属性:
FileName: 'untitled.a2l'
FilePath: 'E:\学习\博客\Simulink代码生成\ASAP2\untitled_ert_rtw\untitled.a2l'
SlaveName: 'ModuleName'
ProtocolLayerInfo: []
DAQInfo: []
TransportLayerCANInfo: []
TransportLayerUDPInfo: []
TransportLayerTCPInfo: []
Events: {}
Measurements: {'Signal1' 'Signal2'}
Characteristics: {}
EventInfo: []
MeasurementInfo: [2×1 containers.Map]
CharacteristicInfo: [0×1 containers.Map]
AxisInfo: [0×1 containers.Map]
RecordLayouts: [45×1 containers.Map]
CompuMethods: [2×1 containers.Map]
CompuTabs: [0×1 containers.Map]
CompuVTabs: [0×1 containers.Map]
Matlab就会返回一个A2L对象a2lfile,其中包含了这个A2L中的许多重要信息,比方说Measurements这个成员里,是两个观测量 {‘Signal1’ ‘Signal2’}的元胞数组。
如果想要获取观测量Signal1的更多信息,则只要使用getMeasurementInfo函数,将之前的A2L对象和观测量作为第一和第二个参数传入:
>> info = getMeasurementInfo(a2lfile,'Signal1')
info =
Measurement - 属性:
Resolution: 0
Accuracy: 0
LocDataType: 'FLOAT64_IEEE'
Name: 'Signal1'
LongIdentifier: ''
ECUAddress: 0
ECUAddressExtension: 0
Conversion: [1×1 xcp.CompuMethodRational]
Dimension: 1
LowerLimit: -1.7000e+308
UpperLimit: 1.7000e+308
BitMask: []
这里就会返回出输出类型、最大最小值等属性,以及非常关键的ECUAddress地址信息。这里地址为零时因为该A2L文件中的地址还没有通过elf文件或者map文件更新进去。
这一章节会通过一个完整的脚本将A2L中的观测量和标定量导入表格中,其他的属性,类似于轴信息的导入,可以举一反三。
在第2章的基础上,给A2L文件中再加上一个标定量Parameter1,也就是包含了如下三个观测量或标定量。
A2L文件中的部分信息:
/begin CHARACTERISTIC
/* Name */ Parameter1
/* Long Identifier */ ""
/* Type */ VALUE
/* ECU Address */ 0x0000 /* @ECU_Address@Parameter1@ */
/* Record Layout */ Scalar_FLOAT32_IEEE
/* Maximum Difference */ 0
/* Conversion Method */ untitled_CM_single
/* Lower Limit */ -3.4E+38
/* Upper Limit */ 3.4E+38
/end CHARACTERISTIC
/begin MEASUREMENT
/* Name */ Signal1
/* Long identifier */ ""
/* Data type */ UBYTE
/* Conversion method */ untitled_CM_uint8
/* Resolution (Not used) */ 0
/* Accuracy (Not used) */ 0
/* Lower limit */ 0
/* Upper limit */ 255
ECU_ADDRESS 0x0000 /* @ECU_Address@Signal1@ */
/end MEASUREMENT
/begin MEASUREMENT
/* Name */ Signal2
/* Long identifier */ ""
/* Data type */ UWORD
/* Conversion method */ untitled_CM_ufix16_En6
/* Resolution (Not used) */ 0
/* Accuracy (Not used) */ 0
/* Lower limit */ 0
/* Upper limit */ 1023.984375
ECU_ADDRESS 0x0000 /* @ECU_Address@Signal2@ */
/end MEASUREMENT
完整的脚本如下:
function ImportA2L()
%% 弹窗选择A2L文件
[file,path] = uigetfile('*.a2l','请选择A2L文件');
A2L_Path = fullfile(path,file);% A2L文件绝对路径
%% 导入A2L文件
a2lfile = xcpA2L(A2L_Path);% A2L对象
MeasurementsName_Cell = a2lfile.Measurements;% 观测量集合
CharacteristicsName_Cell = a2lfile.Characteristics;% 标定量集合
%% 获取属性信息,写入单元数组
Measurements_Cell = {'Name','DataType','Lower','Upper','ECUAddress'};% 观测量工作表内容
Characteristics_Cell = {'Name','Lower','Upper','ECU_ADDRESS'};% 标定量工作表内容
for i = 1:length(MeasurementsName_Cell)% 循环处理观测量
info = getMeasurementInfo(a2lfile,MeasurementsName_Cell{i});
NextRow = size(Measurements_Cell,1)+1;% 获取下一行行数
Measurements_Cell{NextRow,1} = MeasurementsName_Cell{i};
Measurements_Cell{NextRow,2} = info.LocDataType;
Measurements_Cell{NextRow,3} = num2str(info.LowerLimit);
Measurements_Cell{NextRow,4} = num2str(info.UpperLimit);
Measurements_Cell{NextRow,5} = ['0x',dec2hex(info.ECUAddress)];
end
for i = 1:length(CharacteristicsName_Cell)
info = getCharacteristicInfo(a2lfile,CharacteristicsName_Cell{i});
NextRow = size(Characteristics_Cell,1)+1;
Characteristics_Cell{NextRow,1} = CharacteristicsName_Cell{i};
Characteristics_Cell{NextRow,2} = num2str(info.LowerLimit);
Characteristics_Cell{NextRow,3} = num2str(info.UpperLimit);
Characteristics_Cell{NextRow,4} = ['0x',dec2hex(info.ECUAddress)];
end
%% 将数组写入表格
Excel_Path = strrep(A2L_Path,'.a2l','.xlsx');% 表格与A2L同名同路径
xlswrite(Excel_Path,Measurements_Cell,'Measurements');
xlswrite(Excel_Path,Characteristics_Cell,'Characteristics');
end
这部分脚本比较简单,根据注释也能看懂,博主也就不做过多的解释了。
最终的效果是,在A2L路径下生成一个同名的表格文件,里面的两个工作表中分别包含了标定量和观测量信息。
博主工作中有许多处理A2L文件的场景,但是Matlab中关于处理A2L的函数并不多。Vector公司的ASAP2 Tool-Set工具就涵盖了处理A2L文件的各种场景,所以在本文中顺便介绍一下。博主会经常用到以下机中功能:
另外,该工具全面支持命令行调用,也就是说可以通过Matlab脚本调用实现自动化。
通过Matlab封装好的函数导入A2L中的一些信息不算很困难,只需要按照实际需要灵活使用即可。
>>返回个人博客总目录