Commit d8e350b5 authored by fmg005's avatar fmg005

Intergrated pulse with serial communication

parent 8be9dd81
builds/ builds/
logs/
results/
include/configure_prosim_paths.h include/configure_prosim_paths.h
...@@ -2,25 +2,25 @@ ...@@ -2,25 +2,25 @@
CLA::LOGGER::LOGGER() { CLA::LOGGER::LOGGER() {
m_logstream.open("prosim_"+current_time(false)+".log"); // timestamped logs m_logstream.open(prosim_logs_dir+"prosim_"+current_time(false)+".log"); // timestamped logs
} }
CLA::LOGGER::LOGGER(const string& filename): m_filename(move(filename)) { CLA::LOGGER::LOGGER(const string& filename): m_filename(move(filename)) {
m_logstream.open(m_filename); m_logstream.open(prosim_logs_dir+m_filename);
} }
string CLA::LOGGER::current_time(bool display_tz){ string CLA::LOGGER::current_time(bool display_tz){
time_t now = time(0); time_t now = time(0);
struct tm* timeinfo; struct tm* timeinfo;
char buffer[50]; char buffer[50];
timeinfo = localtime(&now); timeinfo = localtime(&now);
if (display_tz) if (display_tz)
strftime(buffer, 50, "%Y-%M-%d.%X-%Z", timeinfo); strftime(buffer, 50, "%Y-%M-%d.%X-%Z", timeinfo);
else else
strftime(buffer, 50, "%Y-%M-%d.%X", timeinfo); strftime(buffer, 50, "%Y-%M-%d.%X", timeinfo);
return buffer; return buffer;
} }
......
...@@ -3,19 +3,43 @@ ...@@ -3,19 +3,43 @@
HardwareSimulator::HardwareSimulator(serial::Serial* HardwareSimulator::HardwareSimulator(serial::Serial*
my_serial, CLA::LOGGER* logger):m_serial(my_serial), m_logger(logger) { my_serial, CLA::LOGGER* logger):m_serial(my_serial), m_logger(logger) {
respondToData = &HardwareSimulator::SetInitalIBP;
}
void HardwareSimulator::update(std::unique_ptr<PhysiologyEngine>& engine) {
//((this)->*respondToData)(systolic_pressure, diastolic_pressure);
} }
void SetInitalIBP(double syst, double diast){ HardwareSimulator::HardwareSimulator(serial::Serial*
my_serial, CLA::LOGGER* logger, CLA::Environment* env):m_serial(my_serial), m_logger(logger), m_env(env) {
nextUpdateTime = 0;
respondToData = &HardwareSimulator::updateIBP;
}
void HardwareSimulator::update(std::unique_ptr<PhysiologyEngine>& engine) {
systolic_pressure =
engine->GetCardiovascularSystem()->GetSystolicArterialPressure(PressureUnit::mmHg);
diastolic_pressure = engine->GetCardiovascularSystem()->GetDiastolicArterialPressure(PressureUnit::mmHg);
((this)->*respondToData)(systolic_pressure, diastolic_pressure);
} }
void updateIBP(double syst, double diast){ void HardwareSimulator::updateIBP(double syst, double diast) {
if(m_env->time_index == nextUpdateTime) {
SetIBP(1, syst, diast);
nextUpdateTime += DELAY_5_SECONDS;
respondToData = &HardwareSimulator::updateIBP;
}
}
void HardwareSimulator::LoadConfig(std::unique_ptr<PhysiologyEngine>& engine, const char* file_path) {
try {
cfg.readFile(file_path); // Read configration file
}
catch(const FileIOException &fioex) {
m_logger->error("I/O error while reading file.");
}
catch(const ParseException &pex) {
m_logger->error("Error parsing configuration file");
}
double time_step = engine->GetTimeStep(TimeUnit::s);
DELAY_5_SECONDS = cfg.lookup("prosim.delay_5_sec");
DELAY_5_SECONDS = DELAY_5_SECONDS/time_step; // 5 seconds delay
} }
bool HardwareSimulator::isOpen() { bool HardwareSimulator::isOpen() {
...@@ -140,6 +164,7 @@ string HardwareSimulator::GetResponse() { ...@@ -140,6 +164,7 @@ string HardwareSimulator::GetResponse() {
void HardwareSimulator::Clear() { void HardwareSimulator::Clear() {
m_serial = nullptr; m_serial = nullptr;
m_logger = nullptr; m_logger = nullptr;
m_env = nullptr;
} }
HardwareSimulator::~HardwareSimulator() { HardwareSimulator::~HardwareSimulator() {
......
#include <iostream>
#include <string>
#include <thread>
#include <vector>
#include <map>
#include <libconfig.h++>
#include <time.h> /* clock_t, clock, CLOCKS_PER_SEC */
#include "serial/serial.h"
#include "HardwareSimulator.h"
#include "CLA_Logger.h"
#include "SimulationEngine.h"
// 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;
int main(){
auto cf = std::make_shared<Config>();
string f_path = prosim_config_dir+"scenario.cfg";
const char* filepath = f_path.c_str();
Simulation("Hassan", cf, filepath);
}
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("./states/StandardMale@0s.pba"))
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);
pe->GetEngineTracker()->GetDataRequestManager().SetResultsFilename(prosim_results_dir+"PulseSimEngine_"+patient_name+".txt");
SEHemorrhage hemorrhageLeg;
double currentMAP;
double initialMAP = 70.0;
CLA::Environment sim_env;
Global_LoadConfig(pe, cfg, filepath, &sim_env);
/*serial instance arguments*/
std::string port = "/dev/ttySB0"; // arbitrary port
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);
prosim.LoadConfig(pe, filepath);
//sim_env.logger = std::make_shared<SimulationLogger>(prosim_results_dir"SimulationEngineLog_"+patient_name+".txt");
bool STOP = false; // Execute stop hemmorrhage only once; without this it be executed for each timestep
bool DEVICES_START = false;
// stop when the set time is reached
while (sim_env.time_index <= sim_env.simulation_timesteps) {
// event_hemorrage_start
if(sim_env.time_index == sim_env.simulation_injury_start_timestep ){
// 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
hemorrhageLeg.GetRate().SetValue(150,VolumePerTimeUnit::mL_Per_min);
pe->ProcessAction(hemorrhageLeg);
STOP = true;
}
currentMAP = pe->GetCardiovascularSystem()->GetMeanArterialPressure(PressureUnit::mmHg);
if( currentMAP <= initialMAP && STOP){
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;
DEVICES_START = true; // instruct devices to start
cout << "START DEVICES" << endl;
}
if (DEVICES_START) {
prosim.update(pe);
}
// track patient data
pe->GetEngineTracker()->TrackData(pe->GetSimulationTime(TimeUnit::s));
pe->AdvanceModelTime();
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
env->engine_timestep = engine->GetTimeStep(TimeUnit::s);
env->simulation_timesteps = env->simulation_time / env->engine_timestep;
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
...@@ -22,8 +22,8 @@ int main() { ...@@ -22,8 +22,8 @@ int main() {
serial::flowcontrol_t flowcontrol = serial::flowcontrol_hardware; serial::flowcontrol_t flowcontrol = serial::flowcontrol_hardware;
/*end serial instance arguments*/ /*end serial instance arguments*/
CLA::LOGGER logger("mylog.log"); CLA::LOGGER logger("mylog.log");
// or CLA::LOGGER logger; /* for timestamped logs */ // or CLA::LOGGER logger; /* for timestamped logs */
...@@ -35,7 +35,7 @@ int main() { ...@@ -35,7 +35,7 @@ int main() {
/* /*
Do stuff with simulator object Do stuff with simulator object
*/ */
return 0; return 0;
} }
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <utility> #include <utility>
#include <sstream> #include <sstream>
#include <iostream> #include <iostream>
#include "configure_prosim_paths.h"
using namespace std; using namespace std;
...@@ -21,14 +22,14 @@ namespace CLA { ...@@ -21,14 +22,14 @@ namespace CLA {
ofstream m_logstream; ofstream m_logstream;
ostringstream ss; ostringstream ss;
enum LEVEL {DEBUG, INFO, WARNING, ERROR, FATAL}; enum LEVEL {DEBUG, INFO, WARNING, ERROR, FATAL};
string current_time(bool); string current_time(bool);
string set_level(LEVEL); string set_level(LEVEL);
public: public:
LOGGER(); LOGGER();
LOGGER(const string&); LOGGER(const string&);
~LOGGER(); ~LOGGER();
template <typename T> template <typename T>
void debug(const T& t) { void debug(const T& t) {
ss << t; ss << t;
...@@ -51,7 +52,7 @@ namespace CLA { ...@@ -51,7 +52,7 @@ namespace CLA {
void warning(const T& t) { void warning(const T& t) {
ss << t; ss << t;
m_logstream<<current_time(true)<<","<<set_level(LOGGER::WARNING)<<","+ss.str()+"\n"; m_logstream<<current_time(true)<<","<<set_level(LOGGER::WARNING)<<","+ss.str()+"\n";
cout<<current_time(false)<<":"<<set_level(LOGGER::WARNING)<<":"+ss.str()<<endl; cout<<current_time(false)<<":"<<set_level(LOGGER::WARNING)<<":"+ss.str()<<endl;
ss.str(""); ss.str("");
ss.clear(); ss.clear();
...@@ -74,7 +75,7 @@ namespace CLA { ...@@ -74,7 +75,7 @@ namespace CLA {
ss.str(""); ss.str("");
ss.clear(); ss.clear();
} }
}; };
} }
......
#ifndef ENVIRONMENT_H
#define ENVIRONMENT_H
#include <memory>
namespace CLA {
struct Environment {
double engine_timestep; // engine period
double simulation_time; // grab from config file in seconds
unsigned long simulation_timesteps; // how long should simulation run
unsigned long time_index; // track engine advancement time
double simulation_injury_start;
double simulation_injury_stop;
double sim_currentTime;
unsigned long simulation_injury_start_timestep;
unsigned long simulation_injury_stop_timestep;
};
}
#endif
...@@ -5,27 +5,38 @@ ...@@ -5,27 +5,38 @@
#include <iostream> #include <iostream>
#include <cstdio> #include <cstdio>
#include <unistd.h> #include <unistd.h>
#include <libconfig.h++>
#include "serial/serial.h" #include "serial/serial.h"
#include "CLA_Logger.h" #include "CLA_Logger.h"
#include "Environment.h"
/* Pulse stuff */
#include "CommonDataModel.h"
#include "PulsePhysiologyEngine.h" #include "PulsePhysiologyEngine.h"
#include "properties/SEScalarTime.h"
#include "properties/SEScalarPressure.h"
#include "system/physiology/SECardiovascularSystem.h"
using namespace std; using namespace std;
using namespace libconfig;
class HardwareSimulator { class HardwareSimulator {
private: private:
serial::Serial* m_serial; serial::Serial* m_serial;
CLA::LOGGER* m_logger;
CLA::Environment* m_env;
void Clear(); void Clear();
size_t SendCommand(string); size_t SendCommand(string);
string GetResponse(); string GetResponse();
double systolic_pressure; double systolic_pressure;
double diastolic_pressure; double diastolic_pressure;
CLA::LOGGER* m_logger; double nextUpdateTime;
double DELAY_5_SECONDS;
Config cfg; // API for accessing configuration files
string mode; string mode;
public: public:
HardwareSimulator(serial::Serial*, CLA::LOGGER*, CLA::Environment*);
HardwareSimulator(serial::Serial*, CLA::LOGGER*); HardwareSimulator(serial::Serial*, CLA::LOGGER*);
~HardwareSimulator(); ~HardwareSimulator();
bool isOpen(); bool isOpen();
...@@ -36,10 +47,10 @@ public: ...@@ -36,10 +47,10 @@ public:
void SetRemoteMode(); void SetRemoteMode();
void SetLocalMode(); void SetLocalMode();
string GetCurrentMode(); string GetCurrentMode();
void SetInitalIBP(double, double);
void updateIBP(double, double); void updateIBP(double, double);
void (HardwareSimulator::*respondToData)(double, double); void (HardwareSimulator::*respondToData)(double, double);
void update(std::unique_ptr<PhysiologyEngine>&); void update(std::unique_ptr<PhysiologyEngine>&);
void LoadConfig(std::unique_ptr<PhysiologyEngine>&, const char*);
}; };
#endif #endif
#ifndef SIMENGINE_H
#define SIMENGINE_H
#include "configure_prosim_paths.h"
void Simulation(const std::string, const std::shared_ptr<Config>&, const char*);
void Global_LoadConfig(std::unique_ptr<PhysiologyEngine>&, const std::shared_ptr<Config>&, const char*, CLA::Environment*);
#endif
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include <string> #include <string>
const char* prosim_config_dir = "@PROSIM_CONFIG_DIR@"; const std::string prosim_config_dir = "@PROSIM_CONFIG_DIR@";
const std::string pulse_state_dir = "@PULSE_STATE_DIR@"; const std::string pulse_state_dir = "@PULSE_STATE_DIR@";
const std::string prosim_results_dir = "@PROSIM_RESULTS_DIR@"; const std::string prosim_results_dir = "@PROSIM_RESULTS_DIR@";
const std::string prosim_logs_dir = "@PROSIM_LOGS_DIR@"; const std::string prosim_logs_dir = "@PROSIM_LOGS_DIR@";
......
...@@ -7,7 +7,7 @@ find_path(CONFIG++_INCLUDE_DIR libconfig.h++ <libconfig.h++ location>) ...@@ -7,7 +7,7 @@ find_path(CONFIG++_INCLUDE_DIR libconfig.h++ <libconfig.h++ location>)
find_library(CONFIG++_LIBRARY NAMES libconfig++.a PATH <libconfig++.a location>) find_library(CONFIG++_LIBRARY NAMES libconfig++.a PATH <libconfig++.a location>)
#prosim depends on pulse this will call will give you access to pulse directories #prosim depends on pulse this will call will give you access to pulse directories
#needed by clasim #needed by prosim
find_package(Pulse REQUIRED NO_MODULE) find_package(Pulse REQUIRED NO_MODULE)
# for serial communication with the prosim hardware simulator # for serial communication with the prosim hardware simulator
...@@ -16,7 +16,7 @@ find_package(serial REQUIRED) ...@@ -16,7 +16,7 @@ find_package(serial REQUIRED)
set(PROSIM_CONFIG_DIR ${CMAKE_CURRENT_SOURCE_DIR}/resources/) set(PROSIM_CONFIG_DIR ${CMAKE_CURRENT_SOURCE_DIR}/resources/)
set(PROSIM_RESULTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/results/) set(PROSIM_RESULTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/results/)
set(PROSIM_LOGS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/logs/) set(PROSIM_LOGS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/logs/)
set(PUlSE_STATE_DIR ${Pulse_INSTALL}/bin/states/) set(PULSE_STATE_DIR ${Pulse_INSTALL}/bin/states/)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/results) file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/results)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/logs) file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/logs)
...@@ -30,14 +30,14 @@ set( my_srcs ...@@ -30,14 +30,14 @@ set( my_srcs
HardwareSimulator.cpp HardwareSimulator.cpp
CLA_Logger.cpp CLA_Logger.cpp
example.cpp example.cpp
SimulationEngine.cpp # SimulationEngine.cpp
) )
add_executable(prosim ${my_srcs}) add_executable(prosim ${my_srcs})
#include directories #include directories
target_include_directories(prosim PRIVATE target_include_directories(prosim PRIVATE
${serial_INCLUDE_DIRS} ${serial_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/include
${Pulse_INCLUDE_DIRS} ${Pulse_INCLUDE_DIRS}
${CONFIG++_INCLUDE_DIR} ${CONFIG++_INCLUDE_DIR}
...@@ -45,7 +45,7 @@ target_include_directories(prosim PRIVATE ...@@ -45,7 +45,7 @@ target_include_directories(prosim PRIVATE
#libraries #libraries
target_link_libraries(prosim debug "${Pulse_DEBUG_LIBS}") target_link_libraries(prosim debug "${Pulse_DEBUG_LIBS}")
target_link_libraries(prosim optimized target_link_libraries(prosim optimized
${serial_LIBRARIES} ${serial_LIBRARIES}
${Pulse_LIBS} ${Pulse_LIBS}
${CONFIG++_LIBRARY}) ${CONFIG++_LIBRARY})
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment