Background
I am learning Modelica lang and following Modelica By Example, page by page, and have arrived at interpolation. The software-in-the-loop page has a similar approach, using C scripts in Modelica: SITL.
I am using OpenModelica Connection Editor to run the MBE scripts, which are written in VS Code (I'm open to other approaches). However, I am struggling to interface the two languages, in both situations.
Here are my SITL scripts, as per MBE:
Model
model HysteresisEmbeddedControl "A control strategy that uses embedded C code"
type HeatCapacitance=Real(unit="J/K");
type Temperature=Real(unit="K");
type Heat=Real(unit="W");
type Mass=Real(unit="kg");
type HeatTransferCoefficient=Real(unit="W/K");
parameter HeatCapacitance C=1.0;
parameter HeatTransferCoefficient h=2.0;
parameter Heat Qcapacity=25.0;
parameter Temperature Tamb=285;
parameter Temperature Tbar=295;
Temperature T;
Heat Q;
initial equation
T = Tbar+5;
equation
when sample(0, 0.01) then
Q = computeHeat(T, Tbar, Qcapacity);
end when;
C*der(T) = Q-h*(T-Tamb);
end HysteresisEmbeddedControl;
Function
impure function computeHeat "Modelica wrapper for an embedded C controller"
input Real T;
input Real Tbar;
input Real Q;
output Real heat;
external "C" annotation (Include="#include \"ComputeHeat.c\"",
IncludeDirectory="C:\dev\OpenModelica\modelica_by_example\working_with_C\SITL\ComputeHeat.c");
end computeHeat;
C Script
#ifndef _COMPUTE_HEAT_C_
#define _COMPUTE_HEAT_C_
#define UNINITIALIZED -1
#define ON 1
#define OFF 0
double
computeHeat(double T, double Tbar, double Q) {
static int state = UNINITIALIZED;
if (state==UNINITIALIZED) {
if (T>Tbar) state = OFF;
else state = ON;
}
if (state==OFF && T<Tbar-2) state = ON;
if (state==ON && T>Tbar+2) state = OFF;
if (state==ON) return Q;
else return 0;
}
#endif
Error
In file included from HysteresisEmbeddedControl_functions.c:7:
./HysteresisEmbeddedControl_includes.h:7:10: fatal error: 'ComputeHeat.c' file not found
#include "ComputeHeat.c"
^~~~~~~~~~~~~~~
1 error generated.
mingw32-make: *** [<builtin>: HysteresisEmbeddedControl_functions.o] Error 1
mingw32-make: *** Waiting for unfinished jobs....
mingw32-make: Leaving directory 'C:/Users/szuddas/AppData/Local/Temp/OPENMO~1/OMEdit/HYSTER~2'
Compilation process failed. Exited with code 0x00000002.
My Assumptions
I believe the problem is to do with paths of the scripts, and I probably need to better set up my modelica dev environment. I've used some C before but only covered the basics, and that was a few years ago. However, I don't believe this problem originates from the C code, more likely where the scripts are vs where they should be. Open to suggestions on all these fronts.
Where I was going wrong
The MBE book assumes you're using the MBE library, installed within OpenModelica itself. I was writing my own scripts, rather than running the scripts made in the library. In the MBE library, the C script was being called from a subdirectory where the Modelica script itself was located. When using the MBE library itself, it worked!
Where I'm still stuck
Despite getting the script working, I'm stuck with calling the C script. I've adjusted the \ and called both of the following:
IncludeDirectory="C:\dev\OpenModelica\modelica_by_example\working_with_C\SITL\ComputeHeat.c");
and
IncludeDirectory="C:\dev\OpenModelica\modelica_by_example\working_with_C\SITL");
I still do not understand why it's not being called in my script which is not part of the MBE library, considering I'm giving it the direct path.