Ejemplo n.º 1
0
 def _sensor_to_COPY(self):
     # And the sensor measurements
     self._lock.acquire()
     self.COPY_sensor_values = SensorValues(
         pip=self._DATA_PIP,
         peep=self._DATA_PEEP,
         fio2=self.Balloon.fio2,
         temp=self.Balloon.temperature,
         humidity=self.Balloon.humidity,
         pressure=self.Balloon.current_pressure,
         vte=self._DATA_VTE,
         breaths_per_minute=self._DATA_BPM,
         inspiration_time_sec=self._DATA_I_PHASE,
         timestamp=time.time(),
         loop_counter=self._loop_counter)
     self._lock.release()
Ejemplo n.º 2
0
    def _fake_sensor(arg=None):
        # make an empty SensorValues
        vals = {k:0 for k in ValueName}
        vals.update({k:0 for k in SensorValues.additional_values})

        # since 0 is out of range for fio2, manually set it
        # FIXME: find values that by definition don't raise any of the default rules
        vals[ValueName.FIO2] = 80

        # update with any in kwargs
        if arg:
            for k, v in arg.items():
                vals[k] = v

        sensors = SensorValues(vals=vals)

        return sensors
Ejemplo n.º 3
0
 def _sensor_to_COPY(self):
     # And the sensor measurements
     self._lock.acquire()
     self.COPY_sensor_values = SensorValues(
         vals={
             ValueName.PIP: self._DATA_PIP,
             ValueName.PEEP: self._DATA_PEEP,
             ValueName.FIO2: 70,
             ValueName.PRESSURE: self.HAL.pressure,
             ValueName.VTE: self._DATA_VTE,
             ValueName.BREATHS_PER_MINUTE: self._DATA_BPM,
             ValueName.INSPIRATION_TIME_SEC: self._DATA_I_PHASE,
             'timestamp': time.time(),
             'loop_counter': self._loop_counter,
             'breath_count': self._DATA_BREATH_COUNT
         })
     self._lock.release()
Ejemplo n.º 4
0
    def get_sensors_values(self):
        # returns SensorValues and a time stamp

        self.update_alarms()  # Make sure we are up to date

        self.sensor_values = SensorValues(
            pip=self.Controller.PIP,
            peep=self.PEEP,
            fio2=self.Balloon.fio2,
            temp=self.Balloon.temperature,
            humidity=self.Balloon.humidity,
            pressure=self.Balloon.current_pressure,
            vte=self.vte,
            breaths_per_minute=self.bpm,
            inspiration_time_sec=self.I_phase,
            timestamp=time.time())

        return self.sensor_values
Ejemplo n.º 5
0
 def _sensor_to_COPY(self):
     # And the sensor measurements
     self._lock.acquire()
     self.COPY_sensor_values = SensorValues(
         vals={
             ValueName.PIP.name: self._DATA_PIP,
             ValueName.PEEP.name: self._DATA_PEEP,
             ValueName.FIO2.name: self.Balloon.fio2,
             ValueName.TEMP.name: self.Balloon.temperature,
             ValueName.HUMIDITY.name: self.Balloon.humidity,
             ValueName.PRESSURE.name: self.Balloon.current_pressure,
             ValueName.VTE.name: self._DATA_VTE,
             ValueName.BREATHS_PER_MINUTE.name: self._DATA_BPM,
             ValueName.INSPIRATION_TIME_SEC.name: self._DATA_I_PHASE,
             'timestamp': time.time(),
             'loop_counter': self._loop_counter,
             'breath_count': self._DATA_BREATH_COUNT
         })
     self._lock.release()
