Commit 832898cc authored by fmg005's avatar fmg005
Browse files

Modified algorithm implementation

parent 432d0fbc
builds/
cmdsim_old.cmake
......@@ -49,8 +49,8 @@ class Controller {
PhysiologyData* m_data;
std::map<string, Pump*> m_pumps;
double WAIT_10;
double WAIT_5;
double WAIT_10_MIN;
double WAIT_5_MIN;
unsigned long initialize_time_index;
unsigned long checkmap_time_index;
unsigned long ensure_map_time_index;
......@@ -77,19 +77,36 @@ class Controller {
bool STAY_IN_4;
bool ELSE_STAY_IN_4;
double currentNorepiRate;
;
//Algorithm stuff
double currentMAP;
double currentNorepiInfusionRate;
double SalineInfusionRate;
double maxNorepinephrineInfusionRate;
double percentOfRate;
double targetMAPRangeMax;
double targetMAPRangeMin;
double MAPIncreaseThreshold;
unsigned long nextUpdateTime;
/* Pointer to current function to run for algorithm */
void (Controller::*respondToData)(void);
/* Initialize in "Simulation Plan" */
void initializeInfusions(void);
/* Wait for MAP increase in "Simulation Plan" */
void waitForMAPIncrease(void);
/* Ensure MAP decline after increase in "Simulation Plan" */
void ensureMAPDeclineAfterIncrease(void);
/* Maintain MAP in range in "Simulation Plan" */
void maintainMAPInRange(void);
double MAP;
//function variable for functions to set pump rates
//void pumpSetRate; // assuming dictionary
public:
......
......@@ -20,6 +20,8 @@ namespace CMD {
double simulation_injury_start;
double simulation_injury_stop;
double sim_currentTime;
unsigned long simulation_injury_start_timestep;
unsigned long simulation_injury_stop_timestep;
......
......@@ -54,6 +54,9 @@ class Pump : public MedicalDevice {
SESubstanceCompoundInfusion* m_infusion;
SESubstanceInfusion* bpdrug_infusion;
double NorepiConcentration;
double SalineBagVolume;
public:
......
......@@ -31,7 +31,7 @@ class SimulationLogger {
void LogData(double, string, string, string, PhysiologyData&);
void LogRate(double, string, string, string, int);
void LogRate(double, string, string, string, double);
//Destructor
~SimulationLogger();
......
......@@ -10,53 +10,18 @@ Controller::Controller(): MAX_RATE_Hz(50.0) {
Controller::Controller(CMD::Environment* env, PhysiologyData* data, std::map<string, Pump*>& pumps ) : m_env(env),
m_data(data), m_pumps(pumps), MAX_RATE_Hz(50.0) {
/*
srand(time(0)); // seed values using system time
// initialise array from which rates will be picked randomly
array_rate[0] = 300;
array_rate[1] = 350;
array_rate[2] = 200;
//array_rate[3] = 50;
*/
currentNorepiRate = 0;
SalineInfusionRate = 50.0;
// Initalize algorithm configuration variables
currentNorepiInfusionRate = 0;
SalineInfusionRate = 75.0;
maxNorepinephrineInfusionRate = 112.5;
targetMAPRangeMax = 80.0;
targetMAPRangeMin = 65.0;
MAPIncreaseThreshold = 100;
percentOfRate = 0.5;
MAP = 0;
set_initialize_time_index = false;
set_checkmap_timeindex = false;
set_ensure_map_time_index = false;
set_maintain_map_time_index = false;
set_else_maintain_map_time_index = false;
INITIALIZED = false;
checkmap_initialized = false;
ensure_map_initialized = false;
maintain_map_initialized = false;
else_maintain_map_initialized = false;
STAY_IN_2 = true;
STAY_IN_3 = true;
STAY_IN_4 = true;
ELSE_STAY_IN_4 = true;
DEACTIVATE_INIT = false;
WAIT_FOR_MAP_INCREASE = false;
ENSURE_MAP_DECREASE = false;
MAINTAIN_MAP_RANGE = false;
initialize_time_index = 0;
checkmap_time_index = 0;
ensure_map_time_index = 0;
maintain_map_time_index = 0;
else_maintain_map_time_index = 0;
targetMAPRangeMin = 75.0;
MAPIncreaseThreshold = 85;
percentOfRate = 0;
currentMAP = 0;
/* The first action the controller should take is initialize infusions */
respondToData = &Controller::initializeInfusions;
}
......@@ -67,320 +32,21 @@ void Controller::update(std::unique_ptr<PhysiologyEngine>& engine) {
// check controller input rate
if (m_env->time_index % input_period == 0) {
cout<<"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
cout<<"Controller receives data from Monitor at: "<<engine->
GetSimulationTime(TimeUnit::s)<<"s\n";
// Gets data from Monitor
GetData();
m_env->logger->LogData(engine->GetSimulationTime(TimeUnit::s),"Controller",
"RECEIVE","Received data from Monitor BP", patient_state.at(m_env->vector_index-1) );
/*
// why cant't I compare using patient value
double p = patient_state.at(m_env->vector_index-1).pressure;
double value = (int)(p*100 + .5);
double v = (double)value / 100;
bool x = (p > 95.07);
cout <<x<<endl;
*/
//if ( x) doesn't work if x is not true for first loop
/*
if ( m_env->time_index % 96 == 0 ) {
//new_rate = array_rate[rand() % 3];
m_env->logger->LogRate(
engine->GetSimulationTime(TimeUnit::s),
"Controller",
"RATE_CHANGE",
"Controller sends Command to saline Pump",
50
);
cout<< "Command SENT to saline PUMP: "<< engine->
GetSimulationTime(TimeUnit::s)<<"s\n";
//Send information to pump (rate, time index)
//SetRate(new_rate, m_env->time_index);
//cout << "Invoking Change Pump rate command" << endl;
//cout << "new rate " << new_rate << endl;
//cout << "Controller time index " << m_env->time_index << endl;
m_pumps["saline"]->ChangePumpRate(50, m_env->time_index);
cout<< "Command SENT to bpdrug PUMP: "<< engine->
GetSimulationTime(TimeUnit::s)<<"s\n";
m_env->logger->LogRate(
engine->GetSimulationTime(TimeUnit::s),
"Controller",
"RATE_CHANGE",
"Controller sends Command to bpdrug Pump",
40
);
m_pumps["bpdrug"]->ChangePumpRate(40, m_env->time_index);
//pumpSetRate['saline'](salinerate);
//pumpSetRate['BPdrug'](bprate);
//cout << "wait 10 mins: "<< WAIT_10<< endl;
//cout << "wait 5 mins "<< WAIT_5 << endl;
//m_env->pump_index++;
}
*/
// Capture time index to be used later in the Wait Condition
if (!set_initialize_time_index){
initialize_time_index = m_env->time_index;
set_initialize_time_index = true;
}
// Run initialization only once
if(!INITIALIZED) {
//Log rate
m_env->logger->LogRate(engine->GetSimulationTime(TimeUnit::s),"Controller",
"RATE_CHANGE","Controller sends Command to saline Pump",SalineInfusionRate);
m_env->logger->LogRate(engine->GetSimulationTime(TimeUnit::s),"Controller",
"RATE_CHANGE","Controller sends Command to saline Pump",maxNorepinephrineInfusionRate);
m_pumps["saline"]->ChangePumpRate(SalineInfusionRate, m_env->time_index);
m_pumps["bpdrug"]->ChangePumpRate(maxNorepinephrineInfusionRate, m_env->time_index);
INITIALIZED = true;
}
// Handover from initialization to Wait for MAP increase state after 10 mins
if(!DEACTIVATE_INIT && m_env->time_index - initialize_time_index == WAIT_10) {
// Exit initialize state
DEACTIVATE_INIT = true;
// go to wait for MAP increase state
WAIT_FOR_MAP_INCREASE = true;
}
if (WAIT_FOR_MAP_INCREASE) {
// Capture time index
if(!set_checkmap_timeindex) {
checkmap_time_index = m_env->time_index;
set_checkmap_timeindex = true;
}
MAP = patient_state.at(m_env->vector_index-1).pressure;
if ( MAP > MAPIncreaseThreshold && STAY_IN_2 ){
if(!checkmap_initialized){
cout << endl << "INSIDE WAIT_FOR_MAP_INCREASE "<<endl;
currentNorepiRate = percentOfRate * maxNorepinephrineInfusionRate;
//Log rate
m_env->logger->LogRate(engine->GetSimulationTime(TimeUnit::s),"Controller",
"RATE_CHANGE","Controller sends Command to saline Pump",SalineInfusionRate);
m_env->logger->LogRate(engine->GetSimulationTime(TimeUnit::s),"Controller",
"RATE_CHANGE","Controller sends Command to saline Pump",currentNorepiRate);
m_pumps["saline"]->ChangePumpRate(SalineInfusionRate, m_env->time_index);
m_pumps["bpdrug"]->ChangePumpRate(currentNorepiRate, m_env->time_index);
// So that it is not called in subsequent time loops
checkmap_initialized = true;
}
//Wait for 10 minutes
if( m_env->time_index - checkmap_time_index == WAIT_10 ) {
cout << endl << "INSIDE WAIT_FOR_MAP_INCREASE WAIT_10 "<<endl;
// Exit wait for MAP to increase state
WAIT_FOR_MAP_INCREASE = false;
// go to enure MAP decrease state
ENSURE_MAP_DECREASE = true;
}
}
else {
cout << endl << "INSIDE WAIT_FOR_MAP_INCREASE ELSE "<<endl;
// Disable IF so that only ELSE is seen in the time loop --> 2
STAY_IN_2 = false;
// Wait for 5 minutes
if (m_env->time_index - checkmap_time_index == WAIT_5){
cout << endl << "INSIDE WAIT_FOR_MAP_INCREASE ELSE WAIT_5 "<<endl;
// go back to wait for MAP increase state
STAY_IN_2 = true;
checkmap_initialized = false; // To allow new rates to be sent to pumps
set_checkmap_timeindex = false; // Allow new time index to be stored
}
} // End else --> 2
}//END WAIT_FOR_MAP_INCREASE
if(ENSURE_MAP_DECREASE){
// Capture time index
if(!set_ensure_map_time_index) {
ensure_map_time_index = m_env->time_index;
set_ensure_map_time_index = true;
}
MAP = patient_state.at(m_env->vector_index-1).pressure;
if( MAP > MAPIncreaseThreshold && STAY_IN_3 ){
if(!ensure_map_initialized) {
cout << endl << "INSIDE ENSURE_MAP_DECREASE "<<endl;
currentNorepiRate *= percentOfRate;
// Log rate
m_env->logger->LogRate(engine->GetSimulationTime(TimeUnit::s),"Controller",
"RATE_CHANGE","Controller sends Command to saline Pump",SalineInfusionRate);
m_env->logger->LogRate(engine->GetSimulationTime(TimeUnit::s),"Controller",
"RATE_CHANGE","Controller sends Command to saline Pump",currentNorepiRate);
m_pumps["saline"]->ChangePumpRate(SalineInfusionRate, m_env->time_index);
m_pumps["bpdrug"]->ChangePumpRate(currentNorepiRate, m_env->time_index);
ensure_map_initialized = true;
}
// Wait for 10 minutes
if(m_env->time_index - ensure_map_time_index == WAIT_10) {
cout << endl << "INSIDE ENSURE_MAP_DECREASE IF WAIT_10 "<<endl;
// go back to 3
set_ensure_map_time_index = false;
ensure_map_initialized = false;
}
}
else {
cout << endl << "INSIDE ENSURE_MAP_DECREASE ELSE "<<endl;
//Disable IF so that only ELSE is seen in the time loop --> 3
STAY_IN_3 = false;
// Wait for 10 minutes
if( m_env->time_index - ensure_map_time_index == WAIT_10 ){
cout << endl << "INSIDE ENSURE_MAP_DECREASE ELSE WAIT_10 "<<endl;
// go to maintain MAP range state
MAINTAIN_MAP_RANGE = true;
// Exit ensure MAP decrease state
ENSURE_MAP_DECREASE = false;
}
} // End else -->3
}// End GOTO 3
cout<<"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
cout<<"Controller receives data from Monitor at: "<<engine->
GetSimulationTime(TimeUnit::s)<<"s\n";
if(MAINTAIN_MAP_RANGE){
// Capture time index
if(!set_maintain_map_time_index) {
maintain_map_time_index = m_env->time_index;
set_maintain_map_time_index = true;
}
// Gets data from Monitor
GetData();
m_env->logger->LogData(m_env->sim_currentTime,"Controller",
"RECEIVE","Received data from Monitor BP", patient_state.at(m_env->vector_index-1) );
MAP = patient_state.at(m_env->vector_index-1).pressure;
// Get the current MAP value
currentMAP = patient_state.at(m_env->vector_index-1).pressure;
if( MAP > targetMAPRangeMax && STAY_IN_4) {
/* execute the algorithm to respond to the data */
((this)->*respondToData)();
cout << endl << "INSIDE MAINTAIN_MAP_RANGE "<<endl;
if(!maintain_map_initialized) {
currentNorepiRate *= percentOfRate;
// Log rate
m_env->logger->LogRate(engine->GetSimulationTime(TimeUnit::s),"Controller",
"RATE_CHANGE","Controller sends Command to saline Pump",SalineInfusionRate);
m_env->logger->LogRate(engine->GetSimulationTime(TimeUnit::s),"Controller",
"RATE_CHANGE","Controller sends Command to saline Pump",currentNorepiRate);
m_pumps["saline"]->ChangePumpRate(SalineInfusionRate, m_env->time_index);
m_pumps["bpdrug"]->ChangePumpRate(currentNorepiRate, m_env->time_index);
maintain_map_initialized = true;
}
// Wait for 10 minutes
if(m_env->time_index - maintain_map_time_index == WAIT_10) {
// go back to 4
set_maintain_map_time_index = false;
maintain_map_initialized = false;
}
}
else if( MAP < targetMAPRangeMin && ELSE_STAY_IN_4 ) {
// Disable main IF so that only ELSE IF is seen in the time loop --> 4
STAY_IN_4 = false;
if(!set_else_maintain_map_time_index) {
else_maintain_map_time_index = m_env->time_index;
set_else_maintain_map_time_index = true;
}
cout << endl << "INSIDE MAINTAIN_MAP_RANGE ELSE IF "<<endl;
if(!else_maintain_map_initialized) {
currentNorepiRate = percentOfRate * maxNorepinephrineInfusionRate;
// Log rate
m_env->logger->LogRate(engine->GetSimulationTime(TimeUnit::s),"Controller",
"RATE_CHANGE","Controller sends Command to saline Pump",SalineInfusionRate);
m_env->logger->LogRate(engine->GetSimulationTime(TimeUnit::s),"Controller",
"RATE_CHANGE","Controller sends Command to saline Pump",currentNorepiRate);
m_pumps["saline"]->ChangePumpRate(SalineInfusionRate, m_env->time_index);
m_pumps["bpdrug"]->ChangePumpRate(currentNorepiRate, m_env->time_index);
else_maintain_map_initialized = true;
}
// Wait for 5 minutes
if(m_env->time_index - else_maintain_map_time_index == WAIT_5) {
// go back to main IF --> 4
STAY_IN_4 = true;
set_maintain_map_time_index = false;
maintain_map_initialized = false;
}
} /// End else if --> 4
else {
// Disable main IF and ELSE IF so that only ELSE is seen in the time loop--> 4
STAY_IN_4 = false;
ELSE_STAY_IN_4 = false;
// Wait for 10 minutes
if(m_env->time_index - maintain_map_time_index == WAIT_10) {
cout << endl << "INSIDE MAINTAIN_MAP_RANGE ELSE "<<endl;
//go back to min IF --> 4
STAY_IN_4 = true;
ELSE_STAY_IN_4 = true;
set_maintain_map_time_index = false;
maintain_map_initialized = false;
}
} // End else --> 4
}// End MAINTAIN_MAP_RANGE
} // End check input rate condition
......@@ -439,11 +105,11 @@ void Controller::LoadConfig(std::unique_ptr<PhysiologyEngine>& engine, const cha
time_step = engine->GetTimeStep(TimeUnit::s);
//MAX_RATE_Hz = 1/time_step;
WAIT_10 = cfg.lookup("controller.algorithm.wait_10");
WAIT_5 = cfg.lookup("controller.algorithm.wait_5");
WAIT_10_MIN = cfg.lookup("controller.algorithm.wait_10");
WAIT_5_MIN = cfg.lookup("controller.algorithm.wait_5");
WAIT_10 = (60 * WAIT_10)/time_step; // 10 min
WAIT_5 = (60 * WAIT_5)/time_step; // 5 min
WAIT_10_MIN = (60 * WAIT_10_MIN)/time_step; // 10 min
WAIT_5_MIN = (60 * WAIT_5_MIN)/time_step; // 5 min
// integer input rate for controller
input_period = (1/controller_rate_Hz) / time_step;
......@@ -552,3 +218,110 @@ Controller::~Controller() {
patient_state.clear();
}
//Algorithm functions------------------------
/* Initialize in "Simulation Plan" */
void Controller::initializeInfusions(void){
currentNorepiInfusionRate = maxNorepinephrineInfusionRate;
// log rate
m_env->logger->LogRate(m_env->sim_currentTime,"Controller",
"RATE_CHANGE","Controller sends Command to saline Pump",SalineInfusionRate);
m_env->logger->LogRate(m_env->sim_currentTime,"Controller",
"RATE_CHANGE","Controller sends Command to saline Pump",currentNorepiInfusionRate);
m_pumps["saline"]->ChangePumpRate(SalineInfusionRate, m_env->time_index);
m_pumps["bpdrug"]->ChangePumpRate(currentNorepiInfusionRate, m_env->time_index);
// set next update time
nextUpdateTime = m_env->time_index + WAIT_10_MIN;
respondToData = &Controller::waitForMAPIncrease;
}
/* Wait for MAP increase in "Simulation Plan" */
void Controller::waitForMAPIncrease(void){
if(m_env->time_index == nextUpdateTime) {
if(currentMAP > MAPIncreaseThreshold) {
currentNorepiInfusionRate = percentOfRate * maxNorepinephrineInfusionRate;
m_env->logger->LogRate(m_env->sim_currentTime,"Controller",
"RATE_CHANGE","Controller sends Command to saline Pump",currentNorepiInfusionRate);
m_pumps["bpdrug"]->ChangePumpRate(currentNorepiInfusionRate, m_env->time_index);
nextUpdateTime = m_env->time_index + WAIT_10_MIN;
respondToData = &Controller::ensureMAPDeclineAfterIncrease;
}
else {
nextUpdateTime = m_env->time_index + WAIT_5_MIN;
}
}
}
/* Ensure MAP decline after increase in "Simulation Plan" */
void Controller::ensureMAPDeclineAfterIncrease(void){
if(m_env->time_index == nextUpdateTime) {
if(currentMAP > MAPIncreaseThreshold){
currentNorepiInfusionRate = percentOfRate * currentNorepiInfusionRate;
m_env->logger->LogRate(m_env->sim_currentTime,"Controller",
"RATE_CHANGE","Controller sends Command to saline Pump",currentNorepiInfusionRate);
m_pumps["bpdrug"]->ChangePumpRate(currentNorepiInfusionRate, m_env->time_index);
nextUpdateTime = m_env->time_index + WAIT_10_MIN;
}
else {
nextUpdateTime = m_env->time_index + WAIT_10_MIN;
respondToData = &Controller::maintainMAPInRange;
}
}
}
/* Maintain MAP in range in "Simulation Plan" */
void Controller::maintainMAPInRange(void){
if(m_env->time_index == nextUpdateTime) {
if(currentMAP > targetMAPRangeMax){
currentNorepiInfusionRate = percentOfRate * currentNorepiInfusionRate;
m_env->logger->LogRate(m_env->sim_currentTime,"Controller",
"RATE_CHANGE","Controller sends Command to saline Pump",currentNorepiInfusionRate);
m_pumps["bpdrug"]->ChangePumpRate(currentNorepiInfusionRate, m_env->time_index);
nextUpdateTime = m_env->time_index + WAIT_10_MIN;
}
else if(currentMAP < targetMAPRangeMin) {
currentNorepiInfusionRate = percentOfRate * maxNorepinephrineInfusionRate;
m_env->logger->LogRate(m_env->sim_currentTime,"Controller",
"RATE_CHANGE","Controller sends Command to saline Pump",currentNorepiInfusionRate);
m_pumps["bpdrug"]->ChangePumpRate(currentNorepiInfusionRate, m_env->time_index);
nextUpdateTime = m_env->time_index + WAIT_5_MIN;
}
else {
nextUpdateTime = m_env->time_index + WAIT_10_MIN;
}
}
}
......@@ -10,8 +10,10 @@ Pump::Pump()
//Overload Constructor
Pump::Pump(CMD::Environment* env, PhysiologyData* data, string substance): m_env(env), m_data(data),
m_substance(substance), pump_rate(0), LOG_INITIAL_PUMP_RATE(true), pump_data{make_pair(0,0ul)} {
//pump_data = {make_pair(0,0ul)};
m_substance(substance), pump_rate(0), LOG_INITIAL_PUMP_RATE(true), pump_data{make_pair(0.0,0ul)} {
NorepiConcentration = 32;
SalineBagVolume = 500;
}
......@@ -114,14 +116,14 @@ void Pump::LoadConfig(std::unique_ptr<PhysiologyEngine>& engine, const char* fil
SESubstanceCompound* saline = engine->GetSubstanceManager().GetCompound(m_substance);
m_infusion = new SESubstanceCompoundInfusion(*saline);
//the total volume in the bag of Saline
m_infusion->GetBagVolume().SetValue(500,VolumeUnit::mL);
m_infusion->GetBagVolume().SetValue(SalineBagVolume, VolumeUnit::mL);