Marine systems simulation
Integrate FhSim in own applications

This tutorial explains how integrate a FhSim simulation into your own application.

The FhSim model specification

The model can be specified either by an input file or as an input string. The latter is often the preferred choice when calling from another application. To be able to interact with FhSim from "outside", at least one SimObject of the type ExternalLink must be present. This specifies the interface between the simulation and the outside. A simple example is shown below.

<Contents>
<OBJECTS>
<Lib
LibName="fhsim_base"
SimObject="System/ExternalLinkStandard"
Name="ExtLink"
outputPortNames="out1"
Initial_out1="0,0,1"
inputPortNames="in1"
Size_in1="3"
Initial_in1="2,2,2"
/>
<Lib
LibName="fhsim_base"
SimObject="Body/Mass"
Name="M"
Scale="1"
Mass="1"
/>
</OBJECTS>
<INTERCONNECTIONS>
<Connection
ExtLink.in1="M.Pos"
M.Force="ExtLink.out1"
/>
</INTERCONNECTIONS>
<INITIALIZATION>
<InitialCondition
M.Pos="1,1,1"
M.Vel="0,0,0"
/>
</INITIALIZATION>
<INTEGRATION>
<Engine
IntegratorMethod="2"
NumCores="1"
TOutput="0, 0,1,2, 30"
LogStates ="1"
stepsize ="0"
HMax="0.002"
HMin="0.00000001"
AbsTol="1e-3" RelTol="1e-3"
UseRSSNormInsteadOfInfNorm="0"
FileOutput="objects:all"
/>
</INTEGRATION>
</Contents>

Calling FhSim from your application

From C++

From C++ it is easiest to use the library fhSimDllLib.lib or fhVisDllLib.lib depending on if you want visualization or not. From your source code, (in a simplified example), do:

#include <CFhSimDll.h>
CFhSimDll simulation("path/to/fhsim.dll");
simulation.InitFromString(modelstring-xml, "out/results.csv", "out/log.txt", fileLoglevel, displayLoglevel);
double deltaSimTime = 0.1;
double maxDeltaRealTime = 0.1;
for(int i = 0; i < 1000; ++i) {
bool ok = simulation.Simulate(deltaSimTime, maxDeltaRealTime);
if(!ok)
throw std::runtime_exception("Error in simulation at time " + dbl2str(deltaSimTime*i));
const double* output1 = simulation.GetOutput("ExtLink", "out1");
const double input1[3] = {1,2,3};
SetInput("ExtLink", "in1", input1);
std::cout << "Input port: " << input1[0] << " " << input1[1] << " " << input1[2] << std::endl;
std::cout << "Output port: " << output1[0] << " " << output1[1] << " " << output1[2] << std::endl;
}
simulation.StopSim();

This example only shows a very simple use case. For reference, the complete public API of CFhSimDll is:

CFhSimDll(std::string sPath);
~CFhSimDll(void);
bool InitFromFile(std::string sModelFile,
std::string sResultsFile,
std::string sLogFile,
int iFileLogLevel,
int iDisplayLogLevel);
bool InitFromString(std::string sModelString,
std::string sResultsFile,
std::string sLogFile,
int iFileLogLevel,
int iDisplayLogLevel);
bool Simulate(double dDeltaSimTime, double dMaxDeltaRealTime);
const double* GetOutput(std::string objectName, std::string portName);
int GetOutputSize(const std::string objectName,const std::string portName);
bool SetInput(std::string objectName, std::string portName, const double* portValues);
bool SetInputCopy(std::string objectName, std::string portName, const double* portValues);
int GetInputSize (const std::string objectName,const std::string portName);
bool GetErrorString(std::string *psError);
bool StopSim();
double GetStates(double** padStates);
int GetNumStates();
void GetStateObjects(char*** const paacStateObjects);
void GetStateTags(char*** const paacStateTags);
CFhSimMgr* GetSimMgr();
void* GetObjectPtr(std::string sPtrName);
void SetObjectPtr(std::string sPtrName, void* pObj);