Automotive Electronics Toolbox

Home
Contact Us
Links
Notes on developing the Automotive Electronics (AE) Toolbox

Welcome to the Automotive Electronics Toolbox developers notebook. The Automotive Electronics Toolbox is MATLAB® addon supporting ASAM® Automotive Electronics (MCD) standards. The first standard to be supported is the MC3 standard for communication between MATLAB and MC3 compliant Calibration tools. A presentation on this capability is available here. This website will provide notes on the development of this toolbox and examples of using ASAM AE standards with MATLAB.

 

May 29, 2008


A First Look at Octave 3.0.1 on Windows

I had not looked at Octave, an open source math program with many similarities to MATLAB, for several years. Going to http://www.octave.org/ I found that Octave 3.0.1 was released on April 28, 2008. There are binary distributions available at http://octave.sourceforge.net/. A list of things I like about Octave follows.

  1. There is a native distribution for Windows available compiles with either Visual Studio 2005 or Visual Studio 2008.
  2. There is a package available which adds Java support using your system Java runtime environment.
  3. It is still in alpha but if your Java version is a graphics package call jhandles which aims to be compatible with MATLABs Handle Graphics.
  4. The Windows distribution includes a Windows package which provides COM support.
  5. There is a Development Environment GUI that is similar to MATLABs providing a command history view, workspace and file browsers.

 

I plan to provide an Octave version of the DCM File Translator in a future post.


April 29, 2008


DCM File Translator for MATLAB


Download

 

The translator can be downloaded here.

 

To set up the translator unzip dcmxlate to MATLAB's toolbox directory. This will create the directories toolbox/aetools, toolbox/aetools/dcmfun, and toolbox/aetools/java. Next add the directory toolbox/aetools/dcmfun to MATLAB's path. Finally open MATLAB's classpath.txt and add the toolbox/aetools/java/dcmfun.jar and toolbox/aetools/java/antlr.jar to the end of the classpath list. restart MATLAB. The command to translate a file is:

 

str = translate_dcm(dcmFileName, stgFileName)

 

Type help translate_dcm at the MATLAB command prompt for more information.

If you have questions, comments or suggestions let me know here.

February 16, 2008


MATLAB, ANTLR, StringTemplate and DCM Calibration Files, Part 3


Download

 

The files for the first part of this tutorial can be downloaded here.

 

Introduction

I did not finish last time with getting to where we actually use the parser inside of MATLAB. So this installment will cover generating a parser for use with MATLAB and writing the m-code to call the parser. In Part 4 I'll show the full DCM StringTemplate and parser.

Creating the Parser


Creating the parser consists of the following three steps

 

  1. Run the antlr code generation tool to create the java source files.
  2. Compile the java source files.
  3. Use the java jar utility to package the files.

 

I want to place the generated code into a package so I have uncommented the two package definition lines in the dcm.g file from Part2.

 

@parser::header {package com.aetools.dcm;}
@lexer::header {package com.aetools.dcm;}

Then from MATLAB with my working directory set to C:\MATLAB\R71\toolbox\aetools\dcmfun I issued the following command:

>> system('java org.antlr.Tool dcm.g')
ANTLR Parser Generator Version 3.0.1 (August 13, 2007) 1989-2007

ans =

0

>>

 

This generated the following files:

 

dcm.tokens

dcm__.g

dcmLexer.java

dcmParser.java

 

I now want to compile these files so I use the following command:

 

>> system('javac dcmParser.java dcmLexer.java -d ..\java')

ans =

0

>>

 

This places the compiled files and package directory structure in the directory C:\MATLAB\R71\toolbox\aetools\java. Next I set my working directory to the that directory with the command:

 

>> cd ..\java
>>

 

Then I create the jar file and place it in the dcmfun directory with the command

 

>> system('jar cvf ..\dcmfun\dcm.jar *')

 

Now change back to the dcm fun directory with the command:

 

>> cd ..\dcmfun
>>

 

Next I need an m-file to call the parser. The following function m-file allows us to pass in a dcm file name and then parses it.

 

function test_dcm(dcmFile)

import org.antlr.runtime.*;
import org.antlr.stringtemplate.*;
import java.io.*;
import com.aetools.dcm.*;

% PARSE INPUT AND COMPUTE TEMPLATE
inp = ANTLRFileStream(dcmFile);
lexer = dcmLexer(inp);
tokens = CommonTokenStream(lexer);
parser = dcmParser(tokens);
try
    parser.konservierung;
catch
end

return;

 

I can run this function with the command:

 

>> test_dcm('test_objects.dcm')
>>

 

If we are really lucky this is not very interesting at all because nothing happens. The file is opend converted to an antlr file stream which is then passed to the lexer whcih converts it to tokens. These are passed to the parser and the parser is invoked with the start rule. Since the file parses correctly no exceptions are generated and nothing is produced. To make the parser useful we need to ask it to generate something while it is parsing. We will look at two methods of getting our parser to do something useful.

 

February 11, 2008


MATLAB, ANTLR, StringTemplate and DCM Calibration Files, Part 2

 

Preliminaries

Using ANTLR with MATLAB requires a number of things to be set up. I'm sure everyone has their own ideas on how they would like things to be set up. I am going to describe my setup and the reasons why I did it this way. DCM file import and export are functions I want to add to the Automotive Electronics Toolbox. I would like this toolbox to be easy for users to navigate and understand, so I need it to be structured like other toolboxes. I will begin with the directory structure. I am using MATLAB version 7.1. I wanted MATLAB installed in a path with no spaces and a path which would be compatible with future versions of MATLAB. I installed MATLAB in the following directory C:\MATLAB\R71. The toolbox directory is C:\MATLAB\R71\toolbox. I am basing my toolbox directory on the ideas shown in the Matlab Toolbox directory. The Automotive Toolbox root directory will be C:\MATLAB\R71\toolbox\aetools. Individual portions of the toolbox will be placed in subdirectories of this root directory. For this tutorial there will be two subdirectories C:\MATLAB\R71\toolbox\aetools\dcmfun for the DCM functions and C:\MATLAB\R71\aetools\antlr which where we will place the antlrworks jar file.

 

Java Setup

MATLAB has a Java Virtual Machine built in. This is great for using StringTemplate since we are just using prebuilt classes. To use antlr however, we are going to need to be able to compile Java code so we need a Java JDK (Java Development Kit). I will want to use a version of the JDK that is compatible with the Java Virtual Machine MATLAB uses. MATLAB's Java version can be obtained at the MATLAB prompt with the following command:

 

>> version -java

ans =

Java 1.5.0 with Sun Microsystems Inc. Java HotSpot(TM) Client VM mixed mode

>>

This is a little old, so I went to http://java.sun.com and looked under downloads for previous releases and was able to download jdk-1_5_0_14-windows-i586-p.exe. I installed this to the default location C:\Program Files\Java\jdk1.5.0_14. Next I set a couple of environment variables. To set environment variables click the start button then right click on My Computer and choose Properties. Select the Advanced Tab in the System Properties dialog and then click the Environment Variables button. I added two new variables to the System variables JAVA_HOME = C:\MATLAB\R71\sys\java\jre\win32\jre1.5.0, and CLASSPATH = C:\MATLAB\R71\toolbox\aetools\antlr\antlrworks.jar;. Then I opened a new MATLAB session and checked these settings with the following commands:

>> getenv('CLASSPATH')

ans =

C:\MATLAB\R71\toolbox\aetools\antlr\antlrworks.jar;.

>> getenv('JAVA_HOME')

ans =

C:\MATLAB\R71\sys\java\jre\win32\jre1.5.0

>>

Things look OK.

Next I'll describe how I set up MATLAB to use antlr and StringTemplate. I know I described this already in the post "Setting up Terence Parr's ANTLR and StringTemplate for use with MATLAB". That probably should have been called "Setting up MATLAB to use Terence Parr's ANTLR and StringTemplate". Anyway I downloaded antlrworks-1.1.7.jar. Since I used Internet Explorer to download this it ended up as antlrworks-1.1.7.zip. I moved this file to C:\MATLAB\R71\toolbox\aetools\antlr and renamed it antlrworks.jar. I renamed it so that as new versions of antlrworks become available I can just replace this version with the new version and I wont need to change my system environment variables or MATLAB's classpath. Back in MATLAB I made a couple of changes to the matlab environment first add our new directories to MATLAB's path with the commands:

>> addpath('C:\MATLAB\R71\toolbox\aetools\dcmfun')
>> addpath('C:\MATLAB\R71\toolbox\aetools\antlr')
>> savepath
>>

Then update MATLAB's java classpath. To do this edit the classpath.text file with the command:

 

>> edit(which('classpath.txt'))
>> 

This will open classpath.txt in MATLAB's editor. Add the following line to the end of the classpath.txt file:

$matlabroot/toolbox/aetools/antlr/antlrworks.jar

Now close and then reopen MATLAB. We are now ready work with antlr. The following is an antlr combined grammar for the simplified eleven rule DCM format I showed last time in the String Template tutorial. I will provide a zip file with these files for download so you can try this out for yourself. This file is saved as dcm.g.

////////////////////////////////////////////////////////////////////////////////
//
// Simplified grammar file for parsing calibration files in DCM format
//
// References: 1. "DCM File Formats Tech Note", ETAS GmbH
//             2. "StringTemplate Documentation", Terence Parr
//
//
// German                     English
// -----------------------------------------------
// konservierung              preservation
// kons_rumpf                 kons_trunk
// kenngroesse                characteristic
// kennwert                   characteristic value
// festwert                   fixed value
// wert                       worth
// kennwerteblock             characteristic value block
// festwert                   fixed value block
// einheit                    unit
// funktionszugehörigkeit     function affiliation
// funktion                   function
// werteliste                 would worth-list
//
// Donn Shull
// Copyright 2007 L & D Engineering LLC. All Rights Reserved.
// $Revision: $
// $Date: $
//
////////////////////////////////////////////////////////////////////////////////

grammar dcm;

//@parser::header {package com.aetools.dcm;}
//@lexer::header {package com.aetools.dcm;}

////////////////////////////////////////////////////////////////////////////////
//
// konservierung            ::= "KONSERVIERUNG_FORMAT" "2.0"
//                              [kons-kopf]
//                              kons-rumpf
//
////////////////////////////////////////////////////////////////////////////////
konservierung            : ('\n')* 'KONSERVIERUNG_FORMAT' '2.0' ('\n')+
                           kons_rumpf
                         ;

////////////////////////////////////////////////////////////////////////////////
//
// kons-rumpf               ::= ( kenngroesse )*
//
////////////////////////////////////////////////////////////////////////////////
kons_rumpf               : ( kenngroesse )*
                         ;

////////////////////////////////////////////////////////////////////////////////
//
// kenngroesse              ::= kennwert
//
////////////////////////////////////////////////////////////////////////////////
kenngroesse              : kennwert
                         | kennwerteblock
                         ;

////////////////////////////////////////////////////////////////////////////////
//
// kennwert                 ::= "FESTWERT"
//                                  kgr-info
//                                  [einheit_w]
//                                  "WERT"
//                              "END"
//
////////////////////////////////////////////////////////////////////////////////
kennwert                 : 'FESTWERT' NAME '\n'
                               kgr_info
                               (einheit_w)?
                               'WERT' realzahl '\n'
                           'END' ('\n')+
                         ;

////////////////////////////////////////////////////////////////////////////////
//
// kennwerteblock           ::= "FESTWERTEBLOCK"
//                                  kgr-info
//                                  [einheit_w]
//                                  werteliste-kwb
//                              "END" ;
//
////////////////////////////////////////////////////////////////////////////////
kennwerteblock           : 'FESTWERTEBLOCK' NAME '\n'
                               kgr_info
                               (einheit_w)?
                               (werteliste)*
                           'END' ('\n')+
                         ;

////////////////////////////////////////////////////////////////////////////////
//
// kgr-info                 ::= [langname]
//                              [displayname]
//                              [funktionszugehörigkeit]
//
////////////////////////////////////////////////////////////////////////////////
kgr_info                 : (langname)?
                           (displayname)?
                           (funktionszugehorigkeit)?
                         ;

////////////////////////////////////////////////////////////////////////////////
//
// einheit_w                ::= "einheit_W" TEXT
//
////////////////////////////////////////////////////////////////////////////////
einheit_w                : 'einheit_W' TEXT '\n'
                         ;

////////////////////////////////////////////////////////////////////////////////
//
// langname                 ::= "LANGNAME" TEXT
//
////////////////////////////////////////////////////////////////////////////////
langname                 : 'LANGNAME' TEXT '\n'
                         ;

////////////////////////////////////////////////////////////////////////////////
//
// displayname              ::= "DISPLAYNAME" NAME
//
////////////////////////////////////////////////////////////////////////////////
displayname              : 'DISPLAYNAME' TEXT '\n'
                         ;

////////////////////////////////////////////////////////////////////////////////
//
// funktionszugehörigkeit   ::= "FUNKTION" (NAME)+
//
////////////////////////////////////////////////////////////////////////////////
funktionszugehorigkeit   : 'FUNKTION' ( NAME )+ '\n'
                         ;

