SimulationEngine.cpp 6.14 KB
Newer Older
1 2 3 4 5
#include <iostream>
#include <string>
#include <thread>
#include <vector>
#include <libconfig.h++>
6
#include <map>
7 8 9 10 11

#include "serial/serial.h"
#include "HardwareSimulator.h"
#include "CLA_Logger.h"
#include "SimulationEngine.h"
fmg005's avatar
fmg005 committed
12
#include "Timer.h"
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37

// Include the various types you will be using in your code
#include "scenario/SEDataRequestManager.h"
#include "patient/actions/SEHemorrhage.h"
#include "patient/actions/SESubstanceCompoundInfusion.h"
#include "system/physiology/SEBloodChemistrySystem.h"
#include "system/physiology/SECardiovascularSystem.h"
#include "system/physiology/SEEnergySystem.h"
#include "system/physiology/SERespiratorySystem.h"
#include "substance/SESubstanceManager.h"
#include "substance/SESubstanceCompound.h"
#include "properties/SEScalar0To1.h"
#include "properties/SEScalarFrequency.h"
#include "properties/SEScalarMass.h"
#include "properties/SEScalarMassPerVolume.h"
#include "properties/SEScalarPressure.h"
#include "properties/SEScalarTemperature.h"
#include "properties/SEScalarTime.h"
#include "properties/SEScalarVolume.h"
#include "properties/SEScalarVolumePerTime.h"
#include "engine/SEEngineTracker.h"
#include "compartment/SECompartmentManager.h"

using namespace libconfig;

fmg005's avatar
fmg005 committed
38 39
int main() {
    CLA::Timer timer;
40 41 42 43
    auto cf = std::make_shared<Config>();
    string f_path = prosim_config_dir+"scenario.cfg";
    const char* filepath = f_path.c_str();

fmg005's avatar
fmg005 committed
44
    Simulation("Cynthia", cf, filepath);
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
}

void Simulation(const string patient_name, const std::shared_ptr<Config>& cfg, const char* filepath )
{
    // Create the engine and load the patient
    std::unique_ptr<PhysiologyEngine> pe = CreatePulseEngine(prosim_results_dir+"SimulationEngine_"+patient_name+".log");
    pe->GetLogger()->Info("CLA_Prosim Simulation");
    if (!pe->LoadStateFile(pulse_state_dir+patient_name+"@0s.pba"))
    {
	pe->GetLogger()->Error("Could not load state, check the error");
	return;
    }
    // Create data requests for each value that should be written to the output log as the engine is executing
    pe->GetEngineTracker()->GetDataRequestManager().CreatePhysiologyDataRequest("SystolicArterialPressure", PressureUnit::mmHg);
    pe->GetEngineTracker()->GetDataRequestManager().CreatePhysiologyDataRequest("DiastolicArterialPressure", PressureUnit::mmHg);
    pe->GetEngineTracker()->GetDataRequestManager().CreatePhysiologyDataRequest("MeanArterialPressure", PressureUnit::mmHg);
61 62 63
    pe->GetEngineTracker()->GetDataRequestManager().CreatePhysiologyDataRequest("HeartRate", FrequencyUnit::Per_min);
    pe->GetEngineTracker()->GetDataRequestManager().CreatePhysiologyDataRequest("RespirationRate", FrequencyUnit::Per_min);
    pe->GetEngineTracker()->GetDataRequestManager().CreatePhysiologyDataRequest("OxygenSaturation");
64 65 66
    pe->GetEngineTracker()->GetDataRequestManager().SetResultsFilename(prosim_results_dir+"PulseSimEngine_"+patient_name+".txt");

    SEHemorrhage hemorrhageLeg;
fmg005's avatar
fmg005 committed
67
    double initialMAP = 70.0;
68 69 70 71 72
    double currentMAP;
    CLA::Environment sim_env;
    Global_LoadConfig(pe, cfg, filepath, &sim_env);

    /*serial instance arguments*/
fmg005's avatar
fmg005 committed
73
    std::string port = "/dev/ttyACM0"; // arbitrary port
74 75 76 77 78 79 80 81 82 83 84
    uint32_t baudrate = 115200;
    serial::Timeout timeout = serial::Timeout();
    serial::bytesize_t bytesize = serial::eightbits;
    serial::parity_t parity = serial::parity_none;
    serial::stopbits_t stopbits = serial::stopbits_one;
    serial::flowcontrol_t flowcontrol = serial::flowcontrol_hardware;
    /*end serial instance arguments*/
    serial::Serial myserial(port, baudrate, timeout, bytesize, parity, stopbits,
                             flowcontrol);
    CLA::LOGGER logger; /* for timestamped logs */
    HardwareSimulator prosim(&myserial, &logger, &sim_env);
fmg005's avatar
fmg005 committed
85
    prosim.LoadConfig(filepath);
86 87 88 89

    bool STOP = false; // Execute stop hemmorrhage only once; without this it be executed for each timestep
    bool DEVICES_START = false;

fmg005's avatar
fmg005 committed
90
    prosim.SetRemoteMode();
91 92 93
    // stop when the set time is reached
    while (sim_env.time_index <= sim_env.simulation_timesteps) {
	// event_hemorrage_start
fmg005's avatar
fmg005 committed
94
	if(sim_env.time_index == sim_env.simulation_injury_start_timestep) {
fmg005's avatar
fmg005 committed
95
      cout<< "The time_index "<<sim_env.time_index;
96 97 98 99
	    // Hemorrhage Starts - instantiate a hemorrhage action and have the engine process it
	    cout<<"\nHemorrhage Started at: "<<pe->GetSimulationTime(TimeUnit::s)<<endl;
	    hemorrhageLeg.SetCompartment(pulse::VascularCompartment::RightLeg);
	    //the rate of hemorrhage
fmg005's avatar
fmg005 committed
100
	    hemorrhageLeg.GetRate().SetValue(350,VolumePerTimeUnit::mL_Per_min);
101 102 103 104 105 106
	    pe->ProcessAction(hemorrhageLeg);
	    STOP = true;
	}

	currentMAP = pe->GetCardiovascularSystem()->GetMeanArterialPressure(PressureUnit::mmHg);

fmg005's avatar
fmg005 committed
107
	if( currentMAP <= initialMAP && STOP) {
108 109 110 111 112 113
	    cout<<"\nHemorrhage Stoppd at: "<<pe->GetSimulationTime(TimeUnit::s)<<endl;
	    hemorrhageLeg.SetCompartment(pulse::VascularCompartment::RightLeg);
	    hemorrhageLeg.GetRate().SetValue(0,VolumePerTimeUnit::mL_Per_min);
	    pe->ProcessAction(hemorrhageLeg);
	    STOP = false;
	}
fmg005's avatar
fmg005 committed
114 115
  /* We both track data and advance engine inside the update method */
	prosim.update(pe);
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
	sim_env.time_index++;
    }// End while looop
}// End Simulation function

void Global_LoadConfig(std::unique_ptr<PhysiologyEngine>& engine, const std::shared_ptr<Config>& cf, const char* file_path, CLA::Environment* env) {
    try {
	cf->readFile(file_path); // Read configration file
    }
    catch(const FileIOException &fioex) {
	std::cerr << "I/O error while reading file." << std::endl;
    }
    catch(const ParseException &pex) {
	std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine()
	<< " - " << pex.getError() << std::endl;
    }
    env->simulation_time = cf->lookup("simulation.time.run");
    env->simulation_injury_start = cf->lookup("simulation.time.injury_start");
    env->simulation_injury_stop = cf->lookup("simulation.time.injury_stop");
    env->time_index = 0; // initialize the time index
fmg005's avatar
fmg005 committed
135 136
    env->engine_timestep = cf->lookup("pulse.advance_time");
    env->simulation_timesteps = env->simulation_time/env->engine_timestep;
137 138 139
    env->simulation_injury_start_timestep = env->simulation_injury_start/env->engine_timestep;
    env->simulation_injury_stop_timestep = env->simulation_injury_stop/env->engine_timestep;
}// End Global_LoadConfig