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

org.javafmi.proxy.v21.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.v21;

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.FmiProxyV21;
import org.javafmi.proxy.FmuProxyState;
import org.javafmi.proxy.MethodExecutionException;
import org.javafmi.proxy.Status;
import org.javafmi.proxy.v2.State;

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

public class FmuProxy implements FmiProxyV21 {

	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,
				false);
		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 RealsAtEvent getRealsAtEvent(double communicationPoint, int... valueReference) {
		double[] beforeEvent = getReal(valueReference);
		boolean occurredEvent = hybridDoStep(communicationPoint, 0).isOccurredEvent();
		double[] afterEvent = getReal(valueReference);
		return new RealsAtEvent(occurredEvent, beforeEvent, afterEvent);
	}

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

	@Override
	public IntegersAtEvent getIntegersAtEvent(double communicationPoint, int... valueReference) {
		int[] beforeEvent = getInteger(valueReference);
		boolean occurredEvent = hybridDoStep(communicationPoint, 0).isOccurredEvent();
		int[] afterEvent = getInteger(valueReference);
		return new IntegersAtEvent(occurredEvent, beforeEvent, afterEvent);
	}

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

	@Override
	public BooleansAtEvent getBooleansAtEvent(double communicationPoint, int... valueReference) {
		boolean[] beforeEvent = getBoolean(valueReference);
		boolean occurredEvent = hybridDoStep(communicationPoint, 0).isOccurredEvent();
		boolean[] afterEvent = getBoolean(valueReference);
		return new BooleansAtEvent(occurredEvent, beforeEvent, afterEvent);
	}

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

	@Override
	public StringsAtEvent getStringsAtEvent(double communicationPoint, int... valueReference) {
		String[] beforeEvent = getString(valueReference);
		boolean occurredEvent = hybridDoStep(communicationPoint, 0).isOccurredEvent();
		String[] afterEvent = getString(valueReference);
		return new StringsAtEvent(occurredEvent, beforeEvent, afterEvent);
	}

	@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 double getNextEventTime() {
		return library.getNextEventTime();
	}

	@Override
	public Status newDiscreteStates(EventInfo info) {
		return Status.translateStatus(library.newDiscreteStates(info));
	}

	@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 HybridDoStepStatus hybridDoStep(double communicationPoint, double stepSize) {
		Object[] results = library.hybridDoStep(communicationPoint, stepSize, false);
		return new HybridDoStepStatus(Status.translateStatus((int) results[0]), ((int) results[1]) == 1, (double) results[2]);
	}

	@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