
com.velasolaris.plugin.controller.matlab.matconsolectl.MatlabRuntimePluginController Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of polysun-public-plugin Show documentation
Show all versions of polysun-public-plugin Show documentation
Polysun plugin with controllers for Polysun simulations.
The newest version!
package com.velasolaris.plugin.controller.matlab.matconsolectl;
import static com.velasolaris.plugin.controller.spi.PluginControllerConfiguration.DEFAULT_TIMESTEP;
import static com.velasolaris.plugin.util.PluginUtils.*;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import com.velasolaris.plugin.controller.spi.PluginControllerConfiguration;
import com.velasolaris.plugin.controller.spi.PluginControllerConfiguration.ControlSignal;
import com.velasolaris.plugin.controller.spi.PluginControllerConfiguration.Log;
import com.velasolaris.plugin.controller.spi.PluginControllerConfiguration.Property;
import com.velasolaris.plugin.controller.spi.PluginControllerConfiguration.Sensor;
import com.velasolaris.plugin.controller.spi.PluginControllerException;
import com.velasolaris.plugin.painter.MCRPluginControllerPainter;
/**
* Matlab Runtime (MCR) plugin controller.
* This plugin controller allows Matlab control() that have been compiled to a JAR using Matlab's library compiler to be used with Polysun.
* @author MAJ
* @since Polysun 11.1
*/
public class MatlabRuntimePluginController extends AbstractMatlabPluginController {
private static final int CONTROL_SIGNALS_IDX = 0;
private static final int LOG_VALUES_IDX = 1;
private static final int TIME_POINTS_IDX = 2;
private static ClassLoader sPluginClassLoader;
private static Method sControlMethod;
private static Method sGetFloatDataMethod;
private static Method sGetIntDataMethod;
private static Object sMcrPluginControllerInstance;
private static Object sMWNumericArrayInstance;
private String mMcrJavaBuilder = "C:\\Program Files\\MATLAB\\MATLAB Runtime\\v95\\toolbox\\javabuilder\\jar\\javabuilder.jar";
@Override
public String getName() {
return "Matlab MCR";
}
@Override
public String getDescription() {
return "Loads a JAR file 'McrPlugin.jar' generated by the Matlab Library Compiler for use without a Matlab installation. The plugin contains a class 'McrPluginController' "
+ "with the Matlab control() method used with the Matlab Plugin Controller. Requires the Matlab Compiler Runtime (MCR).";
}
@Override
public void initialiseSimulation(Map parameters) throws PluginControllerException {
super.initialiseSimulation(parameters);
try {
if (sPluginClassLoader == null) {
URL pluginUrl = new File(pluginDataPath + System.getProperty("file.separator") + "McrPlugin.jar").toURI().toURL();
JarFile jarFile = new JarFile(mMcrJavaBuilder);
Enumeration e = jarFile.entries();
URL[] urls = { new URL("jar:file:" + mMcrJavaBuilder + "!/"), pluginUrl };
sPluginClassLoader = URLClassLoader.newInstance(urls);
while (e.hasMoreElements()) {
JarEntry je = e.nextElement();
if(je.isDirectory() || !je.getName().endsWith(".class")){
continue;
}
// -6 because of .class
String className = je.getName().substring(0,je.getName().length()-6);
className = className.replace('/', '.');
className = className.replace("$1", "");
try {
sPluginClassLoader.loadClass(className);
} catch (ClassNotFoundException | NoClassDefFoundError ex) {
sLog.warning("Class not found: " + className);
}
}
}
Class> classToLoad = Class.forName("McrPlugin.McrPluginController", true, sPluginClassLoader);
Class>[] params = new Class[2];
params[0] = int.class;
params[1] = Object[].class;
sControlMethod = classToLoad.getDeclaredMethod("control", params);
sMcrPluginControllerInstance = classToLoad.newInstance();
classToLoad = Class.forName("com.mathworks.toolbox.javabuilder.MWNumericArray", true, sPluginClassLoader);
sGetFloatDataMethod = classToLoad.getDeclaredMethod("getFloatData");
sGetIntDataMethod = classToLoad.getDeclaredMethod("getIntData");
sMWNumericArrayInstance = classToLoad.newInstance();
} catch (Throwable t) {
cleanup();
throw new PluginControllerException("Unable to load MCR plugin", t);
}
try {
Object[] args = new Object[] {3, new Object[] { 0, false, new float[sensorsUsed.length], sensorsUsed, matlabPropertiesFloat, matlabPropertiesString, true, controlSignalsUsed, 0, FUNCTION_STAGE_INIT, fixedTimestep, verboseLevel, 0} };
sControlMethod.invoke(sMcrPluginControllerInstance, args);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
cleanup();
throw new PluginControllerException(e);
}
}
@Override
public int[] control(int simulationTime, boolean status, float[] sensors, float[] controlSignals, float[] logValues,
boolean preRun, Map parameters) throws PluginControllerException {
Object[] result;
try {
Object[] args = new Object[] {3, new Object[] {simulationTime, status ? 1.0 : 0.0, sensors, sensorsUsed, matlabPropertiesFloat, matlabPropertiesString, preRun ? 1.0 : 0.0, controlSignalsUsed, logValues.length, FUNCTION_STAGE_SIMULATION, fixedTimestep, verboseLevel, 0 } };
result = (Object[]) sControlMethod.invoke(sMcrPluginControllerInstance, args);
cleanup();
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new PluginControllerException(e);
}
try {
controlSignals = getResultFloat(result[CONTROL_SIGNALS_IDX]);
logValues = getResultFloat(result[LOG_VALUES_IDX]);
return getResultInt(result[TIME_POINTS_IDX]);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
cleanup();
throw new PluginControllerException(e);
}
}
@Override
public void terminateSimulation(Map parameters) {
super.terminateSimulation(parameters);
try {
if (verboseLevel > VERBOSE_LEVEL_STANDARD) {
logPerfMeasure("Overall: ", parameters);
}
Object[] args = new Object[] {3, new Object[] { 0, false, new float[sensorsUsed.length], sensorsUsed, matlabPropertiesFloat, matlabPropertiesString, true, controlSignalsUsed, 0, FUNCTION_STAGE_TERMINATE, fixedTimestep, verboseLevel, 0} };
sControlMethod.invoke(sMcrPluginControllerInstance, args);
} catch (Throwable t) {
cleanup();
sLog.warning(getRootCauseStackTrace(t));
}
cleanup();
}
@Override
public void cleanupOnSimulationException() {
super.cleanupOnSimulationException();
cleanup();
}
@Override
public void cleanupOnSimulationAbort() {
super.cleanupOnSimulationAbort();
cleanup();
}
private void cleanup() {
// Attempt to unload plugin JARs.
sPluginClassLoader = null;
System.gc();
}
private float[] getResultFloat(Object aResult) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
return (float[]) sGetFloatDataMethod.invoke(sMWNumericArrayInstance.getClass().cast(aResult));
}
private int[] getResultInt(Object aResult) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
return (int[]) sGetIntDataMethod.invoke(sMWNumericArrayInstance.getClass().cast(aResult));
}
@Override
public PluginControllerConfiguration getConfiguration(Map parameters) throws PluginControllerException {
setConfiguration(parameters);
Properties config = new Properties();
int defaultNumGenericSensors = 3;
int defaultNumGenericControlSignals = 3;
int defaultNumGenericProperties = 5;
int defaultNumLogValues = 1;
int defaultFixedTimestep = DEFAULT_TIMESTEP;
Integer defaultVerboseLevel = 1;
List printMessage = new ArrayList<>();
File configFile = new File(pluginDataPath + File.separator + "config.properties");
try {
if (configFile.exists()) {
try(FileReader fileReader = new FileReader(configFile);
BufferedReader reader = new BufferedReader(fileReader);) {
config.load(reader);
Object obj;
defaultNumGenericProperties = (obj = config.get("defaultNumGenericProperties")) != null && !"".equals(obj) ? Integer.parseInt(obj.toString()) : defaultNumGenericProperties;
defaultNumGenericSensors = (obj = config.get("defaultNumGenericSensors")) != null && !"".equals(obj) ? Integer.parseInt(obj.toString()) : defaultNumGenericSensors;
defaultNumGenericControlSignals = (obj = config.get("defaultNumGenericControlSignals")) != null && !"".equals(obj) ? Integer.parseInt(obj.toString()) : defaultNumGenericControlSignals;
defaultFixedTimestep = (obj = config.get("defaultFixedTimestep")) != null && !"".equals(obj) ? Integer.parseInt(obj.toString()) : defaultFixedTimestep;
defaultNumLogValues = (obj = config.get("defaultNumLogValues")) != null && !"".equals(obj) ? Integer.parseInt(obj.toString()) : defaultNumLogValues;
defaultVerboseLevel = (obj = config.get("defaultVerboseLevel")) != null && !"".equals(obj) ? Integer.parseInt(obj.toString()) : defaultVerboseLevel;
mMcrJavaBuilder = (obj = config.get("mcr.javabuilder.location")) != null && !"".equals(obj) ? obj.toString() : null;
sLog.info("Config.properties read: " + configFile);
} catch (IOException e) {
sLog.warning(getRootCauseStackTrace(e));
}
} else {
new File(pluginDataPath).mkdirs();
try (FileWriter fileWriter = new FileWriter(configFile);
BufferedWriter writer = new BufferedWriter(fileWriter)) {
config.put("defaultNumGenericProperties", "" + defaultNumGenericProperties);
config.put("defaultNumGenericSensors", "" + defaultNumGenericSensors);
config.put("defaultNumGenericControlSignals", "" + defaultNumGenericControlSignals);
config.put("defaultNumLogValues", "" + defaultNumLogValues);
config.put("defaultFixedTimestep", "" + defaultFixedTimestep);
config.put("defaultVerboseLevel", "" + defaultVerboseLevel);
config.put("mcr.javabuilder.location", mMcrJavaBuilder != null ? mMcrJavaBuilder : "");
config.store(writer, "Properties of the Polysun MatlabPluginController + [" + getId() + "]");
sLog.info("Config file written: " + configFile);
} catch(IOException e) {
sLog.warning(getRootCauseStackTrace(e));
}
}
} catch (Exception e) {
sLog.warning(getRootCauseStackTrace(e));
}
List properties = new ArrayList<>();
properties.add(new Property(PROPERTY_FIXED_TIMESTEP, defaultFixedTimestep, 0f, 900, "s"));
properties.add(new Property(PROPERTY_NUM_GENERIC_SENSORS, defaultNumGenericSensors, 0, 100));
properties.add(new Property(PROPERTY_NUM_GENERIC_CONTROL_SIGNALS, defaultNumGenericControlSignals, 0, 100));
properties.add(new Property(PROPERTY_NUM_GENERIC_LOGS, defaultNumLogValues, 0, 100));
properties.add(new Property(PROPERTY_VERBOSE_LEVEL, new String[] { "Standard", "Verbose", "Debug" }, defaultVerboseLevel));
numInternProperties = properties.size();
List sensors = new ArrayList<>();
List controlSignals = new ArrayList<>();
List logs = new ArrayList<>();
parameters.put("Plugin.PrintMessage", printMessage);
PluginControllerConfiguration.Builder builder = new PluginControllerConfiguration.Builder();
builder.setProperties(properties);
builder.setSensors(sensors);
builder.setControlSignals(controlSignals);
builder.setLogs(logs);
builder.setNumGenericProperties(defaultNumGenericProperties);
builder.setNumGenericSensors(defaultNumGenericSensors);
builder.setNumGenericControlSignals(defaultNumGenericControlSignals);
builder.setPropertyNameNumGenericSensors(PROPERTY_NUM_GENERIC_SENSORS);
builder.setPropertyNameNumGenericControlSignals(PROPERTY_NUM_GENERIC_CONTROL_SIGNALS);
builder.setPropertyNameNumGenericLogs(PROPERTY_NUM_GENERIC_LOGS);
builder.setImagePainter(new MCRPluginControllerPainter());
return builder.build();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy