I'm developing a Simulink modell with many C-s-functions. For an easier handling I want to use constants in the c-s-function as in the simulink-modell. So I have a c-header with preprocesser constants like:
#define THIS_IS_A_CONSANT 10
And there is the question:
How it is possible to include this in Simulink in this way I can use THIS_IS_A_CONSANT for example in a constant source like a workspace-variable?
Thanks and regards
Alex
There is functionality in Simulink that will allow you to include custom C header files that define constants, variables, etc.; however, as far as I know (and as one might expect) this really is only pertinent in cases where code is being generated and compiled.
So, for the most part, this particular functionality is only relevant when you are using Simulink Coder to generate a stand-alone executable from your model. For example, this link shows how to include parameters stored in an external header file during code generation through the use of Simulink.Parameter objects with Custom Storage Classes and the Code Generation - Custom Code Pane under the model's Configuration Parameters.
This link from the Simulink doc shows how to use the #define custom storage class to achieve similar results.
However, it sounds like neither of these really solve your issue, as you want to make use of the code in the header file during simulation.
That said, considering that there are elements in Simulink, such as Stateflow Charts and MATLAB Function blocks, that generate and build code "under the hood" during simulation, it's (at least hypothetically) possible that you might be able to use some of the concepts described above to access the values in your header file from one of those elements during simulation. For example, I was successfully able to access preprocessor macros in a Stateflow chart just by going to the Simulation Target->Custom Code pane under Configuration Parameters and including the text #include "header.h" under Include custom C code in generated: Header file. (In this case, header.h contained the line of C code that you included in your post)
Although it seems like you should be able to extend this functionality further, this really was the limit of what I was able to achieve as far as accessing the header file during simulation was concerned. For example, I know that running a model in Rapid Accelerator mode actually generates and builds code under the hood, so seemingly you should be able to use some combination of the techniques I described above to be able to access values from the header file during simulation. It looks like the code that Rapid Accelerator mode generates doesn't respect all of the settings defined by those techniques in the same way that Simulink/Embedded Coder do, though, so I just kept running into compilation errors. (Although maybe I'm just missing some creative combination of settings that could make that work).
Hopefully that helps explain Simulink's abilities (and limitations) regarding the inclusion of C header files. So to summarize, according to the links included above, what you are asking for is almost barely possible, but in practice... not really.
So if really all you want is to be able to create workspace variables out of the preprocessor #define's in your header file, it probably is just easiest to manually parse the file with a MATLAB script, as had previously been suggested in the comments. Here is a quick-and-dirty script that loads in a header file, iterates over each line, uses a regular expression (which you can improve upon if needed) to parse #define statements, and then calls eval to create variables from the parsed input.
filename = 'header.h';
pattern = '^\s*#define\s*(\w*)\s*(\d*\.?\d+)';
fid = fopen(filename);
tline = fgetl(fid);
while ischar(tline)
tokens = regexp(tline, pattern,'tokens','once');
if(numel(tokens) == 2)
eval([tokens{1} ' = ' tokens{2}]);
end
tline = fgetl(fid);
end
fclose(fid);
You could put this code in a callback so that it will execute every time you load your model. Just goto File->Model Properties->Model Properties, click on the Callbacks tab, and then place the code under whichever callback you desire (such as PreLoadFcn if you want it to run immediately before the model loads).
Related
I am interested to replace my own PID-regulator models with MSL/Blocks/Continuous/LimPID. The problem is that this model restricts limitations of output signals to be parameters and thus do not allow time-varying limits, which I need to have.
Studying the code I understand that the output limitation is created by a block MSL/Blocks/Nonlinear/Limiter and I just want to change this to the block VariableLimiter.
I can imagine that you need to ensure that changes of output-limitations vary in a time-scale slower than the regulator in order to not excite unwanted behaviour of the controller. Still here is a class of problems where it would be very useful to allow this limits to vary slowly.
Thanks for the good input to my question and below a very simple example to refine my question. (The LimPID is more complicated and I come back to that).
Let us instead just modify the block Add to a local block in MyModel.
I copy the code from Modelica.Blocks.Math.Add and call it Addb in MyModel. Since here is a dependence of Interfaces.SI2SO I need to make an import before the extends-clause. This import I take from the ordinary general MSL package, instead of copying also that in to MyModel. Then I introduce a new parameter "bias" and modify the equation. The annotation may need some update as well but we do not bother with that now.
MyModel
...
block Addb "Output the sum of the two inputs"
import Modelica.Blocks.Interfaces;
extends Interfaces.SI2SO;
parameter Real k1=+1 "Gain of input signal 1";
parameter Real k2=+1 "Gain of input signal 2";
parameter Real bias=0 "Bias term";
equation
y = k1*u1 + k2*u2 + bias;
annotation (...);
end Addb;
MyModel;
This code seems to work.
My added new question is whether it is enough to look up "extends-clauses" and other references to MSL and make the proper imports since the code is now local, or here are more aspects to think of? The LimPID code is rather complex with procedures for initialization etc so I just wonder if here is more to do than just bring in a number of import-clauses?
The models in Modelica Standard Library (MSL) should only be seen as exemplary models, not covering all possible applications. MSL is write protected and it is not possible to replace the limiter block in LimPID (and add max/min input connectors). Also, it wouldn't work out if you shared your simulation model with others, expecting their MSL to work like your modified MSL.
Personally, I have my own libraries of components where MSL models are inadequate. For example, I have PID controllers with variable limits, manual/automatic functions and many more functions which are needed in my applications.
Often, I create a copy of an MSL model, place it in the same package in my own library and make the necessary modifications and additions, e.g. MyLibrary.Blocks.Continuous.PID.
I'm developing a Simulink model with many constants.
I'm trying to:
Avoid hardcoding every constant in the model and have something unreadable.
Be able to know what that 9.73288483... constant in the middle of my model stands for.
I wanted to add all my constants to a header file to have them as global constants (/including the header file everywhere) so that I could directly refer to their name instead of the value and it would also simplify my model.
Another reason for me to use a header file is that I will then generate my model in C using Simulink coder, and I really want to have that header file to have a clean generated code
I've seen people in here referring to the existence of such function.
So I've been wondering if anyone here could help me out?
Then I could also apply it to replace my functions parameters by global constants in another header file which would let me simply load a different "parameters_values.h" file when I want to change the conditions of my simulation easily.
You can specify under "file->model properties" callback functions
I have an .m file which I wish to share with my friends but I am not interested in giving .m file. Could someone help me with best possible ways to convert it to a file that is not decodable?
I tried converting it to .p file by simply typing pcode example.m
however I don't believe it is really protecting it. I was able to convert my .p file back to .m file with the following link. https://sites.google.com/site/sippeyfunlabs/matlab-hacks/please-do-not-secure-your-password-in-matlab-p-code
This actually confirms that my code is not protected.
It'll be nice if someone shares the best methodology to protect .m file and sharing.
Thanks
The link you provided yourself already indicates that it is very difficult to obfuscate MATLAB code:
In fact, MATLAB language is very difficult to be secured or even obfuscated.
This is due to the late binding (or dynamic binding) feature of
MATLAB. [...] The amount of meta information associated with this
feature basically forbid any attempt of adding code level security.
Simply put, if there is a MATLAB file, and it calls a function foo
inside it. Until the runtime, the MATLAB interpreter do not even know
if foo is a function stored in M file or a built-in function or a mex
function or even a workspace function handle. Thus, it must store foo
as is somewhere inside the generated P-code.
Also to best solution is already mentioned on that page:
If there is really a need to do this, using the good old binary is a
much better solution. Or you can put critical code on a server, away
from the user.
Create a binary, i.e. mex file (see the answer of Wolfie): Note that to some extent also binary code can be decompiled especially small ones.
Host your code on a server (and run the code server-side): This is the best method to protect your code. You should let the user upload the input for your script and return the result. You can also automatize this process using a matlab script to make this process transparent to the user.
You could build a mex file.
This will completely obfuscate your actual MATLAB code, since it will be written in C/C++/FORTRAN, but the algorithms will still be there if your friends are determined enough to look for them.
I would like to import an existing C code (or any other text) into my generated code by Matlab simulink.I have some tasks that made in C,but in the future i want to develop in matlab.I work in simulink,and I can compile the models,but I want to use some special function what I previously wrote in C (because of pointer etc.).
The problem is that I don't know how to put in these texts into the model,and after the code generation these texts stay in the original format,and placed in the expected line.
And what I would like:
You can achieve this using the S-Function Builder. It allows one to create C code blocks, which get compiled with the model run. If using Code Generator, it gets inserted into generated code.
I generally use it to call functions from my external code or libraries, as in some Raspberry Pi Driver blocks I created.
It generates .c, .h and .mex files for each block and is quite clunky but does work!
BTW: If it's just to use an external pointer, you can happily use ImportedPointer/ExportedPointer for this. I find this handy for variables between generated code and container.
I need to load experimental data into scicoslab, a (pretty badly designed) clone fork of scilab which happens to support graphical modeling. The documentation on the web is pretty poor, but it's reasonably similar to scilab and octave.
The data I need to process is contained into a certain number of text files: Data_005, Data_010, …, Data_100. Each of them can be loaded using the -ascii flag for the loadmatfile command.
The problem comes from the fact that loadmatfile("foo", "-ascii") loads the file foo.mat into a variable named foo. In order to to cycle on the data files, I would need to do something like:
for i = [5:5:100]
name = sprintf("Data_%02d", i);
loadmatfile(name, "-ascii");
x = read_var_from_name(name);
do_something(x);
end
where what I search for is a builtin read_var_from_name which would allow me to access the internal symbol table by string.
Do you know if there exist a similar function?
Notes:
There's no way of overriding this behavior if your file is in ascii format;
In this phase I could also use octave (no graphical modelling is involved), although it behaves in the same way.
>> foo = 3.14; name = 'foo'; eval(name)
foo =
3.1400
The above works in MATLAB, and Scilab's documentation says it also has an eval function. Not sure if I understood you correctly, though.
#arne.b has a good answer.
In your case you can also do that in matlab:
a=load('filename.mat')
x=a.('variable_name')
lets go through your points one by one:
"ScicosLab, a (pretty badly designed) clone of Scilab" This in my opinion is an inaccurate way of introducing the software. ScicosLab is not a clone of Scilab but a fork of it. The team behind ScicosLab (INRIA) are the ones who made scocos (now called xcos in Scilab development line). At some point (from Scilab v4) the Scilab team decided to move away from Tcl/tk towards Java, but the SciccosLab/scicos team departed, keep using the language (Tcl) and it's graphical user interface design package (tk). Giving the ScocosLab community the credit that the whole Scilab documentation and support is not very good in general. :) (more about Scilab and the forks here)
Regarding the technical question I'm not sure what you are trying to achieve here, Scilab/ScicosLab still have the eval function which basically does what you want. However this function is to be deprecated in favor of evstr. There is also the execstr function which worth studying.
The loadmatfile, as far as I have understood, "tries" to load the variables defined in a MATLAB .mat file (MATLAB's proprietary tabular format) into the Scilab workspace. For example if there is a variable foo it will "try" to create the variable foo and loads its value from the MATLAB script. Check this example. I would create a variable x(i) = foo in the for loop. again your question is not completely clear.
As a side note maybe you could consider exporting your data as CSV instead of .mat files.