Commit dfc706d9 authored by Simon Barner's avatar Simon Barner
Browse files

Merge branch '3847' into 'master'

3847: Co-Simulation in binary product

See merge request af3/af3!255
parents 04db574e b30366bc
CCodeGeneratorEasyStartMenu.java aee60ea30cbe51832305ffd448cabc4fafab4452 GREEN
CGeneratorExecutionTarget.java 270fd30aaa67a294fd2bf4585044b46a54ee907f GREEN
FMUGeneratorEasyStartMenu.java 88f2027a0f456ab5d2333ef701af13c5dd1c081d GREEN
FMUGeneratorExecutionTarget.java 0791801a5215ea8627b1c9b993c5d2d0a0bf1042 GREEN
FMUGeneratorEasyStartMenu.java 4c2ae30d89d32bb045affa580c052db467c3d35d GREEN
FMUGeneratorExecutionTarget.java 5f9d46042f23a92e0775bdca5ebb3c99b735ee40 GREEN
JavaCodeGeneratorEasyStartMenu.java 08a5ef75fe3ff45840c1cf9e705cb226a1232efb GREEN
JavaGeneratorExecutionTarget.java dba521d1b700365c0522b7c70e49653fcced66cb GREEN
......@@ -81,10 +81,14 @@ public class FMUGeneratorEasyStartMenu extends EasyStartMenuBase {
"The FMU generator failed. Please check if your model is free of error markers and every component has a defined behavior. Please consult the error log for detailed error information.";
Throwable lastException = e;
while(lastException.getCause() != null) {
while(lastException.getCause() != null && lastException.getCause().getMessage() != null) {
lastException = lastException.getCause();
}
return str + "\n\nDetailed errors:\n" + lastException.getMessage();
str += "\n\nDetailed errors:\n";
if(lastException != e) {
return str + lastException.getMessage();
}
return str + e.toString();
}
}
......@@ -15,18 +15,23 @@
+--------------------------------------------------------------------------*/
package org.fortiss.af3.component.ui.generator;
import static java.lang.Double.parseDouble;
import static java.lang.System.lineSeparator;
import static java.nio.file.Files.createTempDirectory;
import static org.apache.commons.io.FileUtils.deleteDirectory;
import static org.apache.commons.lang.ArrayUtils.addAll;
import static org.eclipse.core.runtime.FileLocator.resolve;
import static org.eclipse.jface.dialogs.MessageDialog.openInformation;
import static org.eclipse.ui.PlatformUI.getWorkbench;
import static org.fortiss.af3.component.ui.utils.GeneratorUtils.checkArchitecture;
import static org.fortiss.af3.expression.utils.DataDictionaryUtils.findDataDictionary;
import static org.fortiss.af3.generator.common.textgen.c.FMUModelDescriptionTextGenerator.fmuArchiveToXML;
import static org.fortiss.af3.generator.common.textgen.c.FMUTopCEntryTextGenerator.fmuArchiveToTopCEntry;
import static org.fortiss.af3.project.ui.utils.FolderOrProjectDialogUtils.openFolderDialog;
import static org.fortiss.af3.project.utils.FileUtils.getAF3EclipseProject;
import static org.fortiss.tooling.base.utils.SystemUtils.isMacOSXPlatform;
import static org.fortiss.tooling.base.utils.SystemUtils.isOs64BitArch;
import static org.fortiss.tooling.base.utils.SystemUtils.isWindowsPlatform;
import static org.fortiss.tooling.kernel.ui.util.MessageUtilsExtended.showErrorInUIThread;
import static org.fortiss.tooling.kernel.utils.LoggingUtils.error;
import static org.fortiss.tooling.kernel.utils.ResourceUtils.getResourceURI;
......@@ -97,6 +102,12 @@ public class FMUGeneratorExecutionTarget extends ExecutionTargetBase {
/** {@inheritDoc} */
@Override
protected void doExecute(Executable executable) {
if(isMacOSXPlatform()) {
showErrorInUIThread("No macOS support for this feature",
"Exporting a component as FMU is currently not supported on macOS.");
return;
}
FMUArchivePackage fmuSource = (FMUArchivePackage)executable.getExecutableObject();
ExecutionConfiguration config = executable.getConfiguration();
Shell currentShell = getWorkbench().getActiveWorkbenchWindow().getShell();
......@@ -139,8 +150,10 @@ public class FMUGeneratorExecutionTarget extends ExecutionTargetBase {
String[] command = (String[])addAll(getGccCommandAndPath(fmiLibPath), src);
if(runCommand(command, tempBuildDirectoryPath) != 0) {
throw new RuntimeException("[FMI export] the compiler failed on compilation.");
int exitCode = runCommand(command, tempBuildDirectoryPath);
if(exitCode != 0) {
throw new RuntimeException(
"[FMI export] the compiler failed on compilation. Exit code: " + exitCode);
}
String[] obj = collectSourceFiles(fmuSource, "", "o");
......@@ -148,8 +161,10 @@ public class FMUGeneratorExecutionTarget extends ExecutionTargetBase {
fmuSource.getModelDescription().getName() + getLibraryExtension()};
String[] command2 = (String[])ArrayUtils.addAll(temp, obj);
if(runCommand(command2, tempBuildDirectoryPath) != 0) {
throw new RuntimeException("[FMI export] the compiler failed on linking.");
exitCode = runCommand(command2, tempBuildDirectoryPath);
if(exitCode != 0) {
throw new RuntimeException(
"[FMI export] the compiler failed on linking. Exit code: " + exitCode);
}
makeZip(fmuSource, targetFolder.getLocation().toOSString(), tempBuildDirectoryPath);
deleteDirectory(new File(tempBuildDirectoryPath));
......@@ -172,24 +187,22 @@ public class FMUGeneratorExecutionTarget extends ExecutionTargetBase {
}
/** Provide the library extension based on machine architecture */
private String getLibraryExtension() throws IOException {
private String getLibraryExtension() {
String ext = null;
if(checkArchitecture().contains("win")) {
if(isWindowsPlatform()) {
ext = ".dll";
}
if(checkArchitecture().contains("linux")) {
} else {
ext = ".so";
}
return ext;
}
/** Provide the GCC command and library path based on machine architecture */
private String[] getGccCommandAndPath(String fmiLibPath) throws IOException {
private String[] getGccCommandAndPath(String fmiLibPath) {
String[] path = null;
if(checkArchitecture().contains("win")) {
if(isWindowsPlatform()) {
path = new String[] {"gcc", "-w", "-I" + fmiLibPath, "-iquote.", "-c"};
}
if(checkArchitecture().contains("linux")) {
} else {
path = new String[] {"gcc", "-fPIC", "-I" + "/" + fmiLibPath, "-iquote.", "-c"};
}
return path;
......@@ -208,19 +221,18 @@ public class FMUGeneratorExecutionTarget extends ExecutionTargetBase {
for(FunctionDefinition function : dd.getFunctions()) {
if(function.getFunction().getName().toString().equals("samplingTime")) {
if(!function.getReturnType().toString().contains("double")) {
message += baseMsg + "return a value of type \"double\"." +
System.lineSeparator();
message += baseMsg + "return a value of type \"double\"." + lineSeparator();
}
EList<IStatementTerm> statements = function.getDefinition().getStatements();
if(statements.size() != 1) {
message += baseMsg + "contain one and only one statement." +
System.lineSeparator();
message +=
baseMsg + "contain one and only one statement." + lineSeparator();
} else {
// get(0): this is fine because of the check above
IStatementTerm singleStatement = statements.get(0);
if(!(singleStatement instanceof Return)) {
message += baseMsg + "contain a \"return\" statement." +
System.lineSeparator();
message +=
baseMsg + "contain a \"return\" statement." + lineSeparator();
}
Return returnStatement = (Return)singleStatement;
if(!(returnStatement.getValue() instanceof DoubleConst)) {
......@@ -235,15 +247,15 @@ public class FMUGeneratorExecutionTarget extends ExecutionTargetBase {
}
if(message.equals("")) {
InputDialog durationDlg = new InputDialog(currentShell, "Frequency",
"samplingTime() function definition error:" + System.lineSeparator() + message +
System.lineSeparator() +
"samplingTime() function definition error:" + lineSeparator() + message +
lineSeparator() +
"As sampling time function is not (properly) defined, please provide the frequency of the component in Hertz:",
lastSelectedFrequency + "", new NumberValidator());
if(durationDlg.open() != Window.OK) {
return null;
}
// Parsing should not throw any exception since the string went through NumberValidator
lastSelectedFrequency = Double.parseDouble(durationDlg.getValue());
lastSelectedFrequency = parseDouble(durationDlg.getValue());
// Multiplying with 1000 to convert time to milliseconds
samplingTime = 1 / lastSelectedFrequency;
}
......@@ -283,7 +295,7 @@ public class FMUGeneratorExecutionTarget extends ExecutionTargetBase {
out.putNextEntry(new ZipEntry("modelDescription.xml"));
writeEntryToZip("modelDescription.xml", srcLocation, out);
out.putNextEntry(new ZipEntry("binaries" + File.separator + checkArchitecture() +
out.putNextEntry(new ZipEntry("binaries" + File.separator + getSystemIdentifier() +
File.separator + fmuName + getLibraryExtension()));
writeEntryToZip(fmuName + getLibraryExtension(), srcLocation, out);
......@@ -295,6 +307,13 @@ public class FMUGeneratorExecutionTarget extends ExecutionTargetBase {
}
}
/** Returns a string defining the OS and architecture of the system. **/
private static String getSystemIdentifier() {
String identifier = isWindowsPlatform() ? "win" : "linux";
identifier += isOs64BitArch() ? "64" : "32";
return identifier;
}
/** Add source folder in fmu containing c files */
static void addSourceFilesInFMU(File dirObj, ZipOutputStream out) throws IOException {
File[] files = dirObj.listFiles();
......@@ -363,7 +382,7 @@ public class FMUGeneratorExecutionTarget extends ExecutionTargetBase {
public String isValid(String input) {
try {
if(Double.parseDouble(input) == 0) {
if(parseDouble(input) == 0) {
return "Please enter a non-null number.";
}
} catch(NumberFormatException x) {
......
SimulationManager.java e01235f2c4eed4139c31556092b967490c9a57a2 GREEN
SimulationManager.java d1d0df983a08206bed9d6675a8dc6818562bd429 GREEN
SimulationPerspective.java 6d99ef287c75a0b0d40327a1ae5ddf9ff6003f2f GREEN
SimulationView.java 9e364404ebbb86f436b208ba289f47788b24fbc4 GREEN
SimulatorEasyStartMenu.java 69d36c739c6a2f1aec081c3f08731554c2a3dde3 GREEN
......
......@@ -157,10 +157,8 @@ public class SimulationManager extends Observable {
}
}
if(remainingDelay < 0 && !ignoreSpeedWarning) {
System.out.println("vor question " + i);
ignoreSpeedWarning = askQuestionInUIThread("Simulation Error",
"The length of the simulation step is too small. Do you want to continue?");
System.out.println("nach question " + i);
i++;
if(!ignoreSpeedWarning) {
reset();
......
/*-------------------------------------------------------------------------+
| Copyright 2017 fortiss GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.af3.component.ui.utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* Utility methods for generator.
*
*/
public class GeneratorUtils {
/**
* Check the architecture of the GCC(32-Bit or 64-Bit) and operating system and returns the
* necessary folder name for fmu binaries
*/
public static String checkArchitecture() throws IOException {
ProcessBuilder gccProcessBuilder = new ProcessBuilder("gcc", "-v");
gccProcessBuilder.redirectErrorStream(true);
Process gccProcess = gccProcessBuilder.start();
String architecture = "32";
String OS = "win";
BufferedReader in = new BufferedReader(new InputStreamReader(gccProcess.getInputStream()));
String line = null;
while((line = in.readLine()) != null) {
String lowerLine = line.toLowerCase();
if(lowerLine.contains("target:") && lowerLine.contains("x86_64")) {
architecture = "64";
}
if(lowerLine.contains("target:") && lowerLine.contains("linux")) {
OS = "linux";
}
}
return OS + architecture;
}
}
......@@ -7,6 +7,7 @@
</classpathentry>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="res"/>
<classpathentry exported="true" kind="lib" path="lib/xchart-3.5.2.jar"/>
<classpathentry kind="output" path="build"/>
</classpath>
......@@ -16,3 +16,4 @@ Bundle-RequiredExecutionEnvironment: JavaSE-11
Bundle-Vendor: fortiss GmbH
Bundle-ClassPath: .,
lib/xchart-3.5.2.jar
Eclipse-BundleShape: dir
......@@ -4,6 +4,8 @@ bin.includes = META-INF/,\
plugin.xml,\
.,\
lib/,\
icons/
icons/,\
res/
output.. = build/
source.. = src/
source.. = src/,\
res/
CosimulationConfigurationsDialog.java 9fcc43de9ff6ee40b7cb9136155ba937e65b12bb GREEN
CosimulatorGraphGenerator.java 3f786448ab2d977ab9b855d09289df6b6eef61c1 GREEN
FMUSimulatorEasyStartMenu.java d11e36db19e4e46b9f662f6e1d2d762bf0a2c67b GREEN
FMUSimulatorExecutionTarget.java a2828862a818782c229c63c324fe96b15fbe25ac GREEN
FMUSimulatorExecutionTarget.java e4985e5a691a851db84eac6b015b68b8c15de681 GREEN
......@@ -15,14 +15,19 @@
+--------------------------------------------------------------------------*/
package org.fortiss.af3.cosimulation.ui.simulator;
import static java.lang.Runtime.getRuntime;
import static org.apache.commons.io.FileUtils.deleteQuietly;
import static org.eclipse.core.runtime.FileLocator.resolve;
import static org.eclipse.jface.dialogs.MessageDialog.openInformation;
import static org.eclipse.ui.PlatformUI.getWorkbench;
import static org.fortiss.af3.component.ui.utils.GeneratorUtils.checkArchitecture;
import static org.fortiss.af3.component.utils.ComponentArchitectureUtils.createTemporaryComponentArchitecture;
import static org.fortiss.af3.component.utils.ComponentArchitectureUtils.hasReadOnlyBehaviorSpecification;
import static org.fortiss.af3.cosimulation.ui.simulator.CosimulatorGraphGenerator.displayCosimulationResults;
import static org.fortiss.af3.expression.utils.DataDictionaryUtils.findDataDictionary;
import static org.fortiss.af3.project.utils.FileUtils.getAF3EclipseProject;
import static org.fortiss.tooling.base.utils.SystemUtils.isMacOSXPlatform;
import static org.fortiss.tooling.base.utils.SystemUtils.isWindowsPlatform;
import static org.fortiss.tooling.kernel.ui.util.MessageUtilsExtended.showErrorInUIThread;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.copy;
import static org.fortiss.tooling.kernel.utils.ResourceUtils.getResourceURI;
import static org.fortiss.tooling.kernel.utils.TransformationUtils.createTransformedObjectFor;
......@@ -39,7 +44,6 @@ import java.nio.file.Files;
import org.apache.commons.io.FileUtils;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Shell;
import org.fortiss.af3.component.model.Component;
......@@ -81,6 +85,12 @@ public class FMUSimulatorExecutionTarget extends ExecutionTargetBase {
/** {@inheritDoc} */
@Override
protected void doExecute(Executable executable) {
if(isMacOSXPlatform()) {
showErrorInUIThread("No macOS support for this feature",
"Running a co-simulation is currently not supported on macOS.");
return;
}
Shell currentShell = getWorkbench().getActiveWorkbenchWindow().getShell();
ExternalSimulationConfiguration simConfig =
(ExternalSimulationConfiguration)executable.getExecutableObject();
......@@ -126,25 +136,22 @@ public class FMUSimulatorExecutionTarget extends ExecutionTargetBase {
process.waitFor();
FileUtils.deleteDirectory(new File(tempBuildDirectoryPath));
} catch(Exception e) {
MessageDialog.openInformation(currentShell, "[Error]",
"Detailed Error: \n" + e.getMessage());
openInformation(currentShell, "[Error]", "Detailed Error: \n" + e.getMessage());
}
}
// TODO (#3853): Check if we really have to call the 'java' binary
/** Run cosimulation orchestration engine */
private Process runCosimulationServer(String tempBuildDirectoryPath)
throws IOException, InterruptedException {
String pluginID = getResourceURI(AF3CosimulationUIActivator.PLUGIN_ID, "/lib");
String targetFolder =
FileLocator.resolve(new URL(pluginID)).getPath().substring(1) + "coe.jar";
String[] coe = null;
if(checkArchitecture().contains("win")) {
coe = new String[] {"java", "-jar", targetFolder};
}
if(checkArchitecture().contains("linux")) {
coe = new String[] {"java", "-jar", "/" + targetFolder};
String jarsFolder = "/res/org/fortiss/af3/cosimulation/ui/jars";
String pluginID = getResourceURI(AF3CosimulationUIActivator.PLUGIN_ID, jarsFolder);
String targetFolder = resolve(new URL(pluginID)).getPath() + "coe.jar";
if(isWindowsPlatform()) {
targetFolder = targetFolder.substring(1);
}
Process process = Runtime.getRuntime().exec(coe, null, new File(tempBuildDirectoryPath));
String[] coe = new String[] {"java", "-jar", targetFolder};
Process process = getRuntime().exec(coe, null, new File(tempBuildDirectoryPath));
Thread.sleep(5000);
return process;
}
......
......@@ -36,3 +36,4 @@ Export-Package: org.fortiss.af3.generator.common,
org.fortiss.af3.generator.common.textgen.c.templates,
org.fortiss.af3.generator.common.textgen.java,
org.fortiss.af3.generator.common.utils
Eclipse-BundleShape: dir
......@@ -5,7 +5,8 @@ bin.includes = .,\
META-INF/,\
plugin.xml,\
plugin.properties,\
lib/antlr-3.5-complete.jar
templates/,\
lib/
jars.compile.order = .
source.. = generated-src/,\
src/
......
......@@ -3,4 +3,4 @@ CLanguageConstructTextGenerator.java 444c3bc9664c924532e96df296ca1456ad91cf89 GR
CLanguageTypesTextGenerator.java 05944390c13c907d932df6e59ef3c43e47b0fdd2 GREEN
CStaticFilesTextGenerator.java 0243875b7fc69a5ca9a0d130b9b814a159de5ec3 GREEN
FMUModelDescriptionTextGenerator.java 360ab398e36738652bf24f51170525a40782fbe2 GREEN
FMUTopCEntryTextGenerator.java 371755645276da61a5b5214ed1a71029b1b18603 GREEN
FMUTopCEntryTextGenerator.java 750775089b4134173a73fcf80e0db710802bf3ba GREEN
......@@ -43,22 +43,17 @@ public class FMUTopCEntryTextGenerator {
private static final String PREFIX = "PLACEHOLDER_";
/** Returns the XML string for the given FMU package description. */
public static String fmuArchiveToTopCEntry(FMUArchivePackage fmuPkg) {
public static String fmuArchiveToTopCEntry(FMUArchivePackage fmuPkg) throws IOException {
StringBuffer buf = new StringBuffer();
buf.append("/* generated by AutoFOCUS 3 (");
buf.append(AF3GeneratorCommonActivator.getPlainBundleVersion());
buf.append(") on ").append(new Date().toString()).append(" */\n");
try {
List<String> lines = getStringContentFromResource(AF3GeneratorCommonActivator.PLUGIN_ID,
"/templates/fmuTopEntry.c");
lines.forEach(l -> lineDispatcher(l, fmuPkg, buf));
return buf.toString();
} catch(IOException e) {
// Should not happen
return null;
}
List<String> lines = getStringContentFromResource(AF3GeneratorCommonActivator.PLUGIN_ID,
"/templates/fmuTopEntry.c");
lines.forEach(l -> lineDispatcher(l, fmuPkg, buf));
return buf.toString();
}
/**
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment