All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.javafmi.proxy.v2.FmuProxy Maven / Gradle / Ivy

Go to download

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).

There is a newer version: 2.26.5
Show newest version
/*
 *  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.v2;

import org.javafmi.modeldescription.FmiVersion;
import org.javafmi.modeldescription.ScalarVariable;
import org.javafmi.modeldescription.v2.Capabilities;
import org.javafmi.modeldescription.v2.EnumerationType;
import org.javafmi.modeldescription.v2.ModelDescription;
import org.javafmi.proxy.*;

import static java.lang.System.currentTimeMillis;
import static org.javafmi.modeldescription.v2.Capabilities.Capability;
import static org.javafmi.proxy.Status.*;

public class FmuProxy implements FmiProxyV2 {

    private final Fmu library;
    private final ModelDescription modelDescription;
    private final CallbackFunctions callbacks;
    private FmuProxyState fmuProxyState;

    public FmuProxy(Fmu library, ModelDescription modelDescription) {
        if (!hasCoSimulationSupport(modelDescription))
            throw new RuntimeException("This Fmu does not support co-simulation execution");
        this.library = library;
        this.modelDescription = modelDescription;
        this.callbacks = createCallbacks();
    }

    private boolean hasCoSimulationSupport(ModelDescription modelDescription) {
        return modelDescription.getCoSimulation() != null;
    }

    private CallbackFunctions createCallbacks() {
        return checkCanRunAsynchronously(new CallbackFunctions());
    }

    private CallbackFunctions checkCanRunAsynchronously(CallbackFunctions callbackFunctions) {
        if (!modelDescription.check(Capabilities.CanRunAsynchronously))
            callbackFunctions.stepFinished = null;
        return callbackFunctions;
    }

    @Override
    public String getVersion() {
        return FmiVersion.Two;
    }

    @Override
    public void instantiate(String resourcesPath) {
        this.library.instantiate(
                uniqueInstanceName(),
                Callbacks.FmiType.fmiCoSimulation,
                modelDescription.getGuid(),
                "file:///" + resourcesPath.replace("\\","/"),
                callbacks,
                false,
                true);
        this.fmuProxyState = FmuProxyState.INSTANTIATED;
    }

    private String uniqueInstanceName() {
        return currentTimeMillis() + "_" + modelDescription.getModelName();
    }

    @Override
    public void freeInstance() {
        library.free();
    }

    @Override
    public Status setDebugLogging(boolean loggingOn, String[] categories) {
        return Status.translateStatus(library.setDebugLogging(loggingOn, categories));
    }

    @Override
    public Status initialize(double startTime, double stopTime) {
        if (fmuProxyState.equals(FmuProxyState.INITED)) return WARNING;
		if (ERROR == setUpExperiment(true, modelDescription.getDefaultExperiment().getTolerance(), startTime, !Double.isNaN(stopTime), Double.isNaN(stopTime) ? Double.MAX_VALUE : stopTime))
            throw new MethodExecutionException("fmi2SetupExperiment: " + modelDescription.getModelIdentifier());
        if (ERROR == enterInitializationMode())
            throw new MethodExecutionException("fmi2SetupExperiment: " + modelDescription.getModelIdentifier());
        if (ERROR == exitInitializationMode())
            throw new MethodExecutionException("fmi2SetupExperiment: " + modelDescription.getModelIdentifier());
        return OK;
    }

    @Override
    public Status setUpExperiment(boolean toleranceDefined, double tolerance, double startTime, boolean stopTimeDefined, double stopTime) {
        return Status.translateStatus(library.setUpExperiment(toleranceDefined, tolerance, startTime, stopTimeDefined, stopTime));
    }

    @Override
    public Status enterInitializationMode() {
        Status enterInitStatus = Status.translateStatus(library.enterInitializationMode());
        if (enterInitStatus.equals(OK)) fmuProxyState = FmuProxyState.INITTING;
        return enterInitStatus;
    }

    @Override
    public Status exitInitializationMode() {
        Status exitInitStatus = Status.translateStatus(library.exitInitializationMode());
        if (exitInitStatus == OK) fmuProxyState = FmuProxyState.INITED;
        return exitInitStatus;
    }

    @Override
    public Status terminate() {
        Status terminateStatus = Status.translateStatus(library.terminate());
        if (terminateStatus.equals(OK)) fmuProxyState = FmuProxyState.TERMINATED;
        else fmuProxyState = FmuProxyState.INITED;
        return terminateStatus;
    }

    @Override
    public Status reset() {
        Status resetStatus = Status.translateStatus(library.reset());
        if (resetStatus.equals(Status.OK)) fmuProxyState = FmuProxyState.INSTANTIATED;
        return resetStatus;
    }

    @Override
    public ModelDescription getModelDescription() {
        return modelDescription;
    }

    @Override
    public Status setRealInputDerivatives(int[] valueReferences, int[] orders, double[] values) {
        return Status.translateStatus(library.setRealInputDerivatives(valueReferences, orders, values));
    }

    @Override
    public double[] getRealOutputDerivatives(int[] valueReferences, int[] orders) {
        return library.getRealOutputDerivatives(valueReferences, orders);
    }

    @Override
    public double[] getReal(int... valueReference) {
        return library.getReal(valueReference);
    }

    @Override
    public int[] getInteger(int... valueReference) {
        return library.getInteger(valueReference);
    }

    @Override
    public boolean[] getBoolean(int... valueReference) {
        return library.getBoolean(valueReference);
    }

    @Override
    public String[] getString(int... valueReference) {
        return library.getString(valueReference);
    }

    @Override
    public Object getEnumeration(ScalarVariable modelVariable) {
        EnumerationType enumeration = (EnumerationType) modelVariable.getType();
        Integer enumerationIndex;
        EnumerationType enumerationType = (EnumerationType) modelDescription.getTypeFromTypeDefinition(enumeration.getDeclaredType());
        if (modelVariable.getVariability().equalsIgnoreCase("constant")) {
            enumerationIndex = enumeration.getStart();
            return enumerationType.getItems().get(enumerationIndex - 1).getName();
        }
        enumerationIndex = getInteger(modelVariable.getValueReference())[0];
        return enumerationType.getItems().get(enumerationIndex - 1).getName();
    }

    @Override
    public Status setReal(int[] valueReferences, double[] doubleValues) {
        return Status.translateStatus(library.setReal(valueReferences, doubleValues));
    }

    @Override
    public Status setInteger(int[] valueReference, int[] intValue) {
        return Status.translateStatus(library.setInteger(valueReference, intValue));
    }

    @Override
    public Status setBoolean(int[] valueReference, boolean[] booleanValue) {
        return Status.translateStatus(library.setBoolean(valueReference, booleanValue));
    }

    @Override
    public Status setString(int[] valueReference, String[] stringValue) {
        return Status.translateStatus(library.setString(valueReference, stringValue));
    }

    @Override
    public State getState(State state) {
        checkCapability("getState", Capabilities.CanGetAndSetFmuState);
        return state.SetPointer(library.getFmuState(state.GetPointer()));
    }

    @Override
    public Status setState(State state) {
        checkCapability("setState", Capabilities.CanGetAndSetFmuState);
        return Status.translateStatus(library.setFmuState(state.GetPointer()));
    }

    @Override
    public Status freeState(State state) {
        checkCapability("freeState", Capabilities.CanGetAndSetFmuState);
        return Status.translateStatus(library.freeFmuState(state.GetPointer()));
    }

    @Override
    public int getStateSize(State state) {
        checkCapability("getStateSize", Capabilities.CanGetAndSetFmuState, Capabilities.CanSerializeFmuState);
        return library.serializedFmuStateSize(state.GetPointer());
    }

    @Override
    public byte[] serializeState(State state) {
        checkCapability("serializeState", Capabilities.CanGetAndSetFmuState, Capabilities.CanSerializeFmuState);
        return library.serializeFmuState(state.GetPointer());
    }

    @Override
    public State deserializeState(byte[] serializedState) {
        checkCapability("deserializeState", Capabilities.CanGetAndSetFmuState, Capabilities.CanSerializeFmuState);
        return State.newStateFrom(library.deSerializeFMUState(serializedState));
    }

    @Override
    public void checkCapability(String method, Capability... capabilitiesToCheck) {
        for (Capability capability : capabilitiesToCheck)
            if (!modelDescription.check(capability))
                throw new UnsupportedOperationException(method + " " + modelDescription.getModelIdentifier());
    }

    @Override
    public double[] getDirectionalDerivative(int[] unknownVariablesValueReferences, int[] knownVariablesValueReferences, double[] knownDifferential) {
        if (!modelDescription.check(Capabilities.ProvidesDirectionalDerivatives))
            throw new UnsupportedOperationException("getDirectionalDerivative: " + modelDescription.getModelIdentifier());
        return library.getDirectionalDerivative(unknownVariablesValueReferences, knownVariablesValueReferences, knownDifferential);
    }

    @Override
    public Status doStep(double communicationPoint, double stepSize) {
        return Status.translateStatus(library.doStep(communicationPoint, stepSize, false));
    }

    @Override
    public Status cancelStep() {
        return Status.translateStatus(library.cancelStep());
    }

    @Override
    public boolean isTerminated() {
        return fmuProxyState.equals(FmuProxyState.TERMINATED);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy