I'm trying to simulate a very simple model using an embedded matlab function that takes the input and add's 10 to the value using a constant block that inputs into the matlab function, which then outputs to a display block.
As soon as I press simulate I get an abundance of errors. First I get a huge paragraph in orange text stating a warning out the solver 'variableStepDiscrete' instead of solver 'ode45'
Here is the remaining lines that are echo'd from the command prompt:
Code Directory :
"/Users/dazgti/Documents/MATLAB/slprj/_sfprj/embeddedFunction/_self/sfun/src"
Machine (#32): "embeddedFunction" Target : "sfun"
Chart "MATLAB Function" (#49):
.
"c2_embeddedFunction.h"
"c2_embeddedFunction.c"
"embeddedFunction_sfun.h"
"embeddedFunction_sfun.c"
"embeddedFunction_sfun_debug_macros.h"
Interface and Support files:
"embeddedFunction_sfun_registry.c"
Code generation failed Attempt to execute SCRIPT union as a function:
/Users/dazgti/Documents/MATLAB/union.m
I have a script file within my matlab directory called union.m, but I have no idea why its mentioning it.
function y = fcn(u)
%#codegen
x = u + 10;
y = x;
MATLAB Function block works by generating "C" code for the MATLAB code you entered in the block. In the process of generating code there could have been a call to union function in MATLAB from MATLAB Function block infrastructure. Since you have overridden the union function instead of the built-in function MATLAB might have attempted to call your script which caused the error. It is better to avoid naming your functions same as MATLAB built-in functions.
Related
Can I open a local Simulink MATLAB function block's code in the MATLAB editor via some command?
For example, let us say I have a Simulink model named mainModel.slx.
In it, there is a MATLAB function block named localFunction.
This is not defined in a .m-file.
I would be able to edit the function which path is mainModel/localFunction, without having to open the simulink window and double click on the function block. Is this possible?
I have of course already tried open mainModel/localFunction and edit mainModel/localFunction. I have access to the handle for its StateFlow.EMChart object.
EDIT: Minimal, (hopefully) Complete and Verifiable Example
My minimal Simulink model is shown in the picture below. Code is present below it. For readability, I have not addressed bugs or glitches. It is not for general usage.
The function code for the MATLAB function block localFunction is
function y = fcn(u)
y = 'findThis'; % I want to end up here, in the MATLAB editor!
end
I am using the following code to load the model, search through all MATLAB function blocks and find the ones containing the string 'findThis'. The MATLAB function block named 'localFunction' should then be found. Again, ignore the bugs. The code is saved in a script called tmpScript.m.
% User set
model = 'mainModel';
expression = 'findThis';
blockType = 'Stateflow.EMChart'; % MATLAB function block, right?
% Load model
load_system(model)
% Find all MATLAB function block handles
blockHandles = find(slroot, '-isa', blockType);
% Find first block containing the defined expression
for iHandle = 1:numel(blockHandles)
tmpFind = strfind(blockHandles(iHandle).Script, expression);
if ~isempty(tmpFind)
break
end
end
foundBlockPath = blockHandles(iHandle ).Path; % Function block path
foundCharIdx = tmpFind; % Character index
% Print results in command window
fprintf('Function path: %s\n', foundBlockPath)
fprintf('Character index: %d\n', foundCharIdx)
In this example, the path should be mainModel/localFunction and the character index 29 (Note the three leading white spaces on the function's second line, and that the line break '\n' is worth one characters). The command window shows
>> tmpScript
Function path: mainModel/localFunction
Character index: 29
>>
I can thus load models and search through their MATLAB function blocks for specific strings. When I have found this function, I would like to be able to open it in the matlab editor. What is called when I double click on the block in the Simulink window?
These do NOT work
open(foundBlockPath)
edit(foundBlockPath)
blockHandles(iHandle).openEditor
I cannot change the Simulink model itself. I do not want to change the function script. I just want to be able to open it in the MATLAB editor.
You can open the code in the Editor using,
view(blockHandles(iHandle))
You could change the Matlab function block to an Interpreted Matlab function block.
This does have the limitation that it only can have one input and one output (which can be vectors), so depending on your problem, you might have to mux/demux some data.
Alternatively you can change to an S-function, which gives more flexibility, but might be a bit more complex to setup.
I have a simulink file, where I need to call a certain optimization function:
function u = MPC(r, x0, Thorizon, Q, W, cons)
R = [];
for s=1:Thorizon+1
R = vertcat(R, r);
end
ops = sdpsettings('solver','quadprog','verbose',0);
U = sdpvar(Thorizon+1,1);
cost = (R - (Q*U+W*x0))'*(R-(Q*U+W*x0))+U'*U;
optimize(cons,cost,ops);
u = value(U);
u = u(1);
end
However, I'm not sure how to implement this in Simulink.
I tried it with a matlab function block, but a couple of problems arise.
First of all, it returns some errors like
Function 'eval' is not supported for code generation. Consider adding
coder.extrinsic('eval') at the top of the function to bypass code
generation.
or like
Function 'sdpsettings.m' (#103.12741.12757), line 355, column 12:
"temporaryOptions" Launch diagnostic report.
It has (probably) to do with the fact that the optimizer (sdp) is an external function, one that is part of a seperately installed library.
The other possible issue, is one with the input arguments.
If I were to use a Matlab function block, there would be a problem with the cons argument, one that can take inequality forms, like
U<1
The function, does however, work in the Matlab environment itself.
But the output of this function, needs to be the input of a continuous non-linearm model present in simulink.
So my question is,
are there any suggestions, to either: Make such function in Simulink work, like via a Matlab function block, or use the function in the matlab runtime environment itself, and send the output value repeatedly to the simulink model?
I have a function to be optimized to find its maxima (using Matlab). The function part of the simulation model and hence it is stored in a Matlab script file.
Note that in normal case of function usage, I can do the maximization using fminbnd command and then taking the negative of the function. Such that
g(x) = –f(x)
e.g.
[x fval] = fminbnd(#(x)-tan(cos(x)),3,8)
But I am looking for a way to do find maxima using the (or -ve of function to find maxima) for a script function.
If I understand correctly what you are looking for, you have a set of commands that take some input variable(s), and produce a result, but these commands are located within a script file rather than a MATLAB function. You want to run fminbnd on the script, rather than rewriting the commands into a function?
The obvious question is why don't you want to take the easy option and put the code into a function. Assuming you can't, for some reason, how about constructing a 'container' function that runs your script and returns the result? Something like:
function result = containerFunction(myScriptName, inputData)
% Input Arguments:
% myScriptName : string, filename (not extension), e.g. 'myScript'
% inputData : any data compatible with the script defined in myScriptName
% Output Arguments:
% result : must be created by the script defined in myScriptName
eval(myScriptName);
You can then call containerFunction from fminbnd instead.
I am building a reduced order observer in MATLAB. The matrices are calculated using functions/script files outside matlab and simulink function blocks are using these functions to calculate values.
The problem is that some commands like 'acker', 'place' etc which used to work on command window/function/script files are not working in simulink function block and showing errors.
I tried using simin block to take these matrices from workspace but it is also showing errors which I can't understand.
Thanks for your help.
If I get your question correctly then, from User defined functions, you could add a Matlab function block with the following code:
function fcn(in)
%#codegen
coder.extrinsic('acker', 'place')
# Now you can use acker, place so add more code.
I have observed a strange behavior in running the same code in a Matlab function and in the command window. It's already described in How does scoping in Matlab work? , but I don't understand how I could solve my specific problem.
The code is the following:
exporteddata.m %File created by an external program
%to export data in Matlab format
surface = struct('vertices', [...]) ;
%I can't specify in the external program
%the name of the variable, it's always "surface"
My actual code is:
myfunction.m
function output = myfunction(input)
load(input);
n = size(surface.vertices);
....
When running
myfunction('exporteddata.m');
I get the following error:
??? No appropriate method, property, or field vertices for class hg.surface.
When running the same instructions from the command window or in debug mode, the code works well.
How can I specify in the function that I need the variable surface present in the workspace, not the Matlab function?
First of all, I must point out that surface is a built-in function in MATLAB, so overloading it is just... bad. Bad, bad, BAD!
Having said that, the MATLAB interpreter does a pretty good job at resolving variable names and usually tells them apart from function names correctly. So where's your problem, you ask?
I believe that you're using the wrong function: load is a function that loads data from MAT files into the workspace. It is not fit for m-files. By not executing "exportedata.m" properly, surface has never been created as a variable, so MATLAB identifies it as a function name. If you want to execute "exportedata.m", just type:
exportedata
and if you want to run the file with the filename stored in input, you can use run:
run(input)
By executing run(input) from within myfunction, surface should be created in myfunction's local scope, and it should work.
EDIT:
I've just tested it, and the interpreter still gets confused. so the issue of the variable name resolution remains. Here's a workaround:
function output = myfunction(input)
surface = 0; %// <-- Pay attention to this line
run(input);
n = size(surface.vertices);
Predefining surface allows the interpreter to identify it as a variable throughout your entire function. I've tried it and it works.