software:firmware
MakAir Firmware
VC_CMV_Controller Class Reference

Controller for the Volume Controled mode. More...

#include <vc_cmv_controller.h>

+ Inheritance diagram for VC_CMV_Controller:

Public Member Functions

 VC_CMV_Controller ()
 Default constructor. More...
 
void setup () override
 Initialize controller. More...
 
void initCycle () override
 Begin a new breathing cycle. More...
 
void inhale () override
 Control the inhalation. More...
 
void exhale () override
 Control the exhalation. More...
 
void endCycle () override
 End the current breathing cycle. More...
 
struct Alarms enabledAlarms () const override
 List of alarms that must be enabled for this mode. More...
 

Private Member Functions

void calculateBlower ()
 Determine the blower speed to adopt for next cycle. More...
 
int32_t PCexpiratoryPID (int32_t targetPressure, int32_t currentPressure, int32_t dt)
 PID to control the patient valve during some specific steps of the cycle. More...
 

Private Attributes

bool m_duringPlateau = true
 
uint16_t m_blowerSpeed
 Current blower speed. More...
 
int32_t m_targetFlowMultiplyBy1000
 
bool m_expiratoryPidFastMode
 Fast mode at start of expiration. More...
 
int32_t m_expiratoryPidIntegral
 Integral gain of the expiratory PID. More...
 
int32_t m_inspiratoryPidIntegral
 Integral gain of the inspiratory PID. More...
 
int32_t m_inspiratoryValveLastAperture
 Last aperture of the inspiratory valve. More...
 
int32_t m_expiratoryValveLastAperture
 Last aperture of the blower valve. More...
 
int32_t m_expiratoryPidLastError
 Error of the last computation of the PID. More...
 
int32_t m_expiratoryPidLastErrors [PC_NUMBER_OF_SAMPLE_DERIVATIVE_MOVING_MEAN]
 Last errors in expiratory PID. More...
 
int32_t m_expiratoryPidLastErrorsIndex
 Last error index in expiratory PID. More...
 
int32_t m_inspiratoryFlowLastValues [NUMBER_OF_SAMPLE_LAST_VALUES]
 Last flow values. More...
 
int32_t m_inspiratoryFlowLastValuesIndex
 Last flow index. More...
 
int32_t m_maxInspiratoryFlow
 Max flow during inspiration. More...
 
int32_t m_blowerTicks
 Blower ticks. More...
 

Detailed Description

Controller for the Volume Controled mode.

Definition at line 14 of file vc_cmv_controller.h.

Constructor & Destructor Documentation

◆ VC_CMV_Controller()

VC_CMV_Controller::VC_CMV_Controller ( )

Default constructor.

Definition at line 28 of file vc_cmv_controller.cpp.

28  {
31 
34  for (uint8_t i = 0u; i < NUMBER_OF_SAMPLE_LAST_VALUES; i++) {
36  }
37  for (uint8_t i = 0u; i < PC_NUMBER_OF_SAMPLE_DERIVATIVE_MOVING_MEAN; i++) {
39  }
40 
42  m_blowerTicks = 0;
49 }
uint16_t maxAperture() const
Maximum valve aperture angle in degrees.
uint16_t m_blowerSpeed
Current blower speed.
int32_t m_blowerTicks
Blower ticks.
int32_t m_inspiratoryFlowLastValuesIndex
Last flow index.
int32_t m_inspiratoryPidIntegral
Integral gain of the inspiratory PID.
int32_t m_expiratoryPidLastErrorsIndex
Last error index in expiratory PID.
int32_t m_maxInspiratoryFlow
Max flow during inspiration.
int32_t m_expiratoryPidLastErrors[PC_NUMBER_OF_SAMPLE_DERIVATIVE_MOVING_MEAN]
Last errors in expiratory PID.
int32_t m_expiratoryPidIntegral
Integral gain of the expiratory PID.
bool m_expiratoryPidFastMode
Fast mode at start of expiration.
int32_t m_inspiratoryFlowLastValues[NUMBER_OF_SAMPLE_LAST_VALUES]
Last flow values.
int32_t m_expiratoryPidLastError
Error of the last computation of the PID.
int32_t m_expiratoryValveLastAperture
Last aperture of the blower valve.
int32_t m_targetFlowMultiplyBy1000
int32_t m_inspiratoryValveLastAperture
Last aperture of the inspiratory valve.
uint16_t i
#define NUMBER_OF_SAMPLE_LAST_VALUES
Definition: parameters.h:154
#define PC_NUMBER_OF_SAMPLE_DERIVATIVE_MOVING_MEAN
Definition: parameters.h:152
#define DEFAULT_BLOWER_SPEED
Definition: parameters.h:194
PressureValve inspiratoryValve
PressureValve expiratoryValve

