org.javafmi.proxy.v21.Fmu Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fmu-wrapper Show documentation
Show all versions of fmu-wrapper Show documentation
javaFMI is a Java Library for the functional mock-up interface (or FMI). FMI defines a standardized interface to be used in computer simulations. The FMI Standard has beed developed by a large number of software companies and research centers that have worked in a cooperation project under the name of MODELISAR. This library addresses the connection of a java application with a FMU (functional mock-up unit).
/*
* Copyright 2013-2016 SIANI - ULPGC
*
* This File is part of JavaFMI Project
*
* JavaFMI Project is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License.
*
* JavaFMI Project is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with JavaFMI. If not, see .
*/
package org.javafmi.proxy.v21;
import com.sun.jna.*;
import com.sun.jna.ptr.PointerByReference;
import org.javafmi.kernel.OS;
import org.javafmi.proxy.FmiProxyV21;
import org.javafmi.proxy.MethodExecutionException;
import org.javafmi.proxy.NativeBoolean;
import org.javafmi.proxy.Status;
import java.util.HashMap;
import java.util.Map;
public class Fmu {
private final NativeLibrary instance;
private final Map functions;
private Pointer component;
private String[] functionNames = {"Instantiate", "FreeInstance", "SetDebugLogging", "SetupExperiment", "EnterInitializationMode", "ExitInitializationMode", "Terminate", "Reset", "GetReal",
"GetInteger", "GetBoolean", "GetString", "SetReal", "SetInteger", "SetBoolean", "SetString", "GetNextEventTime", "GetFMUstate", "SetFMUstate", "FreeFMUstate", "SerializedFMUstateSize",
"SerializeFMUstate", "DeSerializeFMUstate", "NewDiscreteStates", "GetDirectionalDerivative", "SetRealInputDerivatives", "GetRealOutputDerivatives", "DoStep", "HybridDoStep", "CancelStep",
"GetStatus", "GetRealStatus", "GetIntegerStatus", "GetBooleanStatus", "GetStringStatus"};
public Fmu(String libraryPath, String generationTool) {
instance = getInstance(libraryPath, generationTool);
functions = loadFmiFunctions(instance);
}
private NativeLibrary getInstance(String libraryPath, String generationTool) {
int RTLD_NOW = 0x00002, RTLD_DEEPBIND = 0x00008;
Map options = new HashMap<>();
if (OS.isLinux32() || OS.isLinux64()) options.put(Library.OPTION_OPEN_FLAGS, RTLD_NOW | RTLD_DEEPBIND);
return NativeLibrary.getInstance(libraryPath, options);
}
private Map loadFmiFunctions(NativeLibrary instance) {
Map result = new HashMap<>();
for (String functionName : functionNames)
try {
result.put(functionName, instance.getFunction(fmi21(functionName)));
} catch (UnsatisfiedLinkError e) {
System.err.println("This FMU is not fully FMI V2.1 hybrid compliant, function not found: " + fmi21(functionName));
}
return result;
}
public void instantiate(String modelName, int fmiType, String guID, String resourcesLocation, CallbackFunctions callbacks, boolean visible, boolean loggingOn) {
component = invoke("Instantiate")
.with(modelName, fmiType, guID, resourcesLocation, callbacks, visible, loggingOn).asPointer();
if (component == null)
throw new MethodExecutionException("Impossible to instantiate " + modelName + " fmi2Instantiate returns null");
}
public void free() {
invoke("FreeInstance").with(component).asVoid();
instance.dispose();
}
public int setDebugLogging(boolean loggingOn, String... categories) {
return invoke("SetDebugLogging").with(component, loggingOn, categories.length, categories).asInt();
}
public int setUpExperiment(boolean toleranceDefined, double tolerance, double startTime, boolean stopTimeDefined, double stopTime) {
return invoke("SetupExperiment").with(component, toleranceDefined, tolerance, startTime, stopTimeDefined, stopTime).asInt();
}
public int enterInitializationMode() {
return invoke("EnterInitializationMode").with(component).asInt();
}
public int exitInitializationMode() {
return invoke("ExitInitializationMode").with(component).asInt();
}
public int terminate() {
return invoke("Terminate").with(component).asInt();
}
public int reset() {
return invoke("Reset").with(component).asInt();
}
public double[] getReal(int... valueReferences) {
double[] doubleValues = new double[valueReferences.length];
int status = invoke("GetReal").with(component, valueReferences, valueReferences.length, doubleValues).asInt();
if (Status.translateStatus(status) != Status.OK)
throw new RuntimeException("There was an error getting a variable inside the FMU");
return doubleValues;
}
public int[] getInteger(int... valueReferences) {
int[] integerValues = new int[valueReferences.length];
int status = invoke("GetInteger").with(component, valueReferences, valueReferences.length, integerValues).asInt();
if (Status.translateStatus(status) != Status.OK)
throw new RuntimeException("There was an error getting a variable inside the FMU");
return integerValues;
}
public boolean[] getBoolean(int... valueReferences) {
int[] booleanValues = new int[valueReferences.length];
int status = invoke("GetBoolean").with(component, valueReferences, valueReferences.length, booleanValues).asInt();
if (Status.translateStatus(status) != Status.OK)
throw new RuntimeException("There was an error getting a variable inside the FMU");
boolean[] result = new boolean[booleanValues.length];
for (int i = 0; i < result.length; i++) {
result[i] = NativeBoolean.getBooleanFor((byte) booleanValues[i]);
}
return result;
}
public String[] getString(int... valueReferences) {
String[] stringValues = new String[valueReferences.length];
int status = invoke("GetString").with(component, valueReferences, valueReferences.length, stringValues).asInt();
if (Status.translateStatus(status) != Status.OK)
throw new RuntimeException("There was an error getting a variable inside the FMU");
return stringValues;
}
public int setReal(int[] valueReferences, double[] values) {
return invoke("SetReal").with(component, valueReferences, valueReferences.length, values).asInt();
}
public int setInteger(int[] valueReferences, int[] intValues) {
return invoke("SetInteger").with(component, valueReferences, valueReferences.length, intValues).asInt();
}
public int setBoolean(int[] valueReferences, boolean[] booleanValues) {
int[] booleanAsIntegers = new int[booleanValues.length];
for (int i = 0; i < booleanAsIntegers.length; i++) {
booleanAsIntegers[i] = NativeBoolean.getValueFor(booleanValues[i]);
}
return invoke("SetBoolean").with(component, valueReferences, valueReferences.length, booleanAsIntegers).asInt();
}
public int setString(int[] valueReferences, String[] stringValues) {
return invoke("SetString").with(component, valueReferences, valueReferences.length, stringValues).asInt();
}
public double getNextEventTime() {
Memory memory = new Memory(Pointer.SIZE);
invoke("GetNextEventTime").with(component, memory).asInt();
double result = memory.getDouble(0);
memory.clear();
return result;
}
public Pointer getFmuState(Pointer state) {
PointerByReference pointerByReference = new PointerByReference(state);
invoke("GetFMUstate").with(component, pointerByReference).asInt();
return pointerByReference.getValue();
}
public int setFmuState(Pointer pointer) {
return invoke("SetFMUstate").with(component, pointer).asInt();
}
public int freeFmuState(Pointer state) {
return invoke("FreeFMUstate").with(component, new PointerByReference(state)).asInt();
}
public int serializedFmuStateSize(Pointer state) {
Memory memory = new Memory(Pointer.SIZE);
invoke("SerializedFMUstateSize").with(component, state, memory).asInt();
return memory.getInt(0);
}
public byte[] serializeFmuState(Pointer state) {
int size = serializedFmuStateSize(state);
byte[] byteBuffer = new byte[size];
invoke("SerializeFMUstate").with(component, state, byteBuffer, size).asInt();
return byteBuffer;
}
public Pointer deSerializeFMUState(byte[] serializedState) {
PointerByReference pointerByReference = new PointerByReference(new Memory(Pointer.SIZE));
invoke("DeSerializeFMUstate").with(component, serializedState, serializedState.length, pointerByReference).asInt();
return pointerByReference.getValue();
}
public double[] getDirectionalDerivative(int[] unknownValueReferences, int[] knownValueReferences, double[] knownDifferential) {
double[] sharedDoubles = new double[knownDifferential.length];
invoke("GetDirectionalDerivative").with(component, unknownValueReferences, unknownValueReferences.length, knownValueReferences, knownValueReferences.length, knownDifferential, sharedDoubles).asInt();
return sharedDoubles;
}
public int setRealInputDerivatives(int[] valueReferences, int[] orders, double[] values) {
return invoke("SetRealInputDerivatives").with(component, valueReferences, valueReferences.length, orders, values).asInt();
}
public double[] getRealOutputDerivatives(int[] valueReferences, int[] orders) {
double[] values = new double[valueReferences.length];
invoke("GetRealOutputDerivatives").with(component, valueReferences, valueReferences.length, orders, values).asInt();
return values;
}
public int doStep(double currentSimulationTime, double stepSize, boolean noSetFmuStatePriorToCurrentPoint) {
return invoke("DoStep").with(component, currentSimulationTime, stepSize, noSetFmuStatePriorToCurrentPoint).asInt();
}
public Object[] hybridDoStep(double currentSimulationTime, double stepSize, boolean noSetFmuStatePriorToCurrentPoint) {
Memory eventOccurred = new Memory(Pointer.SIZE);
Memory endTime = new Memory(Pointer.SIZE);
int status = invoke("HybridDoStep").with(component, currentSimulationTime, stepSize, noSetFmuStatePriorToCurrentPoint, eventOccurred, endTime).asInt();
int eventOccurredValue = eventOccurred.getInt(0);
double endTimeValue = endTime.getDouble(0);
eventOccurred.clear();
endTime.clear();
return new Object[]{status, eventOccurredValue, endTimeValue};
}
public int newDiscreteStates(FmiProxyV21.EventInfo info) {
return invoke("NewDiscreteStates").with(component, info).asInt();
}
public int cancelStep() {
return invoke("CancelStep").with(component).asInt();
}
public int getStatus(int statusKind) {
Memory status = new Memory(Pointer.SIZE);
invoke("GetStatus").with(component, statusKind, status).asInt();
return status.getInt(0);
}
public double getRealStatus(int statusKind) {
double[] realStatus = new double[1];
invoke("GetRealStatus").with(component, statusKind, realStatus).asInt();
return realStatus[0];
}
public int getIntegerStatus(int statusKind) {
Memory integerStatus = new Memory(Pointer.SIZE);
invoke("GetIntegerStatus").with(component, statusKind, integerStatus).asInt();
return integerStatus.getInt(0);
}
public boolean getBooleanStatus(int statusKind) {
Memory booleanStatus = new Memory(Pointer.SIZE);
invoke("GetBooleanStatus").with(component, statusKind, booleanStatus).asInt();
return booleanStatus.getInt(0) == 1;
}
public String getStringStatus(int statusKind) {
PointerByReference stringStatus = new PointerByReference(new Memory(Pointer.SIZE));
invoke("GetStringStatus").with(component, statusKind, stringStatus).asInt();
return stringStatus.getValue().getString(0);
}
private Invocation invoke(final String name) {
return args -> new Invocation.Result() {
@Override
public Pointer asPointer() {
return (Pointer) function(name).invoke(Pointer.class, args);
}
@Override
public int asInt() {
return function(name).invokeInt(args);
}
@Override
public void asVoid() {
function(name).invoke(args);
}
};
}
private Function function(String name) {
return functions.get(name);
}
private String fmi21(String name) {
return "fmi2" + name;
}
private interface Invocation {
Result with(Object... args);
interface Result {
public Pointer asPointer();
public int asInt();
public void asVoid();
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy