diff --git a/core/color.cpp b/core/color.cpp index b5bbc3269..6ac7fc761 100644 --- a/core/color.cpp +++ b/core/color.cpp @@ -32,6 +32,8 @@ void fill_profile_color() profile_color[CCRSENSOR1] = COLOR(TUNDORA1_MED_TRANS, BLACK1_LOW_TRANS, TUNDORA1_MED_TRANS); profile_color[CCRSENSOR2] = COLOR(ROYALBLUE2_LOW_TRANS, BLACK1_LOW_TRANS, ROYALBLUE2_LOW_TRANS); profile_color[CCRSENSOR3] = COLOR(PEANUT, BLACK1_LOW_TRANS, PEANUT); + profile_color[SCR_OCPO2] = COLOR(PIRATEGOLD1_MED_TRANS, BLACK1_LOW_TRANS, PIRATEGOLD1_MED_TRANS); + profile_color[PP_LINES] = COLOR(BLACK1_HIGH_TRANS, BLACK1_LOW_TRANS, BLACK1_HIGH_TRANS); profile_color[TEXT_BACKGROUND] = COLOR(CONCRETE1_LOWER_TRANS, WHITE1, CONCRETE1_LOWER_TRANS); diff --git a/core/color.h b/core/color.h index 9e2496c8b..bf2f1ddcb 100644 --- a/core/color.h +++ b/core/color.h @@ -29,6 +29,7 @@ #define PERSIANRED1 QColor::fromRgbF(0.8, 0.2, 0.2, 1) #define TUSCANY1 QColor::fromRgbF(0.8, 0.4, 0.2, 1) #define PIRATEGOLD1 QColor::fromRgbF(0.8, 0.5, 0.0, 1) +#define PIRATEGOLD1_MED_TRANS QColor::fromRgbF(0.8, 0.5, 0.0, 0.75) #define HOKEYPOKEY1 QColor::fromRgbF(0.8, 0.6, 0.2, 1) #define CINNABAR1 QColor::fromRgbF(0.9, 0.3, 0.2, 1) #define REDORANGE1 QColor::fromRgbF(1.0, 0.2, 0.2, 1) @@ -102,6 +103,7 @@ typedef enum { CCRSENSOR1, CCRSENSOR2, CCRSENSOR3, + SCR_OCPO2, PP_LINES, /* Other colors */ diff --git a/core/pref.h b/core/pref.h index 3ba7c26d3..2628c3677 100644 --- a/core/pref.h +++ b/core/pref.h @@ -87,6 +87,7 @@ struct preferences { bool gf_low_at_maxdepth; bool show_ccr_setpoint; bool show_ccr_sensors; + bool show_scr_ocpo2; bool display_invalid_dives; short unit_system; struct units units; diff --git a/core/profile.c b/core/profile.c index 835e68dcc..c5105c4f5 100644 --- a/core/profile.c +++ b/core/profile.c @@ -1214,6 +1214,8 @@ static void calculate_gas_information_new(struct dive *dive, struct divecomputer fill_pressures(&entry->pressures, amb_pressure, gasmix, entry->o2pressure.mbar / 1000.0, dive->dc.divemode); fn2 = (int)(1000.0 * entry->pressures.n2 / amb_pressure); fhe = (int)(1000.0 * entry->pressures.he / amb_pressure); + if (dc->divemode == PSCR) // OC pO2 is calulated for PSCR with or without external PO2 monitoring. + entry->scr_OC_pO2.mbar = (int) depth_to_mbar(entry->depth, dive) * get_o2(get_gasmix(dive, dc, entry->sec, &ev, gasmix)) / 1000; /* Calculate MOD, EAD, END and EADD based on partial pressures calculated before * so there is no difference in calculating between OC and CC diff --git a/core/profile.h b/core/profile.h index 0a215d47e..58c44d955 100644 --- a/core/profile.h +++ b/core/profile.h @@ -46,6 +46,7 @@ struct plot_data { pressure_t o2pressure; // for rebreathers, this is consensus measured po2, or setpoint otherwise. 0 for OC. pressure_t o2sensor[3]; //for rebreathers with up to 3 PO2 sensors pressure_t o2setpoint; + pressure_t scr_OC_pO2; double mod, ead, end, eadd; velocity_t velocity; int speed; diff --git a/core/subsurface-qt/SettingsObjectWrapper.cpp b/core/subsurface-qt/SettingsObjectWrapper.cpp index cd1054b97..aaa907759 100644 --- a/core/subsurface-qt/SettingsObjectWrapper.cpp +++ b/core/subsurface-qt/SettingsObjectWrapper.cpp @@ -392,6 +392,11 @@ bool TechnicalDetailsSettings::rulerGraph() const return prefs.rulergraph; } +bool TechnicalDetailsSettings::showSCROCpO2() const +{ + return prefs.show_scr_ocpo2; +} + bool TechnicalDetailsSettings::showCCRSetpoint() const { return prefs.show_ccr_setpoint; @@ -667,6 +672,18 @@ void TechnicalDetailsSettings::setShowCCRSetpoint(bool value) emit showCCRSetpointChanged(value); } +void TechnicalDetailsSettings::setShowSCROCpO2(bool value) +{ + if (value == prefs.show_scr_ocpo2) + return; + + QSettings s; + s.beginGroup(group); + s.setValue("show_scr_ocpo2", value); + prefs.show_scr_ocpo2 = value; + emit showSCROCpO2Changed(value); +} + void TechnicalDetailsSettings::setShowCCRSensors(bool value) { if (value == prefs.show_ccr_sensors) @@ -2222,6 +2239,7 @@ void SettingsObjectWrapper::load() GET_BOOL("gf_low_at_maxdepth", gf_low_at_maxdepth); GET_BOOL("show_ccr_setpoint",show_ccr_setpoint); GET_BOOL("show_ccr_sensors",show_ccr_sensors); + GET_BOOL("show_scr_ocpo2",show_scr_ocpo2); GET_BOOL("zoomed_plot", zoomed_plot); set_gf(prefs.gflow, prefs.gfhigh); set_vpmb_conservatism(prefs.vpmb_conservatism); diff --git a/core/subsurface-qt/SettingsObjectWrapper.h b/core/subsurface-qt/SettingsObjectWrapper.h index 94bbcf5fc..f2c6745d8 100644 --- a/core/subsurface-qt/SettingsObjectWrapper.h +++ b/core/subsurface-qt/SettingsObjectWrapper.h @@ -135,6 +135,7 @@ class TechnicalDetailsSettings : public QObject { Q_PROPERTY(bool rulergraph READ rulerGraph WRITE setRulerGraph NOTIFY rulerGraphChanged) Q_PROPERTY(bool show_ccr_setpoint READ showCCRSetpoint WRITE setShowCCRSetpoint NOTIFY showCCRSetpointChanged) Q_PROPERTY(bool show_ccr_sensors READ showCCRSensors WRITE setShowCCRSensors NOTIFY showCCRSensorsChanged) + Q_PROPERTY(bool show_scr_ocpo2 READ showSCROCpO2 WRITE setShowSCROCpO2 NOTIFY showSCROCpO2Changed) Q_PROPERTY(bool zoomed_plot READ zoomedPlot WRITE setZoomedPlot NOTIFY zoomedPlotChanged) Q_PROPERTY(bool show_sac READ showSac WRITE setShowSac NOTIFY showSacChanged) Q_PROPERTY(bool display_unused_tanks READ displayUnusedTanks WRITE setDisplayUnusedTanks NOTIFY displayUnusedTanksChanged) @@ -165,6 +166,7 @@ public: bool rulerGraph() const; bool showCCRSetpoint() const; bool showCCRSensors() const; + bool showSCROCpO2() const; bool zoomedPlot() const; bool showSac() const; bool displayUnusedTanks() const; @@ -193,6 +195,7 @@ public slots: void setRulerGraph(bool value); void setShowCCRSetpoint(bool value); void setShowCCRSensors(bool value); + void setShowSCROCpO2(bool value); void setZoomedPlot(bool value); void setShowSac(bool value); void setDisplayUnusedTanks(bool value); @@ -221,6 +224,7 @@ signals: void rulerGraphChanged(bool value); void showCCRSetpointChanged(bool value); void showCCRSensorsChanged(bool value); + void showSCROCpO2Changed(bool value); void zoomedPlotChanged(bool value); void showSacChanged(bool value); void displayUnusedTanksChanged(bool value); diff --git a/core/subsurfacestartup.c b/core/subsurfacestartup.c index 1f71d2117..9d7d9494b 100644 --- a/core/subsurfacestartup.c +++ b/core/subsurfacestartup.c @@ -42,6 +42,7 @@ struct preferences default_prefs = { .gf_low_at_maxdepth = false, .show_ccr_setpoint = false, .show_ccr_sensors = false, + .show_scr_ocpo2 = false, .font_size = -1, .display_invalid_dives = false, .show_sac = false, diff --git a/desktop-widgets/preferences/preferences_graph.cpp b/desktop-widgets/preferences/preferences_graph.cpp index ccc9aee65..91cd773d8 100644 --- a/desktop-widgets/preferences/preferences_graph.cpp +++ b/desktop-widgets/preferences/preferences_graph.cpp @@ -40,6 +40,7 @@ void PreferencesGraph::refreshSettings() ui->vpmb_conservatism->setValue(prefs.vpmb_conservatism); ui->show_ccr_setpoint->setChecked(prefs.show_ccr_setpoint); ui->show_ccr_sensors->setChecked(prefs.show_ccr_sensors); + ui->show_scr_ocpo2->setChecked(prefs.show_scr_ocpo2); ui->defaultSetpoint->setValue((double)prefs.defaultsetpoint / 1000.0); ui->psro2rate->setValue(prefs.o2consumption / 1000.0); ui->pscrfactor->setValue(lrint(1000.0 / prefs.pscr_ratio)); @@ -71,6 +72,7 @@ void PreferencesGraph::syncSettings() tech->setVpmbConservatism(ui->vpmb_conservatism->value()); tech->setShowCCRSetpoint(ui->show_ccr_setpoint->isChecked()); tech->setShowCCRSensors(ui->show_ccr_sensors->isChecked()); + tech->setShowSCROCpO2(ui->show_scr_ocpo2->isChecked()); tech->setDisplayUnusedTanks(ui->display_unused_tanks->isChecked()); tech->setShowAverageDepth(ui->show_average_depth->isChecked()); tech->setShowIcd(ui->show_icd->isChecked()); diff --git a/desktop-widgets/preferences/preferences_graph.ui b/desktop-widgets/preferences/preferences_graph.ui index e711ea1c7..020ae498f 100644 --- a/desktop-widgets/preferences/preferences_graph.ui +++ b/desktop-widgets/preferences/preferences_graph.ui @@ -158,18 +158,72 @@ - Show individual O₂ sensor values when viewing pO₂ + Show O₂ sensor values when viewing pO₂ - Show setpoints when viewing pO₂ + Show CCR setpoints when viewing pO₂ + + + pSCR options: + + + + + + + pSCR metabolic rate O₂ + + + Qt::AlignCenter + + + + + + + ℓ/min + + + 3 + + + + + + + Dilution ratio + + + Qt::AlignCenter + + + + + + + + + + 1: + + + + + + + Show equivalent OC pO₂ with pSCR pO₂ + + + + Show warnings for isobaric counterdiffusion @@ -195,16 +249,6 @@ - - - - - - - 1: - - - @@ -225,16 +269,6 @@ - - - - Dilution ratio - - - Qt::AlignCenter - - - @@ -271,16 +305,6 @@ - - - - Metabolic rate O₂ - - - Qt::AlignCenter - - - @@ -291,16 +315,6 @@ - - - - ℓ/min - - - 3 - - - @@ -321,13 +335,6 @@ - - - - pSCR options: - - - @@ -386,16 +393,18 @@ pheThreshold maxpo2 defaultSetpoint - show_ccr_setpoint show_ccr_sensors + show_ccr_setpoint + psro2rate + pscrfactor + show_scr_ocpo2 + show_icd red_ceiling vpmb vpmb_conservatism buehlmann gflow gfhigh - psro2rate - pscrfactor display_unused_tanks show_average_depth diff --git a/profile-widget/profilewidget2.cpp b/profile-widget/profilewidget2.cpp index 16d08f119..da3eaad90 100644 --- a/profile-widget/profilewidget2.cpp +++ b/profile-widget/profilewidget2.cpp @@ -109,6 +109,7 @@ ProfileWidget2::ProfileWidget2(QWidget *parent) : QGraphicsView(parent), ccrsensor1GasItem(new PartialPressureGasItem()), ccrsensor2GasItem(new PartialPressureGasItem()), ccrsensor3GasItem(new PartialPressureGasItem()), + ocpo2GasItem(new PartialPressureGasItem()), #ifndef SUBSURFACE_MOBILE diveCeiling(new DiveCalculatedCeiling(this)), decoModelParameters(new DiveTextItem()), @@ -198,6 +199,7 @@ void ProfileWidget2::addItemsToScene() scene()->addItem(ccrsensor1GasItem); scene()->addItem(ccrsensor2GasItem); scene()->addItem(ccrsensor3GasItem); + scene()->addItem(ocpo2GasItem); #ifndef SUBSURFACE_MOBILE scene()->addItem(toolTipItem); scene()->addItem(diveCeiling); @@ -315,6 +317,7 @@ void ProfileWidget2::setupItemOnScene() createPPGas(ccrsensor1GasItem, DivePlotDataModel::CCRSENSOR1, CCRSENSOR1, PO2_ALERT, &prefs.pp_graphs.po2_threshold_min, &prefs.pp_graphs.po2_threshold_max); createPPGas(ccrsensor2GasItem, DivePlotDataModel::CCRSENSOR2, CCRSENSOR2, PO2_ALERT, &prefs.pp_graphs.po2_threshold_min, &prefs.pp_graphs.po2_threshold_max); createPPGas(ccrsensor3GasItem, DivePlotDataModel::CCRSENSOR3, CCRSENSOR3, PO2_ALERT, &prefs.pp_graphs.po2_threshold_min, &prefs.pp_graphs.po2_threshold_max); + createPPGas(ocpo2GasItem, DivePlotDataModel::SCR_OC_PO2, SCR_OCPO2, PO2_ALERT, &prefs.pp_graphs.po2_threshold_min, &prefs.pp_graphs.po2_threshold_max); #undef CREATE_PP_GAS #ifndef SUBSURFACE_MOBILE @@ -327,6 +330,7 @@ void ProfileWidget2::setupItemOnScene() //WARNING: The old code was broken, I'm not sure what should trigger the visibility of those graphs, since the old code didn't triggered them // because it was using a wrong settings. + connect(SettingsObjectWrapper::instance()->techDetails, &TechnicalDetailsSettings::showSCROCpO2Changed, ocpo2GasItem, &PartialPressureGasItem::setVisible); connect(SettingsObjectWrapper::instance()->techDetails, &TechnicalDetailsSettings::showCCRSensorsChanged, ccrsensor1GasItem, &PartialPressureGasItem::setVisible); connect(SettingsObjectWrapper::instance()->techDetails, &TechnicalDetailsSettings::showCCRSensorsChanged, ccrsensor2GasItem, &PartialPressureGasItem::setVisible); connect(SettingsObjectWrapper::instance()->techDetails, &TechnicalDetailsSettings::showCCRSensorsChanged, ccrsensor3GasItem, &PartialPressureGasItem::setVisible); @@ -598,6 +602,7 @@ void ProfileWidget2::plotDive(struct dive *d, bool force) ccrsensor1GasItem->setVisible(sensorflag); ccrsensor2GasItem->setVisible(sensorflag && (currentdc->no_o2sensors > 1)); ccrsensor3GasItem->setVisible(sensorflag && (currentdc->no_o2sensors > 2)); + ocpo2GasItem->setVisible((currentdc->divemode == PSCR) && prefs.show_scr_ocpo2); /* This struct holds all the data that's about to be plotted. * I'm not sure this is the best approach ( but since we are @@ -705,6 +710,7 @@ void ProfileWidget2::plotDive(struct dive *d, bool force) ccrsensor1GasItem->setVisible(prefs.show_ccr_sensors); ccrsensor2GasItem->setVisible(prefs.show_ccr_sensors && (currentdc->no_o2sensors > 1)); ccrsensor3GasItem->setVisible(prefs.show_ccr_sensors && (currentdc->no_o2sensors > 1)); + ocpo2GasItem->setVisible((currentdc->divemode == PSCR) && prefs.show_scr_ocpo2); temperatureItem->setVisible(false); } else { tankItem->setVisible(prefs.tankbar); @@ -716,6 +722,7 @@ void ProfileWidget2::plotDive(struct dive *d, bool force) ccrsensor1GasItem->setVisible(false); ccrsensor2GasItem->setVisible(false); ccrsensor3GasItem->setVisible(false); + ocpo2GasItem->setVisible(false); } #endif tankItem->setData(dataModel, &plotInfo, &displayed_dive); @@ -1074,6 +1081,7 @@ void ProfileWidget2::setEmptyState() ccrsensor1GasItem->setVisible(false); ccrsensor2GasItem->setVisible(false); ccrsensor3GasItem->setVisible(false); + ocpo2GasItem->setVisible(false); #ifndef SUBSURFACE_MOBILE toolTipItem->setVisible(false); diveCeiling->setVisible(false); @@ -1193,6 +1201,7 @@ void ProfileWidget2::setProfileState() ccrsensor1GasItem->setVisible(sensorflag); ccrsensor2GasItem->setVisible(sensorflag && (current_dc->no_o2sensors > 1)); ccrsensor3GasItem->setVisible(sensorflag && (current_dc->no_o2sensors > 2)); + ocpo2GasItem->setVisible((current_dc->divemode == PSCR) && prefs.show_scr_ocpo2); heartBeatItem->setVisible(prefs.hrgraph); diveCeiling->setVisible(prefs.calcceiling); diff --git a/profile-widget/profilewidget2.h b/profile-widget/profilewidget2.h index 937e0ee4b..0e44424ee 100644 --- a/profile-widget/profilewidget2.h +++ b/profile-widget/profilewidget2.h @@ -202,6 +202,7 @@ private: PartialPressureGasItem *ccrsensor1GasItem; PartialPressureGasItem *ccrsensor2GasItem; PartialPressureGasItem *ccrsensor3GasItem; + PartialPressureGasItem *ocpo2GasItem; #ifndef SUBSURFACE_MOBILE DiveCalculatedCeiling *diveCeiling; DiveTextItem *decoModelParameters; diff --git a/qt-models/diveplotdatamodel.cpp b/qt-models/diveplotdatamodel.cpp index a2b411bdf..944510167 100644 --- a/qt-models/diveplotdatamodel.cpp +++ b/qt-models/diveplotdatamodel.cpp @@ -63,6 +63,8 @@ QVariant DivePlotDataModel::data(const QModelIndex &index, int role) const return item.o2sensor[1].mbar / 1000.0; case CCRSENSOR3: return item.o2sensor[2].mbar / 1000.0; + case SCR_OC_PO2: + return item.scr_OC_pO2.mbar / 1000.0; case HEARTBEAT: return item.heartbeat; case AMBPRESSURE: diff --git a/qt-models/diveplotdatamodel.h b/qt-models/diveplotdatamodel.h index 3316b442c..51dc44176 100644 --- a/qt-models/diveplotdatamodel.h +++ b/qt-models/diveplotdatamodel.h @@ -64,6 +64,7 @@ public: CCRSENSOR1, CCRSENSOR2, CCRSENSOR3, + SCR_OC_PO2, HEARTBEAT, AMBPRESSURE, GFLINE,