Ejemplo n.º 6
0
 def get_sensors(self):
     self._running.wait()
     return SensorValues(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
Ejemplo n.º 7
0
    def __init__(self):

        #####################  Algorithm/Program parameters  ##################
        # Hyper-Parameters
        self._LOOP_UPDATE_TIME = 0.01  # Run the main control loop every 0.01 sec
        self._NUMBER_CONTROLL_LOOPS_UNTIL_UPDATE = 10  # After every 10 main control loop iterations, update COPYs.
        self._RINGBUFFER_SIZE = 100  # Maximum number of breath cycles kept in memory

        #########################  Control management  #########################

        # This is what the machine has controll over:
        self.__control_signal_in = 0  # State of a valve on the inspiratory side - could be a proportional valve.
        self.__control_signal_out = 0  # State of a valve on the exspiratory side - this is open/close
        self._pid_control_flag = True  # Default is: use PID control

        # Internal Control variables. "SET" indicates that this is set.
        self.__SET_PIP = CONTROL[ValueName.PIP].default  # Target PIP pressure
        self.__SET_PIP_TIME = CONTROL[
            ValueName.PIP_TIME].default  # Target time to reach PIP in seconds
        self.__SET_PEEP = CONTROL[
            ValueName.PEEP].default  # Target PEEP pressure
        self.__SET_PEEP_TIME = CONTROL[
            ValueName.
            PEEP_TIME].default  # Target time to reach PEEP from PIP plateau
        self.__SET_BPM = CONTROL[
            ValueName.BREATHS_PER_MINUTE].default  # Target breaths per minute
        self.__SET_I_PHASE = CONTROL[
            ValueName.
            INSPIRATION_TIME_SEC].default  # Target duration of inspiratory phase

        # Derived internal control variables - fully defined by numbers above
        self.__SET_CYCLE_DURATION = 60 / self.__SET_BPM
        self.__SET_E_PHASE = self.__SET_CYCLE_DURATION - self.__SET_I_PHASE
        self.__SET_T_PLATEAU = self.__SET_I_PHASE - self.__SET_PIP_TIME
        self.__SET_T_PEEP = self.__SET_E_PHASE - self.__SET_PEEP_TIME

        #########################  Data management  #########################

        # These are measurements from the last breath cycle.
        self._DATA_PIP = None  # Measured value of PIP
        self._DATA_PIP_TIME = None  # Measured time of reaching PIP plateau
        self._DATA_PEEP = None  # Measured valued of PEEP
        self._DATA_I_PHASE = None  # Measured duration of inspiratory phase
        self.__DATA_LAST_PEEP = None  # Last time of PEEP - by definition end of breath cycle
        self._DATA_BPM = None  # Measured breathing rate, by definition 60sec / length_of_breath_cycle
        self._DATA_VTE = None  # Maximum air displacement in last breath cycle
        self._DATA_P = 0  # Last measurements of the proportional term for PID-control
        self._DATA_I = 0  # Last measurements of the integral term for PID-control
        self._DATA_D = 0  # Last measurements of the differential term for PID-control

        # Parameters to keep track of breath-cycle
        self.__cycle_start = time.time()
        self.__cycle_waveform = np.array(
            [[0, 0, 0]])  # To build up the current cycle's waveform
        self.__cycle_waveform_archive = deque(
            maxlen=self._RINGBUFFER_SIZE)  # An archive of past waveforms.

        # These are measurements that change from timepoint to timepoint
        self._DATA_PRESSURE = 0
        self.__DATA_VOLUME = 0
        self._DATA_Qin = 0  # Measurement of the airflow in
        self._DATA_Qout = 0  # Measurement of the airflow out
        self._DATA_dpdt = 0  # Current sample of the rate of change of pressure dP/dt in cmH2O/sec
        self._last_update = time.time()

        #########################  Alarm management  #########################
        self.__active_alarms = {}  # Dictionary of active alarms
        self.__logged_alarms = deque(
            maxlen=self._RINGBUFFER_SIZE)  # List of all resolved alarms

        # Variable limits to raise alarms, initialized as small deviation of what the controller initializes
        self.__PIP_min = CONTROL[ValueName.PIP].safe_range[0]
        self.__PIP_max = CONTROL[ValueName.PIP].safe_range[1]
        self.__PIP_lastset = time.time()
        self.__PIP_time_min = CONTROL[ValueName.PIP_TIME].safe_range[0]
        self.__PIP_time_max = CONTROL[ValueName.PIP_TIME].safe_range[1]
        self.__PIP_time_lastset = time.time()
        self.__PEEP_min = CONTROL[ValueName.PEEP].safe_range[0]
        self.__PEEP_max = CONTROL[ValueName.PEEP].safe_range[1]
        self.__PEEP_lastset = time.time()
        self.__bpm_min = CONTROL[ValueName.BREATHS_PER_MINUTE].safe_range[0]
        self.__bpm_max = CONTROL[ValueName.BREATHS_PER_MINUTE].safe_range[1]
        self.__bpm_lastset = time.time()
        self.__I_phase_min = CONTROL[
            ValueName.INSPIRATION_TIME_SEC].safe_range[0]
        self.__I_phase_max = CONTROL[
            ValueName.INSPIRATION_TIME_SEC].safe_range[1]
        self.__I_phase_lastset = time.time()

        ############### Initialize COPY variables for threads  ##############
        # COPY variables that later updated on a regular basis
        self.COPY_active_alarms = {}
        self.COPY_logged_alarms = list(self.__logged_alarms)
        self.COPY_sensor_values = SensorValues()

        ###########################  Threading init  #########################
        # Run the start() method as a thread
        self._loop_counter = 0
        self._running = False
        self._lock = threading.Lock()
        self._alarm_to_COPY()  #These require the lock
        self._initialize_set_to_COPY()

        self.__thread = threading.Thread(target=self._start_mainloop,
                                         daemon=True)
        self.__thread.start()