////////////////////////////////////////////////////////////////////////////////
//
// werteliste               ::= ("WERT" ()* \n)*
//
////////////////////////////////////////////////////////////////////////////////
werteliste               : 'WERT' ( realzahl )* '\n'
                         ;

realzahl                 : INT
                         | FLOAT 
                         ;

// Lexer

NAME                     : LETTER (LETTER|'0'..'9')*
                         ;

fragment
LETTER                   : 'A'..'Z'
                         | 'a'..'z'
                         | '_'
                         ;

TEXT                     : QUOTE s=STRING QUOTE
                         ;

fragment
STRING                   : (options{greedy=true;}:'a'..'z'|'A'..'Z'|'_'|' '|'0'..'9'|'/')*
                         ;

fragment
QUOTE                    : '"'
                         ;

MINUS                    : '-'
                         ;

INT                      : MINUS? '0'..'9' +
                         ;

FLOAT                    : MINUS? '0'..'9' + ('.' '0'..'9' *)?
                         ;

WS                       : (' '|'\r'|'\t'|'\u000C') {skip();}
                         ;

COMMENT                  : ('*'|'!'|'.') ( options {greedy=false;} : . )* '\n' {skip();}

                         ;


We can launch antlrworks from MATLAB with the command:

>> system(which('antlrworks.jar'))

This will start the antlrworks GUI and wait for you to exit it. In the antlrworks gui select File, then Open and the the file C:\MATLAB\R71\toolbox\aetools\dcmfun\dcm.g. Next select the Debugger, and then Debug. Select the radio button Text and place the following text in the textbox:

 

KONSERVIERUNG_FORMAT 2.0

FESTWERTEBLOCK A1
    LANGNAME "a"
    DISPLAYNAME "A1"
    FUNKTION Auto
    einheit_W "a"
    WERT 1.00000 -0.74082
END

FESTWERT DISABLED
    LANGNAME ""
    DISPLAYNAME "DISABLED"
    FUNKTION Auto
    einheit_W ""
    WERT 3.00000
END

Set the start rule to konservierung and click OK. Next click on the fast forward button to have the parser parse your input text. If all went well you should see a list of tokens in the input window, a nice graphical tree structure in the Parse Tree Window. Antlrworks is a great tool for developing and testing grammars. Since this grammar passed the test we can close the GUI and return to MATLAB by selecting File and then Quit. Note that if you use the red  x in the upper right hand corner to close antlrworks MATLAB will hang. If you have done that press "ctrl c" to unfreeze MATLAB.

OK so now we have a grammar and have tested it with antlrworks.

 

January 1, 2008


MATLAB, StringTemplate and DCM Calibration Files, Part 1


Introduction

This is a tutorial covering an approach to generating a Model View Controller (MVC) system with StringTemplate and MATLAB. In this example the Model will be the set of Simulink.Parameter objects in MATLABs base workspace. The controller will be a MATLAB mfile, and the View will be a string in DCM format wihch can be saved to a file. The full DCM 2.0 grammar can be found in reference 1 below. I am going to use a simplified version of the grammar obtained by removing all of the grammar elements related to tables.


The Simplified DCM Grammar


konservierung ::= "KONSERVIERUNG_FORMAT" "2.0"
[kons-kopf]
kons-rumpf

kons-rumpf ::= ( kenngroesse )*

kenngroesse ::= kennwert | kennwerteblock

kennwert ::= "FESTWERT" <KGR-NAME>
kgr-info
[einheit_w]
"WERT" <REALZAHL>
"END"

kennwerteblock ::= "FESTWERTEBLOCK" <KGR-NAME>
kgr-info
[einheit_w]
werteliste-kwb
"END"

