#include "../../../include/simulation/Simulation.h"
#include "../../../include/communication/InputBooleanArrayDriver.h"
#include "../../../include/communication/OutputBooleanArrayDriver.h"
#include "../../../include/communication/FileOutputSpikeDriver.h"
#include "../../../include/communication/FileOutputWeightDriver.h"
#include <ctime>
#define PARAMNET ssGetSFcnParam(S,0)
#define PARAMWEIGHT ssGetSFcnParam(S,1)
#define PARAMLOG ssGetSFcnParam(S,2)
#define PARAMTDSTEP ssGetSFcnParam(S,3)
#define PARAMINPUT ssGetSFcnParam(S,4)
#define PARAMOUTPUT ssGetSFcnParam(S,5)
#define PARAMSWFILE ssGetSFcnParam(S,6)
#define PARAMSWTIME ssGetSFcnParam(S,7)
SimulinkBlockInterface::SimulinkBlockInterface(): Simul(0), InputDriver(0), OutputDriver(0), FileDriver(0), WeightDriver(0){
}
SimulinkBlockInterface::~SimulinkBlockInterface() {
if (this->Simul!=0){
delete this->Simul;
}
this->Simul = 0;
if (this->InputDriver!=0){
delete this->InputDriver;
}
this->InputDriver = 0;
if (this->OutputDriver!=0){
delete this->OutputDriver;
}
this->OutputDriver = 0;
if (this->FileDriver!=0){
delete this->FileDriver;
}
this->FileDriver = 0;
if (this->WeightDriver!=0){
delete this->WeightDriver;
}
this->WeightDriver;
}
void SimulinkBlockInterface::InitializeSimulation(SimStruct *S){
double SimulationTime = 1e100;
char NetworkFile[128];
mxGetString(PARAMNET, NetworkFile, 128);
char WeightFile[128];
mxGetString(PARAMWEIGHT, WeightFile, 128);
char LogFile[128];
mxGetString(PARAMLOG, LogFile, 128);
char SavingWeightFile[128];
mxGetString(PARAMSWFILE, SavingWeightFile, 128);
srand (time(NULL));
time_T Step = ssGetSampleTime(S, 0);
try {
this->Simul = new Simulation(NetworkFile, WeightFile, SimulationTime, 0);
this->WeightDriver = new FileOutputWeightDriver (SavingWeightFile);
this->Simul->AddOutputWeightDriver(this->WeightDriver);
real_T * SavingWeightStep = (real_T *)mxGetData(PARAMSWTIME);
double SWStep = (double) SavingWeightStep[0];
if (SWStep!=0){
this->Simul->SetSaveStep(SWStep);
}
real_T * InputCells = (real_T *)mxGetData(PARAMINPUT);
unsigned int NumberOfElements = (unsigned int) mxGetNumberOfElements(PARAMINPUT);
int * IntInputCells = new int [NumberOfElements];
for (unsigned int i=0; i<NumberOfElements; ++i){
IntInputCells[i] = (int)(InputCells[i]);
}
this->InputDriver = new InputBooleanArrayDriver(NumberOfElements, IntInputCells);
this->Simul->AddInputSpikeDriver(this->InputDriver);
delete [] IntInputCells;
real_T * OutputCells = (real_T *) mxGetData(PARAMOUTPUT);
unsigned int NumberOfElementsOut = (unsigned int) mxGetNumberOfElements(PARAMOUTPUT);
int * IntOutputCells = new int [NumberOfElementsOut];
for (unsigned int i=0; i<NumberOfElementsOut; ++i){
IntOutputCells[i] = (int) OutputCells[i];
}
this->OutputDriver = new OutputBooleanArrayDriver(NumberOfElementsOut, IntOutputCells);
this->Simul->AddOutputSpikeDriver(this->OutputDriver);
delete [] IntOutputCells;
this->FileDriver = new FileOutputSpikeDriver(LogFile,false);
Simul->AddMonitorActivityDriver(this->FileDriver);
this->Simul->InitSimulation();
} catch (EDLUTFileException Exc){
ssPrintf("Error %li: %s in %s\n",Exc.GetErrorNum(),Exc.GetErrorMsg(),Exc.GetTaskMsg());
ssPrintf("Try %s\n",Exc.GetRepairMsg());
ssSetErrorStatus(S, "File error in initializing simulation object");
} catch (EDLUTException Exc){
ssPrintf("Error %li: %s in %s\n",Exc.GetErrorNum(),Exc.GetErrorMsg(),Exc.GetTaskMsg());
ssPrintf("Try %s\n",Exc.GetRepairMsg());
ssSetErrorStatus(S, "Error in initializing simulation object");
return;
}
}
void SimulinkBlockInterface::SimulateStep(SimStruct *S, int_T tid){
if (ssIsSampleHit(S,0,tid)){
unsigned int NumberOfElements = (unsigned int) mxGetNumberOfElements(PARAMINPUT);
bool * InputSignals = new bool [NumberOfElements];
InputPtrsType u = ssGetInputPortSignalPtrs(S,0);
InputBooleanPtrsType uPtrs = (InputBooleanPtrsType)u;
for (unsigned int i=0; i<NumberOfElements; ++i){
boolean_T value = *uPtrs[i];
InputSignals[i] = value;
}
time_T Step = ssGetSampleTime(S, 0);
double StepTime = (double) Step;
double CurrentTime = (double) ssGetT(S);
double NextTime = CurrentTime+StepTime;
this->InputDriver->LoadInputs(Simul->GetQueue(),Simul->GetNetwork(), (bool *) InputSignals, CurrentTime);
Simul->RunSimulationSlot(NextTime);
delete [] InputSignals;
}
}
void SimulinkBlockInterface::AssignOutputs(SimStruct *S){
unsigned int NumberOfElements = (unsigned int) mxGetNumberOfElements(PARAMOUTPUT);
bool * OutputSignals = new bool [NumberOfElements];
this->OutputDriver->GetBufferedSpikes(OutputSignals);
boolean_T * u = (boolean_T *) ssGetOutputPortSignal(S,0);
for (unsigned int i=0; i<NumberOfElements; ++i){
u[i] = (boolean_T) OutputSignals[i];
}
delete [] OutputSignals;
}