To use the dcm.stg file wiith MATLAB first you need to set up MATLAB to use StringTemplate (see the previous post). To keep the notation simple I am going to import the java classes I need with the folowing statements:
import java.io.*;
import org.antlr.stringtemplate.*;
To create a StringTemplateGroup instance in MATLAB I will use the following code:
reader = FileReader(which(templateFileName));
group = StringTemplateGroup(reader);
reader.close;
clear('reader');
Then I will follow a topdown approach to creating the view. First I will create an instance of the root template:
konservierung = group.getInstanceOf('konservierung');
Then I'll work my way down the grammar setting attributes of the current template to either MATLAB strings or other templates as required. I'll use one of the following thmbol ree patterns depending on the circumstance.
The first pattern simply replaces a symbol with a string:
template.setAttribute('template_symbol', matlab_string);
The second pattern replaces a symbol with a template and then assigns that template to a MATLAB variable for further use
template.setAttribute('template_symbol', group.getInstanceOf('new_template'));
new_template = template.getAttribute('template_symbol');
The last pattern is used when a template is assigned to a symbol more than once this pattern assigns the last template added to a symbol to a MATLAB variable for further use
template.setAttribute('template_symbol', group.getInstanceOf('new_template'));
new_template = template.getAttribute('template_symbol');
if strcmp(class(new_template), 'org.antlr.stringtemplate.StringTemplate$STAttributeList')
new_template = new_template.toArray;
new_template = new_template(end);
end
The MATLAB Controller
Using those three program patterns the controller program sdo2dcm is listed below
function str = sdo2dcm(templateFileName)
%SDO2DCM Convert Simulink.Parameters to a dcm 2.0 format string
%
% [STR] = SDO2DCM(TEMPLATEFILENAME)
%
% INPUTS:
% TEMPLATEFILENAME :
%
% OUTPUTS:
% STR :
% Donn Shull
% Copyright 2007 L & D Engineering LLC. All Rights Reserved.
% $Revision: $
% $Date: $
% Java imports
import java.io.*;
import org.antlr.stringtemplate.*;
%Create list of items
itemList= {};
workspaceList = evalin('base', 'who');
for i = 1:length(workspaceList)
varClass = evalin('base', ['class(', workspaceList{i}, ')']);
if strcmp(varClass, 'Simulink.Parameter')
variable = evalin('base', workspaceList{i});
itemList{end+1} = workspaceList{i};
end
end
% Load the StringTemplate Group file
reader = FileReader(which(templateFileName));
group = StringTemplateGroup(reader);
reader.close;
clear('reader');
% Get an instance of the root template
konservierung = group.getInstanceOf('konservierung');
konservierung.setAttribute('kons_rumpf', group.getInstanceOf('kons_rumpf'));
kons_rumpf = konservierung.getAttribute('kons_rumpf');
for i = 1:length(itemList)
variable = evalin('base', itemList{i});
kons_rumpf.setAttribute('kenngroesse', group.getInstanceOf('kenngroesse'));
kenngroesse = kons_rumpf.getAttribute('kenngroesse');
if strcmp(class(kenngroesse), 'org.antlr.stringtemplate.StringTemplate$STAttributeList')
kenngroesse = kenngroesse.toArray;
kenngroesse = kenngroesse(end);
end
if (variable.Dimension(1) == 1) && (variable.Dimension(2) == 1)
kenngroesse.setAttribute('kennwert', group.getInstanceOf('kennwert'));
kennwert = kenngroesse.getAttribute('kennwert');
kennwert.setAttribute('kgr_name', itemList{i});
kennwert.setAttribute('kgr_info', group.getInstanceOf('kgr_info'));
kgr_info = kennwert.getAttribute('kgr_info');
kgr_info.setAttribute('langname', group.getInstanceOf('langname'));
kgr_info.getAttribute('langname').setAttribute('text', strrep(variable.Description, sprintf('\n'), '\n'));
kgr_info.setAttribute('displayname', group.getInstanceOf('displayname'));
kgr_info.getAttribute('displayname').setAttribute('name', itemList{i});
kgr_info.setAttribute('funktionszugehorigkeit', group.getInstanceOf('funktionszugehorigkeit'));
funktionszugehorigkeit = kgr_info.getAttribute('funktionszugehorigkeit');
funktionszugehorigkeit.setAttribute('name', variable.StorageClass);
kennwert.setAttribute('einheit_w', group.getInstanceOf('einheit_w'));
einheit_w = kennwert.getAttribute('einheit_w');
einheit_w.setAttribute('text', variable.DocUnits);
kennwert.setAttribute('realzahl', sprintf('%19.18f', variable.Value));
else
kenngroesse.setAttribute('kennwerteblock', group.getInstanceOf('kennwerteblock'));
kennwerteblock = kenngroesse.getAttribute('kennwerteblock');
kennwerteblock.setAttribute('kgr_name', itemList{i});
kennwerteblock.setAttribute('kgr_info', group.getInstanceOf('kgr_info'));
kgr_info = kennwerteblock.getAttribute('kgr_info');
kgr_info.setAttribute('langname', group.getInstanceOf('langname'));
kgr_info.getAttribute('langname').setAttribute('text', strrep(variable.Description, sprintf('\n'), '\n'));
kgr_info.setAttribute('displayname', group.getInstanceOf('displayname'));
kgr_info.getAttribute('displayname').setAttribute('name', itemList{i});
kgr_info.setAttribute('funktionszugehorigkeit', group.getInstanceOf('funktionszugehorigkeit'));
funktionszugehorigkeit = kgr_info.getAttribute('funktionszugehorigkeit');
funktionszugehorigkeit.setAttribute('name', variable.StorageClass);
kennwerteblock.setAttribute('einheit_w', group.getInstanceOf('einheit_w'));
einheit_w = kennwerteblock.getAttribute('einheit_w');
einheit_w.setAttribute('text', variable.DocUnits);
for i = 1:variable.Dimension(1)
kennwerteblock.setAttribute('werteliste', group.getInstanceOf('werteliste'));
werteliste = kennwerteblock.getAttribute('werteliste');
if strcmp(class(werteliste), 'org.antlr.stringtemplate.StringTemplate$STAttributeList')
werteliste = werteliste.toArray;
werteliste = werteliste(end);
end
for j = 1:variable.Dimension(2)
werteliste.setAttribute('realzahl', sprintf('%19.18f', variable.Value(i,j)));
end
end
end
end
str = char(konservierung.toString);
return;
If you have questions, comments or suggestions let me know here.
References:
1. "DCM File Formats Tech Note", ETAS GmbH
2. "StringTemplate Documentation", Terence Parr
November 28, 2007
Setting up Terence Parr's ANTLR and StringTemplate for use with MATLAB
The easiest way to set up ANTLR and StringTemplate for use with MATLAB is to go to http://www.antlr.org/download.html and click on the link to download Version 1.1.4 - for Windows, Linux and Mac OS X. This a java jar file containing ANTLR, StringTemplate and a very nice ANTLR development environment called ANTLRWorks. When I downloaded the file the file extension changed from .jar to .zip. I renamed the file to antlrworks.1.1.4.jar. Next you need to let MATLAB know about this file. This is done by adding this file to MATLAB's classpath. I placed the file in the directory C:\MATLAB\R71\toolbox\aetools\antlr. Then I opened MATLAB and used the command edit classpath.txt to open classpath.txt and added the line matlabroot/toolbox/aetools/antlr/antlrworks.1.1.4.jar to the end of the file and saved it. It is necessary to shut MATLAB down and restart it in order for changes to classpath.txt to take effect. To check to see if this has all worked open MATLAB and type the following at the MATLAB prompt:
>> tmpl = org.antlr.stringtemplate.StringTemplate('$template_symbol$')
tmpl =
>> tmpl.setAttribute('template_symbol', 'Hello World')
>> char(tmpl)
ans =
Hello World
If all went well you have successfully created a simple template with a single template symbol and assigned it a string value. Next time I will look at using StringTemplate group files and building structured text using StringTemplate.
November 2, 2007
Using Terence Parr's StringTemplate in MATLAB
If you run MATLAB with its Java Virtual Machine enabled (the standard way to run MATLAB), you can Terence Parr's antlr, and StringTemplate for parsing text and creating text files from templates. Today I'll describe how to "install" StringTemplate for MATLAB and create a simple text file from a template.
First you need to download StringTemplate from Terence Parr's StringTemplate web site http://www.stringtemplate.org
September 7, 2007
Exploring ASAM MC3 with MATLAB
Over the next several weeks I will look at using MC3 on COM to communicate between MATLAB and calibration tools. To get started we need a recent version of MATLAB (release 14 or higher) and a calibration tool with a calibration tool with an MC3 COM compliant interface. I am going to start with CalDeskr from dSPACE, but as we go along I will also include information about INCAr from ETAS, and possibly CANaper from Vector.
The following reference material will be useful to have on hand.
"ASAM MCD 3 Programmers Reference Guide", January 6, 2003
"ASAM MCD 3 Application Programmers Interface Specification", January 6, 2003
"CalDesk Automation Guide", December 2006
Note the ASAM standards can be found athttp://www.asam.net.
To use MC3 communication with CalDesk you need a CAL_AUTOMATION license. Once you have MATLAB and CalDesk installed launch MATLAB and type the following command at the command prompt:
>> x = actxserver('caldesk.mc3system')
There will be a pause while CalDesk is started following the pause the response to the MATLAB command window should be:
x =
COM.caldesk_mc3system
You may be wondering where CalDesk is since no new windows have been created. CalDesk has been created without a GUI. If you launch CalDesk from the start menu now what happens is that you are activating the GUI for the instance of CalDesk that was started from MATLAB. Also if you launch the GUI and then exit CalDesk does not really exit if there is a connection to it from a COM client. The exit command simply closes the GUI.
Now that we have an instance of the MC3 COM server we can look at its properties with the command:
>> x.get
ObjectType: 'eMCDSYSTEM'
Parent: []
Description: ''
LongName: 'C:\dSPACE\CalDesk\Bin\CalDesk.exe'
ShortName: 'CalDesk'
ASAMMCDVersion: [1x1 Interface.MCSystemLib_1.0_Type_Library_Build_1.IMCVersion]
ActiveProject: []
DbProjectConfiguration: [1x1 Interface.MCSystemLib_1.0_Type_Library_Build_1.IMCDbProjectConfiguration]
DbProjectDescriptions: [1x1 Interface.MCSystemLib_1.0_Type_Library_Build_1.IMCDbProjectDescriptions]
LockState: 'eUNLOCKED'
NoOfMaxClients: -1
ServerType: 'eMC'
State: 'eINITIALIZED'
Version: [1x1 Interface.MCSystemLib_1.0_Type_Library_Build_1.IMCVersion]
And look at the methods for this object with the command:
>> x.methods
Methods for class COM.caldesk_mc3system:
DeselectProject Unlock events load save
Lock addproperty get move send
SelectProject delete interfaces propedit set
SelectProjectByName deleteproperty invoke release
More detailed information about the methods can be obtained with the command:
x.methodsview
This command launches a window with the following information:

There are two steps necessary to prepare for taking measurements and adjusting calibrations.
- Set the ActiveProject.
- Add a LogicalLink to the ActiveProject
To set the ActiveProject we will use the SelectProjectByName method. So the first thing to do is find out the name of the project we want to use. In CalDesk the MC3 Project corresponds to the experiment name (see "CalDesk Automation Guide", page 30). To get a list of projects which are available use the command:
projects = x.DbProjectDescriptions.Names
This will return a cell array of Project Names:
projects =
'XCP on CAN'
'MCD_XCP_UDS'
'MicroAutoBox (DS1401)'
'DS1005 PPC Board'
Select the project with the following command:
x.SelectProjectByName('XCP on CAN')
If we look at the properties of x now we will see that there is an interface assigned to the ActiveProject property
>> x.get
ObjectType: 'eMCDSYSTEM'
Parent: []
Description: ''
LongName: 'C:\dSPACE\CalDesk\Bin\CalDesk.exe'
ShortName: 'CalDesk'
ASAMMCDVersion: [1x1 Interface.MCSystemLib_1.0_Type_Library_Build_1.IMCVersion]
ActiveProject: [1x1 Interface.MCSystemLib_1.0_Type_Library_Build_1.IMCProject]
DbProjectConfiguration: [1x1 Interface.MCSystemLib_1.0_Type_Library_Build_1.IMCDbProjectConfiguration]
DbProjectDescriptions: [1x1 Interface.MCSystemLib_1.0_Type_Library_Build_1.IMCDbProjectDescriptions]
LockState: 'eUNLOCKED'
NoOfMaxClients: -1
ServerType: 'eMC'
State: 'ePROJECT_SELECTED'
Version: [1x1 Interface.MCSystemLib_1.0_Type_Library_Build_1.IMCVersion]
and the State property changed to ePROJECT_SELECTED. Next we need to add a logical link and its associated image file to the active project. We will do this in three steps:
find the logical links available for this project
find the available images for the logical link we want to use
add the logical link and the associated image to the selected project
To find the available logical links use the following command:
>> x.ActiveProject.DbProject.DbVehicleInformations.GetItemByIndex(0).DbLogicalLinks.Names
ans =
'XCP'
We see that XCP is the only available logical link for this project. To find out the binary images available for this logical link use the command:
>> x.ActiveProject.DbProject.DbVehicleInformations.GetItemByIndex(0).DbLogicalLinks.GetItemByName ...('XCP').DbLocation.DbBinaries.Names
ans =
'CalDemo'
The only image available for the XCP logical link is the CalDemo image. We can now add this logical link with this command:
>> x.ActiveProject.LogicalLinks.AddByNames('XCP', 'CalDemo')
ans =
Interface.MCSystemLib_1.0_Type_Library_Build_1.IMCLogicalLink
Now we are finally ready to manipulate calibration values. We will start by getting a list of the calibrations with the following command:
>> x.ActiveProject.LogicalLinks.GetItemByIndex(0).DbObject.DbLocation.DbCharacteristics.Names
ans =
'DummyAirMass'
'DummyOmega'
'Fac_F32_gain'
'Fac_I16_gain'
'Fac_I32_gain'
'Fac_I8_gain'
'Fac_U16_gain'
'Fac_U32_gain'
'Fac_U8_gain'
'FrequencyPrescaler'
'LUT1D_1_z_table'
'LUT2D_1_z_table'
'ParamVector'
'ParamVectorIncrement'
'Rec2Sine_z_table'
'SelectColumn'
'Select_param_set'
'SignalAmplitude'
'SignalForm'
'SignalOffset'
'SignalPhase'
'Soll_Lambda'
'abs_sinp2_cosp2_table'
'f_Kd_1'
'f_Kd_2'
'f_Ki_1'
'f_Ki_2'
'f_Kp_1'
'f_Kp_2'
'inj_offset'
'inv_c_kumsrl'
'opt_ing_angle_z_table'
'sinp2_cosp2_table'
'throttle2percent_z_table'
'triangle_z_table'
'y_sin_z_table'
Armed with this list of available characteristics we can now read and write these characteristics