I have a Simulink model that calls a script in the InitFcn of the Model callbacks. This script initializes a bunch of variables in the base workspace so that they can be used by the Simulink model. When using Classes, I found that using the load_system function will make Matlab crash and the open_system function will work just fine.
Here the Class:
classdef simulinkModel
properties
model = '';
end
methods
function obj = simulinkModel(modelName)
obj.model = modelName;
end
function openModel(obj)
% Make sure any previously open model are closed, and open the model.
if bdIsLoaded(obj.model)
obj.closeModel()
end
%load_system(obj.model) % Matlab crash
open_system(obj.model) % Matlab run the model correctly
end
function closeModel(obj)
close_system(obj.model, 0)
end
function runModel(obj)
sim(obj.model)
end
end
end
And in the command window:
objModel = simulinkModel('test');
objModel.openModel
objModel.runModel
So how comes it crashs with the load_system vs the open_system? Is there something that the open_system function do with the base workspace that the load_system function doesn't do?
EDIT
I decided to try running simple commands outside of the class to see if the problem is elsewhere. So typing in the command window:
load_system('test')
sim('test')
When executing this in the command window, Matlab will also crash. So I'm starting to wonder if the model callbacks are not executed when the load_system function is called.
I can confirm there is indeed very different behaviour between load_system and open_system. I am currently debugging a weird problem under 2015b to be, and I just realized the LoadFcn callback of my simulink models is not called when I use load_system, but is is called properly when I use open_system. I don't know that this is documented anywhere. I find this callback name misleading if it is not called when you "load" the system !!! If I find more info, I will post back on this thread.
Related
Consider a Simulink Simulation model including two model-reference blocks, one of them referenced to a model which calls the Add() function, the implementation of the Add() function is in the second model referenced by the second model-reference block.
Now imagine, in the Second model the Add() function is a Simulink Function scoped globally and inside it, there is a MATLAB Function block that calls a Helper() function, note that the Helper() function calls from the MATLAB function. The implementation of the Helper() function is also in the second model as expected.
Now when running the Simulation model the following error is observed:
Cannot Generate Code for Call to Simulink Function 'Helper()' from Stateflow Chart.
Now anyone can help to overcome this problem?
To test the above scenario just download the project from the following link, then open the Simulation.slx and hit run.
I am currently having problems calling a static method located in an m-file, through the octave command interface. The error I'm getting is error: invalid call to script path/to/Test.m
Test.m:
classdef Test
methods(Static=true)
function ret = test_function()
ret = 0;
end
end
end
I am trying to call the method in the following way: > Test.test_function(). It's important to note that the script resides in the same directory in which I invoked the octave command, the script Test.m shows up using tab completion so the location is not at fault here I guess.
Any help is much appreciated,
thanks in advance!
From the Octave FAQ: "Matlab classdef object oriented programming is not yet supported, though work is underway in a branch of the development tree."
So the error is likely arising from the lack of classdef support, and the parser can't make sense of the call at all.
I have a problem that I'm having a hard time even framing for this question's title.
I have a library that calculates the properties of refrigerants. For example, you give pressure and enthalpy, and it tells you the temperature. That library is coded in Fortran with a mex file to interface with Matlab. Now, I am 100% sure that library is thoroughly debugged (it was coded by people much smarter than me, and has been used for almost a decade). The problem is definitely in how I call it.
And that problem is this. I call the library from a StartFcn callback (a .m script file) in a subsystem of a simulink model. The first time I run this model, it runs perfectly. The values I'm sedning to the function are therefore correct. The second time I run it, however, it crashes. The inputs both times are exactly the same.
Also, if I do a clear all between the two runs, then there is no crash. But if I do only clearvars or clear, I still get a crash. When I debug and look at the variables being passed in the function call, they are valid and the same both times.
Does someone have any experience with this, or can advise me on what I might be doing wrong? Is there something persisting within the function call that only clear all can remove and not clear? Save My Soul!
Yes, persistent variables can be declared by the persistent keyword.
If you want to clear only those, try
clear StartFcn
to clear all variables of the function StartFcn. A quote from the documentation:
If name is a function name, then clear name reinitializes any persistent variables in the function.
A quick thing to try would be clear mex inbetween simulations - this should clear all the mex code from matlab.
Other questions to think about..
Can you call the fortran interface directly from the matlab command line two times in a row?
I believe that using a m-file sfunction to call fortran in simulink is quite inefficient. Possibly consider writing your own fortran or C sfunction to interface to the code and compile in directly?
in case you're using LoadLibrary to load fortran code compiled into a dll, are you calling FreeLibrary in the mdlTerminate function?
Hope some of this helps.
I would try to put a clear all inside the function that you are calling in the StartFcn Callback.
So let's say your function is:
function [out] = nameoffunction(a,b,c)
%do calculation with a,b,c
d = a + b + c;
%output out
out = d;
assignin('base','out',d)
clear all
And you can call the function:
nameoffunction(a,b,c)
Let me know if it changes something. If this works, you could try other clear command but inside the function.
I created a GUI named SCADA and I added a boolean variable called StatusData which is a flag that that is set to false when the GUI is launched
handles.StatusData=false;
guidata(handles.output,handles);
I press a button and then a function is called which executes continuously (the function has infinite loop). After some time I press another button which sets the StatusData to true.
handles.StatusData=true;
guidata(handles.output,handles);
Now, I need to access the StatusData from the callback function (the same function I mentioned above), In order to acheieve this I sent the handle as a parameter when I called that function. Now, When the pressed the button that changes the StatusData, the data in the actual handle changes but I cannot access the updated StatusData as the function is already called.
How can I access the updated handle of GUI without sending it as a parameter.
Thanks
You can just pass in the hObject parameter to your function instead, and retrieve your value when it's needed using guidata; i.e.,
function some_callback(hObject, handles, ...)
myLoopingFunction(hObject, ...);
function myLoopingFunction(hObject, ...)
for someVar = something
% Update handles structure
handles = guidata(hObject);
end
Alternatively you could create a handle object and put that in the handles structure; e.g.,
% In a separate file:
classdef uiState < handle
% Probably should give this class a less general name...
properties
StatusData
end
end
% In your UI file:
function some_callback(hObject, handles, ...)
handles.state = uiState();
handles.state.StatusData = false;
% Now, when you modify handles.StatusData, the version used by
% myLoopingFunction will also be updated, because they point to
% the same object!
myLoopingFunction(handles.state);
function myLoopingFunction(state, ...)
for someVar = something
% Now you just have to check state.StatusData
end
For simple cases, I'd use the first method. For more complicated situations, where several parameters must be kept track of and they interact in complex ways, I would use the second. The second is also useful if you have a large chunk of data in some variable and want to stop it from being copied into every call to the UI.
Personally, for a complex UI I would usually create some application class that keeps track of the user interface (and provides a command-line interface to it) and make sure that was always available to my UI, but that is a bit like using a sledgehammer to open a jam jar in this simple case.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Declaring a global variable in MATLAB
Currently my matlab code is in one big script file with no internal functions. I would like to have functions declared within my script, to make my code more readable and reuse code etc. This in itself is not difficult in matlab, e.g.
Example 1:
function main()
myfunc('goat');
end
function myfunc(x)
fprintf(x);
end
My problem is that I have a biig datafile, which I want to load only once, such that I can re-run my code during development without spending time on re-loading the data. This is not a problem in my current framework with one big script with no internal functions. One solution is to have two matlab script files. One for loading data and then calling the functions in another script.
However in the above example 1 a true global variable declaration will not work, and I am forced load the biig file every time I run the script. What I would like to do can be shown in two examples:
Example 2:
% Global variable
if ~exist('data',var)
data = load biigdatafile.mat; %FAILS, outside function.
end
function main()
myfunc('goat');
end
function myfunc(x)
fprintf(x);
end
Example 3:
function main()
% Global variable
if ~exist('data',var)
global data; % Is not really global after whole script is completed.
data = load biigdatafile.mat;
end
myfunc('goat');
end
function myfunc(x)
fprintf(x);
end
So my question is how to declare a true global variable as in example 2, where I load my data once to stay in workspace, while calling my functions inside one script?
Use input arguments, that's what they're made for
You could just use arguments to the main function, load the dataset once into the base workspace and call your function with that dataset as an argument. If any subfunctions also use the dataset, pass it along
function main(data)
if nargin<1
disp('hey, you forgot to supply the dataset!');
end
% do your stuff
showData(data);
end
and then in the base workspace:
Data = load('biigdatafile.mat');
main(Data);
Use persistent variables
persistent X Y Z defines X, Y, and Z as variables that are local to the function in which they are declared; yet their values are retained in memory between calls to the function. Persistent variables are similar to global variables because the MATLAB software creates permanent storage for both. They differ from global variables in that persistent variables are known only to the function in which they are declared.
So you could easily use:
function main()
persistent data;
if isempty(data)
disp('loading dataset');
data=load('biigdatafile.mat');
end
% do your stuff
showData(data);
end
First time you call this function on a cleared base workspace or cleared function*, the dataset will be loaded. Every next time (when the function hasn't been edited), the dataset will already/still be in memory.
I usually do this when I'm just using one dataset; it's tedious to always load the dataset and when testing a function, it's also easier to just press F5.
* when is a function cleared you might ask?
Whenever you clear or modify a function that is in memory, MATLAB also clears all persistent variables declared by that function. To keep a function in memory until MATLAB quits, use mlock.
Global variables have to be declared everywhere they are used. Just add the global data to whereever you need it, and it will work.
It is not a duplicate of declaring global variables in matlab. A global var is only accesible to all functions, but when the script is complete, the global variables are gone and I need to read them into memory again.
What I need is to move the local variable into the base workspace and then access it again during other function calls. I actually solved it myself, just now with this code
function main()
try
Data = evalin('base','Data'); % Move back from base workspace
fprintf('Already loaded...\n');
catch
fprintf('Loading data...');
data = load biigdatafile.mat;
assignin('base', 'Data', Data); % Move to base workspace
fprintf('Ok\n');
end
showDocID(Data{1});
end
function showData(Data)
fprintf(['Data: "' Data '"\n']);
end