diff --git a/SimulationRuntime/interactive/CMakeLists.txt b/SimulationRuntime/interactive/CMakeLists.txt deleted file mode 100644 index eb1a8747d6e..00000000000 --- a/SimulationRuntime/interactive/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ -# includes -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../c) -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../c/linearization) -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../c/math-support) -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../c/meta) -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../c/meta/gc) -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../c/ModelicaExternalC) -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../c/simulation) -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../c/util) -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../c/simulation/libf2c) -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../c/simulation/results) -INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../c/simulation/solver) - -# Quellen und Header -SET(interactive_sources omi_Calculation.cpp omi_Control.cpp omi_ResultManager.cpp - omi_ServiceInterface.cpp omi_Transfer.cpp socket.cpp thread.cpp) - -SET(interactive_headers omi_Calculation.h omi_Control.h omi_ResultManager.h - omi_ServiceInterface.h omi_Transfer.h socket.h thread.h) - -# Library util -ADD_LIBRARY(interactive ${interactive_sources} ${interactive_headers}) -#TARGET_LINK_LIBRARIES(util) - -# Install -INSTALL(TARGETS interactive - ARCHIVE DESTINATION lib) - -INSTALL(FILES ${interactive_headers} DESTINATION include) diff --git a/SimulationRuntime/interactive/Makefile.in b/SimulationRuntime/interactive/Makefile.in deleted file mode 100644 index 57e2aad4679..00000000000 --- a/SimulationRuntime/interactive/Makefile.in +++ /dev/null @@ -1,40 +0,0 @@ -# -# Makefile for SimulationRuntime/interactive -# - -top_builddir= ../.. - -CPPSRC = omi_Calculation.cpp omi_Control.cpp omi_ResultManager.cpp \ - omi_ServiceInterface.cpp omi_Transfer.cpp socket.cpp thread.cpp -#CPPSRC = socket.cpp thread.cpp - -SHELL = /bin/sh -CC = @CC@ -CXX = @CXX@ -CFLAGS += @CFLAGS@ -CXXFLAGS = $(CFLAGS) -CPPFLAGS = -I.. -Wall -I../c/simulation/results/ -I../c/linearization -I../c/simulation/solver/ -I../c/util/ -I../c/ -I../c/simulation/ -I../c/math-support/ -I../../build/include/omc/c -LDFLAGS = @LDFLAGS@ - -OBJ = $(CPPSRC:.cpp=.o) - -all: libinteractive.a SampleClient/interactiveclient@EXE@ - -omc_ServiceInterface.o: omi_ServiceInterface.cpp \ - omi_ServiceInterface.h omi_Control.h omi_Transfer.h \ - ../simulation_runtime.h ../simulation_input.h \ - ../solver_main.h ../options.h - - -libinteractive.a : $(OBJ) - $(AR) -s -r $@ $(OBJ) - -SampleClient/interactiveclient@EXE@: client.cpp socket.h socket.cpp socket_win.cpp socket_unix.cpp thread.h thread.cpp - @echo "Building client for interactive simulation ... " - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ client.cpp socket.cpp thread.cpp $(LDFLAGS) -lpthread @LDFLAGS_SOCKET@ - -clean: - $(RM) -rf *.o *.a SampleClient/interactiveclient - -Makefile: Makefile.in - cd $(top_builddir); ./config.status diff --git a/SimulationRuntime/interactive/README.txt b/SimulationRuntime/interactive/README.txt deleted file mode 100644 index a926bed77a4..00000000000 --- a/SimulationRuntime/interactive/README.txt +++ /dev/null @@ -1,39 +0,0 @@ -Interactive simulation client code and application test -======================================================= -Last update: 2010-12-17 Adrian Pop [adrpo@ida.liu.se] - -Documentation: --------------- -See Chapter 5 in OpenModelica User's Guide for -more information on interactive simulation. - -Sample application: -------------------- -A complete application test is in: -https://openmodelica.org/svn/OpenModelica/trunk/testsuite/openmodelica/interactive-simulation -user: anonymous -pass: none <-- write "none" without quotes here - -An already build application test executable for Windows is in: -https://openmodelica.org/svn/OpenModelica/trunk/SimulationRuntime/interactive/SampleClient -directory - -Code: ------ -To get the code for an interactive client look at: -https://openmodelica.org/svn/OpenModelica/trunk/SimulationRuntime/interactive -user: anonymous -pass: none <-- write "none" without quotes here - -File - client.cpp - and all the other dependencies: thread.* socket.* - -Another (better) way would be to use Subversion (TortoiseSVN) and checkout: -https://openmodelica.org/svn/OpenModelica/trunk/SimulationRuntime/interactive -user: anonymous -pass: none <-- write "none" without quotes here - - -Cheers, -Adrian Pop/ diff --git a/SimulationRuntime/interactive/client.cpp b/SimulationRuntime/interactive/client.cpp deleted file mode 100644 index 861ad83a037..00000000000 --- a/SimulationRuntime/interactive/client.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Simple client to test OMI. - * - * Author: Per Östlund - * Last revision: 2010-02-23 - */ - -#include -#include -#include -#include -#include -#include - -#include "thread.h" -#include "socket.h" - -static bool run = true; - -using namespace std; - -static string* fileName = 0; -static fstream* fileStream = 0; -static int shutDownInProgress = 0; - - -THREAD_RET_TYPE threadServerControl(void*) -{ - Socket s1; - - s1.create(); - s1.bind(10500); - s1.listen(); - - cout << "Control server on: 127.0.0.1:10500" << endl; fflush(stdout); - - Socket s2; - s1.accept(s2); - - while(run) - { - string message; - - if(!s2.recv(message)) - { - if (!shutDownInProgress) - { - cout << "threadServerControl: Failed to recieve message!" << endl; fflush(stdout); - return 0; - } - } - - if (!shutDownInProgress) - { - cout << ("Server recieved message: " + message) << endl; fflush(stdout); - } - } - return 0; -} - -THREAD_RET_TYPE threadServerTransfer(void*) -{ - Socket s1; - - s1.create(); - s1.bind(10502); - s1.listen(); - - cout << "Transfer server on: 127.0.0.1:10502" << endl; fflush(stdout); - - Socket s2; - s1.accept(s2); - - while(run) - { - string message; - - if(!s2.recv(message)) - { - if (!shutDownInProgress) - { - cout << "threadServerTransfer: Failed to recieve message!" << endl; fflush(stdout); - return 0; - } - } - - if (!shutDownInProgress) - { - cout << ("Server recieved message: " + message) << endl; fflush(stdout); - } - } - return 0; -} - -THREAD_RET_TYPE threadControlClient(void*) -{ - Socket s1; - - s1.create(); - - int retries_left = 5; - - for(; retries_left >= 0; --retries_left) - { - if(!s1.connect("127.0.0.1", 10501)) - { - if(retries_left) - { - cout << "Connect failed, retrying to connect to 127.0.0.1:10501 after 2 seconds" << endl; fflush(stdout); - delay(2000); - continue; - } - else - { - cout << "Connect failed, max number of retries reached." << endl; fflush(stdout); - run = false; - cout << "Exiting..." << endl; fflush(stdout); - exit(1); - } - } - - break; - } - - while(true) - { - string message; - cout << "Enter operation to be sent to server: " << endl; fflush(stdout); - if (!fileName) // no file, read from stdin - { - cin >> message; - } - else // some file, read from it - { - if (!fileStream->eof()) - { - (*fileStream) >> message; - } - else - { - cout << "End of commands file: " << fileName->c_str() << " has been reached!" << endl; fflush(stdout); - cout << "Sending \"end\" to the server and exiting ..." << endl; fflush(stdout); - message = ""; - } - } - - if (!message.empty()) - { - if (!message.compare(0,5,"delay")) // delay - { - // we have a delay in the text, see how much - string delayTime = message.substr(5,message.size()-5); - cout << "Command to delay the client for: " << delayTime << " seconds." << endl; fflush(stdout); - delay(atoi(delayTime.c_str()) * 1000); - cout << "End delay of " << delayTime << " seconds." << endl; fflush(stdout); - } - else // send the message - { - cout << "Message to be send: " << message << endl; fflush(stdout); - - // set the shutDownInProgress flag so we don't get failure on receive messages - // from the transfer thread and server control thread - if(message.compare(0, 8, "shutdown") == 0) - { - shutDownInProgress = 1; - } - - if(!s1.send(message)) - { - cout << "Failed to send message!" << endl; fflush(stdout); - break; - } - - if(message.compare(0, 8, "shutdown") == 0) - { - cout << "Shuting down in 2 seconds .... due to shutdown message: " << message << endl; fflush(stdout); - shutDownInProgress = 1; - delay(2000); - break; - } - } - } - else - { - cout << "Message: [is empty]" << endl; fflush(stdout); - } - } - - run = false; - return 0; -} - -int main(int argc, char **argv) -{ - if (argc == 2) - { - if (strcmp(argv[1], "-help") == 0 && strcmp(argv[1], "/?") == 0) - { - cout << "usage: client [file-with-commands.txt] [-help|/?]" << endl; fflush(stdout); - exit(1); - } - fileName = new string(argv[1]); - fileStream = new fstream(fileName->c_str(), fstream::in); - if (fileStream->fail()) - { - cout << "Unable to open file: " << fileName->c_str() << "!" << endl; fflush(stdout); - cout << "usage: client [file-with-commands.txt] [-help|/?]" << endl; fflush(stdout); - exit(1); - } - } - - Thread serverControl; - Thread serverTransfer; - Thread clientControl; - - serverControl.Create(threadServerControl); - delay(1000); - serverTransfer.Create(threadServerTransfer); - delay(1000); - clientControl.Create(threadControlClient); - delay(1000); - - clientControl.Join(); - serverTransfer.Join(); - serverControl.Join(); - - if (fileName) - { - fileStream->close(); - } - - return 0; -} - diff --git a/SimulationRuntime/interactive/omi_Calculation.cpp b/SimulationRuntime/interactive/omi_Calculation.cpp deleted file mode 100644 index 9ee998f63f8..00000000000 --- a/SimulationRuntime/interactive/omi_Calculation.cpp +++ /dev/null @@ -1,242 +0,0 @@ -/* - * OpenModelica Interactive (Ver 0.75) - * Last Modification: 23. May 2011 - * - * Developed by: - * EADS IW Germany - * Developer: Parham Vasaiely - * Contact: Parham.Vasaiely@eads.com - * - * File description: omi_Calculation.cpp - * The "Calculation" thread is synonymous to a producer which uses the "OM Solving Service" - * to get results for a specific time step and to inform the "ResultManager" - * about the new simulation results. It uses parameters to calculate the interval between single calculation steps - * in a loop, until the simulation is interrupted by the "Control" or because of an occurred error. - * If a single solving step is very complex and takes a long time to be solved, - * it is possible to create more than one producer to start the next simulation step during the data storing time. - * - * Full specification available in the bachelor thesis of Parham Vasaiely - * "Interactive Simulation of SysML Models using Modelica" (Chapter 5) - */ - -#include "omi_ServiceInterface.h" -#include "omi_Control.h" -#include "omi_Calculation.h" - -using namespace std; - -static bool debugCalculation = false; //Set true to print out comments which describes the program flow to the console - -static bool calculationInterrupted = false; - -static SimStepData simStepData_from_Calculation; //Simulation Step Data structure used by a calculation thread to store simulation result data for a specific time step data -static SimStepData* p_SimStepData_from_Calculation = 0; - -static int calculate(void); -static void createSSDEntry(string); -static void printSSDCalculation(long, long, long); - -/** - * Calculates all simulation steps in a loop until the calculation is interrupted - */ -static int calculate(void) -{ - int retVal = -1; - double start = 0.0; - double stop = 1.0; - double stepSize = 1; - long outputSteps = 1; //unnecessary for interactive simulation - double tolerance = 1e-4; - string method; - string outputFormat; - - - intializeSolverStartData(&stepSize, &outputSteps, &tolerance, &method, &outputFormat); - //TODO 20100217 pv catch correct stepSize value for calculation loop - if (debugCalculation) { - cout << "Calculation:\tFunct.: calculate\tData 1: start: " << start - << " stop: " << stop << " stepSize: " << stepSize - << " outputSteps: " << outputSteps << " method: " << method - << " outputFormat: " << outputFormat; - fflush( stdout); - } - - set_timeValue(start); - set_forceEmit(0); - - - while (!calculationInterrupted) { //TODO 20100210 pv Interrupt is not implemented yet - - mutexSimulationStatus->Lock(); // Lock to see the simulation status. - if (simulationStatus == SimulationStatus::STOPPED) { - // If the simulation should stop, unlock and break out of the loop. - mutexSimulationStatus->Unlock(); - } - - if (simulationStatus == SimulationStatus::SHUTDOWN) { - // If the simulation should stop, unlock and break out of the loop. - mutexSimulationStatus->Unlock(); - break; - } - - if (simulationStatus == SimulationStatus::RUNNING) { - // If the simulation should continue, increase the semaphore. - waitForResume->Post(); - } - // Unlock and see if we need to wait for resume or not. - mutexSimulationStatus->Unlock(); - waitForResume->Wait(); //wait and reduce semaphore - - //TODO 20100210 pv testing rungekutter... - start = get_timeValue(); - stop = get_timeValue() + stepSize; - if (debugCalculation) { - cout << "Calculation:\tFunct.: calculate\tData 2: p_SimStepData_from_Calculation->forTimeStep: " << p_SimStepData_from_Calculation->forTimeStep << " ------" << endl; fflush( stdout); - cout << "Calculation:\tFunct.: calculate\tData 3: start " << start << " stop: " << stop << endl; fflush(stdout); - } - - retVal = performSolverStepFromOM(start, stop, stepSize); - - if (retVal != 0) { - cout << "Calculation:\tFunct.: calculate\tMessage: omi_Calculation: error occurred while calculating" << endl; fflush( stdout); - return 1; - } - - set_stepSize(stepSize); - createSSDEntry(method); - calculationInterrupted = false; - - setResultData(p_SimStepData_from_Calculation); //ssd(tn) as parameter - } - - deintializeSolverStartData(); - //if (debugCalculation) - cout - << "Calculation:\tFunct.: calculate\tMessage: Calculation end: calculationInterrupted -> " - << calculationInterrupted << endl; - fflush( stdout); - //return retVal; //TODO 20100210 pv Implement the return value correctly - return 0; -} - -/** - * Asks the ServiceInterface for the last simulation results to put into the simulation step data structure - */ -static void createSSDEntry(string method) -{ - fillSimulationStepDataWithValuesFromGlobalData(method, p_SimStepData_from_Calculation); - - p_sdnMutex->Lock(); - - p_sdnMutex->Unlock(); - if (debugCalculation) - { - //printSSDCalculation(nStates, nAlgebraic, nParameters); - cout - << "Calculation:\tFunct.: createSSDEntry\tData: p_SimStepData_from_Calculation->forTimeStep: " - << p_SimStepData_from_Calculation->forTimeStep - << " --------------------" << endl; - fflush( stdout); - } -} - -/** - * Only for debugging - * Prints out the actual calculated Simulation Step Data structure - */ -static void printSSDCalculation(long nStates, long nAlgebraic, long nParameters) -{ - cout - << "Calculation:\tFunct.: printSSDCalculation\tMessage: OutPutSSD-CALCULATION***********" - << endl; - fflush( stdout); - cout - << "Calculation:\tFunct.: printSSDCalculation\tData: p_SimStepData_from_Calculation->forTimeStep: " - << p_SimStepData_from_Calculation->forTimeStep - << " --------------------" << endl; - fflush(stdout); - - cout << "Calculation:\tFunct.: printSSDCalculation\tMessage: Parmeters--- " - << endl; - fflush(stdout); - for (int t = 0; t < nParameters; t++) - { - cout << t << ": " - << p_simDataNames_SimulationResult->parametersNames[t] << ": " - << p_SimStepData_from_Calculation->parameters[t] << endl; - fflush(stdout); - } - - if (nAlgebraic > 0) { - cout - << "Calculation:\tFunct.: printSSDCalculation\tMessage: Algebraics---" - << endl; - fflush(stdout); - for (int t = 0; t < nAlgebraic; t++) { - cout << t << ": " - << p_simDataNames_SimulationResult->algebraicsNames[t] - << ": " << p_SimStepData_from_Calculation->algebraics[t] - << endl; - fflush(stdout); - } - } - - if (nStates > 0) { - cout << "Calculation:\tFunct.: printSSDCalculation\tMessage: States---" - << endl; - fflush(stdout); - for (int t = 0; t < nStates; t++) { - cout << t << ": " - << p_simDataNames_SimulationResult->statesNames[t] << ": " - << p_SimStepData_from_Calculation->states[t] << endl; - fflush(stdout); - cout << t << ": " - << p_simDataNames_SimulationResult->stateDerivativesNames[t] - << ": " - << p_SimStepData_from_Calculation->statesDerivatives[t] - << endl; - fflush(stdout); - } - } -} - -/** - * Main thread method initializes all data - */ -THREAD_RET_TYPE threadSimulationCalculation(THREAD_PARAM_TYPE lpParam) -{ - long retValue = -1; //Not used yet - - if (debugCalculation) { - cout << "Calculation:\tMessage: Calculation Thread Start*****" << endl; - fflush( stdout); - } - - p_sdnMutex->Lock(); - long nStates = p_simdatanumbers->nStates; - long nAlgebraic = p_simdatanumbers->nAlgebraic; - long nParameters = p_simdatanumbers->nParameters; - p_sdnMutex->Unlock(); - - p_SimStepData_from_Calculation = &simStepData_from_Calculation; - - double *statesTMP2 = new double[nStates]; - double *statesDerivativesTMP2 = new double[nStates]; - double *algebraicsTMP2 = new double[nAlgebraic]; - double *parametersTMP2 = new double[nParameters]; - p_SimStepData_from_Calculation->states = statesTMP2; - p_SimStepData_from_Calculation->statesDerivatives = statesDerivativesTMP2; - p_SimStepData_from_Calculation->algebraics = algebraicsTMP2; - p_SimStepData_from_Calculation->parameters = parametersTMP2; - - - - retValue = calculate(); - - if (debugCalculation) { - cout << "Calculation:\tMessage: Calculation Thread End*****" << endl; - fflush( stdout); - } - - return (THREAD_RET_TYPE_NO_API) retValue; -} diff --git a/SimulationRuntime/interactive/omi_Calculation.h b/SimulationRuntime/interactive/omi_Calculation.h deleted file mode 100644 index d993b4fd082..00000000000 --- a/SimulationRuntime/interactive/omi_Calculation.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * OpenModelica Interactive (Ver 0.7) - * Last Modification: 3. October 2009 - * - * Developed by: - * EADS IW Germany - * Developer: Parham Vasaiely - * Contact: vasaie_p@informatik.haw-hamburg.de - * - * File description: omi_Calculation.h - * - * Full specification available in the bachelor thesis of Parham Vasaiely - * "Interactive Simulation of SysML Models using Modelica" (Chapter 5) - */ - -//#ifndef _MY_SIMULATIONCALCULATION_H -#define _MY_SIMULATIONCALCULATION_H - -#include "thread.h" - -extern bool* p_forZero; -THREAD_RET_TYPE threadSimulationCalculation(THREAD_PARAM_TYPE); diff --git a/SimulationRuntime/interactive/omi_Control.cpp b/SimulationRuntime/interactive/omi_Control.cpp deleted file mode 100644 index b867c785927..00000000000 --- a/SimulationRuntime/interactive/omi_Control.cpp +++ /dev/null @@ -1,1172 +0,0 @@ -/* - * OpenModelica Interactive (Ver 0.75) - * Last Modification: 23. May 2011 - * - * Developed by: - * EADS IW Germany - * Developer: Parham Vasaiely - * Contact: Parham.Vasaiely@eads.com - * - * File description: omi_Control.cpp - * The `Control' module is the interface between OMI and a GUI. - * It is implemented as a single thread to support parallel tasks and independent reactivity. - * As the main controlling and communication instance at simulation initialisation phase and - * while simulation is running it manages simulation properties and also behaviour. - * A client can permanently send operations as messages to the `Control' unit, - * it can react at any time to feedback from the `Calculation' or `Transfer' threads and - * it also sends messages to a client, for example error or status messages. - * - * Full specification available in the bachelor thesis of Parham Vasaiely - * "Interactive Simulation of SysML Models using Modelica" (Chapter 5) - */ - -#include "socket.h" -#include "omi_ServiceInterface.h" -#include "omi_Control.h" -#include "omi_Calculation.h" -#include "omi_Transfer.h" - -using namespace std; - -//#pragma comment(lib, "ws2_32.lib") - -#define NUMBER_CONSUMER 1 -#define NUMBER_PRODUCER 1 - -#define DEFAULT_CLIENT_PORT 10500 -#define DEFAULT_SERVER_PORT 10501 - -const int control_default_client_port = 10500; -const int control_default_server_port = 10501; -const int transfer_default_server_port = 10502; -const string control_default_client_ip = "127.0.0.1"; //localhost ip for control client -const string control_default_server_ip = "127.0.0.1"; //localhost ip for control server -const string transfer_default_server_ip = "127.0.0.1"; //localhost ip for transfer server - -string control_client_ip = ""; -int control_client_port = 0; -int control_server_port = 0; - -int debugLevelControl = 0; //Set the debug level higher zero to print out messages which describes the program flow to the console [0= debug off, 1= min-debug, 2= max-debug] -bool shutDownSignal = false; -bool error = false; -string messageForClient; -string status; - -long nStates, nAlgebraic, nParameters; -bool initDone = false; //True if initialization is done -bool clientDone = false; //True if client ip and port was configured -bool transferDone = false; //True if transfer ip and port was configured - -SimulationStatus::type simulationStatus = SimulationStatus::STOPPED; -Mutex mutexSimulationStatus_; -Mutex* mutexSimulationStatus = &mutexSimulationStatus_; -Semaphore waitForResume_(0, NUMBER_PRODUCER + NUMBER_CONSUMER); -Semaphore* waitForResume = &waitForResume_; - -Thread producerThreads[NUMBER_PRODUCER]; -Thread consumerThreads[NUMBER_CONSUMER]; -Thread threadClient; - -Semaphore semaphoreMessagesToClient(0, 1); - -//General initialization for control thread -static void initialize(void); -static void createProducerAndConsumer(void); -static void createControlClient(void); -static void connectToControlServer(Socket*); -//Organisation and Management of simulation data -static void reInitAll(void); -static void changeSimulationTime(double); -static void changeParameterValues(double, string); -static void setFilterForTransfer(string); -//Controlling for simulation -static void startSimulation(void); -static void stopSimulation(void); -static void pauseSimulation(void); -static void endSimulation(void); -static void shutDown(void); -//Network -//int sendMessageToClient(SOCKET*, string); -static void parseMessageFromClient(string); - -static void createMessage(string); -THREAD_RET_TYPE threadClientControl(THREAD_PARAM_TYPE); - -//Common help methods -static string parseIP(string); -static int parsePort(string); -static void setValuesFrom_A_SSD(SimStepData*, char, string); -static void parseState(SimStepData*, string); -static void parseAlgebraic(SimStepData*, string); -static void parseParameter(SimStepData*, string); -static void parseNameTypes(string); -static void parseNames(SimDataNamesFilter*, char, string); -static void addNameTo_A_SimDataNames(SimDataNamesFilter*, char, string); - -/***************************************************************** - * Setups for the whole simulation environment - *****************************************************************/ - -/** - * Initializes all needed variables for the control thread - * initializes the DataNames structure - */ -static void initialize(void) -{ - nStates = get_NStates(); - nAlgebraic = get_NAlgebraic(); - nParameters = get_NParameters(); - - initializeSSD_AND_SRDF(nStates, nAlgebraic, nParameters); - status = "stop"; - - if (debugLevelControl > 0) - { - cout << "Control:\tMessage: Store the DataNames Start" << endl; fflush(stdout); - } - fillSimDataNames_AND_SimDataNamesFilter_WithValuesFromGlobalData( - p_simDataNames_SimulationResult, p_simDataNamesFilterForTransfer); - - if (debugLevelControl > 0) - { - cout << "Control:\tMessage: Store the DataNames End" << endl; fflush(stdout); - } -//TODO initDone is obsolete - initDone = true; - if (debugLevelControl > 0) - { - cout << "Control:\tMessage: Initialize done..." << endl; fflush(stdout); - } -}//End Initialize - -/** - * Creates all producers and consumers - * The settransferclienturl#ip#port#end operation have to be called first - */ -static void createProducerAndConsumer(void) -{ - std::cout << "Creating producers and consumers!" << std::endl; fflush(stdout); - if (transferDone) - { - for(int i = 0; i < NUMBER_PRODUCER; ++i) - { - producerThreads[i].Create(threadSimulationCalculation); - } - - for(int i = 0; i < NUMBER_CONSUMER; ++i) - { - consumerThreads[i].Create(threadClientTransfer); - } - - if (debugLevelControl > 0) - { - cout << "Control:\tMessage: Create producer and consumer done..." << endl; fflush(stdout); - } - } - else - { - //Set Transfer IP & PORT - } -} - -/** - * Creates the control client thread - * the setcontrolclienturl#ip#port#end operation have to be called first - */ -static void createControlClient(void) -{ - if (clientDone) { - - /* - * Creates client thread to communicate with GUI - */ - threadClient.Create(threadClientControl); - if (debugLevelControl > 0) - { - cout << "Control:\tMessage: Create client done..." << endl; fflush(stdout); - } - } -} - -/** - * Sets the IP and Port of the control network client to user specific values - * To use Default IP (localhost - 127.0.0.1) send an empty string as ip parameter ("") - * Note: Call this function before starting simulation - */ -void setControlClientIPandPort(string ip, int port){ - if (debugLevelControl > 0) - { - cout << "Control:\tMessage: Control-Client IP and Port: " << ip << ":" << port << endl; fflush(stdout); - } - control_client_ip = ip; - control_client_port = port; -} - -/** - * Note: Call this function before starting simulation - */ -void resetControlClientIPandPortToDefault(){ - control_client_ip = ""; - control_client_port = 0; -} - -/** - * Sets only the Port of the control network server to user specific value - * The IP (localhost - 127.0.0.1) mustn't change - * Note: Call this function before starting simulation - */ -void setControlServerPort(int port){ - control_server_port = port; -} - -/** - * Note: Call this function before starting simulation - */ -void resetControlServerPortToDefault(){ - control_client_port = 0; -} - -/** - * This function establishes the connection to a client's control server - * respective user specific network configurations - */ -static void connectToControlServer(Socket* p_sock) -{ - if (control_client_ip != string("")) - { - if (control_client_port != 0) - { - if (debugLevelControl > 0) - { - cout << "Control:\tMessage: Connect to server with user specific ip and port, ip = " << control_client_ip << ", port = " << control_client_port << endl; fflush(stdout); - } - // Connect to server with user specific ip and port - (*p_sock).connect(control_client_ip, control_client_port); - } - else - { - if (debugLevelControl > 0) - { - cout << "Control:\tMessage: Connect to server with user specific ip and default port (10500)" << endl; fflush(stdout); - } - // Connect to server with user specific ip and default port - (*p_sock).connect(control_client_ip, control_default_client_port); - } - } - else - { - if (control_client_port != 0) - { - if (debugLevelControl > 0) - { - cout << "Control:\tMessage: Connect to server on default IP(localhost) but user specific port" << endl; fflush(stdout); - } - // Connect to server on default IP(localhost) but user specific port - (*p_sock).connect(control_default_client_ip, control_client_port); - } - else - { - if (debugLevelControl > 0) - { - cout << "Control:\tMessage: Connect to server on default IP(localhost) and default port (10500)" << endl; fflush(stdout); - } - // Connect to server on default IP(localhost) and default port (10502) - (*p_sock).connect(control_default_client_ip, control_default_client_port); - } - } -} - -/***************************************************************** - * Organisation and Management of simulation data - * e.g. Parameters, Variables, Simulation Setup... - * Initialization for simulation data - *****************************************************************/ - -/** - * Re-initializes the whole simulation runtime so the simulation can start from beginning - */ -static void reInitAll(void) -{ - SimStepData* p_ssdAtSimulationTime = getResultDataFirstStart(); - if (debugLevelControl > 0) - { - cout << "Control:\tFunct.: reInitAll\tData: p_ssdAtChangedSimulationTime->forTimeStep: " << p_ssdAtSimulationTime->forTimeStep << endl; fflush(stdout); - } - setGlobalSimulationValuesFromSimulationStepData(p_ssdAtSimulationTime); - resetSRDFAfterChangetime(); //Resets the SRDF Array and the producer and consumer semaphores - resetSSDArrayWithNullSSD(nStates, nAlgebraic, nParameters); //overrides all SSD Slots with nullSSD elements - if (debugLevelControl > 0) - { - cout << "Control:\tFunct.: reInitAll\tData: globalData->lastEmittedTime: " << get_lastEmittedTime() << endl; fflush(stdout); - cout << "Control:\tFunct.: reInitAll\tData: globalData->timeValue: " << get_timeValue() << endl; fflush(stdout); - } - -} - -/** - * Changes values for parameters for a specified simulationTime - * The parameter variable contains all names and new values as one string, separated with symbols - */ -static void changeParameterValues(double changedSimulationTime, string parameter) -{ - if (debugLevelControl > 0) - { - cout << "Control:\tFunct.: changeParameterValues\tData: time: " << changedSimulationTime << " parameter: " << parameter << endl; fflush(stdout); - } - - //If the parameter changed while simulation is running, the simulation must go on after changing parameter in global data - string preStatus = status; - if (status.compare("start") == 0) - pauseSimulation(); - - SimStepData* p_ssdAtChangedSimulationTime = getResultDataForTime(get_stepSize(), changedSimulationTime); - if (debugLevelControl > 0) - { - cout << "Control:\tFunct.: changeParameterValues\tData: p_ssdAtChangedSimulationTime->forTimeStep: " << p_ssdAtChangedSimulationTime->forTimeStep << endl; fflush(stdout); - } - - if (p_ssdAtChangedSimulationTime->forTimeStep != -1) - { - parseParameter(p_ssdAtChangedSimulationTime, parameter); - if (debugLevelControl > 0) - { - cout << "Control:\tFunct.: parseParameter " << endl; fflush(stdout); - } - setGlobalSimulationValuesFromSimulationStepData(p_ssdAtChangedSimulationTime); - - //resetSRDFAfterChangetime(); //Resets the SRDF Array and the producer and consumer semaphores - //setSimulationTimeReversed(get_stepSize() + changedSimulationTime); - if (debugLevelControl > 0) - { - cout << "Control:\tFunct.: changeParameterValues\tData:globalData->lastEmittedTime: " << get_lastEmittedTime() << endl; fflush(stdout); - cout << "Control:\tFunct.: changeParameterValues\tData:globalData->timeValue: " << get_timeValue() << endl; fflush(stdout); - } - } - else - { - createMessage("Error: Time is not stored anymore"); - } - //If the parameter changed while simulation is running, the simulation must go on after changing parameter in global data - if (preStatus.compare("start") == 0) - startSimulation(); -} - -/** - * Changes the simulation time to a previously timestep - * All values which are stored for this time step will be reused - */ -static void changeSimulationTime(double changedSimulationTime) -{ - - double stepSize = get_stepSize(); - - //If the parameter changed while simulation is running, the simulation must go on after changing parameter in global data - string preStatus = status; - - if (status.compare("start") == 0) - pauseSimulation(); - - SimStepData* p_ssdAtChangedSimulationTime = getResultDataForTime(stepSize, changedSimulationTime); - - if (p_ssdAtChangedSimulationTime->forTimeStep >= stepSize) - { - setGlobalSimulationValuesFromSimulationStepData(p_ssdAtChangedSimulationTime); - resetSRDFAfterChangetime(); //Resets the SRDF Array and the producer and consumer semaphores - //cout << "Control:\tFunct.: changeSimulationTime\tData: get_stepSize() " << stepSize << endl; fflush(stdout); - setSimulationTimeReversed(stepSize + changedSimulationTime); - } - else - { - createMessage("Error: Time is not stored anymore"); - } - - //If the parameter changed while simulation is running, the simulation must go on after changing parameter in global data - if (preStatus.compare("start") == 0) - startSimulation(); -} - -/* - * void changeSimulationTime(double changedSimulationTime) { - if (debugLevelControl > 0) - { - cout << "Control:\tFunct.: changeSimulationTime\tData: time: " << changedSimulationTime << endl; fflush(stdout); - } - - double stepSize = get_stepSize(); - - //If the parameter changed while simulation is running, the simulation must go on after changing parameter in global data - string preStatus = status; - - if (debugLevelControl > 0) - { - cout << "Control:\tFunct.: changeSimulationTime\tData: preStatus: " << preStatus << endl; fflush(stdout); - } - - if (status.compare("start") == 0) - pauseSimulation(); - - if (debugLevelControl > 0) - { - cout << "Control:\tFunct.: changeSimulationTime\tData: preStatus: " << preStatus << endl; fflush(stdout); - } - - SimStepData* p_ssdAtChangedSimulationTime = getResultDataForTime(stepSize, - changedSimulationTime); - if (debugLevelControl > 0) - { - cout << "Control:\tFunct.: changeSimulationTime\tData: p_ssdAtChangedSimulationTime->forTimeStep: " << p_ssdAtChangedSimulationTime->forTimeStep << endl; fflush(stdout); - } - - if (p_ssdAtChangedSimulationTime->forTimeStep >= stepSize) - { - setGlobalSimulationValuesFromSimulationStepData(p_ssdAtChangedSimulationTime); - resetSRDFAfterChangetime(); //Resets the SRDF Array and the producer and consumer semaphores - cout << "Control:\tFunct.: changeSimulationTime\tData: get_stepSize() " << stepSize << endl; fflush(stdout); - setSimulationTimeReversed(stepSize + changedSimulationTime); - if (debugLevelControl > 0) - { - cout << "Control:\tFunct.: changeSimulationTime\tData: globalData->lastEmittedTime: " << get_lastEmittedTime() << endl; fflush(stdout); - cout << "Control:\tFunct.: changeSimulationTime\tData: globalData->timeValue: " << get_timeValue() << endl; fflush(stdout); - } - } - else - { - createMessage("Error: Time is not stored anymore"); - } - - //If the parameter changed while simulation is running, the simulation must go on after changing parameter in global data - if (preStatus.compare("start") == 0) - startSimulation(); -} - */ - -/** - * This method defines the mask for filter transfer - * variable#parameter - * If one type doesn't care the space between ## has to be empty - */ -static void setFilterForTransfer(string filterstring) -{ - if (debugLevelControl > 0) - { - cout << "Control:\tFunct.: setFilterForTransfer\tData: filterstring: " << filterstring << endl; fflush(stdout); - } - - parseNameTypes(filterstring); -} - -/***************************************************************** - * Controlling of simulation runtime - *****************************************************************/ - -/** - * Starts all producers and consumers, afterwards the simulation is running - */ -static void startSimulation(void) -{ - if (status.compare("start") != 0) { - mutexSimulationStatus->Lock(); - simulationStatus = SimulationStatus::RUNNING; - waitForResume->Post(NUMBER_PRODUCER + NUMBER_CONSUMER); - mutexSimulationStatus->Unlock(); - - status = "start"; - if (debugLevelControl > 0) - cout << "Control:\tFunct.: startSimulation\tMessage: start done" << endl; fflush( stdout); - } else { - if (debugLevelControl > 0) - cout << "Control:\tFunct.: startSimulation\tMessage: already started" << endl; fflush( stdout); - } -} - -/** - * interrupts the simulation but the actual state will be save - */ -static void pauseSimulation(void) -{ - if (status.compare("start") == 0) { - /*Try lock the mutex is necessary, because the producer and consumer threads are working on the - * global data which is protected by a mutex - * A lock in pause ensures that the threads finished their job before they will be interrupted - */ - - // Is this necessary anymore? - lockMutexSSD(); - - denied_work_on_GD(); - - mutexSimulationStatus->Lock(); - simulationStatus = SimulationStatus::PAUSED; - mutexSimulationStatus->Unlock(); - - allow_work_on_GD(); - - releaseMutexSSD(); - - status = "pause"; - if (debugLevelControl > 0) - cout << "Control:\tFunct.: pauseSimulation\tMessage: pause done" << endl; fflush( stdout); - } else { - if (debugLevelControl > 0) - cout << "Control:\tFunct.: pauseSimulation\tMessage: already paused or stopped" << endl; fflush( stdout); - } - if (debugLevelControl > 0) - cout << "Control:\tFunct.: pauseSimulation\t[" << getMinTime_inSSD() << " - " << getMaxTime_inSSD() << "]" << endl; fflush( stdout); -} - -/** - * Interrupts the simulation and reset all simulation data to initial state - */ -static void stopSimulation(void) -{ - if (status.compare("stop") != 0) - { - pauseSimulation(); - - // Is this necessary anymore: pv yes, because the ssdArray must be synchronized - lockMutexSSD(); - denied_work_on_GD(); - - reInitAll(); - - mutexSimulationStatus->Lock(); - simulationStatus = SimulationStatus::STOPPED; - mutexSimulationStatus->Unlock(); - - allow_work_on_GD(); - releaseMutexSSD(); - - status = "stop"; - - if (debugLevelControl > 0) - cout << "Control:\tFunct.: stopSimulation\tMessage: stop done" << endl; fflush(stdout); - } - else - { - if (debugLevelControl > 0) - cout << "Control:\tFunct.: stopSimulation\tMessage: already stopped" << endl; fflush(stdout); - } -} - -static void endSimulation(void) -{ - mutexSimulationStatus->Lock(); - simulationStatus = SimulationStatus::SHUTDOWN; - mutexSimulationStatus->Unlock(); - shutDown(); -} - -/***************************************************************** - * Standard methods for controlling of simulation runtime - *****************************************************************/ - -/** - * Sets the shutdown signal on true, in order to signal simulation shutdown - * to all running control threads - * - */ -static void shutDown(void) -{ - shutDownSignal = true; -} - -/***************************************************************** - * Network Communication between the simulation runtime as server and gui,script file,... as client - * gobalError management, future network configuration - *****************************************************************/ -/* -int sendMessageToClient(SOCKET* p_ConnectSocket, string message) -{ - int iResult; - iResult = send(*p_ConnectSocket, message.data(), message.size(), 0); - - if (iResult == SOCKET_ERROR) - { - printf("send failed: %d\n", WSAGetLastError()); - closesocket(*p_ConnectSocket); - WSACleanup(); - return 1; - } - - return iResult; -}*/ - -/** - * Parses a message from a client and calls the needed operation - * If the message is correct it will be replied with an done message afterwards, - * otherwise it will be replied with an error message. - * See OM Documentation for a list of all available operations (Chapter 5.4.2 Operation Messages) - */ -static void parseMessageFromClient(string message) -{ - // IMPORTANT: The Control Server should be able to reply with an error message while the Control Client is not initialized e.g. if an user sends an malformed operation - - /*SYSTEMTIME systime; - GetSystemTime(&systime); - cout << systime.wSecond << systime.wMilliseconds << endl; fflush(stdout); - cout << operation << endl; fflush(stdout); */ - - //"start","pause","stop","shutdown","init","setfilter","changetime","changevalue", - //string::npos is the maximum value for size_t - string::size_type checkForSharpSymbol = message.find_last_of("#"); - if (checkForSharpSymbol != string::npos) { - string end = message.substr(checkForSharpSymbol + 1); - - if (end.compare("end") == 0) { - //Operation send via message - string operation; - //Sequence number send via message - string seqNumber; - //Attributes send via message - string attributes; - - //op#seq#attr - string opANDseqANDattr; - - opANDseqANDattr = message.substr(0, checkForSharpSymbol); - string::size_type checkForSharpSymbolAfterOperation = - opANDseqANDattr.find_first_of("#"); - - if (checkForSharpSymbolAfterOperation != string::npos) { - operation = opANDseqANDattr.substr(0, - checkForSharpSymbolAfterOperation); - - //seq#attr - string seqANDattr; - seqANDattr = opANDseqANDattr.substr( - checkForSharpSymbolAfterOperation + 1); - - string::size_type checkForSharpSymbolAfterSeqNumber = - seqANDattr.find_first_of("#"); - if (checkForSharpSymbolAfterSeqNumber != string::npos) { //Used with operations which needs seq and attribute - seqNumber = seqANDattr.substr(0, - checkForSharpSymbolAfterSeqNumber); - attributes = seqANDattr.substr( - checkForSharpSymbolAfterSeqNumber + 1); - //Used with operations which doesn't need attributes e.g. start, stop, pause,... - } else if ((operation.compare("start") == 0) - || (operation.compare("pause") == 0) - || (operation.compare("stop") == 0) - || (operation.compare("shutdown") == 0)) { - seqNumber = seqANDattr; - } else { - createMessage( - "Error: Missing '#' symbol to separate sequence number from attribute"); - return; - } - } else { - createMessage( - "Error: Missing '#' symbol to separate operation from sequence number"); - return; - } - /* - * To optimize the reaction on a user interaction, most used operations should - * be at beginning of the if else queries - */ - if (debugLevelControl > 0) { - cout << "Control:\tMessage: Operation: " << operation << endl; - fflush( stdout); - } - - if (operation.compare("setcontrolclienturl") == 0) { - string ip = parseIP(attributes); - - if (debugLevelControl > 0) { - cout << "Control:\tMessage: control client ip: " << ip << endl; - fflush( stdout); - } - - int port = parsePort(attributes); - if (debugLevelControl > 0) { - cout << " port: " << port << endl; - fflush( stdout); - } - setControlClientIPandPort(ip, port); - clientDone = true; - createControlClient(); - } else if (operation.compare("settransferclienturl") == 0) { - string ip = parseIP(attributes); - - if (debugLevelControl > 0) { - cout << "Control:\tMessage: transfer client ip: " << ip << endl; - fflush( stdout); - } - - int port = parsePort(attributes); - - if (debugLevelControl > 0) { - cout << " port: " << port << endl; - fflush( stdout); - } - - setTransferIPandPort(ip, port); - transferDone = true; - createProducerAndConsumer(); - } else { - - /* - * If the default network settings should be used the clientDone and transferDone variables are false - */ - { - if (!clientDone) { - setControlClientIPandPort(control_default_client_ip, - control_default_client_port); - clientDone = true; - createControlClient(); - } - if (!transferDone) { - setTransferIPandPort(transfer_default_server_ip, - transfer_default_server_port); - transferDone = true; - createProducerAndConsumer(); - } - } - - //This block parses the commonly used messages from a client - { - if (operation.compare("changevalue") == 0) { - string::size_type endOfTime = attributes.find_first_of( - "#"); - if (endOfTime != string::npos) { - string time = attributes.substr(0, endOfTime); - string parameter = attributes.substr(endOfTime + 1); - - //Check if time is a valid double value - char* rest = 0; - double d = strtod(time.c_str(), &rest); - if (*rest == 0) - changeParameterValues(d, parameter); - else { - createMessage( - "Error: The time value is not a valid double value"); - return; - } - } else { - createMessage( - "Error: Missing '#' symbol to separate time from parameter"); - return; - } - } else if (operation.compare("changetime") == 0) { - string time = attributes; - //Check if time is a valid double value - char* rest = 0; - double d = strtod(time.c_str(), &rest); - if (*rest == 0) - changeSimulationTime(d); - else { - createMessage( - "Error: The time value is not a valid double value"); - return; - } - } else if (operation.compare("pause") == 0) { - pauseSimulation(); - } else if (operation.compare("start") == 0) { - startSimulation(); - } else if (operation.compare("stop") == 0) { - stopSimulation(); - } else if (operation.compare("shutdown") == 0) { - endSimulation(); - } else if (operation.compare("setfilter") == 0) { - string parameter = attributes; - setFilterForTransfer(parameter); - } else { - createMessage( - "Error: Unknown operation [please view documentation]"); - return; - } - } - } - //Send done message if the message was correct and the operation has been executed - ostringstream formatter; - formatter << "done#" << seqNumber << "#end"; - createMessage(formatter.str()); - } else { - createMessage( - "Error: Missing 'end' string at the end of the message"); - return; - } - } else { - createMessage("Error: Missing '#' symbol to separate tokens from end"); - return; - } -} - -/***************************************************************** - * Global Error handling - *****************************************************************/ - -static void createMessage(string newmessageForClient) -{ - messageForClient = newmessageForClient; - semaphoreMessagesToClient.Post(); -} - -/***************************************************************** - * Common help methods - *****************************************************************/ - -/** - * This functions parses a string like "ip#port" - * and returns the ip value of it as an string - */ -static string parseIP(string ip_port) -{ - string::size_type checkForSharpSymbol = ip_port.find_first_of("#"); - if (checkForSharpSymbol != string::npos) { - string ip = ip_port.substr(0, checkForSharpSymbol); - return ip; - } else { - createMessage("Error: Missing '#' symbol to separate ip from parameter"); - return ""; - } -} - -/** - * This functions parses a string like "ip#port" - * and returns the port value of it as an int - */ -static int parsePort(string ip_port) -{ - string::size_type checkForSharpSymbol = ip_port.find_first_of("#"); - if (checkForSharpSymbol != string::npos) { - string port = ip_port.substr(checkForSharpSymbol + 1); - std::istringstream stream(port); - int portvalue; - stream >> portvalue; - return portvalue; - - } else { - createMessage( - "Error: Missing '#' symbol to separate port from parameter"); - return 0; - } -} - -/** - * Recursive method to parse all names and values from the string state and set the values to the to the p_SSD parameter - */ -static void parseState(SimStepData* p_SSD, string state) -{ - string::size_type checkForDoublePoint = state.find_first_of(":"); - if (checkForDoublePoint != string::npos) { - string statenameANDstatevalue = state.substr(0, checkForDoublePoint); - state = state.substr(checkForDoublePoint + 1); - setValuesFrom_A_SSD(p_SSD, 's', statenameANDstatevalue); - parseState(p_SSD, state); - } else { - setValuesFrom_A_SSD(p_SSD, 's', state); - } -} - -/** - * Recursive method to parse all names and values from the string algebraic and set the values to the to the p_SSD parameter - */ -static void parseAlgebraic(SimStepData* p_SSD, string algebraic) -{ - string::size_type checkForDoublePoint = algebraic.find_first_of(":"); - if (checkForDoublePoint != string::npos) { - string algnameANDalgvalue = algebraic.substr(0, checkForDoublePoint); - algebraic = algebraic.substr(checkForDoublePoint + 1); - setValuesFrom_A_SSD(p_SSD, 'a', algnameANDalgvalue); - parseAlgebraic(p_SSD, algebraic); - } else { - setValuesFrom_A_SSD(p_SSD, 'a', algebraic); - } -} - -/** - * Recursive method to parse all names and values from the string parameter and set the values to the to the p_SSD parameter - */ -static void parseParameter(SimStepData* p_SSD, string parameter) -{ - string::size_type checkForDoublePoint = parameter.find_first_of(":"); - if (checkForDoublePoint != string::npos) { - string parnameANDparvalue = parameter.substr(0, checkForDoublePoint); - parameter = parameter.substr(checkForDoublePoint + 1); - setValuesFrom_A_SSD(p_SSD, 'p', parnameANDparvalue); - parseParameter(p_SSD, parameter); - } else { - setValuesFrom_A_SSD(p_SSD, 'p', parameter); - } -} - -/* - ********** Creating Filtermask - */ - -/** - * This method is used to set the filter mask depends on a filter string from the user/gui - */ -static void parseNameTypes(string filterstring) -{ - if (debugLevelControl > 0) - { - cout << "Control:\tFunct.: parseNameTypes\tData: filter string: " << filterstring << endl; fflush(stdout); - } - string::size_type checkForSharp; - /* - * Filter for variables (state and algebraic) - */ - checkForSharp = filterstring.find_first_of("#"); - if (checkForSharp != string::npos) { - string variablesNames = filterstring.substr(0, checkForSharp); - filterstring = filterstring.substr(checkForSharp + 1); - if (variablesNames.compare("") != 0) //If false, there is no filter for this type - parseNames(p_simDataNamesFilterForTransfer, 'v', variablesNames); - } - - /* - * Filter for parameter - */ - string parametersNames = filterstring; - if (parametersNames.compare("") != 0) //If false, there is no filter for this type - parseNames(p_simDataNamesFilterForTransfer, 'p', parametersNames); -} - -/** - * parses all names from a type (state, algebraic,...) - */ -static void parseNames(SimDataNamesFilter* p_SDN, char type, string names) -{ - //if(debugLevelControl) { cout << "Type: "<< type << " Name: " << names << endl; fflush(stdout); } - string::size_type checkForDoublePoint = names.find_first_of(":"); - if (checkForDoublePoint != string::npos) { - string name = names.substr(0, checkForDoublePoint);//single name - names = names.substr(checkForDoublePoint + 1); //rest of string with more names - addNameTo_A_SimDataNames(p_SDN, type, name); - parseNames(p_SDN, type, names); - } else { - addNameTo_A_SimDataNames(p_SDN, type, names); - } -} - -/** - * Adds a name to a simdatanames structure - * this is used to set the filter for transfer - */ -static void addNameTo_A_SimDataNames(SimDataNamesFilter* p_SDN, char type, string name) -{ - if (debugLevelControl > 1) - { - cout << "Type: " << type << " Name: " << name << endl; fflush(stdout); - } - - switch (type) { - case 'v': - //Check if the variable is an state or an algebraic and what index does it have - { - bool found = false; - int indexInFilterArr = 0; - for (int var = 0; var < nStates; var++, indexInFilterArr++) { - if (debugLevelControl > 1) - { - cout << "STATENAME: " << p_simDataNames_SimulationResult->statesNames[var] << endl; fflush(stdout); - } - - if (p_simDataNames_SimulationResult->statesNames[var] == name - && p_SDN->variablesNames[indexInFilterArr] == string("")) { - p_SDN->variablesNames[indexInFilterArr] = name; - found = true; - if (debugLevelControl > 1) - { - cout << "VARFILTERNAME: " << name << endl; fflush(stdout); - } - break; - } - } - - if (!found) { - if (debugLevelControl > 1) - { - cout << "is not state" << endl; fflush(stdout); - } - for (int var = 0; var < (nStates + nAlgebraic); var++, indexInFilterArr++) { - if (debugLevelControl > 1) - { - cout << "ALGNAME: " << p_simDataNames_SimulationResult->algebraicsNames[var] << endl; fflush(stdout); - } - if (p_simDataNames_SimulationResult->algebraicsNames[var] - == name && p_SDN->variablesNames[indexInFilterArr] - == string("")) { - p_SDN->variablesNames[indexInFilterArr] = name; - if (debugLevelControl > 1) - { - cout << "VARFILTERNAME: " << name << endl; fflush(stdout); - } - break; - } - } - } - } - break; - - case 'p': - for (int var = 0; var < nParameters; var++) { - if (p_SDN->parametersNames[var] == string("")) { - p_SDN->parametersNames[var] = name; - if (debugLevelControl > 1) - { - cout << "PARFILTERNAME: " << name << endl; fflush(stdout); - } - break; - } - } - break; - - default: - if (debugLevelControl > 0) - { - cout << "Incorrect Type" << endl; fflush(stdout); - } - break; - } -} -/* - ********** END Creating Filtermask - */ - -/** - * set a value for a state, algebraic, parameter... from global data - * the string looks like this "name=value" - * type is for variable type - * state: s - * algebraic: a - * parameter: p - * ... - */ -static void setValuesFrom_A_SSD(SimStepData* p_SSD, char type, string nameANDvalue) -{ - bool findElement = false; - - string::size_type checkForEquals = nameANDvalue.find_first_of("="); - if (checkForEquals != string::npos) { - string name = nameANDvalue.substr(0, checkForEquals); - string valueString = nameANDvalue.substr(checkForEquals + 1); - - //Check if time is a valid double value - char* rest = 0; - double valueDouble = strtod(valueString.c_str(), &rest); - if (*rest == 0) { - - switch (type) { - case 's': - for (int var = 0; var < nStates; var++) { - if (p_simDataNames_SimulationResult->statesNames[var] - == string(name)) { - findElement = true; - p_SSD->states[var] = valueDouble; - break; - } - } - break; - - case 'a': - for (int var = 0; var < nAlgebraic; var++) { - if (p_simDataNames_SimulationResult->algebraicsNames[var] - == string(name)) { - findElement = true; - p_SSD->algebraics[var] = valueDouble; - break; - } - } - break; - - case 'p': - for (int var = 0; var < nParameters; var++) { - if (p_simDataNames_SimulationResult->parametersNames[var] - == string(name)) { - findElement = true; - p_SSD->parameters[var] = valueDouble; - break; - } - } - break; - - default: - if (debugLevelControl > 0) - { - cout << "Incorrect Type" << endl; fflush(stdout); - } - break; - } - } else { - createMessage("Error: The value is not a valid double value"); - } - - if (!findElement) - createMessage("Error: Parameter " + name + " not found"); - } else { - createMessage("Error: Missing '=' between name and value"); - } -} - -/***************************************************************** - * ServerControl and ClientControl Threads - *****************************************************************/ - -/** - * Initial Thread which provides a communication server. - * Waits for requests from a client - */ -THREAD_RET_TYPE threadServerControl(THREAD_PARAM_TYPE lpParam) { - Socket sock1; - sock1.create(); - if (control_server_port != 0) { - sock1.bind(control_server_port); - } else { - sock1.bind(control_default_server_port); - } - - sock1.listen(); - Socket sock2; - sock1.accept(sock2); - - initialize(); - - while (!shutDownSignal && !error) { - string operation; - delay(1000); - sock2.recv(operation); - if (operation.compare("") != 0) { - if (debugLevelControl > 0) - { - cout << "Client Message: "; fflush(stdout); - cout << operation << endl; fflush(stdout); - } - parseMessageFromClient(operation); - } - } - sock2.close(); - sock1.close(); - - return (THREAD_RET_TYPE_NO_API)error; -} - -/** - * Client Control Thread which communicates with a server do send status or error messages - */ -THREAD_RET_TYPE threadClientControl(THREAD_PARAM_TYPE lpParam) { - Socket sock; - sock.create(); - - connectToControlServer(&sock); - - //Waits for a message to the client - while (!shutDownSignal) { - semaphoreMessagesToClient.Wait(); - - bool status = sock.send(messageForClient); - if (status) - { - cout << "Message send: " << messageForClient << endl; fflush(stdout); - } - else - { - cout << "Fail to send" << endl; fflush(stdout); - } - } - sock.close(); - - return 0; -} diff --git a/SimulationRuntime/interactive/omi_Control.h b/SimulationRuntime/interactive/omi_Control.h deleted file mode 100644 index f605b3cbbde..00000000000 --- a/SimulationRuntime/interactive/omi_Control.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * OpenModelica Interactive (Ver 0.7) - * Last Modification: 3. October 2009 - * - * Developed by: - * EADS IW Germany - * Developer: Parham Vasaiely - * Contact: vasaie_p@informatik.haw-hamburg.de - * - * File description: omi_Control.h - * - * Full specification available in the bachelor thesis of Parham Vasaiely - * "Interactive Simulation of SysML Models using Modelica" (Chapter 5) - */ - -#include -#include "thread.h" - -//#ifndef _MY_SIMULATIONCONTROL_H -#define _MY_SIMULATIONCONTROL_H - -struct SimulationStatus -{ - enum type - { - RUNNING, - PAUSED, - STOPPED, - SHUTDOWN - }; -}; - -extern SimulationStatus::type simulationStatus; -extern Mutex* mutexSimulationStatus; -/* - * The waitForResume Semaphore signals to the calculation and the transfer thread to start/go-on there process - * The threads will organize there running or waiting using this semaphore. If the status of the simulation has been changed to - * pause there won't increase the semaphore so they have to wait. The start method of control will increase the semaphore again - */ -extern Semaphore* waitForResume; - -THREAD_RET_TYPE threadServerControl(THREAD_PARAM_TYPE); - -//****** Network Configuration ****** -void setControlClientIPandPort(std::string, int); -void resetControlClientIPandPortToDefault(void); -void setControlServerPort(int); -void resetControlServerPortToDefault(void); diff --git a/SimulationRuntime/interactive/omi_ResultManager.cpp b/SimulationRuntime/interactive/omi_ResultManager.cpp deleted file mode 100644 index 7033b3df9ea..00000000000 --- a/SimulationRuntime/interactive/omi_ResultManager.cpp +++ /dev/null @@ -1,719 +0,0 @@ -/* - * OpenModelica Interactive (Ver 0.75) - * Last Modification: 23. May 2011 - * - * Developed by: - * EADS IW Germany - * Developer: Parham Vasaiely - * Contact: Parham.Vasaiely@eads.com - * - * File description: omi_ResultManager.cpp - * While a simulation is running the `Calculation' thread produces simulation results for every time step, - * and the `Transfer' thread sends the single results to a client. - * There is a need for synchronization and organisation of simulation results. - * However, the application cannot store all results because this would cause the system to run out of memory. - * This scenario is the typical `producer and consumer problem with restricted buffer', - * which is well known in IT science. - * The `ResultManager' assumes responsibility for organizing simulation result data and - * synchronizing access to these data. - * - * Full specification available in the bachelor thesis of Parham Vasaiely - * "Interactive Simulation of SysML Models using Modelica" (Chapter 5) - */ - -#include -#include -#include -#include -#include "omi_ResultManager.h" - -using namespace std; - -#define MAX_SSD 200 //Maximum number of Simulation Step Data elements -#define MAX_SRDF 20 //Maximum number of Simulation Result Data elements for Forwarding - -double EPSILON = 0.0001; -int debugResultManager = 0; //Set the debug level higher zero to print out messages which describes the program flow to the console [0= debug off, 1= min-debug, 2= max-debug] -/* - * This element signalizes that the simulation runs for the first time. - * It is important to store data into the "simulationStartSSD" - */ -bool firstRun = true; //TODO [20110522] firstRun zurück setzten für stop - -/* - * After a simulation reset a (all) calculation thread must start from new - * but in some cases the calculation thread is waiting to add a result into SSD. - * In this case the first time which should be added to the SDD is 0 or 2.220446049250313e-13 - */ -double VALID_TIME_AFTER_RESET = 2.220446049250313e-13; -bool simulationReset = false; //Set true after an reset to signal that the simulation has been stopped. - -double VALID_TIME_AFTER_CHANGETIME = 0; -bool simulationChangetime = false; //Set true after an reset to signal that the simulation has been stopped. -/* - * This SimStepData element represents the state at the initial state, - * it is necessary to be saved because of the method reInitAll in control - */ -SimStepData simulationStartSSD; -//Points on the simulation step data at the initial state -SimStepData* p_simulationStartSSD; - -//***** SimStepData buffer ***** -SimStepData ssdArray[MAX_SSD] = {{0}}; - -SimStepData* p_ssdArray_NextFreeSlot = 0; //Points on the next free slot - -/* p_ssdArray_LastSlot points on the last array slot, if the set - * method reached this address the pointer has to point to the first slot of the array - */ -SimStepData* p_ssdArray_LastSlot = 0; - -//***** SimStepData for forwading buffer (SimulationResultDataForwarding)***** - -/* - * This array contains pointers from the type SimStepData, which points on elements - * in the ssdArray, so there is much less redundancy - * - * Note: All pointers which points an this array have to be pointers of pointers - */ -SimStepData* srdfArrayOfPointer[MAX_SRDF] = { 0 }; - -SimStepData** pp_srdfArray_FirstQueueElement = 0;//Points on the smallest time step pointer -SimStepData** pp_srdfArray_NextFreeSlot = 0; //Points on the next free slot from SRDF Array to insert an element -SimStepData** pp_srdfArray_LastSlot = 0; //Points on the lsat slot of the srdfArrayOfPointer - -//***** SimDataNames Contains all Variable, Algebraic and State names***** -SimDataNames simDataNames_SimulationResult; -SimDataNames* p_simDataNames_SimulationResult = 0; - -SimDataNamesFilter simDataNamesFilterForTransfer; -SimDataNamesFilter* p_simDataNamesFilterForTransfer = 0; - -SimDataNumbers simdatanumbers; -P_SimDataNumbers p_simdatanumbers = 0; -//***** Objects for synchronization -Mutex ssdMutex; - -Semaphore ghSemaphore_NumberUsedSlots(0, MAX_SRDF); -Semaphore ghSemaphore_NumberFreeSlots(MAX_SRDF, MAX_SRDF); -//Mutex for simdatanumbers synchronization -Mutex sdnMutex; -Mutex* p_sdnMutex; - -//static void reInitSSD_A(void); -//static bool deinitializeAll(void); -//SSD Organisation -static void addDataToSSD(SimStepData*); -static void pointNextFreeSSDSlot(void); -//SRDF Organisation -static void pointNextFreeSRDFSlot(void); -static void pointNextUsedSRDFSlot(void); -static void pushSRDF(void); -static void popSRDF(SimStepData*); - -//Math help methods -static bool compareDouble(double, double); -//print methods for testing -static void printSSD(void); -static void printSRDF(void); - -/***************************************************************** - * Organisation and Management of SSD, SRDF, SimDataNames... - * e.g. Parameters, Variables, Simulation Setup... - * Initialization for simulation data - *****************************************************************/ -bool initializeSSD_AND_SRDF(long nStates, long nAlgebraic, long nParameters) -{ - bool retValue = true; - //simDataNames_SimulationResult will be initialize from the SimulationControl - - p_ssdArray_NextFreeSlot = ssdArray; - - { //initialize the SSDArray with NullSSDs - for (int i = 0; i < MAX_SSD; i++) { - SimStepData nullSSD; //this SimStepData element represents a null element in the SSD Array - nullSSD.forTimeStep = -1; //if the forTimeStep is -1 the element is null - double *statesTMP1 = new double[nStates]; - double *statesDerivativesTMP1 = new double[nStates]; - double *algebraicsTMP1 = new double[nAlgebraic]; - double *parametersTMP1 = new double[nParameters]; - //TODO [201105222] pv: optimization try putting new array directly into the ssdArraySlot instead of creating an nullSDD first - nullSSD.states = statesTMP1; - nullSSD.statesDerivatives = statesDerivativesTMP1; - nullSSD.algebraics = algebraicsTMP1; - nullSSD.parameters = parametersTMP1; - - ssdArray[i] = nullSSD; - } - } - - { //initialize the SSD for the first simulation run (e.g. at time 0) - p_simulationStartSSD = &simulationStartSSD; - double *statesTMP2 = new double[nStates]; - double *statesDerivativesTMP2 = new double[nStates]; - double *algebraicsTMP2 = new double[nAlgebraic]; - double *parametersTMP2 = new double[nParameters]; - p_simulationStartSSD->states = statesTMP2; - p_simulationStartSSD->statesDerivatives = statesDerivativesTMP2; - p_simulationStartSSD->algebraics = algebraicsTMP2; - p_simulationStartSSD->parameters = parametersTMP2; - } - //p_ssdArray_NextFreeSlot = ssdArray; //Done from resetSSDArrayWithNull... - p_ssdArray_LastSlot = &ssdArray[MAX_SSD - 1]; - - pp_srdfArray_FirstQueueElement = srdfArrayOfPointer; - pp_srdfArray_NextFreeSlot = srdfArrayOfPointer; - pp_srdfArray_LastSlot = &srdfArrayOfPointer[MAX_SRDF - 1]; - - p_simdatanumbers = &simdatanumbers; - p_simdatanumbers->nStates = nStates; - p_simdatanumbers->nAlgebraic = nAlgebraic; - p_simdatanumbers->nParameters = nParameters; - - p_simDataNames_SimulationResult = &simDataNames_SimulationResult; - p_simDataNamesFilterForTransfer = &simDataNamesFilterForTransfer; - - /* - * Dynamic definition of struct data - */ - string *statesNamesTMP = new string[nStates]; - string *stateDerivativesNamesTMP = new string[nStates]; - string *algebraicsNamesTMP = new string[nAlgebraic]; - string *parametersNames1TMP = new string[nParameters]; - p_simDataNames_SimulationResult->statesNames = statesNamesTMP; - p_simDataNames_SimulationResult->stateDerivativesNames = stateDerivativesNamesTMP; - p_simDataNames_SimulationResult->algebraicsNames = algebraicsNamesTMP; - p_simDataNames_SimulationResult->parametersNames = parametersNames1TMP; - //**** - string *variablesNamesTMP = new string[nStates + nAlgebraic]; - string *parametersNames2TMP = new string[nParameters]; - p_simDataNamesFilterForTransfer->variablesNames = variablesNamesTMP; - p_simDataNamesFilterForTransfer->parametersNames = parametersNames2TMP; - //**** - p_sdnMutex = &sdnMutex; - - return retValue; -} - -/* - * Call this function after shutdown to free all allocated memory - * TODO [20110523] pv: TBD - */ -bool deInitializeSSD_AND_SRDF(void) -{ - for (int i = 0; i < MAX_SSD; i++) { - delete [] ssdArray[i].states; - delete [] ssdArray[i].statesDerivatives; - delete [] ssdArray[i].algebraics; - delete [] ssdArray[i].parameters; - } - return true; -} - -/***************************************************************** - * Getter and Setter from the Interface ResultManager.h - *****************************************************************/ - -P_SimDataNumbers getSimDataNumbers(void) -{ - return p_simdatanumbers; -} - -/** - * Reads the SimStepData from a Calculation thread and adds it to the intern SSD buffer and the SRDF buffer. - * parameter: pointer from type SimStepData, it points on a data struct in a Calculation thread - */ -bool setResultData(SimStepData* p_SimStepData_from_Calculation) -{ - bool retValue = true; - - /* - * This part is necessary for the producer &consumer problem with districted buffer - * The any entity which want to use the array must pas this part - */ - // Try to enter the ghSemaphore_NumberFreeSlots gate. - ghSemaphore_NumberFreeSlots.Wait(); - - ssdMutex.Lock(); - /******************************************************************** - * Entity has pas the synchronization section and can work on the SSD buffer - * Restrictions: if the simulation has been reseted the first time value must be VALID_TIME_AFTER_RESET - * otherwise the result won't be added to the system - */ - - //block used by normal running simulation - if(!simulationReset && !simulationChangetime){ - addDataToSSD(p_SimStepData_from_Calculation); - if (debugResultManager > 0) { - cout << "add time: " << p_SimStepData_from_Calculation->forTimeStep << endl; fflush(stdout); - } - }else{//block used once after simulation has been reseted or more if the next time to add into the ssd is not VALID_TIME_AFTER_RESET - if(simulationReset){ - if(p_SimStepData_from_Calculation->forTimeStep == VALID_TIME_AFTER_RESET || p_SimStepData_from_Calculation->forTimeStep == 0){ - addDataToSSD(p_SimStepData_from_Calculation); - //cout << "add after reset time: " << p_SimStepData_from_Calculation->forTimeStep << endl; fflush(stdout); - simulationReset = false; - } - else{ - //cout << "no chance for reset ;) time: " << p_SimStepData_from_Calculation->forTimeStep << endl; fflush(stdout); - } - } else{ - if(simulationChangetime){ - - if(compareDouble(p_SimStepData_from_Calculation->forTimeStep, VALID_TIME_AFTER_CHANGETIME)){ - //cout << "add after change time: " << p_SimStepData_from_Calculation->forTimeStep << endl; fflush(stdout); - addDataToSSD(p_SimStepData_from_Calculation); - simulationChangetime = false; - } else{ - //cout << "no chance for change ;) time: " << p_SimStepData_from_Calculation->forTimeStep << endl; fflush(stdout); - } - } - } - } - - //Work on SSD and SRDF buffer ended ********************************** - - // Release the mutex - if (!ssdMutex.Unlock()) { - //printf("ReleaseMutex ssdMutex error: %d\n", GetLastError()); - return false; - } - //if(debugResultManager) { cout << "set released mutex" << endl; fflush(stdout); } - // Release the semaphore ghSemaphore_NumberUsedSlots - ghSemaphore_NumberUsedSlots.Post(); - - return retValue; -} - -/** - * Fills the SimStepData from a Transfer thread with the first simulation result from the SRD queue - * This method won't filter the data, all existing and available parameter, algebraic and states will be saved. - * parameter: pointer from type SimStepData, it points on a data struct in a Transfer thread - */ -bool getResultData(SimStepData* p_SimResDataForw_from_Transfer) { - bool retValue = true; - - /* - * This part is necessary for the producer &consumer problem with districted buffer - * An entity which want to use the array must pas this part - */ - ghSemaphore_NumberUsedSlots.Wait(); - ssdMutex.Lock(); - - /******************************************************************** - * Entity has pas the synchronization station and can work on the SSD buffer - */ - if ((*pp_srdfArray_FirstQueueElement)->forTimeStep != -1) { - popSRDF(p_SimResDataForw_from_Transfer); - } else{ - //cout << "no chance ;) for time: " << (*pp_srdfArray_FirstQueueElement)->forTimeStep << endl; fflush(stdout); - } - - - // Release the mutex - ssdMutex.Unlock(); - ghSemaphore_NumberFreeSlots.Post(); - - return retValue; -} - -/** - * The SSD array is divided by the NextFreeSlot pointer in two parts. - * e.g. Part A is the higher leveled part containing the highest SimStepData and Part B containing the lowest SimStepData. - * ------------------- - * |8|9|10|11|4|5|6|7| - * ------------------- - * A | B - * the NextFreeSlot pointer points on the element with at the time "4", so we need two different searching algorithms - * for each part. - * - * Return: If the searched step time is not stored in the ssd, the method returns a pointer which points an nullSSD - * otherwise it points on the searched element - */ -SimStepData* getResultDataForTime(double stepSize, double timeStep) { - - if (debugResultManager > 1) { - cout - << "ResultManager:\tFunct.: getResultDataForTime\tMessage: All SSD Array elements START" << endl; fflush( stdout); - for (int i = 0; i < MAX_SSD; i++) { - cout << ssdArray[i].forTimeStep << endl; fflush(stdout); - } - cout - << "ResultManager:\tFunct.: getResultDataForTime\tMessage: All SSD Array elements END" << endl; fflush(stdout); - } - - if (debugResultManager > 1) { - cout - << "ResultManager:\tFunct.: getResultDataForTime\tMessage: ADD of p_ssdArray_NextFreeSlot: " - << p_ssdArray_NextFreeSlot << endl; fflush( stdout); - cout - << "ResultManager:\tFunct.: getResultDataForTime\tMessage: p_ssdArray_NextFreeSlot: " - << p_ssdArray_NextFreeSlot->forTimeStep << endl; fflush(stdout); - cout - << "ResultManager:\tFunct.: getResultDataForTime\tMessage: p_ssdArray_NextFreeSlot-1: " - << (p_ssdArray_NextFreeSlot - 1)->forTimeStep << endl; fflush(stdout); - cout - << "ResultManager:\tFunct.: getResultDataForTime\tMessage: timeStep: " - << timeStep << endl; - fflush(stdout); - } - - SimStepData* temp; - - //check if the searched time step is available in simulationstepdata (ssd) - if (timeStep == p_ssdArray_NextFreeSlot->forTimeStep || (timeStep - > p_ssdArray_NextFreeSlot->forTimeStep && timeStep - <= (p_ssdArray_NextFreeSlot - 1)->forTimeStep)) { - - SimStepData* firstSSD_Element = ssdArray; - - //If this query returns true we have to search in Part B, because the time step is smaller than the lowest ssd in Part A - if (timeStep < firstSSD_Element->forTimeStep) { - temp = static_cast (((timeStep - - p_ssdArray_NextFreeSlot->forTimeStep) / stepSize) - + 0.0001) + p_ssdArray_NextFreeSlot; //+0.0001 is needed because of type cast and vision from int and double - if (debugResultManager > 1) { - cout - << "ResultManager:\tFunct.: getResultDataForTime\tMessage: getResultDataForTime search in Part B temp->forTimeStep: " - << temp->forTimeStep << endl; - fflush( stdout); - } - return temp; - } else { - temp - = static_cast (((timeStep - - firstSSD_Element->forTimeStep) / stepSize) - + 0.0001) //+0.0001 is important while casting from double to integer - + firstSSD_Element; - if (debugResultManager > 1) { - cout - << "ResultManager:\tFunct.: getResultDataForTime\tMessage: getResultDataForTime search in Part A temp->forTimeStep: " - << temp->forTimeStep << endl; - fflush( stdout); - } - return temp; - } - } else { - static SimStepData nullSSD; //this SimStepData element represents a null element in the SSD Array - nullSSD.forTimeStep = -1; //if the forTimeStep is -1 the element is null - /*double *statesTMP1 = new double[1]; - double *statesDerivativesTMP1 = new double[1]; - double *algebraicsTMP1 = new double[1]; - double *parametersTMP1 = new double[1]; - nullSSD.states = statesTMP1; - nullSSD.statesDerivatives = statesDerivativesTMP1; - nullSSD.algebraics = algebraicsTMP1; - nullSSD.parameters = parametersTMP1;*/ - temp = &nullSSD; - if (debugResultManager > 1) { - cout - << "ResultManager:\tFunct.: getResultDataForTime\tMessage: Error time not in SSD" - << endl; - fflush( stdout); - } - } - return temp; -} - -/* - * Retuns the simulation state data at the initial state - */ -SimStepData* getResultDataFirstStart(void) -{ - return p_simulationStartSSD; -} - -/* - * use this method after a change time or value operation from control - * to signal a changed time to the simulation - */ -void setSimulationTimeReversed(double validTime){ - VALID_TIME_AFTER_CHANGETIME = validTime; - if (debugResultManager > 0) { - cout << "ResultManager:\tFunct.: setSimulationTimeReversed\tData: VALID_TIME_AFTER_CHANGETIME: " << VALID_TIME_AFTER_CHANGETIME << endl; fflush( stdout); - } - simulationChangetime = true; -} - -/***************************************************************** - * Help Methods - *****************************************************************/ - -/** - * After changing simulation parameters or starting the simulation from beginning, - * the organization of the SRDF array must start again from the beginning. - * because old simulation data mustn't send to the GUI. - */ -void resetSRDFAfterChangetime(void) -{ - if (debugResultManager > 1) { - cout << "ResultManager:\tFunct.: resetSRDFAfterChangetime\tMessage: START" << endl; fflush( stdout); - } - pp_srdfArray_FirstQueueElement = srdfArrayOfPointer; - pp_srdfArray_NextFreeSlot = srdfArrayOfPointer; - - while (ghSemaphore_NumberUsedSlots.TryWait()) { - ghSemaphore_NumberFreeSlots.Post(); - } - - if (debugResultManager > 1) { - printSRDF(); - cout << "ResultManager:\tFunct.: resetSRDFAfterChangetime\tMessage: END" << endl; fflush( stdout); - } -} - -/** - * If the simulation has to start again from the beginning - * The SSD array has to reset with nullSSD elements - */ -void resetSSDArrayWithNullSSD(long nStates, long nAlgebraic, long nParameters) -{ - p_ssdArray_NextFreeSlot = ssdArray; - simulationReset = true; - for (int i = 0; i < MAX_SSD; i++) { - - delete [] ssdArray[i].states; - delete [] ssdArray[i].statesDerivatives; - delete [] ssdArray[i].algebraics; - delete [] ssdArray[i].parameters; - - SimStepData nullSSD; //this SimStepData element represents a null element in the SSD Array - nullSSD.forTimeStep = -1; //if the forTimeStep is -1 the element is null - double *statesTMP1 = new double[nStates]; - double *statesDerivativesTMP1 = new double[nStates]; - double *algebraicsTMP1 = new double[nAlgebraic]; - double *parametersTMP1 = new double[nParameters]; - //TODO [201105222] optimization try putting new array directly into the ssdArraySlot instead of creating an nullSDD first - nullSSD.states = statesTMP1; - nullSSD.statesDerivatives = statesDerivativesTMP1; - nullSSD.algebraics = algebraicsTMP1; - nullSSD.parameters = parametersTMP1; - - ssdArray[i] = nullSSD; - // if(debugResultManager) { cout << ssdArray[i].forTimeStep << endl; fflush(stdout); } - } - if (debugResultManager > 0) { - cout << "ResultManager:\tFunct.: resetSSDArrayWithNullSSD" << endl; fflush( stdout); - printSSD(); - } -} - -void lockMutexSSD(void) -{ - ssdMutex.Lock(); -} - -void releaseMutexSSD(void) -{ - ssdMutex.Unlock(); -} - -/* - * Returns the minimum time stored in the SSDArray - */ -double getMinTime_inSSD(void) -{ - return p_ssdArray_NextFreeSlot->forTimeStep; -} - -/* - * Returns the maximum time stored in the SSDArray - */ -double getMaxTime_inSSD(void) -{ - return (p_ssdArray_NextFreeSlot - 1)->forTimeStep; -} -/***************************************************************** - * Organization of SSD and SRDF - *****************************************************************/ - -/** - * Adds result data to the SSD Array and tries to add a pointer on it into the SRDF Array - */ -static void addDataToSSD(SimStepData* p_SimStepData_from_Calculation) -{ - - p_ssdArray_NextFreeSlot->forTimeStep = p_SimStepData_from_Calculation->forTimeStep; //is the lastEmittedTime or timeValue of this step - if (firstRun) - p_simulationStartSSD->forTimeStep = p_SimStepData_from_Calculation->forTimeStep; - - for (int i = 0; i < p_simdatanumbers->nStates; i++) { - p_ssdArray_NextFreeSlot->states[i] = p_SimStepData_from_Calculation->states[i]; - p_ssdArray_NextFreeSlot->statesDerivatives[i]= p_SimStepData_from_Calculation->statesDerivatives[i]; - - //Save the first simulation data - if (firstRun) - p_simulationStartSSD->states[i] = p_SimStepData_from_Calculation->states[i]; - if (firstRun) - p_simulationStartSSD->statesDerivatives[i] = p_SimStepData_from_Calculation->statesDerivatives[i]; - } - if (debugResultManager > 1) { - cout << "ResultManager:\tFunct.: addDataToSSD\tData 2: time = " << (p_ssdArray_NextFreeSlot)->forTimeStep << " tank1.h = " << (p_ssdArray_NextFreeSlot)->states[0] << endl; fflush( stdout); - printSSD(); - } - for (int i = 0; i < p_simdatanumbers->nAlgebraic; i++) { - p_ssdArray_NextFreeSlot->algebraics[i] = p_SimStepData_from_Calculation->algebraics[i]; - if (firstRun) - p_simulationStartSSD->algebraics[i] = p_SimStepData_from_Calculation->algebraics[i]; - } - - for (int i = 0; i < p_simdatanumbers->nParameters; i++) { - p_ssdArray_NextFreeSlot->parameters[i] = p_SimStepData_from_Calculation->parameters[i]; - if (firstRun) - p_simulationStartSSD->parameters[i] = p_SimStepData_from_Calculation->parameters[i]; - } - - firstRun = false; //simulationStartSSD should only initialize once - - //If a simulation result is pushed into SSD it also have to push into the SRDF buffer - pushSRDF(); - pointNextFreeSSDSlot(); -} - -/** - * This method points the p_ssdArrayFreeSlot pointer to the next free slot from the SSD array - * If the last slot is reached it will point p_ssdArrayFreeSlot to the first element from the SSD array - * otherwise to the next higher index - */ -static void pointNextFreeSSDSlot(void) -{ - //cout << "pointNextFreeSSDSlot: p_ssdArray_NextFreeSlot " << p_ssdArray_NextFreeSlot->forTimeStep << endl; fflush(stdout); - if (p_ssdArray_NextFreeSlot != p_ssdArray_LastSlot) { - - p_ssdArray_NextFreeSlot++; - } else { - p_ssdArray_NextFreeSlot = ssdArray; - } -} - -/* - * Organisation of SRDF - ************************************************************ - */ - -/** - * This method points the pp_srdfArray_NextFreeSlot pointer to the next free slot from the SRDF array - * If the last slot is reached it will point pp_srdfArray_NextFreeSlot to the first element from the SRDF array - * otherwise to the next higher index - */ -static void pointNextFreeSRDFSlot(void) -{ - if (pp_srdfArray_NextFreeSlot != pp_srdfArray_LastSlot) { - pp_srdfArray_NextFreeSlot++; - } else { - pp_srdfArray_NextFreeSlot = srdfArrayOfPointer; - } -} - -static void pointNextUsedSRDFSlot(void) -{ - if (pp_srdfArray_FirstQueueElement != pp_srdfArray_LastSlot) { - pp_srdfArray_FirstQueueElement++; - } else { - pp_srdfArray_FirstQueueElement = srdfArrayOfPointer; - } -} - -/** - * The SRDF buffer adds the new simulation data to its next free slot - * and calls the pointNextFreeSRDFSlot method - */ -static void pushSRDF(void) -{ - *pp_srdfArray_NextFreeSlot = &(*p_ssdArray_NextFreeSlot); - - if (debugResultManager > 1) { - cout << "ResultManager:\tFunct.: pushSRDF\tData 1: time = " << (*pp_srdfArray_NextFreeSlot)->forTimeStep << " tank1.h = " << (*pp_srdfArray_NextFreeSlot)->states[0] << endl; fflush( stdout); - cout << "ResultManager:\tFunct.: pushSRDF\tData 2: time = " << (*pp_srdfArray_FirstQueueElement)->forTimeStep << " tank1.h = " << (*pp_srdfArray_FirstQueueElement)->states[0] << endl; fflush( stdout); - printSRDF(); - } - pointNextFreeSRDFSlot(); -} - -/* - * Pops a simulation step data for a transfer thread - */ -static void popSRDF(SimStepData* p_SimResDataForw_from_Transfer) -{ - p_SimResDataForw_from_Transfer->forTimeStep - = (*pp_srdfArray_FirstQueueElement)->forTimeStep; //is the lastEmittedTime of this step - - for (int i = 0; i < p_simdatanumbers->nStates; i++) { - p_SimResDataForw_from_Transfer->states[i] - = (*pp_srdfArray_FirstQueueElement)->states[i]; - p_SimResDataForw_from_Transfer->statesDerivatives[i] - = (*pp_srdfArray_FirstQueueElement)->statesDerivatives[i]; - } - - for (int i = 0; i < p_simdatanumbers->nAlgebraic; i++) { - p_SimResDataForw_from_Transfer->algebraics[i] - = (*pp_srdfArray_FirstQueueElement)->algebraics[i]; - } - - for (int i = 0; i < p_simdatanumbers->nParameters; i++) { - p_SimResDataForw_from_Transfer->parameters[i] - = (*pp_srdfArray_FirstQueueElement)->parameters[i]; - } - - if (debugResultManager > 1) { - cout << "ResultManager:\tFunct.: popSRDF\tData: time = " - << (*pp_srdfArray_FirstQueueElement)->forTimeStep - << " tank1.h = " - << (*pp_srdfArray_FirstQueueElement)->states[0] << endl; - fflush( stdout); - } - - pointNextUsedSRDFSlot(); -} - -/***************************************************************** - * Math help methods - *****************************************************************/ - -static bool compareDouble(double a, double b) -{ - return fabs(a - b) < EPSILON; -} - -/***************************************************************** - * Print methods - *****************************************************************/ - -static void printSSD(void) -{ - - cout << "ResultManager:\tFunct.: printSSD****************" << endl; - fflush( stdout); - for (int i = 0; i < MAX_SSD; i++) { - - if (ssdArray[i].forTimeStep != -1) { - cout << "ResultManager:\tFunct.: printSSD\tData: SSD[" << i - << "]: time= " << ssdArray[i].forTimeStep - << " tank1.h = " << ssdArray[i].states[0] - << endl; - fflush(stdout); - } - } -} - -static void printSRDF(void) -{ - cout << "ResultManager:\tFunct.: printSRDF****************" << endl; - fflush( stdout); - for (int i = 0; i < MAX_SRDF; i++) { - if (srdfArrayOfPointer[i] != 0) { - if ((*srdfArrayOfPointer[i]).forTimeStep != -1) { - cout << "ResultManager:\tFunct.: printSRDF\tData: SRDF[" << i - << "]: time = " << (*srdfArrayOfPointer[i]).forTimeStep - << " tank1.h = " << (*srdfArrayOfPointer[i]).states[0] - << endl; - fflush(stdout); - } - } else { - cout << "ResultManager:\tFunct.: printSRDF\tData: SRDF[" << i - << "]: " << srdfArrayOfPointer[i] << endl; - fflush(stdout); - } - - } -} diff --git a/SimulationRuntime/interactive/omi_ResultManager.h b/SimulationRuntime/interactive/omi_ResultManager.h deleted file mode 100644 index e81ba10a3ca..00000000000 --- a/SimulationRuntime/interactive/omi_ResultManager.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * OpenModelica Interactive (Ver 0.75) - * Last Modification: 23. May 2011 - * - * Developed by: - * EADS IW Germany - * Developer: Parham Vasaiely - * Contact: Parham.Vasaiely@eads.com - * - * File description: omi_ResultManager.h - * - * Full specification available in the bachelor thesis of Parham Vasaiely - * "Interactive Simulation of SysML Models using Modelica" (Chapter 5) - */ - -#include -#include "thread.h" -using namespace std; - -//#ifndef _MY_SIMULATIONRESULT_H -#define _MY_SIMULATIONRESULT_H - -typedef struct ssd{ //SimulationStepData struct - double forTimeStep; //is the lastEmittedTime or timeValue of this step - double *states; - double *statesDerivatives; //xd DERIVATIVES - double *algebraics; - double *parameters; -} SimStepData; - -//Property Names of model simulation data (state, algebraic, variables) -typedef struct sdNames{ - string *statesNames; - string *stateDerivativesNames; - string *algebraicsNames; - string *parametersNames; -} SimDataNames; - -//Model property names used to be transfered to a client -typedef struct sdNamesForTransfer{ - string *variablesNames; //statesNames + algebraicsNames - string *parametersNames; //parametersNames -} SimDataNamesFilter; - -//Number of property values -typedef struct nValues{ - long nStates; - long nAlgebraic; - long nParameters; -} SimDataNumbers, *P_SimDataNumbers; - -extern SimDataNames* p_simDataNames_SimulationResult; -extern SimDataNamesFilter* p_simDataNamesFilterForTransfer; -extern P_SimDataNumbers p_simdatanumbers; - -extern Mutex* p_sdnMutex; - -bool initializeSSD_AND_SRDF(long, long, long); -bool deInitializeSSD_AND_SRDF(void); -bool getResultData(SimStepData*); -bool setResultData(SimStepData*); -SimStepData* getResultDataForTime(double, double); -SimStepData* getResultDataFirstStart(void); - -//Resets the SRDF Array and the producer and consumer semaphores, so the Transfer wont send old results after changing the time -void resetSRDFAfterChangetime(void); -void resetSSDArrayWithNullSSD(long, long, long); -void lockMutexSSD(void); -void releaseMutexSSD(void); -/* - * Returns the minimum time stored in the SSDArray - */ -double getMinTime_inSSD(void); -/* - * Returns the maximum time stored in the SSDArray - */ -double getMaxTime_inSSD(void); -/* - * use this method after a change time or value operation from control - * to signal a changed time to the simulation - */ -void setSimulationTimeReversed(double); diff --git a/SimulationRuntime/interactive/omi_ServiceInterface.cpp b/SimulationRuntime/interactive/omi_ServiceInterface.cpp deleted file mode 100644 index 51fc7e54901..00000000000 --- a/SimulationRuntime/interactive/omi_ServiceInterface.cpp +++ /dev/null @@ -1,753 +0,0 @@ -/* - * OpenModelica Interactive (Ver 0.7) - * Last Modification: 17. January 2010 - * - * Developed by: - * EADS IW Germany - * Developer: Parham Vasaiel y - * Contact: vasaie_p@informatik.haw-hamburg.de - * - * File description: omi_ServiceInterface.cpp - * An Interface is needed in order to support the modularization and information hiding - * principles. The OM can be developed further, without respecting the OMI code. - * The only restriction to developing OM and OMI is, to assure all functions in this interface will work - * correctly and specified results won't change after further developing a component. - * - * Full specification available in the bachelor thesis of Parham Vasaiely - * "Interactive Simulation of SysML Models using Modelica" (Chapter 5) - */ - -#include "simulation_data.h" -#include "openmodelica_func.h" -#include "simulation_runtime.h" -#include "simulation_input_xml.h" -#include "solver_main.h" -#include "options.h" -#include "omi_ServiceInterface.h" -#include "omi_Control.h" -#include "omi_Transfer.h" -#include "meta/meta_modelica.h" - -//Global Data Mutex -static Mutex gdMutex; - -int argcTEMP = 0; //From main parameter argc -char** argvTEMP = 0; //From main parameter argv -double global_stepSize = 0.0; - -// Global Data structure -DATA* globalData; -SOLVER_INFO* solverInfo; - -/** - * Initializes the service interface data - * e.g. the used globalDataMutex - * and the arguments of the simulation_runtime main function - */ -int initServiceInterfaceData(int argc, char**argv, void* inData) -{ - //The arguments should be available globally, also in other classes - argcTEMP = argc; - argvTEMP = argv; - globalData = (DATA*) inData; - - return true; -} - -void* getGlobalData(void) -{ - return globalData; -} - -/***************************************************************** - * Communication direction from OMI --> OM * - *****************************************************************/ - -//************ Global Data Value Request and Manipulation ************ - -//****** Number of properties****** - -//NOTE: nStates is similar to nStateDerivatives -long get_NStates(void) -{ - gdMutex.Lock(); - - long temp_val = globalData->modelData.nStates; - - gdMutex.Unlock(); - return temp_val; -} - -long get_NAlgebraic(void) -{ - gdMutex.Lock(); - - long temp_val = globalData->modelData.nVariablesReal-2*globalData->modelData.nStates; - - gdMutex.Unlock(); - - return temp_val; -} - -long get_NParameters(void) -{ - gdMutex.Lock(); - - long temp_val = globalData->modelData.nParametersReal; - - gdMutex.Unlock(); - - return temp_val; -} - -long get_NInputVars(void) -{ - gdMutex.Lock(); - - long temp_val = globalData->modelData.nInputVars; - - gdMutex.Unlock(); - - return temp_val; -} - -long get_NOutputVars(void) -{ - gdMutex.Lock(); - - long temp_val = globalData->modelData.nOutputVars; - - gdMutex.Unlock(); - - return temp_val; -} - -//****** END Number of properties****** - -//****** State Value, Name Request and Manipulation ****** - -void set_StateValue(int index, double value) -{ - gdMutex.Lock(); - - globalData->localData[0]->realVars[index] = value; - - gdMutex.Unlock(); -} - -double get_StateValue(int index) -{ - gdMutex.Lock(); - - double temp_val = globalData->localData[0]->realVars[index]; - - gdMutex.Unlock(); - - return temp_val; -} - -string get_StateName(int index) -{ - gdMutex.Lock(); - - string temp_val = globalData->modelData.realVarsData[index].info.name; - - gdMutex.Unlock(); - - return temp_val; -} - -//****** StateDerivative Value, Name Request and Manipulation ****** -void set_StateDerivativesValue(int index, double value) -{ - gdMutex.Lock(); - - long nStates = globalData->modelData.nStates; - - globalData->localData[0]->realVars[nStates + index] = value; - - gdMutex.Unlock(); -} - -double get_StateDerivativesValue(int index) -{ - gdMutex.Lock(); - - long nStates = globalData->modelData.nStates; - - double temp_val = globalData->localData[0]->realVars[nStates + index]; - - gdMutex.Unlock(); - - return temp_val; -} - -string get_StateDerivativesName(int index) -{ - gdMutex.Lock(); - - long nStates = globalData->modelData.nStates; - - string temp_val = globalData->modelData.realVarsData[nStates + index].info.name; - - gdMutex.Unlock(); - - return temp_val; -} - -//****** Algebraic Value, Name Request and Manipulation ****** -// Currently only Real Variables are supported! -// TODO: extend for other types (e.g. integer, boolean,...) -void set_AlgebraicValue(int index, double value) -{ - gdMutex.Lock(); - - long nStates = globalData->modelData.nStates; - - globalData->localData[0]->realVars[2*nStates + index] = value; - - gdMutex.Unlock(); -} - -double get_AlgebraicValue(int index) -{ - gdMutex.Lock(); - - long nStates = globalData->modelData.nStates; - - double temp_val = globalData->localData[0]->realVars[2*nStates + index]; - - gdMutex.Unlock(); - - return temp_val; -} - -string get_AlgebraicName(int index) -{ - gdMutex.Lock(); - - long nStates = globalData->modelData.nStates; - - string temp_val = globalData->modelData.realVarsData[nStates + index].info.name; - - gdMutex.Unlock(); - - return temp_val; -} - -//****** Parameter Value, Name Request and Manipulation ****** -// Currently only Real Variables are supported! -// TODO: extend for other types (e.g. integer, boolean,...) -void set_ParameterValue(int index, double value) -{ - gdMutex.Lock(); - - globalData->simulationInfo.realParameter[index] = value; - - gdMutex.Unlock(); -} - -double get_ParameterValue(int index) -{ - gdMutex.Lock(); - - double temp_val = globalData->simulationInfo.realParameter[index]; - - gdMutex.Unlock(); - - return temp_val; -} - -string get_ParameterName(int index) -{ - gdMutex.Lock(); - - string temp_val = globalData->modelData.realParameterData[index].info.name; - - gdMutex.Unlock(); - - return temp_val; -} - -//****** InputVariable Value, Name Request and Manipulation ****** -void set_InputVarValue(int index, double value) -{ - gdMutex.Lock(); - - globalData->simulationInfo.inputVars[index] = value; - - gdMutex.Unlock(); -} - -double get_InputVarValue(int index) -{ - gdMutex.Lock(); - - double temp_val = globalData->simulationInfo.inputVars[index]; - - gdMutex.Unlock(); - - return temp_val; -} - -string get_InputVarName(int index) -{ - gdMutex.Lock(); - - // TODO: find name for input values */ - string temp_val = ""; - - gdMutex.Unlock(); - - return temp_val; -} - -//****** OutputVariable Value, Name Request and Manipulation ****** -void set_OutputVarValue(int index, double value) -{ - gdMutex.Lock(); - - globalData->simulationInfo.outputVars[index] = value; - - gdMutex.Unlock(); - -} - -double get_OutputVarValue(int index) -{ - gdMutex.Lock(); - - double temp_val = globalData->simulationInfo.outputVars[index]; - - gdMutex.Unlock(); - - return temp_val; -} - -string get_OutputVarName(int index) -{ - gdMutex.Lock(); - - // TODO: find name for input values */ - string temp_val = ""; - - gdMutex.Unlock(); - - return temp_val; -} -//****** END Value, Name Request and Manipulation ****** - - -//****** Simulation Status Request and Manipulation ****** - -double get_timeValue(void) -{ - gdMutex.Lock(); - - double temp_let = globalData->localData[0]->timeValue; - - gdMutex.Unlock(); - - return temp_let; -} - -void set_timeValue(double new_timeValue) -{ - gdMutex.Lock(); - - globalData->localData[0]->timeValue = new_timeValue; - - gdMutex.Unlock(); -} - -void set_lastEmittedTime(double new_lastEmittedTime) -{ - gdMutex.Lock(); - - // What's the propose of that??? - // One can't change things that were happen already!!! - cout << "set_lastEmittedTime not implemented!" << endl; - - gdMutex.Unlock(); -} - - -double get_lastEmittedTime(void) -{ - gdMutex.Lock(); - - double temp_let = globalData->localData[0]->timeValue - solverInfo->currentStepSize; - - gdMutex.Unlock(); - - return temp_let; -} - -void set_stepSize(double new_globalStepSize) -{ - gdMutex.Lock(); - - globalData->simulationInfo.stepSize = new_globalStepSize; - - gdMutex.Unlock(); -} - -double get_stepSize(void) -{ - gdMutex.Lock(); - - double temp_let = globalData->simulationInfo.stepSize ; - - gdMutex.Unlock(); - - return temp_let; -} - -// TODO: update forceEmit functions -// when the purpose is clear. -void set_forceEmit(int new_forceEmit) -{ - gdMutex.Lock(); - - //globalData->forceEmit = new_forceEmit; - - gdMutex.Unlock(); -} -int get_forceEmit(void){ - gdMutex.Lock(); - - //int fe = globalData->forceEmit; - - gdMutex.Unlock(); - - return 0; -} -//****** END Simulation Status Request and Manipulation ****** - -//****** Request and Manipulate Data from GlobalData via SimulationStepData - -void setGlobalSimulationValuesFromSimulationStepData(SimStepData* p_SimStepData) -{ - gdMutex.Lock(); - - /* - * With the currect implementation it's not possible - * to change the time. - */ - //globalData->localData[0]->timeValue = p_SimStepData->forTimeStep; - - long nStates = globalData->modelData.nStates; - long nParameters = globalData->modelData.nParametersReal; - - /* For now permit only parameter and states changes, since - * changes of stateDerivates and algebraic variables are - * anyway not possible, they are calculated! - */ - for (int i = 0; i < nStates; i++) { - globalData->localData[0]->realVars[i] = p_SimStepData->states[i]; - } - for (int i = 0; i < nParameters; i++) { - globalData->simulationInfo.realParameter[i] = p_SimStepData->parameters[i]; - } - gdMutex.Unlock(); -} - -void fillSimulationStepDataWithValuesFromGlobalData(string method, SimStepData* p_SimStepData) -{ - gdMutex.Lock(); - - long nStates = globalData->modelData.nStates; - long nAlgebraic = globalData->modelData.nVariablesReal-2*globalData->modelData.nStates; - long nParameters = globalData->modelData.nParametersReal; - - p_SimStepData->forTimeStep = globalData->localData[0]->timeValue; //is the lastEmittedTime of this step - - for (int i = 0; i < nStates; i++) - { - p_SimStepData->states[i] = globalData->localData[0]->realVars[i]; - p_SimStepData->statesDerivatives[i] = globalData->localData[0]->realVars[nStates + i]; - } - for (int i = 0; i < nAlgebraic; i++) - { - p_SimStepData->algebraics[i] = globalData->localData[0]->realVars[2*nStates + i]; - } - for (int i = 0; i < nParameters; i++) - { - p_SimStepData->parameters[i] = globalData->simulationInfo.realParameter[i]; - } - - gdMutex.Unlock(); -} -//****** OPTIMIZATION ****** - -/* Because of Optimization while manipulating the whole global data structure - * The mutex will only lock/unlock once - * Kommentar: Normalerweise müsste für jede anfrage der Mutex gelocked werden und erneut frei gegeben - * mit diesen methoden sorgen wir dafür, dass dies nur ein einziges mal geschiecht! - */ - -void fillSimDataNames_AND_SimDataNamesFilter_WithValuesFromGlobalData( - SimDataNames* p_simDataNames, SimDataNamesFilter* p_simDataNamesFilter) -{ - gdMutex.Lock(); - - long nStates = globalData->modelData.nStates; - long nAlgebraic = globalData->modelData.nVariablesReal-2*globalData->modelData.nStates; - long nParameters = globalData->modelData.nParametersReal; - - int variablesNamesPos = 0; - for (int i = 0; i < nStates; i++) - { - p_simDataNames->statesNames[i] = globalData->modelData.realVarsData[i].info.name; - p_simDataNamesFilter->variablesNames[variablesNamesPos] = ""; - p_simDataNames->stateDerivativesNames[i] - = globalData->modelData.realVarsData[nStates + i].info.name; - variablesNamesPos++; - } - for (int i = 0; i < nAlgebraic; i++) - { - p_simDataNames->algebraicsNames[i] = globalData->modelData.realVarsData[2*nStates + i].info.name; - p_simDataNamesFilter->variablesNames[variablesNamesPos] = ""; - variablesNamesPos++; - } - for (int i = 0; i < nParameters; i++) - { - p_simDataNames->parametersNames[i] = globalData->modelData.realParameterData[i].info.name; - p_simDataNamesFilter->parametersNames[i] = ""; - } - gdMutex.Unlock(); -} - -//****** END OPTIMIZATION ****** - -/* - * Calls the "read_input_xml(...)" function from "simulation_input.cpp" and stores the simulation start data into - * a set of variables from "omi_Calculation.cpp" - */ -int intializeSolverStartData(double *stepSize, long *outputSteps, - double *tolerance, string* method, string* outputFormat) -{ - - gdMutex.Lock(); - - int retVal = -1; - - SIMULATION_INFO* simInfo = &globalData->simulationInfo; - - retVal = initializeResultData(globalData, 0); - - solverInfo = (SOLVER_INFO*) malloc(sizeof(SOLVER_INFO)); - - - if (MMC_STRINGDATA(simInfo->solverMethod) == std::string("rungekutta")) - { - solverInfo->solverMethod = 2; - } - else if(MMC_STRINGDATA(simInfo->solverMethod) == std::string("dassl")) - { - solverInfo->solverMethod = 3; - } - /* as fallback and default euler solver is used */ - else - { - solverInfo->solverMethod = 1; - } - - *stepSize = simInfo->stepSize; - *outputSteps = simInfo->stepSize; - *tolerance = simInfo->tolerance; - *method = MMC_STRINGDATA(simInfo->solverMethod); - - - /* allocate SolverInfo memory */ - if (!retVal) - retVal = initializeSolverData(globalData, solverInfo); - - /* initialize all parts of the model */ - if (!retVal) - retVal = initializeModel(globalData, "", "", "", 0.0, 0); - - - gdMutex.Unlock(); - - return retVal; -} - - -/* - * Calls the "read_input_xml(...)" function from "simulation_input.cpp" and stores the simulation start data into - * a set of variables from "omi_Calculation.cpp" - */ -void deintializeSolverStartData(void) -{ - - gdMutex.Lock(); - - /* terminate the simulation */ - finishSimulation(globalData, solverInfo, ""); - - /* free SolverInfo memory */ - freeSolverData(globalData, solverInfo); - - - gdMutex.Unlock(); -} -//************ END Global Data Value Request and Manipulation ************ - -/* - * Calls the solver which is selected in the parameter string "method" - */ -int performSolverStepFromOM(double start, double stop, double stepSize) -{ - int retVal = -1; - gdMutex.Lock(); - - - SIMULATION_INFO* simInfo = &globalData->simulationInfo; - simInfo->stepSize = stepSize; - simInfo->startTime = start; - simInfo->stopTime = stop; - - /* starts the simulation main loop */ - retVal = globalData->callback->performSimulation(globalData, solverInfo); - - gdMutex.Unlock(); - return retVal; -} - -/** - * Bans working on Global Data, this is important for interrupting calculation and transfer threads - * Otherwise one of the consumer or producer threads are still working on the GD and no changes could realized - * while the simulation is paused or an error occurred... - */ -bool denied_work_on_GD(void) -{ - gdMutex.Lock(); - return true; -} - -bool allow_work_on_GD(void) -{ - gdMutex.Unlock(); - - return true; -} - -/***************************************************************** - * Communication direction from OM --> OMI * - *****************************************************************/ - -/** - * Creates the Simulation Control Thread - */ -Thread* createControlThread(void) -{ - //Create the Control Server Thread - Thread *new_thread = new Thread(); - new_thread->Create(threadServerControl); - return new_thread; -} - -//************ Network Configuration Settings ************ - -/** - * Sets the IP and Port of the control network client to user specific values - * To use Default IP (localhost - 127.0.0.1) send an empty string as ip parameter ("") - * Note: Call this function before starting simulation - */ -void setIPAndPortOfControlClient(string ip, int port) -{ - setControlClientIPandPort(ip, port); -} - -/** - * Sets only the Port of the control network server to user specific value - * The IP (localhost - 127.0.0.1) mustn't change - * Note: Call this function before starting simulation - */ -void setPortOfControlServer(int port) -{ - setControlServerPort(port); -} - -/* - * Note: Call this function before starting simulation - */ -void setIPandPortOfTransferClient(string ip, int port) -{ - setTransferIPandPort(ip, port); -} - -//TODO 20100217 pv Implement Reset of IP and Port.. necessary?? - -//************ END Network Configuration Settings ************ - -/***************************************************************** - * Used from both subsystems * - *****************************************************************/ - - -/** - * Prints out the actual global data stored in the simulation_runtime.cpp - * Only for debugging - */ -void printGlobalData(void) -{ - gdMutex.Lock(); - - cout << "OutPutGlobalData***********" << endl; fflush(stdout); - cout << "lastEmittedTime: " << globalData->localData[1]->timeValue << " --------------------" << endl; fflush(stdout); - cout << "timeValue: " << globalData->localData[0]->timeValue << " --------------------" << endl; fflush(stdout); - - long nStates = globalData->modelData.nStates; - long nAlgebraic = globalData->modelData.nVariablesReal-2*globalData->modelData.nStates; - long nParameters = globalData->modelData.nParametersReal; - - if (nStates > 0) - { - cout << "---States---" << endl; fflush(stdout); - for (int t = 0; t < nStates; t++) - { - cout << t << ": " << get_StateName(t) << ": " << get_StateValue(t) << endl; fflush(stdout); - } - } - - if (nAlgebraic > 0) - { - cout << "---Algebraics---" << endl; fflush(stdout); - for (int t = 0; t < nAlgebraic; t++) - { - cout << t << ": " << get_AlgebraicName(t) << ": " << get_AlgebraicValue(t) << endl; fflush(stdout); - } - } - - if (nParameters > 0) - { - cout << "---Parmeters--- " << endl; fflush(stdout); - for (int t = 0; t < nParameters; t++) - { - cout << t << ": " << get_ParameterName(t) << ": " << get_ParameterValue(t) << endl; fflush(stdout); - } - } - /* / - if (globalData->nInputVars > 0) - { - cout << "---InputVars--- " << endl; fflush(stdout); - for (int t = 0; t < globalData->nInputVars; t++) - { - cout << t << ": " << globalData->inputNames[t].name << ": " << globalData->inputVars[t] << endl; fflush(stdout); - } - } - - if (globalData->nOutputVars > 0) - { - cout << "---OutputVars--- " << endl; fflush(stdout); - for (int t = 0; t < globalData->nOutputVars; t++) - { - cout << t << ": " << globalData->outputNames[t].name << ": " << globalData->outputVars[t] << endl; fflush(stdout); - } - } - */ - - gdMutex.Unlock(); -} diff --git a/SimulationRuntime/interactive/omi_ServiceInterface.h b/SimulationRuntime/interactive/omi_ServiceInterface.h deleted file mode 100644 index c54768a544f..00000000000 --- a/SimulationRuntime/interactive/omi_ServiceInterface.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * OpenModelica Interactive (Ver 0.7) - * Last Modification: 17. January 2010 - * - * Developed by: - * EADS IW Germany - * Developer: Parham Vasaiely - * Contact: vasaie_p@informatik.haw-hamburg.de - * - * File description: omi_ServiceInterface.h - * - * Full specification available in the bachelor thesis of Parham Vasaiely - * "Interactive Simulation of SysML Models using Modelica" (Chapter 5) - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "thread.h" -#include "omi_ResultManager.h" - -using namespace std; - -//#ifndef _MY_SERVICEINTERFACE_H -#define _MY_SERVICEINTERFACE_H - -int initServiceInterfaceData(int, char**, void*); -void* getGlobalData(void); - -//************ Global Data Value Request and Manipulation ************ - -//****** Number of properties ****** -long get_NStates(void); -long get_NAlgebraic(void); -long get_NParameters(void); -long get_NInputVars(void); -long get_NOutputVars(void); -//****** END Number of properties ****** - -//****** Value, Name Request and Manipulation ****** -void set_StateValue(int, double); -double get_StateValue(int); -string get_StateName(int); - -//****** StateDerivative Value, Name Request and Manipulation ****** -void set_StateDerivativesValue(int, double); -double get_StateDerivativesValue(int); -string get_StateDerivativesName(int); - -//****** Algebraic Value, Name Request and Manipulation ****** -void set_AlgebraicValue(int, double); -double get_AlgebraicValue(int); -string get_AlgebraicName(int); - -//****** Parameter Value, Name Request and Manipulation ****** -void set_ParameterValue(int, double); -double get_ParameterValue(int); -string get_ParameterName(int); - -//****** InputVariable Value, Name Request and Manipulation ****** -void set_InputVarValue(int, double); -double get_InputVarValue(int); -string get_InputVarName(int); - -//****** OutputVariable Value, Name Request and Manipulation ****** -void set_OutputVarValue(int, double); -double get_OutputVarValue(int); -string get_OutputVarName(int); - -//****** END Value, Name Request and Manipulation ****** - -double get_timeValue(void); -void set_timeValue(double); -void set_lastEmittedTime(double); -double get_lastEmittedTime(void); - -void set_stepSize(double); -double get_stepSize(void); - -void set_forceEmit(int); -int get_forceEmit(void); - -void setGlobalSimulationValuesFromSimulationStepData(SimStepData*); -void fillSimulationStepDataWithValuesFromGlobalData(string, SimStepData*); -void fillSimDataNames_AND_SimDataNamesFilter_WithValuesFromGlobalData( - SimDataNames*, SimDataNamesFilter*); - -//************ END Global Data Value Request and Manipulation ************ - -/* - * Calls the "read_input_xml(...)" function from "simulation_input.cpp" and stores the simulation start data into - * a set of variables from "omi_Calculation.cpp" - */ -int intializeSolverStartData(double *stepSize, long *outputSteps, double *tolerance, string* method, string* outputFormat); -int performSolverStepFromOM(double start, double stop, double stepSize); -void deintializeSolverStartData(void); - -bool denied_work_on_GD(); -bool allow_work_on_GD(); - -Thread* createControlThread(); - -//************ Network Configuration Settings ************ -void setIPAndPortOfControlClient(string, int); -void setPortOfControlServer(int); -void setIPandPortOfTransferClient(string, int); -//************ END Network Configuration Settings ************ - -void printGlobalData(void); diff --git a/SimulationRuntime/interactive/omi_Transfer.cpp b/SimulationRuntime/interactive/omi_Transfer.cpp deleted file mode 100644 index c47faa9262f..00000000000 --- a/SimulationRuntime/interactive/omi_Transfer.cpp +++ /dev/null @@ -1,402 +0,0 @@ -/* - * OpenModelica Interactive (Ver 0.75) - * Last Modification: 23. May 2011 - * - * Developed by: - * EADS IW Germany - * Developer: Parham Vasaiely - * Contact: Parham.Vasaiely@eads.com - * - * File description: omi_Transfer.cpp - * Similar to a consumer, the `Transfer' thread tries to get simulation results from - * the `ResultManager' and send them to the GUI immediately after starting a simulation. - * If the communication takes longer than a calculation step, - * it is also possible to create more than one consumer. - * The `Transfer' uses a property filter mask containing all property names whoes result values are important for the GUI. - * The GUI must set this mask using the `setfilter' operation, - * otherwise the transfer sends only the actual simulation time. - * This is very useful for increasing the communication speed while sending results to the GUI. - * - * Full specification available in the bachelor thesis of Parham Vasaiely - * "Interactive Simulation of SysML Models using Modelica" (Chapter 5) - */ - -#include -#include -#include -#include "socket.h" -#include "omi_Control.h" -//#include "omi_ResultManager.h" -#include "omi_Transfer.h" -#include "omi_ServiceInterface.h" - -using namespace std; - -//#pragma comment(lib, "ws2_32.lib") - -static const int transfer_default_client_port = 10502; -static const string transfer_default_client_ip = "127.0.0.1"; //localhost ip for transfer client -static string transfer_client_ip = ""; -static int transfer_client_port = 0; - -static bool debugTransfer = false; //Set true to print out comments which describes the program flow to the console -static bool transferInterrupted = false; - -static SimStepData simStepData_from_Transfer; //Simulation Step Data structure used by a Transfer thread to store simulation result data for a specific time step data -static SimStepData* p_SimResDataForw_from_Transfer = 0; - -static Socket transfer_client_socket; -static struct sockaddr_in client; - -static int sendMessageToClientGUI(long, long, long); -static string createResultMessageWithNames(long, long, long); -static string createResultMessageWithIndex(long, long, long); -static void connectToTransferServer(void); -static int printSSDTransfer(long, long, long); - -/** - * Generates a simulation result message containing all variables and parameters from the filter mask - * and sends the string to a server via message parsing and tcp/ip - */ -static int sendMessageToClientGUI(long nStates, long nAlgebraic, long nParameters) -{ - bool retValue = true; - - string resultMessage = createResultMessageWithNames(nStates, nAlgebraic, nParameters); - - if (debugTransfer) - { - cout << resultMessage << endl; fflush(stdout); - } - - /* - * Sends the simulation result data string to a server - */ - transfer_client_socket.send(resultMessage); - - return retValue; -} - -/** - * creates a result message containing variables and parameters, identifiable by full qualified names - * e.g. result#var1=0.001:...#par1=9.9:...#end - */ -static string createResultMessageWithNames(long nStates, long nAlgebraic, long nParameters) -{ - ostringstream formatter; - formatter << "result#" << p_SimResDataForw_from_Transfer->forTimeStep - << "#"; - - //string values; - - int var = 0; - bool notFirstElement = false; //signal if the element is the first element in the formatter, if its so there is no need for a ":" at the beginning - for (int i = 0; var < nStates; var++, i++) - { - if (debugTransfer) - { - cout << p_simDataNamesFilterForTransfer->variablesNames[var] << endl; fflush(stdout); - cout << p_simDataNames_SimulationResult->statesNames[i] << endl; fflush(stdout); - } - - if (p_simDataNamesFilterForTransfer->variablesNames[var] != string("")) - { - if (notFirstElement) - { - formatter << ":"; - } - else - { - notFirstElement = true; - } - formatter << p_simDataNamesFilterForTransfer->variablesNames[var] - << "=" << p_SimResDataForw_from_Transfer->states[i]; - } - } - - for (int i = 0; var < (nStates + nAlgebraic); var++, i++) - { - if (debugTransfer) - { - cout << p_simDataNamesFilterForTransfer->variablesNames[var] << endl; fflush(stdout); - cout << p_simDataNames_SimulationResult->algebraicsNames[i] << endl; fflush(stdout); - } - - if (p_simDataNamesFilterForTransfer->variablesNames[var] != string("")) - { - if (notFirstElement) - { - formatter << ":"; - } - else - { - notFirstElement = true; - } - formatter << p_simDataNamesFilterForTransfer->variablesNames[var] - << "=" << p_SimResDataForw_from_Transfer->algebraics[i]; - } - } - formatter << "#"; - notFirstElement = false; - for (int i = 0; i < nParameters; i++) - { - /*if (p_simDataNamesFilterForTransfer->parametersNames[i] != string("")) { - if(notFirstElement)formatter << ":"; - else notFirstElement = true; - formatter << p_simDataNamesFilterForTransfer->variablesNames[var] << "=" << p_SimResDataForw_from_Transfer->parameters[i]; - }*/ - if (p_simDataNamesFilterForTransfer->parametersNames[i] != string("")) - { - if (notFirstElement) - { - formatter << ":"; - } - else - { - notFirstElement = true; - } - formatter << p_simDataNamesFilterForTransfer->parametersNames[i] - << "=" << p_SimResDataForw_from_Transfer->parameters[i]; - } - } - formatter << "#end"; - - return formatter.str(); - - //formatter.clear(); -} - -/** - * creates a result message containing variables and parameters, identifiable by a specified index instead of a full qualified name. - * e.g. result#1=0.001:2=3:...#1=9.9:2=80:...#end - * this will improve the network communication between runtime and a client gui - * TODO 20100211 pv createResultMessageWithIndex not implemented yet - */ -static string createResultMessageWithIndex(long nStates, long nAlgebraic, long nParameters) -{ - return ""; -} - -/** - * Sets the IP and Port of the transfer network client to user specific values - * To use Default IP (localhost - 127.0.0.1) send an empty string as newIP parameter ("") - * Note: Call this function before starting simulation - */ -void setTransferIPandPort(string ip, int port) -{ - if (debugTransfer) - { - cout << "Transfer IP and Port: " << ip << ":" << port << endl; fflush(stdout); - } - - transfer_client_ip = ip; - transfer_client_port = port; -// connectToTransferServer(); //dynamic change during a running simulation possible with mutex... but necessary? -} - -/** - * Note: Call this function before starting simulation - */ -void resetTransferIPandPortToDefault(void) -{ - transfer_client_ip = ""; - transfer_client_port = 0; - //connectToTransferServer(); //dynamic change during a running simulation possible with mutex... but necessary? -} - -string getTransferActIP(void) -{ - if(transfer_client_ip != string("")) - { - return transfer_client_ip; - } - else - { - return transfer_default_client_ip; - } -} - -int getTransferActPort(void) -{ - if(transfer_client_port != 0) - { - return transfer_client_port; - } - else - { - return transfer_default_client_port; - } -} - -/** - * Establishes a connection to a server to transfer the result data to - */ -static void connectToTransferServer(void) -{ - transfer_client_socket.create(); - - if (transfer_client_ip != string("")) - { - if (transfer_client_port != 0) - { - if (debugTransfer) - { - cout << "Connect to server with user specific ip and port" << endl; fflush(stdout); - } - // Connect to server with user specific ip and port - transfer_client_socket.connect(transfer_client_ip, transfer_client_port); - } - else - { - if (debugTransfer) - { - cout << "Connect to server with user specific ip and default port (" << transfer_default_client_port << ")" << endl; fflush(stdout); - } - // Connect to server with user specific ip and default port - transfer_client_socket.connect(transfer_client_ip, transfer_default_client_port); - } - } - else - { - if (transfer_client_port != 0) - { - if (debugTransfer) - { - cout << "Connect to server on default IP(localhost) but user specific port" << endl; fflush(stdout); - } - // Connect to server on default IP(localhost) but user specific port - transfer_client_socket.connect(transfer_default_client_ip, transfer_client_port); - } - else - { - if (debugTransfer) - { - cout << "Connect to server on default IP(localhost) and default port (" << transfer_default_client_port << ")" << endl; fflush(stdout); - } - // Connect to server on default IP(localhost) and default port (10502) - transfer_client_socket.connect(transfer_default_client_ip, transfer_default_client_port); - } - } -} - -/** - * Only for debugging - * Prints out the actual Simulation Step Data structure - */ -static int printSSDTransfer(long nStates, long nAlgebraic, long nParameters) -{ - cout << "printSSDTransfer***********" << endl; fflush(stdout); - cout << "p_simDataNames_SimulationResult->lastEmittedTime: " << p_SimResDataForw_from_Transfer->forTimeStep << " --------------------" << endl; fflush(stdout); - - cout << "---Parmeters--- " << endl; fflush(stdout); - for (int t = 0; t < nParameters; t++) - { - cout << t << ": " /*<< p_simDataNames_SimulationResult->parametersNames[t]*/<< ": " << p_SimResDataForw_from_Transfer->parameters[t] << endl; fflush(stdout); - } - - if (nAlgebraic > 0) - { - cout << "---Algebraics---" << endl; fflush(stdout); - for (int t = 0; t < nAlgebraic; t++) - { - cout << t << ": " /*<< p_simDataNames_SimulationResult->algebraicsNames[t]*/<< ": " << p_SimResDataForw_from_Transfer->algebraics[t] << endl; fflush(stdout); - } - } - - if (nStates > 0) - { - cout << "---States---" << endl; fflush(stdout); - for (int t = 0; t < nStates; t++) - { - cout << t << ": " /*<< p_simDataNames_SimulationResult->statesNames[t]*/<< ": " << p_SimResDataForw_from_Transfer->states[t] << endl; fflush(stdout); - cout << t << ": " /*<< p_simDataNames_SimulationResult->stateDerivativesNames[t]*/<< ": " << p_SimResDataForw_from_Transfer->statesDerivatives[t] << endl; fflush(stdout); - } - } - - return 0; -} - -/** - * This method tries to get the last calculated simulation result data in a loop - */ -static void doTransfer(long nStates, long nAlgebraic, long nParameters) { - - /* TODO: Fix pause and resume of thread! */ - while (!transferInterrupted) - { - mutexSimulationStatus->Lock(); // Lock to see the simulation status. - if(simulationStatus == SimulationStatus::STOPPED) - { - // If the simulation should stop, do nothing for transfer... - mutexSimulationStatus->Unlock(); - } - - if(simulationStatus == SimulationStatus::SHUTDOWN) - { - // If the simulation should shutdown, unlock and break out of the loop. - mutexSimulationStatus->Unlock(); - break; - } - - if(simulationStatus == SimulationStatus::RUNNING) - { - // If the simulation should continue, increase the semaphore. - waitForResume->Post(); - } - // Unlock and see if we need to wait for resume or not. - mutexSimulationStatus->Unlock(); - waitForResume->Wait(); //wait and reduce semaphore - - getResultData(p_SimResDataForw_from_Transfer); - - if (debugTransfer)//TODO doTransfer - { - cout << "Transfer:\tFunct.: doTransfer\tData: time = " << p_SimResDataForw_from_Transfer->forTimeStep << " tank1.h = " << p_SimResDataForw_from_Transfer->states[0] << endl; fflush(stdout); - } - - //printSSDTransfer(nStates, nAlgebraic, nParameters); - sendMessageToClientGUI(nStates, nAlgebraic, nParameters); - delay((unsigned int)(get_stepSize() * 1000)); //TODO 20100427 pv The sending frequency should depend on the real time, **soft real time - } -} - -/** - * Transfer Client Thread - */ -THREAD_RET_TYPE threadClientTransfer(THREAD_PARAM_TYPE lpParam) -{ - bool retValue = true; //Not used yet - - p_sdnMutex->Lock(); - - long nStates = p_simdatanumbers->nStates; - long nAlgebraic = p_simdatanumbers->nAlgebraic; - long nParameters = p_simdatanumbers->nParameters; - - p_sdnMutex->Unlock(); - - p_SimResDataForw_from_Transfer = &simStepData_from_Transfer; - - double *statesTMP2 = new double[nStates]; - double *statesDerivativesTMP2 = new double[nStates]; - double *algebraicsTMP2 = new double[nAlgebraic]; - double *parametersTMP2 = new double[nParameters]; - p_SimResDataForw_from_Transfer->states = statesTMP2; - p_SimResDataForw_from_Transfer->statesDerivatives = statesDerivativesTMP2; - p_SimResDataForw_from_Transfer->algebraics = algebraicsTMP2; - p_SimResDataForw_from_Transfer->parameters = parametersTMP2; - - connectToTransferServer(); - doTransfer(nStates, nAlgebraic, nParameters); - - // cleanup - transfer_client_socket.close(); - transfer_client_socket.cleanup(); - - if (debugTransfer) - { - cout << "*****Transfer Thread End*****" << endl; fflush(stdout); - } - - return (THREAD_RET_TYPE_NO_API)retValue; -} diff --git a/SimulationRuntime/interactive/omi_Transfer.h b/SimulationRuntime/interactive/omi_Transfer.h deleted file mode 100644 index 9f2adcb4b5d..00000000000 --- a/SimulationRuntime/interactive/omi_Transfer.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * OpenModelica Interactive (Ver 0.7) - * Last Modification: 3. October 2009 - * - * Developed by: - * EADS IW Germany - * Developer: Parham Vasaiely - * Contact: vasaie_p@informatik.haw-hamburg.de - * - * File description: omi_Transfer.h - * - * Full specification available in the bachelor thesis of Parham Vasaiely - * "Interactive Simulation of SysML Models using Modelica" (Chapter 5) - */ - -#include -#include "thread.h" - -using namespace std; - -//#ifndef _MY_SIMULATIONTRANSFER_H -#define _MY_SIMULATIONTRANSFER_H - -//****** Network Configuration ****** -void setTransferIPandPort(string, int); -void resetTransferIPandPortToDefault(void); -string getTransferActIP(void); -int getTransferActPort(void); - -THREAD_RET_TYPE threadClientTransfer(THREAD_PARAM_TYPE); diff --git a/SimulationRuntime/interactive/socket.cpp b/SimulationRuntime/interactive/socket.cpp deleted file mode 100644 index c7108702707..00000000000 --- a/SimulationRuntime/interactive/socket.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#if defined(__MINGW32__) || defined(_MSC_VER) - #include "socket_win.cpp" -#else - #include "socket_unix.cpp" -#endif diff --git a/SimulationRuntime/interactive/socket.h b/SimulationRuntime/interactive/socket.h deleted file mode 100644 index cc0f90c7fc0..00000000000 --- a/SimulationRuntime/interactive/socket.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * OpenModelica Interactive (Ver 0.75) - * Last Modification: 26. December 2010 - * - * Developed by: - * EADS IW Germany - * Developer: Parham Vasaiely - * Contact: Parham.Vasaiely@gmx.de - * - * File description: socket.h - * Standard Socket only for MS-Windows - * - * Full specification available in the bachelor thesis of Parham Vasaiely - * "Interactive Simulation of SysML Models using Modelica" (Chapter 5) - */ - -#ifndef SOCKET_H_ -#define SOCKET_H_ - -#include - -#if defined(__MINGW32__) || defined(_MSC_VER) - #include -#else - #include - #include - #include - #include -#endif - -// Max. number of connections -const int MAXCONNECTIONS = 5; -// Max. number of data to receive at once -const int MAXRECV = 1024; - -// Socket class -class Socket -{ -private: - // Socket number (Socket-Descriptor) - int m_sock; - int m_socket_type; - // struct sockaddr_in - sockaddr_in m_addr; - -public: - // Constructor - Socket(); - // virtual destructor - virtual ~Socket(); - - - bool create(); // Create Socket - TCP - bool UDP_create(); // Create Socket - UDP - bool bind(const int port); - bool listen() const; - bool accept( Socket& ) const; - bool connect(const std::string &host, const int port ); - - // Data transmission - TCP - bool send( const std::string& ) const; - bool sendBytes(char* msg, int size) const; - int recv ( std::string& ) const; - - // Data transmission - UDP - bool UDP_send( const std::string&, const std::string&, - const int port ) const; - int UDP_recv( std::string& ) const; - - // Close Socket - bool close() const; - - // WSAcleanup() - void cleanup() const; - bool is_valid() const { return m_sock != -1; } -}; - -#endif diff --git a/SimulationRuntime/interactive/socket_unix.cpp b/SimulationRuntime/interactive/socket_unix.cpp deleted file mode 100644 index 1d632436093..00000000000 --- a/SimulationRuntime/interactive/socket_unix.cpp +++ /dev/null @@ -1,179 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "socket.h" - -template -std::string to_string(T n) -{ - std::stringstream ss; - ss << n; - return ss.str(); -} - -Socket::Socket() - : m_sock(0) -{ -} - -Socket::~Socket() -{ - if(is_valid()) - ::close(m_sock); -} - -bool Socket::create() -{ - if((m_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) - { - std::cerr << "Failed to create TCP socket: " << strerror(errno) << std::endl; - exit(1); - } - - m_socket_type = SOCK_STREAM; - return true; -} - -bool Socket::UDP_create() -{ - if((m_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) - { - std::cerr << "Failed to create UDP socket: " << strerror(errno) << std::endl; - exit(1); - } - - m_socket_type = SOCK_DGRAM; - return true; -} - -bool Socket::bind(const int port) -{ - if(!is_valid()) return false; - - m_addr.sin_family = AF_INET; - m_addr.sin_addr.s_addr = INADDR_ANY; - m_addr.sin_port = htons(port); - - return ::bind(m_sock, (struct sockaddr*)&m_addr, sizeof(m_addr)) != -1; -} - -bool Socket::listen() const -{ - if(!is_valid()) return false; - - return ::listen(m_sock, MAXCONNECTIONS) != -1; -} - -bool Socket::accept(Socket &new_socket) const -{ - socklen_t addr_length = sizeof(m_addr); - new_socket.m_sock = ::accept(m_sock, (sockaddr*)&m_addr, &addr_length); - - return new_socket.m_sock != -1; -} - -bool Socket::connect(const std::string &host, const int port) -{ - addrinfo hints, *res; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = m_socket_type; - - getaddrinfo(host.c_str(), to_string(port).c_str(), &hints, &res); - - if(::connect(m_sock, res->ai_addr, res->ai_addrlen) == -1) - { - std::cerr << "Failed to connect to " << host << " on port " << port << ": " << strerror(errno) << std::endl; - return false; - } - return true; -} - -bool Socket::send(const std::string &s) const -{ - return ::send(m_sock, s.c_str(), s.size(), 0) != -1; -} - -// transmit data via TCP -bool Socket::sendBytes(char* msg, int size) const -{ - return ::send(m_sock, msg, size, 0) != -1; -} - -int Socket::recv(std::string &s) const -{ - char buf[MAXRECV + 1]; - - memset(buf, 0, MAXRECV + 1); - - int bytes_sent = ::recv(m_sock, buf, MAXRECV, 0); - - if(bytes_sent < 0) - { - std::cerr << "Error in Socket::recv: " << strerror(errno) << std::endl; - exit(1); - return 0; - } - else if (bytes_sent == 0) - { - exit(0); - } - - s = buf; - return bytes_sent; -} - -bool Socket::UDP_send(const std::string &addr, const std::string &s, const int port) const -{ - struct addrinfo hints, *res; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_DGRAM; - - getaddrinfo(addr.c_str(), to_string(port).c_str(), &hints, &res); - - if(sendto(m_sock, s.c_str(), s.size(), 0, res->ai_addr, res->ai_addrlen) < 0) - { - std::cerr << "Couldn't send UDP package to " << addr << " on port " << port << ": " << strerror(errno) << std::endl; - exit(1); - } - - return true; -} - -int Socket::UDP_recv(std::string &s) const -{ - struct sockaddr_in addr_recvfrom; - socklen_t len; - int n; - char buf[MAXRECV + 1]; - - memset(buf, 0, MAXRECV + 1); - len = sizeof(addr_recvfrom); - n = ::recvfrom(m_sock, buf, MAXRECV, 0, (struct sockaddr*)&addr_recvfrom, &len); - - if(n <= 0) - { - std::cerr << "Error in Socket::UDP_recv: " << strerror(errno) << std::endl; - exit(1); - return 0; - } - - s = buf; - return n; -} - -void Socket::cleanup() const -{ -} - -bool Socket::close() const -{ - ::close(m_sock); - return true; -} diff --git a/SimulationRuntime/interactive/socket_win.cpp b/SimulationRuntime/interactive/socket_win.cpp deleted file mode 100644 index b8cb1016b11..00000000000 --- a/SimulationRuntime/interactive/socket_win.cpp +++ /dev/null @@ -1,257 +0,0 @@ -/* - * OpenModelica Interactive (Ver 0.75) - * Last Modification: 26. December 2010 - * - * Developed by: - * EADS IW Germany - * Developer: Parham Vasaiely - * Contact: Parham.Vasaiely@gmx.de - * - * File description: socket.cpp - * Standard Socket only for MS-Windows - * - * Full specification available in the bachelor thesis of Parham Vasaiely - * "Interactive Simulation of SysML Models using Modelica" (Chapter 5) - */ - -#include -#include -#include -#include -#include -#include "socket.h" -using namespace std; - -// Constructor -Socket::Socket() : m_sock(0) -{ - // Winsock.DLL Initialization - WORD wVersionRequested; - WSADATA wsaData; - wVersionRequested = MAKEWORD(1, 1); - if (WSAStartup (wVersionRequested, &wsaData) != 0) - { - cout << "Failed to start the windows sockets!" << endl; fflush(stdout); - exit(1); - } -} - -// Destructor -Socket::~Socket() -{ - if (is_valid()) - ::closesocket(m_sock); -} - -// Create Socket - TCP -bool Socket::create() -{ - m_sock = ::socket(AF_INET, SOCK_STREAM,0); - if (m_sock < 0) - { - cout << "Failed to create a TCP socket!" << endl; fflush(stdout); - exit(1); - } - return true; -} - -// Create Socket - UDP -bool Socket::UDP_create() -{ - m_sock = ::socket(AF_INET, SOCK_DGRAM, 0); - if (m_sock < 0) - { - cout << "Failed to creat a UDP socket!" << endl; fflush(stdout); - exit(1); - } - return true; -} - -// Create bind to server address respectively with its specified port -bool Socket::bind(const int port) -{ - if (!is_valid()) - { - return false; - } - - m_addr.sin_family = AF_INET; - m_addr.sin_addr.s_addr = INADDR_ANY; - m_addr.sin_port = htons(port); - - int bind_return = ::bind(m_sock, (struct sockaddr*) &m_addr, sizeof(m_addr)); - if (bind_return == -1) - { - return false; - } - return true; -} - -// allow client connections (MAXCONNECTIONS) -bool Socket::listen() const -{ - if (!is_valid()) - { - return false; - } - - int listen_return = ::listen(m_sock, MAXCONNECTIONS); - - if (listen_return == -1) - { - return false; - } - return true; -} - -// Processes client connections. accept() will block until a client tries to connect -bool Socket::accept(Socket& new_socket) const -{ - int addr_length = sizeof(m_addr); - new_socket.m_sock = ::accept(m_sock, (sockaddr*) &m_addr, (int*) &addr_length); - if (new_socket.m_sock <= 0) - return false; - return true; -} - -// build connection to server -bool Socket::connect(const string &host, const int port) -{ - if (!is_valid()) - return false; - - struct hostent *host_info; - unsigned long addr; - memset(&m_addr, 0, sizeof(m_addr)); - if ((addr = inet_addr(host.c_str())) != INADDR_NONE) - { - /* argv[1] is a numeric IP-Address */ - memcpy( (char *)&m_addr.sin_addr, - &addr, sizeof(addr)); - } - else - { - /* If the address is given as a name * - * e.g. "localhost" it should translated to an IP-Address */ - host_info = gethostbyname(host.c_str()); - if (NULL == host_info) - { - cout << "Unknown host name: " << host.c_str() << "!" << endl; fflush(stdout); - exit(1); - } - memcpy((char *)&m_addr.sin_addr, host_info->h_addr, host_info->h_length); - } - m_addr.sin_family = AF_INET; - m_addr.sin_port = htons(port); - - int status = ::connect(m_sock, (sockaddr*) &m_addr, sizeof(m_addr)); - - if (status == 0) - return true; - return false; -} - -// transmit data via TCP -bool Socket::send(const string &s) const -{ - int status = ::send(m_sock, s.c_str(), s.size(), 0); - if (status == -1) - { - return false; - } - else - { - return true; - } -} - -// transmit data via TCP -bool Socket::sendBytes(char* msg, int size) const -{ - int status = ::send(m_sock, msg, size, 0); - return !(status == -1 ); -} - -//receive data via TCP -int Socket::recv (string& s) const -{ - char buf[MAXRECV + 1]; - s = ""; - memset(buf, 0, MAXRECV + 1); - - int status = ::recv(m_sock, buf, MAXRECV, 0); - if (status > 0 || status != SOCKET_ERROR) - { - s = buf; - return status; - } - else - { - cout << "Error in Socket::recv" << endl; fflush(stdout); - exit(1); - return 0; - } -} - -// transmit data via UDP -bool Socket::UDP_send(const string &addr, const string &s, const int port) const -{ - struct sockaddr_in addr_sento; - struct hostent *h; - int rc; - - h = gethostbyname(addr.c_str()); - if (h == NULL) - { - cout << "Socket::UDP_send: Unknown host address: " << addr.c_str() << "!" << endl; fflush(stdout); - exit(1); - } - addr_sento.sin_family = h->h_addrtype; - memcpy((char *) &addr_sento.sin_addr.s_addr, h->h_addr_list[0], h->h_length); - addr_sento.sin_port = htons (port); - rc = sendto(m_sock, s.c_str(), s.size(), 0, (struct sockaddr *) &addr_sento, sizeof (addr_sento)); - if (rc == SOCKET_ERROR) - { - cout << "Socket::UDP_send: Could not send data: " << s.c_str() << "!" << endl; fflush(stdout); - exit(1); - } - return true; -} - -// receive data vie UDP -int Socket::UDP_recv( string& s ) const -{ - struct sockaddr_in addr_recvfrom; - int len, n; - char buf[MAXRECV + 1]; - s = ""; - memset(buf, 0, MAXRECV + 1); - len = sizeof(addr_recvfrom); - n = recvfrom(m_sock, buf, MAXRECV, 0, (struct sockaddr *) &addr_recvfrom, &len); - if (n == SOCKET_ERROR) - { - cout << "Socket::UDP_recv: failed to receive data!" << endl; fflush(stdout); - exit(1); - return 0; - } - else - { - s = buf; - return n; - } -} - -// free Winsock.dll -void Socket::cleanup() const -{ - /* Cleanup Winsock */ - WSACleanup(); -} - -// Close Socket and free Winsock.dll -bool Socket::close() const -{ - closesocket(m_sock); - cleanup(); - return true; -} diff --git a/SimulationRuntime/interactive/thread.cpp b/SimulationRuntime/interactive/thread.cpp deleted file mode 100644 index e1bccee9acd..00000000000 --- a/SimulationRuntime/interactive/thread.cpp +++ /dev/null @@ -1,236 +0,0 @@ -#include -#include -#include "thread.h" - -/* Windows and mingw32 */ -#if defined(__MINGW32__) || defined(_MSC_VER) - -#include - -void delay(unsigned milliseconds) -{ - Sleep(milliseconds); -} - -Thread::Thread() - : thread_handle(NULL) -{ - running = 0; -} - -Thread::~Thread() -{ - if (thread_handle) { - CloseHandle(thread_handle); - } -} - -bool Thread::Create(THREAD_RET_TYPE (*func)(THREAD_PARAM_TYPE)) -{ - thread_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)*func, NULL, 0, NULL); - return running = thread_handle != NULL; -} - -bool Thread::Join() -{ - if (running) { - bool res = WaitForSingleObject(thread_handle, INFINITE) != WAIT_FAILED; - running = 0; - return res; - } - return 0; -} - - -Mutex::Mutex() -{ - mutex_handle = CreateMutex( - NULL, // default security attributes - FALSE, // initially not owned - NULL); // unnamed mutex - - if(mutex_handle == NULL) - { - throw std::runtime_error("CreateMutex error: " + GetLastError()); - } -} - -Mutex::~Mutex() -{ - CloseHandle(mutex_handle); -} - -bool Mutex::Lock() -{ - return WaitForSingleObject(mutex_handle, INFINITE) != WAIT_FAILED; -} - -bool Mutex::Unlock() -{ - return (ReleaseMutex(mutex_handle))?true:false; -} - - -struct Semaphore::Impl -{ -}; - -Semaphore::Semaphore(unsigned initial_count, unsigned max_count) -{ - semaphore_handle = CreateSemaphore(NULL, initial_count, max_count, NULL); -} - -Semaphore::~Semaphore() -{ - CloseHandle(semaphore_handle); -} - -bool Semaphore::Wait() -{ - return WaitForSingleObject(semaphore_handle, INFINITE) != WAIT_FAILED; -} - -bool Semaphore::TryWait() -{ - return WaitForSingleObject(semaphore_handle, 0) == WAIT_OBJECT_0; -} - -bool Semaphore::Post() -{ - return (ReleaseSemaphore(semaphore_handle, 1, NULL))?true:false; -} - -bool Semaphore::Post(unsigned count) -{ - return (ReleaseSemaphore(semaphore_handle, count, NULL))?true:false; -} - -/* Linux and other POSIX-compliant platforms */ -#else - -void delay(unsigned milliseconds) -{ - usleep(milliseconds * 1000); -} - -Thread::Thread() -{ - running = 0; -} - -Thread::~Thread() -{ - if (running) { - pthread_cancel(thread_handle); - } -} - -bool Thread::Create(THREAD_RET_TYPE (*func)(THREAD_PARAM_TYPE)) -{ - return running = (pthread_create(&thread_handle, NULL, func, NULL) == 0); -} - -bool Thread::Join() -{ - if (running) { - bool res = pthread_join(thread_handle, NULL) == 0; - running = 0; - return res; - } - return 0; -} - - -Mutex::Mutex() -{ - pthread_mutex_init(&mutex_handle, NULL); -} - -Mutex::~Mutex() -{ - pthread_mutex_destroy(&mutex_handle); -} - -bool Mutex::Lock() -{ - return pthread_mutex_lock(&mutex_handle) == 0; -} - -bool Mutex::Unlock() -{ - return pthread_mutex_unlock(&mutex_handle) == 0; -} - - -struct Semaphore::Impl -{ - Impl(unsigned max_count) : max_count(max_count) {} - Mutex mutex; - unsigned max_count; -}; - -Semaphore::Semaphore(unsigned initial_count, unsigned max_count) - : impl(new Impl(max_count)) -{ - sem_init(&semaphore_handle, 0, initial_count); -} - -Semaphore::~Semaphore() -{ - sem_destroy(&semaphore_handle); - delete impl; -} - -bool Semaphore::Wait() -{ - return sem_wait(&semaphore_handle) == 0; -} - -bool Semaphore::TryWait() -{ - return sem_trywait(&semaphore_handle) == 0; -} - -bool Semaphore::Post() -{ - impl->mutex.Lock(); - - int sem_val; - bool success = false; - - if(sem_getvalue(&semaphore_handle, &sem_val) == 0 && sem_val < (int)impl->max_count) - { - success = (sem_post(&semaphore_handle) == 0); - } - - impl->mutex.Unlock(); - return success; -} - -bool Semaphore::Post(unsigned count) -{ - impl->mutex.Lock(); - - int sem_val; - - if(sem_getvalue(&semaphore_handle, &sem_val) != 0) - { - impl->mutex.Unlock(); - return false; - } - - bool success = true; - for(unsigned i = 0; i < count; ++i) - { - if(!(sem_val + i < impl->max_count && sem_post(&semaphore_handle) == 0)) - { - success = false; - break; - } - } - - impl->mutex.Unlock(); - return success; -} - -#endif diff --git a/SimulationRuntime/interactive/thread.h b/SimulationRuntime/interactive/thread.h deleted file mode 100644 index 3a819dd6d9b..00000000000 --- a/SimulationRuntime/interactive/thread.h +++ /dev/null @@ -1,93 +0,0 @@ -#ifndef THREAD_H -#define THREAD_H - -#if defined(__MINGW32__) || defined(_MSC_VER) - #include - - #define THREAD_RET_TYPE DWORD - #define THREAD_RET_TYPE_NO_API DWORD - typedef LPVOID THREAD_PARAM_TYPE; - - typedef HANDLE MUTEX_HANDLE; - typedef HANDLE THREAD_HANDLE; - typedef HANDLE SEMAPHORE_HANDLE; - -#else - #include - #include - - typedef void* THREAD_RET_TYPE; - #define THREAD_RET_TYPE_NO_API THREAD_RET_TYPE - typedef void* THREAD_PARAM_TYPE; - - typedef pthread_mutex_t MUTEX_HANDLE; - typedef pthread_t THREAD_HANDLE; - typedef sem_t SEMAPHORE_HANDLE; -#endif - -/** - * Puts the current thread to sleep for the specified amount of milliseconds. - */ -void delay(unsigned milliseconds); - -class Thread -{ - public: - Thread(); - ~Thread(); -#if defined(_MSC_VER) - bool Create(THREAD_RET_TYPE_NO_API (*func)(THREAD_PARAM_TYPE)); -#else - bool Create(THREAD_RET_TYPE (*func)(THREAD_PARAM_TYPE)); -#endif - bool Join(); - - private: // Not copyable - Thread(const Thread&); - Thread& operator= (const Thread&); - - private: - int running; - THREAD_HANDLE thread_handle; -}; - -class Mutex -{ - public: - Mutex(); - ~Mutex(); - - bool Lock(); - bool Unlock(); - - private: // Not copyable - Mutex(const Mutex&); - Mutex& operator= (const Mutex&); - - private: - MUTEX_HANDLE mutex_handle; -}; - -class Semaphore -{ - struct Impl; - - public: - Semaphore(unsigned initial_count, unsigned max_count); - ~Semaphore(); - - bool Wait(); - bool TryWait(); - bool Post(); - bool Post(unsigned count); - - private: - Semaphore(const Semaphore&); - Semaphore& operator= (const Semaphore&); - - private: - SEMAPHORE_HANDLE semaphore_handle; - Impl *impl; -}; - -#endif /* THREAD_H */