Difference between revisions of "HANtune/MATLAB Interface"
(→Connecting to the MATLAB Engine) |
|||
(17 intermediate revisions by the same user not shown) | |||
Line 6: | Line 6: | ||
*createDaqList.m | *createDaqList.m | ||
*getDaqListData.m | *getDaqListData.m | ||
+ | |||
''Note: You will need to have installed a version of MATLAB® with the Java MATLAB engine.'' | ''Note: You will need to have installed a version of MATLAB® with the Java MATLAB engine.'' | ||
+ | |||
==Connecting to the MATLAB Engine== | ==Connecting to the MATLAB Engine== | ||
− | + | In order to connect to MATLAB engine, HANtune first needs to know where to find it. Open ''ConnectToMatlab.py'' and change the enginePath variable to the location of your MATLAB engine: | |
− | |||
− | Open ''ConnectToMatlab.py'' and change the | ||
<nowiki>#Change this to your location of the MATLAB engine | <nowiki>#Change this to your location of the MATLAB engine | ||
enginePath = "C:\Program Files\MATLAB\R2017b\extern\engines\java\jar\engine.jar"</nowiki> | enginePath = "C:\Program Files\MATLAB\R2017b\extern\engines\java\jar\engine.jar"</nowiki> | ||
+ | Then we need to share an instance of MATLAB. Start MATLAB and enter the following command in the MATLAB command window: | ||
+ | |||
+ | <nowiki>matlab.engine.shareEngine</nowiki> | ||
+ | |||
+ | Now run the script to connect to MATLAB. | ||
+ | |||
+ | ====Explanation of the script==== | ||
+ | |||
+ | Add the engine to the java classpath so we can call it from a script. | ||
<nowiki>#Add matlab engine to the classpath | <nowiki>#Add matlab engine to the classpath | ||
from datahandling import CurrentConfig | from datahandling import CurrentConfig | ||
CurrentConfig.getInstance().addSoftwareLibrary(enginePath)</nowiki> | CurrentConfig.getInstance().addSoftwareLibrary(enginePath)</nowiki> | ||
+ | |||
+ | Import the engine and connect to a running instance of MATLAB. | ||
<nowiki> | <nowiki> | ||
Line 30: | Line 41: | ||
engines = MatlabEngine.findMatlab() | engines = MatlabEngine.findMatlab() | ||
engine = MatlabEngine.connectMatlab(engines[0])</nowiki> | engine = MatlabEngine.connectMatlab(engines[0])</nowiki> | ||
+ | |||
+ | ''Note: The scripts assumes there is shared instance of MATLAB currently running. If you don't want to connect to a running instance, but start an instance of MATLAB in the background instead, remove the '''engines[0]''' argument from the call to MatlabEngine.connectMatlab().'' | ||
+ | |||
+ | Optionally you can set the engine as a global variable across all interpreters. This allows you to initialize the engine once and then call it from another script. | ||
<nowiki>#Add engine as a global variable to all interpreters | <nowiki>#Add engine as a global variable to all interpreters | ||
from nl.han.hantune.scripting import ScriptingManager | from nl.han.hantune.scripting import ScriptingManager | ||
ScriptingManager.getInstance().setGlobal("engine", engine)</nowiki> | ScriptingManager.getInstance().setGlobal("engine", engine)</nowiki> | ||
+ | |||
+ | Optionally we can redirect the output (e.g. print statements, warnings, errors) to the console of HANtune. | ||
<nowiki>#Redirect matlab output to HANtune console | <nowiki>#Redirect matlab output to HANtune console | ||
Line 44: | Line 61: | ||
====Set your model==== | ====Set your model==== | ||
− | + | Open ReadSimulinkModel.py and change the modelName and modelPath variables to that of your model. | |
<nowiki>#Change these to the name and location of your model | <nowiki>#Change these to the name and location of your model | ||
modelName = 'MyModel' | modelName = 'MyModel' | ||
modelPath = 'C:\Users\Michiel Klifman\Desktop'</nowiki> | modelPath = 'C:\Users\Michiel Klifman\Desktop'</nowiki> | ||
− | + | The path to the example scripts and the path to your model must be added to the MATLAB search path so that MATLAB knows where to find them. | |
<nowiki>#Add folders to MATLAB path | <nowiki>#Add folders to MATLAB path | ||
Line 58: | Line 75: | ||
====Creating a daq list==== | ====Creating a daq list==== | ||
− | + | Use the MATLAB engine to call createDaqList.m with your modelName as an argument. The last argument ('signals') determines what items will be in the daq list. If 'signals' is used, a daq list will be created of all signals in your model. If 'blocks' is used, a daq list will be created of all non-virtual blocks in your model. The createDaqList function returns two arrays. The first contains all signal names, used to create signals in HANtune. The second one contains the daq items used to retrieve the data from the model. A daq item has the following format: [blockHandle, portHandle, dataIndex]. | |
<nowiki>#Create a daqlist from signals in the model | <nowiki>#Create a daqlist from signals in the model | ||
result = engine.feval(2, 'createDaqList', modelName, 'signals') | result = engine.feval(2, 'createDaqList', modelName, 'signals') | ||
Line 74: | Line 91: | ||
print 'DAQ list created with ' + str(daqSize) + ' items'</nowiki> | print 'DAQ list created with ' + str(daqSize) + ' items'</nowiki> | ||
− | ====Reading==== | + | ====Reading data from the model==== |
+ | |||
+ | First we will start the simulation: | ||
<nowiki>#Start the simulation | <nowiki>#Start the simulation | ||
Line 80: | Line 99: | ||
print 'Simulation started...'</nowiki> | print 'Simulation started...'</nowiki> | ||
+ | And then start reading the model by calling getDaqListData with the daq list that was created earlier as an argument. | ||
<nowiki>#Read data from the model in Simulink and add it to the signals in HANtune | <nowiki>#Read data from the model in Simulink and add it to the signals in HANtune |
Latest revision as of 18:53, 24 October 2019
HANtune can be interfaced with MATLAB® (and by extension Simulink®). We can do this by using the MATLAB engine and calling it from a script.
The scripts needed to run this example can be found in HANtune\scripts\examples\MATLAB_Interface. These are:
- ConnectToMatlab.py
- ReadSimulinkModel.py
- createDaqList.m
- getDaqListData.m
Note: You will need to have installed a version of MATLAB® with the Java MATLAB engine.
Contents
Connecting to the MATLAB Engine
In order to connect to MATLAB engine, HANtune first needs to know where to find it. Open ConnectToMatlab.py and change the enginePath variable to the location of your MATLAB engine:
#Change this to your location of the MATLAB engine enginePath = "C:\Program Files\MATLAB\R2017b\extern\engines\java\jar\engine.jar"
Then we need to share an instance of MATLAB. Start MATLAB and enter the following command in the MATLAB command window:
matlab.engine.shareEngine
Now run the script to connect to MATLAB.
Explanation of the script
Add the engine to the java classpath so we can call it from a script.
#Add matlab engine to the classpath from datahandling import CurrentConfig CurrentConfig.getInstance().addSoftwareLibrary(enginePath)
Import the engine and connect to a running instance of MATLAB.
#Import matlab engine from com.mathworks.engine import MatlabEngine #Initialize matlab engine engines = MatlabEngine.findMatlab() engine = MatlabEngine.connectMatlab(engines[0])
Note: The scripts assumes there is shared instance of MATLAB currently running. If you don't want to connect to a running instance, but start an instance of MATLAB in the background instead, remove the engines[0] argument from the call to MatlabEngine.connectMatlab().
Optionally you can set the engine as a global variable across all interpreters. This allows you to initialize the engine once and then call it from another script.
#Add engine as a global variable to all interpreters from nl.han.hantune.scripting import ScriptingManager ScriptingManager.getInstance().setGlobal("engine", engine)
Optionally we can redirect the output (e.g. print statements, warnings, errors) to the console of HANtune.
#Redirect matlab output to HANtune console from java.lang import System from nl.han.hantune.scripting import Console System.setOut(Console.getGUI().getOut()) System.setErr(Console.getGUI().getErr())
Reading data from a running Simulink model
Set your model
Open ReadSimulinkModel.py and change the modelName and modelPath variables to that of your model.
#Change these to the name and location of your model modelName = 'MyModel' modelPath = 'C:\Users\Michiel Klifman\Desktop'
The path to the example scripts and the path to your model must be added to the MATLAB search path so that MATLAB knows where to find them.
#Add folders to MATLAB path from java.lang import System scriptPath = System.getProperty("user.dir") + "\scripts\examples\MATLAB_Interface" engine.eval("addpath('" + scriptPath + "')") engine.eval("addpath('" + modelPath + "')")
Creating a daq list
Use the MATLAB engine to call createDaqList.m with your modelName as an argument. The last argument ('signals') determines what items will be in the daq list. If 'signals' is used, a daq list will be created of all signals in your model. If 'blocks' is used, a daq list will be created of all non-virtual blocks in your model. The createDaqList function returns two arrays. The first contains all signal names, used to create signals in HANtune. The second one contains the daq items used to retrieve the data from the model. A daq item has the following format: [blockHandle, portHandle, dataIndex].
#Create a daqlist from signals in the model result = engine.feval(2, 'createDaqList', modelName, 'signals') daqItemNames = result[0] daqList = result[1] daqSize = len(daqList)
#Create a signal for each item in the daq list signals = [] removeAllSignals() for name in daqItemNames: signal = createSignal(name) signals.append(signal) updateLayout() print 'DAQ list created with ' + str(daqSize) + ' items'
Reading data from the model
First we will start the simulation:
#Start the simulation engine.eval("set_param('" + modelName +"','SimulationCommand','start');") print 'Simulation started...'
And then start reading the model by calling getDaqListData with the daq list that was created earlier as an argument.
#Read data from the model in Simulink and add it to the signals in HANtune while (True): data = engine.feval('getDaqListData', modelName, daqList, daqSize) if not data: break i = 0 for value in data: signals[i].setValueAndTime(value, 0) i += 1 print 'Simulation completed!'