Member Function Documentation

◆ calculateBlower()

void VC_CMV_Controller::calculateBlower ( )
private

Determine the blower speed to adopt for next cycle.

Definition at line 164 of file vc_cmv_controller.cpp.

164  {
165  // Compute target flow for inspiration
166  int32_t inspirationDurationMs =
168  - static_cast<uint16_t>(mainController.plateauDurationCommand())); // in ms
169  m_targetFlowMultiplyBy1000 = (inspirationDurationMs == 0)
170  ? 0
171  : (60 * 1000 * mainController.tidalVolumeCommand())
172  / inspirationDurationMs; // in mL/min
173 
174  // Blower always run at full speed
175  m_blowerSpeed = 1800;
176 }
int16_t tidalVolumeCommand() const
int16_t plateauDurationCommand() const
uint32_t ticksPerInhalation() const
Get the duration of an inhalation in ticks.
MainController mainController
#define MAIN_CONTROLLER_COMPUTE_PERIOD_MS
Definition: parameters.h:28

◆ enabledAlarms()

struct Alarms VC_CMV_Controller::enabledAlarms ( ) const
inlineoverridevirtual

List of alarms that must be enabled for this mode.

Implements VentilationController.

Definition at line 32 of file vc_cmv_controller.h.

35  {
36  struct Alarms a = {0u, RCM_SW_2, RCM_SW_3, 0u, 0u, 0u,
37  0u, 0u, 0u, RCM_SW_10, RCM_SW_11, RCM_SW_12,
39  0u, RCM_SW_22, RCM_SW_23};
40  return a;
41  }
#define RCM_SW_11
#define RCM_SW_12
#define RCM_SW_15
#define RCM_SW_3
#define RCM_SW_18
#define RCM_SW_23
#define RCM_SW_19
#define RCM_SW_16
#define RCM_SW_2
#define RCM_SW_22
#define RCM_SW_10
List of alarms (named by their code)

◆ endCycle()

void VC_CMV_Controller::endCycle ( )
overridevirtual

End the current breathing cycle.

Implements VentilationController.

Definition at line 162 of file vc_cmv_controller.cpp.

162 {}

◆ exhale()

void VC_CMV_Controller::exhale ( )
overridevirtual

Control the exhalation.

Implements VentilationController.

Definition at line 151 of file vc_cmv_controller.cpp.

151  {
152  // Open the expiration valve using PID so the patient can exhale outside
153  int32_t expiratoryValveOpenningValue = PCexpiratoryPID(
155 
156  (void)expiratoryValve.openLinear(expiratoryValveOpenningValue);
157 
159  // m_inspiratoryValveLastAperture = inspiratoryValveOpenningValue;
160 }
int32_t dt() const
Get the delta of time since the last cycle (in ms)
int16_t pressure() const
Get the current measured pressure.
int32_t pressureCommand() const
Get the pressure command.
void close()
Request closing of the Pressure Valve.
uint16_t openLinear(uint16_t p_command)
Request opening of the Pressure Valve with a given angle with linearization.
int32_t PCexpiratoryPID(int32_t targetPressure, int32_t currentPressure, int32_t dt)
PID to control the patient valve during some specific steps of the cycle.

◆ inhale()

void VC_CMV_Controller::inhale ( )
overridevirtual

Control the inhalation.

Implements VentilationController.

Definition at line 81 of file vc_cmv_controller.cpp.

81  {
83 
85 
86  int32_t inspirationRemainingDurationMs =
87  static_cast<int32_t>((mainController.ticksPerInhalation() - mainController.tick())
90 
91  if (inspirationRemainingDurationMs > 20) {
92  // m_targetFlowMultiplyBy1000 =
93  // (60 * 1000
94  // * (mainController.tidalVolumeCommand() - mainController.currentDeliveredVolume()))
95  // / inspirationRemainingDurationMs; // in mL/min
96  // m_targetFlowMultiplyBy1000 = max(int32_t(0), m_targetFlowMultiplyBy1000);
98  }
99 
100  // The safety volume is the volume that will be delivered during the closing of the valve.
101  // Taking is into account allows better accuracy on volume delivery
102  int32_t safetyVolume = mainController.inspiratoryFlow() * VALVE_RESPONSE_TIME_MS / 60000;
103  if (!m_duringPlateau
105  > mainController.tidalVolumeCommand() - safetyVolume) {
108  + static_cast<uint16_t>(mainController.plateauDurationCommand())
110  m_duringPlateau = true;
111  }
112  // If before plateau
114  - static_cast<uint16_t>(mainController.plateauDurationCommand())
116  int32_t flow = mainController.inspiratoryFlow();
117  int32_t blowerPressure = blower.getBlowerPressure(flow);
118  int32_t patientPressure = mainController.pressure();
119 
120  // Use Venturi equation to find the sectionToOpen in order to get the target flow.
121  // https://en.wikipedia.org/wiki/Venturi_effect
122  int32_t A1MultiplyBy100 = 3318;
123  int32_t rhoMultiplyBy100 = 120;
124  int32_t twoA1SquareDotDeltaPressureMultiplyBy100 =
125  100 * 2 * (A1MultiplyBy100 * A1MultiplyBy100 / 10000)
126  * (98 * (blowerPressure - patientPressure) / 10);
127  int32_t divider = (rhoMultiplyBy100 * (m_targetFlowMultiplyBy1000 / 60)
128  * (m_targetFlowMultiplyBy1000 / 60) / 100);
129  int32_t tempRatio =
130  (divider == 0) ? 0 : (twoA1SquareDotDeltaPressureMultiplyBy100 / divider);
131  int32_t sectionToOpen;
132  if (m_targetFlowMultiplyBy1000 == 0) {
133  sectionToOpen = 0;
134  } else {
135  int32_t divider2 = ((tempRatio + 100) < 0) ? 0 : sqrt(tempRatio + 100);
136  sectionToOpen = (divider2 == 0) ? 0 : (A1MultiplyBy100 * 10 / divider2);
137  }
138 
139  // Open the valve to a specific section (in mm^2 multiplied by 100)
140  inspiratoryValve.openSection(sectionToOpen);
141  } else { // else : during plateau, valves are closed
143  }
144 
145  // Compute max inspiratory flow
148  }
149 }
Blower blower
Definition: blower.cpp:20
int32_t getBlowerPressure(int32_t p_flow)
Given a flow in mL/min, return an estimated pressure just at the output of the blower.
Definition: blower.cpp:85
uint32_t tick() const
Get the tick number of the current cycle.
const int32_t targetInspiratoryFlowCommand() const
get target inspiratory flow in mL/min (used in VC modes)
int32_t currentDeliveredVolume() const
Get the measured Tidal Volume. Updated in real time.
int32_t inspiratoryFlow() const
Get the current inspiratoryFlow.
void ticksPerInhalationSet(uint32_t p_ticksPerInhalation)
Get the duration of an inhalation in ticks.
void openSection(int32_t p_sectionMultiplyBy100)
Request opening of the Pressure Valve with a given section (in mm^2)
#define VALVE_RESPONSE_TIME_MS
Definition: parameters.h:175

◆ initCycle()

void VC_CMV_Controller::initCycle ( )
overridevirtual

Begin a new breathing cycle.

Implements VentilationController.

Definition at line 55 of file vc_cmv_controller.cpp.

55  {
58  // Reset PID values
64  for (uint8_t i = 0; i < PC_NUMBER_OF_SAMPLE_DERIVATIVE_MOVING_MEAN; i++) {
67  }
68 
69  for (uint8_t i = 0u; i < NUMBER_OF_SAMPLE_LAST_VALUES; i++) {
71  }
73 
78  m_duringPlateau = false;
79 }
uint16_t getTargetSpeed() const
Get target speed value.
Definition: blower.cpp:103
void runSpeedWithRampUp(uint16_t p_targetSpeed)
Run the blower to a given speed applying a ramp-up to prevent high current drain.
Definition: blower.cpp:44
int16_t peepCommand() const
Get the desired PEEP.
int16_t plateauPressureCommand() const
Get the desired plateau pressure.
void calculateBlower()
Determine the blower speed to adopt for next cycle.

◆ PCexpiratoryPID()

int32_t VC_CMV_Controller::PCexpiratoryPID ( int32_t  targetPressure,
int32_t  currentPressure,
int32_t  dt 
)
private

PID to control the patient valve during some specific steps of the cycle.

Parameters
targetPressureThe pressure we want (in mmH2O)
currentPressureThe pressure measured by the sensor (in mmH2O)
dtTime since the last computation (in microsecond)

Definition at line 179 of file vc_cmv_controller.cpp.

179  {
180  int32_t minAperture = expiratoryValve.minAperture();
181  int32_t maxAperture = expiratoryValve.maxAperture();
182  int32_t expiratoryValveAperture;
183  int32_t derivative = 0;
184  int32_t smoothError = 0;
185  int32_t totalValues = 0;
186  int32_t temporaryExpiratoryPidIntegral = 0;
187  int32_t proportionnalWeight;
188  int32_t derivativeWeight;
189 
190  int32_t coefficientP;
191  int32_t coefficientI;
192  int32_t coefficientD;
193 
194  // Compute error
195  int32_t error = targetPressure + PID_PATIENT_SAFETY_PEEP_OFFSET - currentPressure;
196 
197  // Calculate derivative part
198  // Include a moving average on error for smoothing purpose
202  >= static_cast<int32_t>(PC_NUMBER_OF_SAMPLE_DERIVATIVE_MOVING_MEAN)) {
204  }
205  for (uint8_t i = 0u; i < PC_NUMBER_OF_SAMPLE_DERIVATIVE_MOVING_MEAN; i++) {
206  totalValues += m_expiratoryPidLastErrors[i];
207  }
208  smoothError = totalValues / static_cast<int32_t>(PC_NUMBER_OF_SAMPLE_DERIVATIVE_MOVING_MEAN);
209  derivative = (dt == 0) ? 0 : (1000000 * (smoothError - m_expiratoryPidLastError)) / dt;
210 
211  // Windowing (it overrides the parameter.h coefficients)
212  if (error < 0) {
213  coefficientI = 50;
214  coefficientP = 2500;
215  coefficientD = 0;
216  } else {
217  // For a high PEEP, a lower KI is required
218  // For PEEP = 100 mmH2O, KI = 120
219  // For PEEP = 50 mmH2O, KI = 250
220  if (mainController.peepCommand() > 100) {
221  coefficientI = 120;
222  } else {
223  coefficientI = ((-130 * ((int32_t)mainController.peepCommand())) / 50) + 380;
224  }
225  coefficientP = 2500;
226  coefficientD = 0;
227  }
228 
229  // Fast mode ends at 30 mmH20 from target
230  // When changing from fast mode to PID, set the integral to the previous value
231  if (error > -30) {
233  proportionnalWeight = (coefficientP * error) / 1000;
234  derivativeWeight = (coefficientD * derivative / 1000);
235  m_expiratoryPidIntegral = 1000 * ((int32_t)m_expiratoryValveLastAperture - maxAperture)
236  / (maxAperture - minAperture)
237  - (proportionnalWeight + derivativeWeight);
238  }
239  m_expiratoryPidFastMode = false;
240  }
241 
242  // Fast mode: open loop with ramp
244  expiratoryValveAperture = 0;
245  } else { // If not in fast mode, the PID is used
246  temporaryExpiratoryPidIntegral =
247  m_expiratoryPidIntegral + ((coefficientI * error * dt) / 1000000);
248  temporaryExpiratoryPidIntegral =
250  min(PID_PATIENT_INTEGRAL_MAX, temporaryExpiratoryPidIntegral));
251 
252  proportionnalWeight = ((coefficientP * error) / 1000);
253  int32_t integralWeight = temporaryExpiratoryPidIntegral;
254  derivativeWeight = coefficientD * derivative / 1000;
255 
256  int32_t patientCommand = proportionnalWeight + integralWeight + derivativeWeight;
257 
258  expiratoryValveAperture = max(
259  minAperture,
260  min(maxAperture, maxAperture + (maxAperture - minAperture) * patientCommand / 1000));
261  }
262 
263  // If the valve is completely open or completely closed, don't update integral part
264  if ((expiratoryValveAperture != minAperture) && (expiratoryValveAperture != maxAperture)) {
265  m_expiratoryPidIntegral = temporaryExpiratoryPidIntegral;
266  }
267 
268  m_expiratoryPidLastError = smoothError;
269  m_expiratoryValveLastAperture = expiratoryValveAperture;
270 
271  return expiratoryValveAperture;
272 }
uint16_t minAperture() const
Minimum valve aperture angle in degrees.
static const int32_t PID_PATIENT_INTEGRAL_MIN
Definition: parameters.h:146
static const int32_t PID_PATIENT_INTEGRAL_MAX
Definition: parameters.h:145
static const int32_t PID_PATIENT_SAFETY_PEEP_OFFSET
Increase target pressure by an offset (in mmH2O) for safety, to avoid going below the target pressure...
Definition: parameters.h:150

