- Index
- » Usage and Applications
- » OpenModelica Usage and Applications
- » External function using output of an...
External function using output of an other one.
External function using output of an other one.
Hi guys, I have a little problem with the execution of an external C function in openmodelica.
Here is the program that I'm trying to implement :
model ChirpSignal
record Rec
Real a1;
Real a2;
Real a3;
Real a4;
Real a5;
end Rec;
function Chirp
output Rec u1;
external Chirp(u1) annotation(Library = "Chirp");
end Chirp;
function mafonction
input Rec u;
output Rec u1;
external u1 = mafonction(u) annotation(Library = "Chirp");
end mafonction;
Rec u1;
Rec u2;
equation
u1 = Chirp();
u2 = mafonction(u1);
end ChirpSignal;
// the C program is :
typedef struct {
double id ;
double id1 ;
double id2;
double id3;
double id4;
}rec;
rec* Chirp(rec* test)
{
test->id = 7;
test->id1 = 6;
test->id2 = 5;
test->id3 = 4;
test->id4 = 15;
}
rec* mafonction(rec test,rec* test1)
{
memcpy ( &test1, &test, sizeof(rec) );
return test1;
}
I'm trying to use the output of the first function (Chirp) as input of the second one (mafonction).
the problem is that the values of u1 are not transmitted in the correct order.
for exemple : for u1 I get :
a1 = 7;
a2 = 6;
a3 = 5;
a4 = 4;
a5 = 15;
I'm expecting to have the same for u2, but I get :
a1 = 15;
a2 = 4;
a3 = 5;
a4 = 6;
a5 = 7;
Do you have any Idea why the values are in the reverse order ?? Is there an other way to implement this correctly ?
Thanks for your help.
Re: External function using output of an other one.
Hi,
Your code is wrong both in the C file and in the .mo file. See the attached zip.
Model.zip
Code:
function mafonction
input Rec u1;
output Rec u2;
// send BOTH u1 and u2 to the external function as that is the way is defined!
external mafonction(u1, u2) annotation(Library = "Chirp", LibraryDirectory="modelica://ChirpSignal");
end mafonction;
Code:
rec* mafonction(rec test, rec* test1)
{
memcpy ( test1, &test, sizeof(rec) ); // no addres of test1, is already a pointer
return test1;
}
Running model.mos gets you:
Code:
adrpo@ida-liu050 ~/dev/OMTesting/forum/1665
$ /f/OpenModelica1.9.3-v1.9.3-dev-523-g1d963ac/bin/omc +locale=C model.mos
true
""
true
0
""
record SimulationResult
resultFile = "c:/bin/cygwin/home/adrpo/dev/OMTesting/forum/1665/ChirpSignal_res.mat",
simulationOptions = "startTime = 0.0, stopTime = 1.0, numberOfIntervals = 500, tolerance = 1e-006, method = 'dassl', fileNamePrefix = 'ChirpSignal', options = '', outputFormat = 'mat', variableFilter = '.*', cflags = '', simflags = ''",
messages = "",
timeFrontend = 0.7343596380537807,
timeBackend = 1.148104848302405,
timeSimCode = 0.006371707033899545,
timeTemplates = 0.03741838078879516,
timeCompile = 3.829548752874621,
timeSimulation = 0.1699746779308428,
timeTotal = 5.926586016890105
end SimulationResult;
""
"u1"
7.0
""
6.0
""
5.0
""
4.0
""
15.0
""
"u2"
7.0
""
6.0
""
5.0
""
4.0
""
15.0
""
Cheers,
Adrian Pop/
- adrpo
- 885 Posts
Re: External function using output of an other one.
Hi Adrian,
First , thank you for your answer.
What you proposed doesn't change anything.
for the error in C code, I totally agree with you. It was just an error while copying the code.
for the OM code :
"external u1 = mafonction(u) annotation(Library = "Chirp");" and "external mafonction(u1, u2) annotation(Library = "Chirp", LibraryDirectory="modelica://ChirpSignal"); " are totally equivalent (at least in this exemple), I still get the same result.
Actually the solution is to declare the first function as impure and pass it as argument of the second one. :
impure function Chirp
output Rec u;
external Chirp(u) annotation(Library = "Chirp1", LibraryDirectory = "modelica://ChirpSignal");
end Chirp;
function mafonction
input Rec u1;
output Rec u2;
external u2 = mafonction(u1) annotation(Library = "Chirp1", LibraryDirectory = "modelica://ChirpSignal");
end mafonction;
Rec u2;
equation
u2 = mafonction(Chirp());
end ChirpSignal;
Try this and tell me what u get (It works just fine).
Anyway, thanks for your Help.
Cheers,
Olaama
Re: External function using output of an other one.
The C code was wrong. you took the address of the pointer when doing memcpy.
And:
Code:
external u1 = mafonction(u) annotation(Library = "Chirp");
is not equivalent to:
Code:
external mafonction(u1, u2) annotation(Library = "Chirp", LibraryDirectory="modelica://ChirpSignal");
are not equivalent!
in the first case we generate u1 = mafonction(u) in the C code and in the second mafonction(u, &u1).
So if your C function is given as having 2 parameters you need to have the second style!
Do a diff of your code and the code in the zip i attached before to see what i changed!
Cheers,
Adrian Pop/
- adrpo
- 885 Posts
Re: External function using output of an other one.
Hi ,
for the C code I said that I totally agree with u (there was a mistake thank u for reminding me).
for the OM code : OK , I thought it was equivalent . but still, even with what u gave me, the result is the same, the values are in the reverse order.
Have u tried what I gave u ? It works !!
Cheers,
Olaama
Re: External function using output of an other one.
It seems I really don't get what you're saying
So, is the problem solved now?
The values are reversed when in the .mo file you have out = f(in) and in the C code you have f(in, out)
I guess because the stack is somehow corrupted when the function expects 2 parameters and gets only one.
- adrpo
- 885 Posts
Re: External function using output of an other one.
Yes, the problem Is solved, the solution is to define the first function in OM like this : "impure function Chirp" instead of "function chirp", and in the equation part you must call it this way
equation
u1 = Chirp();
u2 = mafonction(Chirp());
end ChirpSignal;
//instead of :
/*
u1=Chirp();
u2 = mafonction(u1);
*/
that's it.
Re: External function using output of an other one.
We do evaluate the functions during compilation if they are not declared impure and they have constant inputs.
An alternative is to use +d=nogen,noevalfunc but is better to declare them impure as you did if you don't want them to be evaluated during compile time.
This should not be a problem at all:
Code:
u1=Chirp();
u2 = mafonction(u1);
It does work fine in the zip i attached and not have things in reverse.
- adrpo
- 885 Posts
- Index
- » Usage and Applications
- » OpenModelica Usage and Applications
- » External function using output of an...