kgr-info ::= [langname]
[displayname]
[funktionszugeh"rigkeit]

einheit_w ::= "einheit_W" <TEXT>

langname ::= "LANGNAME" <TEXT>

displayname ::= "DISPLAYNAME" <NAME>

funktionszugeh"rigkeit ::= "FUNKTION" (<NAME>)+

werteliste ::= ("WERT" (<REALZAHL>)* \n)*



The simplified grammar has eleven rules. These eleven rules are translated into a StringTemplate file dcm.stg shown below.



The Simplified DCM StringTemplate Group File

////////////////////////////////////////////////////////////////////////////////
//
// Simplified stg file for generating calibration files in DCM format
//
// References: 1. "DCM File Formats Tech Note", ETAS GmbH
//             2. "StringTemplate Documentation", Terence Parr
//
//
// German                     English
// -----------------------------------------------
// konservierung              preservation
// kons_rumpf                 kons_trunk
// kenngroesse                characteristic
// kennwert                   characteristic value
// festwert                   fixed value
// wert                       worth
// kennwerteblock             characteristic value block
// festwert                   fixed value block
// einheit                    unit
// funktionszugeh"rigkeit     function affiliation
// funktion                   function
// werteliste                 would worth-list
//
// Donn Shull
// Copyright 2007 L & D Engineering LLC. All Rights Reserved.
// $Revision: $
// $Date: $
//
////////////////////////////////////////////////////////////////////////////////

group dcm;

////////////////////////////////////////////////////////////////////////////////
//
// konservierung ::= "KONSERVIERUNG_FORMAT" "2.0"
// [kons-kopf]
// kons-rumpf
//
////////////////////////////////////////////////////////////////////////////////
konservierung(kons_rumpf) ::= <<
KONSERVIERUNG_FORMAT 2.0
<kons_rumpf>

>>

////////////////////////////////////////////////////////////////////////////////
//
// kons-rumpf ::= ( kenngroesse )*
//
////////////////////////////////////////////////////////////////////////////////
kons_rumpf(kenngroesse) ::= <<
<kenngroesse; separator="\n\n">
>>

////////////////////////////////////////////////////////////////////////////////
//
// kenngroesse ::= kennwert | kennwerteblock
//
////////////////////////////////////////////////////////////////////////////////
kenngroesse(kennwert, kennwerteblock) ::= <<
<kennwert><kennwerteblock>
>>

////////////////////////////////////////////////////////////////////////////////
//
// kennwert ::= "FESTWERT"
// kgr-info
// [einheit_w]
// "WERT"
// "END"
//
////////////////////////////////////////////////////////////////////////////////
kennwert(kgr_name, kgr_info, einheit_w, realzahl) ::= <<
FESTWERT <kgr_name>
    <kgr_info>
    <einheit_w>
    WERT <realzahl>
END
>>

////////////////////////////////////////////////////////////////////////////////
//
// kennwerteblock ::= "FESTWERTEBLOCK"
// kgr-info
// [einheit_w]
// werteliste-kwb
// "END"
//
////////////////////////////////////////////////////////////////////////////////
kennwerteblock(kgr_name, kgr_info, einheit_w, werteliste) ::= <<
FESTWERTEBLOCK <kgr_name>
    <kgr_info>

    <einheit_w>
    <werteliste>
END
>>

////////////////////////////////////////////////////////////////////////////////
//
// kgr-info ::= [langname]
// [displayname]
// [funktionszugeh"rigkeit]
//
////////////////////////////////////////////////////////////////////////////////
kgr_info(langname, displayname, funktionszugehorigkeit) ::= <<
<langname>
<displayname>
<funktionszugehorigkeit>
>>

////////////////////////////////////////////////////////////////////////////////
//
// einheit_w ::= "einheit_W"
//
////////////////////////////////////////////////////////////////////////////////
einheit_w(text) ::= <<
einheit_W "<text>"
>>

////////////////////////////////////////////////////////////////////////////////
//
// langname ::= "LANGNAME"
//
////////////////////////////////////////////////////////////////////////////////
langname(text) ::= <<
LANGNAME "<text>"
>>

////////////////////////////////////////////////////////////////////////////////
//
// displayname ::= "DISPLAYNAME"
//
////////////////////////////////////////////////////////////////////////////////
displayname(name) ::= <<
DISPLAYNAME "<name>"
>>

////////////////////////////////////////////////////////////////////////////////
//
// funktionszugeh"rigkeit ::= "FUNKTION" ()+
//
////////////////////////////////////////////////////////////////////////////////
funktionszugehorigkeit(name) ::= <<
FUNKTION <name>
>>

////////////////////////////////////////////////////////////////////////////////
//
// werteliste ::= ("WERT" ()* \n)*
//
////////////////////////////////////////////////////////////////////////////////
werteliste(realzahl) ::= <<
WERT <realzahl; separator=" ">
>>

Using STG Files with MATLAB

 

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 at http://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.

 

  1. Set the ActiveProject.
  2. 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:

 

  1. find the logical links available for this project
  2. find the available images for the logical link we want to use
  3. 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