Commit d8e350b5 authored by fmg005's avatar fmg005

Intergrated pulse with serial communication

parent 8be9dd81
builds/
logs/
results/
include/configure_prosim_paths.h
......@@ -2,11 +2,11 @@
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)) {
m_logstream.open(m_filename);
m_logstream.open(prosim_logs_dir+m_filename);
}
string CLA::LOGGER::current_time(bool display_tz){
......
......@@ -3,19 +3,43 @@
HardwareSimulator::HardwareSimulator(serial::Serial*
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() {
......@@ -140,6 +164,7 @@ string HardwareSimulator::GetResponse() {
void HardwareSimulator::Clear() {
m_serial = nullptr;
m_logger = nullptr;
m_env = nullptr;
}
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
......@@ -8,6 +8,7 @@
#include <utility>
#include <sstream>
#include <iostream>
#include "configure_prosim_paths.h"
using namespace std;
......
#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 @@
#include <iostream>
#include <cstdio>
#include <unistd.h>
#include <libconfig.h++>
#include "serial/serial.h"
#include "CLA_Logger.h"
#include "Environment.h"
/* Pulse stuff */
#include "CommonDataModel.h"
#include "PulsePhysiologyEngine.h"
#include "properties/SEScalarTime.h"
#include "properties/SEScalarPressure.h"
#include "system/physiology/SECardiovascularSystem.h"
using namespace std;
using namespace libconfig;
class HardwareSimulator {
private:
serial::Serial* m_serial;
CLA::LOGGER* m_logger;
CLA::Environment* m_env;
void Clear();
size_t SendCommand(string);
string GetResponse();
double systolic_pressure;
double diastolic_pressure;
CLA::LOGGER* m_logger;
double nextUpdateTime;
double DELAY_5_SECONDS;
Config cfg; // API for accessing configuration files
string mode;
public:
HardwareSimulator(serial::Serial*, CLA::LOGGER*, CLA::Environment*);
HardwareSimulator(serial::Serial*, CLA::LOGGER*);
~HardwareSimulator();
bool isOpen();
......@@ -36,10 +47,10 @@ public:
void SetRemoteMode();
void SetLocalMode();
string GetCurrentMode();
void SetInitalIBP(double, double);
void updateIBP(double, double);
void (HardwareSimulator::*respondToData)(double, double);
void update(std::unique_ptr<PhysiologyEngine>&);
void LoadConfig(std::unique_ptr<PhysiologyEngine>&, const char*);
};
#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 @@
#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 prosim_results_dir = "@PROSIM_RESULTS_DIR@";
const std::string prosim_logs_dir = "@PROSIM_LOGS_DIR@";
......
......@@ -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>)
#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)
# for serial communication with the prosim hardware simulator
......@@ -16,7 +16,7 @@ find_package(serial REQUIRED)
set(PROSIM_CONFIG_DIR ${CMAKE_CURRENT_SOURCE_DIR}/resources/)
set(PROSIM_RESULTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/results/)
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}/logs)
......@@ -30,7 +30,7 @@ set( my_srcs
HardwareSimulator.cpp
CLA_Logger.cpp
example.cpp
SimulationEngine.cpp
# SimulationEngine.cpp
)
add_executable(prosim ${my_srcs})
......
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