◆ setup()

void VC_CMV_Controller::setup ( )
overridevirtual

Initialize controller.

Implements VentilationController.

Definition at line 51 of file vc_cmv_controller.cpp.

51  {
52  // No specific setup code
53 }

Member Data Documentation

◆ m_blowerSpeed

uint16_t VC_CMV_Controller::m_blowerSpeed
private

Current blower speed.

Definition at line 59 of file vc_cmv_controller.h.

◆ m_blowerTicks

int32_t VC_CMV_Controller::m_blowerTicks
private

Blower ticks.

Definition at line 97 of file vc_cmv_controller.h.

◆ m_duringPlateau

bool VC_CMV_Controller::m_duringPlateau = true
private

Definition at line 56 of file vc_cmv_controller.h.

◆ m_expiratoryPidFastMode

bool VC_CMV_Controller::m_expiratoryPidFastMode
private

Fast mode at start of expiration.

Definition at line 64 of file vc_cmv_controller.h.

◆ m_expiratoryPidIntegral

int32_t VC_CMV_Controller::m_expiratoryPidIntegral
private

Integral gain of the expiratory PID.

Definition at line 67 of file vc_cmv_controller.h.

◆ m_expiratoryPidLastError

int32_t VC_CMV_Controller::m_expiratoryPidLastError
private

Error of the last computation of the PID.

Definition at line 79 of file vc_cmv_controller.h.

◆ m_expiratoryPidLastErrors

int32_t VC_CMV_Controller::m_expiratoryPidLastErrors[PC_NUMBER_OF_SAMPLE_DERIVATIVE_MOVING_MEAN]
private

Last errors in expiratory PID.

Definition at line 82 of file vc_cmv_controller.h.

◆ m_expiratoryPidLastErrorsIndex

int32_t VC_CMV_Controller::m_expiratoryPidLastErrorsIndex
private

Last error index in expiratory PID.

Definition at line 85 of file vc_cmv_controller.h.

◆ m_expiratoryValveLastAperture

int32_t VC_CMV_Controller::m_expiratoryValveLastAperture
private

Last aperture of the blower valve.

Definition at line 76 of file vc_cmv_controller.h.

◆ m_inspiratoryFlowLastValues

int32_t VC_CMV_Controller::m_inspiratoryFlowLastValues[NUMBER_OF_SAMPLE_LAST_VALUES]
private

Last flow values.

Definition at line 88 of file vc_cmv_controller.h.

◆ m_inspiratoryFlowLastValuesIndex

int32_t VC_CMV_Controller::m_inspiratoryFlowLastValuesIndex
private

Last flow index.

Definition at line 91 of file vc_cmv_controller.h.

◆ m_inspiratoryPidIntegral

int32_t VC_CMV_Controller::m_inspiratoryPidIntegral
private

Integral gain of the inspiratory PID.

Definition at line 70 of file vc_cmv_controller.h.

◆ m_inspiratoryValveLastAperture

int32_t VC_CMV_Controller::m_inspiratoryValveLastAperture
private

Last aperture of the inspiratory valve.

Definition at line 73 of file vc_cmv_controller.h.

◆ m_maxInspiratoryFlow

int32_t VC_CMV_Controller::m_maxInspiratoryFlow
private

Max flow during inspiration.

Definition at line 94 of file vc_cmv_controller.h.

◆ m_targetFlowMultiplyBy1000

int32_t VC_CMV_Controller::m_targetFlowMultiplyBy1000
private

Definition at line 61 of file vc_cmv_controller.h.


The documentation for this class was generated from the following files: