Skip to content

Commit e3a3aeb

Browse files
arun3688lochel
andauthored
Reimplement --timeout for fmu (#1397)
Co-authored-by: Lennart Ochel <lennart.ochel@outlook.com>
1 parent db9feec commit e3a3aeb

3 files changed

Lines changed: 82 additions & 50 deletions

File tree

src/OMSimulatorLib/Flags.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ void oms::Flags::setDefaults()
9494
stopTime = 1.0;
9595
stripRoot = false;
9696
suppressPath = true;
97-
timeout = 0.0;
97+
timeout = 0;
9898
tolerance = 1e-4;
9999
wallTime = false;
100100
zeroNominal = false;

src/OMSimulatorLib/Flags.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ namespace oms
8080
static double MinimumStepSize() {return GetInstance().minimumStepSize;}
8181
static double StartTime() {return GetInstance().startTime;}
8282
static double StopTime() {return GetInstance().stopTime;}
83-
static double Timeout() {return GetInstance().timeout;}
8483
static double Tolerance() {return GetInstance().tolerance;}
8584
static oms_alg_solver_enu_t AlgLoopSolver() {return GetInstance().algLoopSolver;}
8685
static oms_solver_enu_t MasterAlgorithm() {return GetInstance().masterAlgorithm;}
@@ -90,6 +89,7 @@ namespace oms
9089
static unsigned int MaxEventIteration() {return GetInstance().maxEventIteration;}
9190
static unsigned int MaxLoopIteration() {return GetInstance().maxLoopIteration;}
9291
static unsigned int NumProcs() {return GetInstance().numProcs;}
92+
static unsigned int Timeout() {return GetInstance().timeout;}
9393

9494
private:
9595
bool addParametersToCSV;
@@ -117,7 +117,6 @@ namespace oms
117117
double minimumStepSize;
118118
double startTime;
119119
double stopTime;
120-
double timeout;
121120
double tolerance;
122121
oms_alg_solver_enu_t algLoopSolver;
123122
oms_solver_enu_t masterAlgorithm;
@@ -127,6 +126,7 @@ namespace oms
127126
unsigned int maxEventIteration;
128127
unsigned int maxLoopIteration;
129128
unsigned int numProcs;
129+
unsigned int timeout;
130130

131131
private:
132132
struct Flag

src/OMSimulatorLib/OMSimulator.cpp

Lines changed: 79 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,11 @@
5555
#include "OMSimulator/Types.h"
5656
#include "Version.h"
5757

58-
#include <chrono>
59-
#include <condition_variable>
60-
#include <iostream>
6158
#include "miniunz.h"
62-
#include <mutex>
63-
#include <pugixml.hpp>
59+
#include "pugixml.hpp"
60+
61+
#include <chrono>
62+
#include <future>
6463
#include <string>
6564
#include <thread>
6665

@@ -1169,60 +1168,93 @@ static int do_simulation(std::string model, std::chrono::duration<double> timeou
11691168
return 0;
11701169
}
11711170

1172-
oms_status_enu_t oms_RunFile(const char* filename)
1171+
oms_status_enu_t SimulateSingleFMU(const filesystem::path& path)
11731172
{
11741173
oms_status_enu_t status;
1175-
filesystem::path path(filename);
1176-
std::string type = path.extension().string();
1174+
std::string modelName("model");
1175+
std::string systemName = modelName + ".root";
1176+
std::string fmuName = systemName + (oms::ComRef::isValidIdent(path.stem().string()) ? ("." + path.stem().string()) : ".fmu");
1177+
oms_fmi_kind_enu_t kind;
11771178

1178-
if (type == ".fmu")
1179-
{
1180-
std::string modelName("model");
1181-
std::string systemName = modelName + ".root";
1182-
std::string fmuName = systemName + (oms::ComRef::isValidIdent(path.stem().string()) ? ("." + path.stem().string()) : ".fmu");
1183-
oms_fmi_kind_enu_t kind;
1179+
/* intialize the defaultExperiment with defaults set in Flags.cpp setDefaults() or
1180+
* values provided from user from commandLine (e.g) OMSimulator A.fmu --stopTime=10 --stepSize=10
1181+
*/
1182+
oms_fmu_default_experiment_settings defaultExperiment = {oms::Flags::StartTime(), oms::Flags::StopTime(), oms::Flags::Tolerance(), oms::Flags::MaximumStepSize()};
11841183

1185-
/* intialize the defaultExperiment with defaults set in Flags.cpp setDefaults() or
1186-
* values provided from user from commandLine (e.g) OMSimulator A.fmu --stopTime=10 --stepSize=10
1187-
*/
1188-
oms_fmu_default_experiment_settings defaultExperiment = {oms::Flags::StartTime(), oms::Flags::StopTime(), oms::Flags::Tolerance(), oms::Flags::MaximumStepSize()};
1184+
status = oms_extractFMIKind(path.string().c_str(), &kind, &defaultExperiment);
1185+
if (oms_status_ok != status) return logError("oms_extractFMIKind failed");
11891186

1190-
status = oms_extractFMIKind(filename, &kind, &defaultExperiment);
1191-
if (oms_status_ok != status) return logError("oms_extractFMIKind failed");
1187+
status = oms_newModel(modelName.c_str());
1188+
if (oms_status_ok != status) return logError("oms_newModel failed");
11921189

1193-
status = oms_newModel(modelName.c_str());
1194-
if (oms_status_ok != status) return logError("oms_newModel failed");
1190+
oms::Model* model = oms::Scope::GetInstance().getModel(oms::ComRef(modelName));
1191+
if (!model)
1192+
return logError_ModelNotInScope(oms::ComRef(modelName));
1193+
model->setIsolatedFMUModel();
11951194

1196-
oms::Model* model = oms::Scope::GetInstance().getModel(oms::ComRef(modelName));
1197-
if (!model)
1198-
return logError_ModelNotInScope(oms::ComRef(modelName));
1199-
model->setIsolatedFMUModel();
1195+
if (kind == oms_fmi_kind_me_and_cs)
1196+
status = oms_addSystem(systemName.c_str(), oms::Flags::DefaultModeIsCS() ? oms_system_wc : oms_system_sc);
1197+
else
1198+
status = oms_addSystem(systemName.c_str(), (kind == oms_fmi_kind_cs) ? oms_system_wc : oms_system_sc);
1199+
if (oms_status_ok != status) return logError("oms_addSystem failed");
1200+
1201+
status = oms_addSubModel(fmuName.c_str(), path.string().c_str());
1202+
if (oms_status_ok != status) return logError("oms_addSubModel failed");
1203+
1204+
if (oms::Flags::ResultFile() != "<default>")
1205+
if(oms_status_ok != oms_setResultFile(modelName.c_str(), oms::Flags::ResultFile().c_str(), 1))
1206+
return logError("oms_setResultFile failed");
1207+
1208+
status = oms_setStartTime(modelName.c_str(), defaultExperiment.startTime);
1209+
if(oms_status_ok != status) return logError("oms_setStartTime failed");
1210+
status = oms_setStopTime(modelName.c_str(), defaultExperiment.stopTime);
1211+
if(oms_status_ok != status) return logError("oms_setStopTime failed");
1212+
status = oms_setTolerance(modelName.c_str(), defaultExperiment.tolerance, defaultExperiment.tolerance);
1213+
if(oms_status_ok != status) return logError("oms_setTolerance failed");
1214+
// set the maximum stepSize
1215+
status = oms_setVariableStepSize(modelName.c_str(), oms::Flags::InitialStepSize(), oms::Flags::MinimumStepSize(), defaultExperiment.stepSize);
1216+
if(oms_status_ok != status) return logError("oms_setVariableStepSize failed");
1217+
1218+
if (kind == oms_fmi_kind_me_and_cs)
1219+
status = oms_setSolver(systemName.c_str(), oms::Flags::DefaultModeIsCS() ? oms::Flags::MasterAlgorithm() : oms::Flags::Solver());
1220+
else
1221+
status = oms_setSolver(systemName.c_str(), (kind == oms_fmi_kind_cs) ? oms::Flags::MasterAlgorithm() : oms::Flags::Solver());
1222+
if(oms_status_ok != status) return logError("oms_setSolver failed");
12001223

1201-
if (kind == oms_fmi_kind_me_and_cs)
1202-
status = oms_addSystem(systemName.c_str(), oms::Flags::DefaultModeIsCS() ? oms_system_wc : oms_system_sc);
1203-
else
1204-
status = oms_addSystem(systemName.c_str(), (kind == oms_fmi_kind_cs) ? oms_system_wc : oms_system_sc);
1205-
if (oms_status_ok != status) return logError("oms_addSystem failed");
1224+
status = oms_instantiate(modelName.c_str());
1225+
if(oms_status_ok != status) return logError("oms_instantiate failed");
1226+
status = oms_initialize(modelName.c_str());
1227+
if(oms_status_ok != status) return logError("oms_initialize failed");
1228+
status = oms_simulate(modelName.c_str());
1229+
if(oms_status_ok != status) return logError("oms_simulate failed");
12061230

1207-
status = oms_addSubModel(fmuName.c_str(), filename);
1208-
if (oms_status_ok != status) return logError("oms_addSubModel failed");
1231+
status = oms_terminate(modelName.c_str());
1232+
if(oms_status_ok != status) return logError("oms_terminate failed");
1233+
status = oms_delete(modelName.c_str());
1234+
if(oms_status_ok != status) return logError("oms_delete failed");
12091235

1210-
if (oms::Flags::ResultFile() != "<default>")
1211-
oms_setResultFile(modelName.c_str(), oms::Flags::ResultFile().c_str(), 1);
1212-
oms_setStartTime(modelName.c_str(), defaultExperiment.startTime);
1213-
oms_setStopTime(modelName.c_str(), defaultExperiment.stopTime);
1214-
oms_setTolerance(modelName.c_str(), defaultExperiment.tolerance, defaultExperiment.tolerance);
1215-
// set the maximum stepSize
1216-
oms_setVariableStepSize(modelName.c_str(), oms::Flags::InitialStepSize(), oms::Flags::MinimumStepSize(), defaultExperiment.stepSize);
1217-
1218-
if (kind == oms_fmi_kind_me_and_cs)
1219-
oms_setSolver(systemName.c_str(), oms::Flags::DefaultModeIsCS() ? oms::Flags::MasterAlgorithm() : oms::Flags::Solver());
1236+
return oms_status_ok;
1237+
}
1238+
1239+
oms_status_enu_t oms_RunFile(const char* filename)
1240+
{
1241+
oms_status_enu_t status;
1242+
filesystem::path path(filename);
1243+
std::string type = path.extension().string();
1244+
1245+
if (type == ".fmu")
1246+
{
1247+
auto future = std::async(std::launch::async, SimulateSingleFMU, path);
1248+
1249+
if (oms::Flags::Timeout() == 0 || future.wait_for(std::chrono::seconds(int(oms::Flags::Timeout()))) == std::future_status::ready)
1250+
status = future.get();
12201251
else
1221-
oms_setSolver(systemName.c_str(), (kind == oms_fmi_kind_cs) ? oms::Flags::MasterAlgorithm() : oms::Flags::Solver());
1252+
{
1253+
logError("Simulation timed out - cleaning up...");
1254+
status = oms_status_error;
1255+
exit(1);
1256+
}
12221257

1223-
status = do_simulation(modelName, std::chrono::duration<double>(oms::Flags::Timeout())) ? oms_status_error : oms_status_ok;
1224-
oms_terminate(modelName.c_str());
1225-
oms_delete(modelName.c_str());
12261258
return status;
12271259
}
12281260
else if (type == ".ssp")

0 commit comments

Comments
 (0)