From a3e87bf1a1901f4e4a17d7344599f361a8f75743 Mon Sep 17 00:00:00 2001 From: Jan Darowski Date: Sat, 15 Aug 2015 13:45:42 +0200 Subject: [PATCH 1/7] VPM-B: Fix trial_ascent() for vpm-b. Previously, current depth was checked, instead of the depth after the move. Signed-off-by: Jan Darowski --- planner.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/planner.c b/planner.c index 9c0c95f45..3723b4056 100644 --- a/planner.c +++ b/planner.c @@ -884,7 +884,7 @@ bool trial_ascent(int trial_depth, int stoplevel, int avg_depth, int bottom_time clear_to_ascend = false; break; } - if (prefs.deco_mode == VPMB && (!is_vpmb_ok(depth_to_mbar(trial_depth, &displayed_dive) / 1000.0))){ + if (prefs.deco_mode == VPMB && (!is_vpmb_ok(depth_to_mbar(trial_depth - deltad, &displayed_dive) / 1000.0))){ clear_to_ascend = false; break; } From a828d528f925cdb5c300dc176c4e6b4e24dabf67 Mon Sep 17 00:00:00 2001 From: Jan Darowski Date: Sat, 15 Aug 2015 14:03:08 +0200 Subject: [PATCH 2/7] VPM-B: Add simple Boyle's law compensation. This is a very basic implementation that uses bin search for solving the cubic. It's not called anywhere at this stage, needs to be changed to analytic solution. Signed-off-by: Jan Darowski --- deco.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/deco.c b/deco.c index a8012213c..3baefc286 100644 --- a/deco.c +++ b/deco.c @@ -114,6 +114,11 @@ double allowable_n2_gradient[16]; double allowable_he_gradient[16]; double total_gradient[16]; +double bottom_n2_gradient[16]; +double bottom_he_gradient[16]; + +double initial_n2_gradient[16]; +double initial_he_gradient[16]; static double tissue_tolerance_calc(const struct dive *dive) { @@ -231,8 +236,8 @@ void vpmb_start_gradient() double gradient_n2, gradient_he; for (ci = 0; ci < 16; ++ci) { - allowable_n2_gradient[ci] = 2.0 * (vpmb_config.surface_tension_gamma / vpmb_config.skin_compression_gammaC) * ((vpmb_config.skin_compression_gammaC - vpmb_config.surface_tension_gamma) / n2_regen_radius[ci]); - allowable_he_gradient[ci] = 2.0 * (vpmb_config.surface_tension_gamma / vpmb_config.skin_compression_gammaC) * ((vpmb_config.skin_compression_gammaC - vpmb_config.surface_tension_gamma) / he_regen_radius[ci]); + initial_n2_gradient[ci] = bottom_n2_gradient[ci] = allowable_n2_gradient[ci] = 2.0 * (vpmb_config.surface_tension_gamma / vpmb_config.skin_compression_gammaC) * ((vpmb_config.skin_compression_gammaC - vpmb_config.surface_tension_gamma) / n2_regen_radius[ci]); + initial_he_gradient[ci] = bottom_he_gradient[ci] = allowable_he_gradient[ci] = 2.0 * (vpmb_config.surface_tension_gamma / vpmb_config.skin_compression_gammaC) * ((vpmb_config.skin_compression_gammaC - vpmb_config.surface_tension_gamma) / he_regen_radius[ci]); total_gradient[ci] = ((allowable_n2_gradient[ci] * tissue_n2_sat[ci]) + (allowable_he_gradient[ci] * tissue_he_sat[ci])) / (tissue_n2_sat[ci] + tissue_he_sat[ci]); } @@ -244,19 +249,53 @@ void vpmb_next_gradient(double deco_time) double gradient_n2, gradient_he; double n2_b, n2_c; double he_b, he_c; - deco_time /= 60.0 ; + double desat_time = deco_time / 60.0; for (ci = 0; ci < 16; ++ci) { - n2_b = allowable_n2_gradient[ci] + ((vpmb_config.crit_volume_lambda * vpmb_config.surface_tension_gamma) / (vpmb_config.skin_compression_gammaC * (deco_time + buehlmann_N2_t_halflife[ci] * 60.0 / log(2.0)))); - he_b = allowable_he_gradient[ci] + ((vpmb_config.crit_volume_lambda * vpmb_config.surface_tension_gamma) / (vpmb_config.skin_compression_gammaC * (deco_time + buehlmann_He_t_halflife[ci] * 60.0 / log(2.0)))); + n2_b = initial_n2_gradient[ci] + (vpmb_config.crit_volume_lambda * vpmb_config.surface_tension_gamma) / (vpmb_config.skin_compression_gammaC * desat_time); + he_b = initial_he_gradient[ci] + (vpmb_config.crit_volume_lambda * vpmb_config.surface_tension_gamma) / (vpmb_config.skin_compression_gammaC * desat_time); n2_c = vpmb_config.surface_tension_gamma * vpmb_config.surface_tension_gamma * vpmb_config.crit_volume_lambda * max_n2_crushing_pressure[ci]; - n2_c = n2_c / (vpmb_config.skin_compression_gammaC * vpmb_config.skin_compression_gammaC * (deco_time + buehlmann_N2_t_halflife[ci] * 60.0 / log(2.0))); + n2_c = n2_c / (vpmb_config.skin_compression_gammaC * vpmb_config.skin_compression_gammaC * desat_time); he_c = vpmb_config.surface_tension_gamma * vpmb_config.surface_tension_gamma * vpmb_config.crit_volume_lambda * max_he_crushing_pressure[ci]; - he_c = he_c / (vpmb_config.skin_compression_gammaC * vpmb_config.skin_compression_gammaC * (deco_time + buehlmann_He_t_halflife[ci] * 60.0 / log(2.0))); + he_c = he_c / (vpmb_config.skin_compression_gammaC * vpmb_config.skin_compression_gammaC * desat_time); - allowable_n2_gradient[ci] = 0.5 * ( n2_b + sqrt(n2_b * n2_b - 4.0 * n2_c)); - allowable_he_gradient[ci] = 0.5 * ( he_b + sqrt(he_b * he_b - 4.0 * he_c)); + bottom_n2_gradient[ci] = allowable_n2_gradient[ci] = 0.5 * ( n2_b + sqrt(n2_b * n2_b - 4.0 * n2_c)); + bottom_he_gradient[ci] = allowable_he_gradient[ci] = 0.5 * ( he_b + sqrt(he_b * he_b - 4.0 * he_c)); + + total_gradient[ci] = ((allowable_n2_gradient[ci] * tissue_n2_sat[ci]) + (allowable_he_gradient[ci] * tissue_he_sat[ci])) / (tissue_n2_sat[ci] + tissue_he_sat[ci]); + } +} + +double update_gradient(double first_stop_pressure, double next_stop_pressure, double first_gradient) +{ + double first_radius = 2.0 * vpmb_config.surface_tension_gamma / first_gradient; + double A = next_stop_pressure; + double B = -2.0 * vpmb_config.surface_tension_gamma; + double C = (first_stop_pressure + 2.0 * vpmb_config.surface_tension_gamma / first_radius) * pow(first_radius, 3.0); + + double low = first_radius; + double high = first_radius * pow(first_stop_pressure / next_stop_pressure, (1.0/3.0)); + double next_radius; + double value; + int ci; + for (ci = 0; ci < 100; ++ci){ + next_radius = (high + low) /2.0; + value = A * pow(next_radius, 3.0) - B * next_radius * next_radius - C; + if (value < 0) + low = next_radius; + else + high = next_radius; + } + return 2.0 * vpmb_config.surface_tension_gamma / next_radius; +} + +void boyles_law(double first_stop_pressure, double next_stop_pressure) +{ + int ci; + for (ci = 0; ci < 16; ++ci) { + allowable_n2_gradient[ci] = update_gradient(first_stop_pressure, next_stop_pressure, bottom_n2_gradient[ci]); + allowable_he_gradient[ci] = update_gradient(first_stop_pressure, next_stop_pressure, bottom_he_gradient[ci]); total_gradient[ci] = ((allowable_n2_gradient[ci] * tissue_n2_sat[ci]) + (allowable_he_gradient[ci] * tissue_he_sat[ci])) / (tissue_n2_sat[ci] + tissue_he_sat[ci]); } From c0fde4f50fe8da93094b918bd84ec76eaf4c4598 Mon Sep 17 00:00:00 2001 From: Jan Darowski Date: Sat, 15 Aug 2015 14:16:48 +0200 Subject: [PATCH 3/7] VPM-B: Add Boyles compensation to the planner. Signed-off-by: Jan Darowski --- dive.h | 1 + planner.c | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/dive.h b/dive.h index 69a01125e..d5dbdd2ee 100644 --- a/dive.h +++ b/dive.h @@ -802,6 +802,7 @@ extern void nuclear_regeneration(double time); extern void vpmb_start_gradient(); extern void vpmb_next_gradient(double deco_time); extern bool is_vpmb_ok(double pressure); +extern void boyles_law(double first_stop_pressure, double next_stop_pressure); /* this should be converted to use our types */ struct divedatapoint { diff --git a/planner.c b/planner.c index 3723b4056..00e73f6b6 100644 --- a/planner.c +++ b/planner.c @@ -919,6 +919,7 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool int bottom_depth; int bottom_gi; int bottom_stopidx; + int first_stop_pressure; bool is_final_plan = true; int deco_time; int previous_deco_time; @@ -1098,6 +1099,9 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool //CVA do { is_final_plan = (prefs.deco_mode == BUEHLMANN) || (previous_deco_time - deco_time < 10); // CVA time converges + if (deco_time != 10000000) + vpmb_next_gradient(deco_time); + previous_deco_time = deco_time; restore_deco_state(bottom_cache); @@ -1111,12 +1115,12 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool breaktime = -1; breakcylinder = 0; o2time = 0; + first_stop_pressure = 0; last_ascend_rate = ascent_velocity(depth, avg_depth, bottom_time); if ((current_cylinder = get_gasidx(&displayed_dive, &gas)) == -1) { report_error(translate("gettextFromC", "Can't find gas %s"), gasname(&gas)); current_cylinder = 0; } - vpmb_next_gradient(deco_time); while (1) { /* We will break out when we hit the surface */ @@ -1200,6 +1204,11 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool plan_add_segment(diveplan, clock - previous_point_time, depth, gas, po2, false); previous_point_time = clock; stopping = true; + + // Boyles Law compensation + if (first_stop_pressure == 0) + first_stop_pressure = depth_to_mbar(depth, &displayed_dive); + boyles_law(first_stop_pressure / 1000.0, depth_to_mbar(stoplevels[stopidx], &displayed_dive) / 1000.0); } /* Are we waiting to switch gas? From 499ec9af2fd152ec5b608eaacf53b2df33eec1d3 Mon Sep 17 00:00:00 2001 From: Jan Darowski Date: Sat, 15 Aug 2015 14:28:44 +0200 Subject: [PATCH 4/7] VPM-B: Add surface decompression time. Now, we calculate the volume of free gas not only based on the deco time but also time on the surface, needed for the full desaturation. Signed-off-by: Jan Darowski --- deco.c | 24 ++++++++++++++++++++++-- dive.h | 2 +- planner.c | 2 +- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/deco.c b/deco.c index 3baefc286..59415d8a9 100644 --- a/deco.c +++ b/deco.c @@ -91,6 +91,7 @@ const double buehlmann_He_factor_expositon_one_second[] = { #define WV_PRESSURE 0.0627 // water vapor pressure in bar #define DECO_STOPS_MULTIPLIER_MM 3000.0 +#define NITROGEN_FRACTION 0.79 double tissue_n2_sat[16]; double tissue_he_sat[16]; @@ -215,6 +216,22 @@ double he_factor(int period_in_seconds, int ci) return cache[ci].last_factor; } +double calc_surface_phase(double surface_pressure, double he_pressure, double n2_pressure, double he_time_constant, double n2_time_constant) +{ + double inspired_n2 = (surface_pressure - WV_PRESSURE) * NITROGEN_FRACTION; + + if (n2_pressure > inspired_n2) + return (he_pressure / he_time_constant + (n2_pressure - inspired_n2) / n2_time_constant) / (he_pressure + n2_pressure - inspired_n2); + + if (he_pressure + n2_pressure >= inspired_n2){ + double gradient_decay_time = 1.0 / (n2_time_constant - he_time_constant) * log ((inspired_n2 - n2_pressure) / he_pressure); + double gradients_integral = he_pressure / he_time_constant * (1.0 - exp(-he_time_constant * gradient_decay_time)) + (n2_pressure - inspired_n2) / n2_time_constant * (1.0 - exp(-n2_time_constant * gradient_decay_time)); + return gradients_integral / (he_pressure + n2_pressure - inspired_n2); + } + + return 0; +} + bool is_vpmb_ok(double pressure) { int ci; @@ -243,15 +260,18 @@ void vpmb_start_gradient() } } -void vpmb_next_gradient(double deco_time) +void vpmb_next_gradient(double deco_time, double surface_pressure) { int ci; double gradient_n2, gradient_he; double n2_b, n2_c; double he_b, he_c; - double desat_time = deco_time / 60.0; + double desat_time; + deco_time /= 60.0; for (ci = 0; ci < 16; ++ci) { + desat_time = deco_time + calc_surface_phase(surface_pressure, tissue_he_sat[ci], tissue_n2_sat[ci], log(2.0) / buehlmann_He_t_halflife[ci], log(2.0) / buehlmann_N2_t_halflife[ci]); + n2_b = initial_n2_gradient[ci] + (vpmb_config.crit_volume_lambda * vpmb_config.surface_tension_gamma) / (vpmb_config.skin_compression_gammaC * desat_time); he_b = initial_he_gradient[ci] + (vpmb_config.crit_volume_lambda * vpmb_config.surface_tension_gamma) / (vpmb_config.skin_compression_gammaC * desat_time); diff --git a/dive.h b/dive.h index d5dbdd2ee..d5681f163 100644 --- a/dive.h +++ b/dive.h @@ -800,7 +800,7 @@ extern void cache_deco_state(double, char **datap); extern double restore_deco_state(char *data); extern void nuclear_regeneration(double time); extern void vpmb_start_gradient(); -extern void vpmb_next_gradient(double deco_time); +extern void vpmb_next_gradient(double deco_time, double surface_pressure); extern bool is_vpmb_ok(double pressure); extern void boyles_law(double first_stop_pressure, double next_stop_pressure); diff --git a/planner.c b/planner.c index 00e73f6b6..0aa34acdc 100644 --- a/planner.c +++ b/planner.c @@ -1100,7 +1100,7 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool do { is_final_plan = (prefs.deco_mode == BUEHLMANN) || (previous_deco_time - deco_time < 10); // CVA time converges if (deco_time != 10000000) - vpmb_next_gradient(deco_time); + vpmb_next_gradient(deco_time, diveplan->surface_pressure / 1000.0); previous_deco_time = deco_time; restore_deco_state(bottom_cache); From cad866013b6ea8f4bdabc3371b5d319209713fa7 Mon Sep 17 00:00:00 2001 From: Jan Darowski Date: Sat, 15 Aug 2015 14:36:07 +0200 Subject: [PATCH 5/7] VPM-B: Add conservatism levels to deco.c Signed-off-by: Jan Darowski --- deco.c | 28 ++++++++++++++++++++++------ pref.h | 1 + subsurfacestartup.c | 3 ++- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/deco.c b/deco.c index 59415d8a9..934818647 100644 --- a/deco.c +++ b/deco.c @@ -89,6 +89,8 @@ const double buehlmann_He_factor_expositon_one_second[] = { 1.00198406028040E-004, 7.83611475491108E-005, 6.13689891868496E-005, 4.81280465299827E-005 }; +const double conservatism_lvls[] = { 1.0, 1.05, 1.12, 1.22, 1.35 }; + #define WV_PRESSURE 0.0627 // water vapor pressure in bar #define DECO_STOPS_MULTIPLIER_MM 3000.0 #define NITROGEN_FRACTION 0.79 @@ -121,6 +123,20 @@ double bottom_he_gradient[16]; double initial_n2_gradient[16]; double initial_he_gradient[16]; +double get_crit_radius_He() +{ + if (prefs.conservatism_level <= 4) + return vpmb_config.crit_radius_He * conservatism_lvls[prefs.conservatism_level]; + return vpmb_config.crit_radius_He; +} + +double get_crit_radius_N2() +{ + if (prefs.conservatism_level <= 4) + return vpmb_config.crit_radius_N2 * conservatism_lvls[prefs.conservatism_level]; + return vpmb_config.crit_radius_N2; +} + static double tissue_tolerance_calc(const struct dive *dive) { int ci = -1; @@ -328,11 +344,11 @@ void nuclear_regeneration(double time) double crushing_radius_N2, crushing_radius_He; for (ci = 0; ci < 16; ++ci) { //rm - crushing_radius_N2 = 1.0 / (max_n2_crushing_pressure[ci] / (2.0 * (vpmb_config.skin_compression_gammaC - vpmb_config.surface_tension_gamma)) + 1.0 / vpmb_config.crit_radius_N2); - crushing_radius_He = 1.0 / (max_he_crushing_pressure[ci] / (2.0 * (vpmb_config.skin_compression_gammaC - vpmb_config.surface_tension_gamma)) + 1.0 / vpmb_config.crit_radius_He); + crushing_radius_N2 = 1.0 / (max_n2_crushing_pressure[ci] / (2.0 * (vpmb_config.skin_compression_gammaC - vpmb_config.surface_tension_gamma)) + 1.0 / get_crit_radius_N2()); + crushing_radius_He = 1.0 / (max_he_crushing_pressure[ci] / (2.0 * (vpmb_config.skin_compression_gammaC - vpmb_config.surface_tension_gamma)) + 1.0 / get_crit_radius_He()); //rs - n2_regen_radius[ci] = crushing_radius_N2 + (vpmb_config.crit_radius_N2 - crushing_radius_N2) * (1.0 - exp (-time / vpmb_config.regeneration_time)); - he_regen_radius[ci] = crushing_radius_He + (vpmb_config.crit_radius_He - crushing_radius_He) * (1.0 - exp (-time / vpmb_config.regeneration_time)); + n2_regen_radius[ci] = crushing_radius_N2 + (get_crit_radius_N2() - crushing_radius_N2) * (1.0 - exp (-time / vpmb_config.regeneration_time)); + he_regen_radius[ci] = crushing_radius_He + (get_crit_radius_He() - crushing_radius_He) * (1.0 - exp (-time / vpmb_config.regeneration_time)); } } @@ -386,8 +402,8 @@ void calc_crushing_pressure(double pressure) if (max_ambient_pressure >= pressure) return; - n2_inner_pressure = calc_inner_pressure(vpmb_config.crit_radius_N2, crushing_onset_tension[ci], pressure); - he_inner_pressure = calc_inner_pressure(vpmb_config.crit_radius_He, crushing_onset_tension[ci], pressure); + n2_inner_pressure = calc_inner_pressure(get_crit_radius_N2(), crushing_onset_tension[ci], pressure); + he_inner_pressure = calc_inner_pressure(get_crit_radius_He(), crushing_onset_tension[ci], pressure); n2_crushing_pressure = pressure - n2_inner_pressure; he_crushing_pressure = pressure - he_inner_pressure; diff --git a/pref.h b/pref.h index 3791f62e7..e471add73 100644 --- a/pref.h +++ b/pref.h @@ -117,6 +117,7 @@ struct preferences { bool cloud_background_sync; geocoding_prefs_t geocoding; enum deco_mode deco_mode; + short conservatism_level; }; enum unit_system_values { METRIC, diff --git a/subsurfacestartup.c b/subsurfacestartup.c index 17bd43e45..18d00d374 100644 --- a/subsurfacestartup.c +++ b/subsurfacestartup.c @@ -75,7 +75,8 @@ struct preferences default_prefs = { .tag_existing_dives = false, .category = { 0 } }, - .deco_mode = BUEHLMANN + .deco_mode = BUEHLMANN, + .conservatism_level = 0 }; int run_survey; From 6856e87689c554bfa7ac058451e030fecfe941f5 Mon Sep 17 00:00:00 2001 From: Jan Darowski Date: Sat, 15 Aug 2015 15:16:51 +0200 Subject: [PATCH 6/7] VPM-B: Add conservatism levels to the ui. Fix planner settings disabling. Conservatism level can now be changed from gui, is saved in settings. Also way of disabling the planner settings in the ui was improved to support more deco models and be called at the widget creation. Signed-off-by: Jan Darowski --- qt-models/diveplannermodel.cpp | 6 + qt-models/diveplannermodel.h | 1 + qt-ui/diveplanner.cpp | 58 +++--- qt-ui/diveplanner.h | 2 +- qt-ui/plannerSettings.ui | 332 +++++++++++++++++---------------- 5 files changed, 215 insertions(+), 184 deletions(-) diff --git a/qt-models/diveplannermodel.cpp b/qt-models/diveplannermodel.cpp index e82daba11..005061feb 100644 --- a/qt-models/diveplannermodel.cpp +++ b/qt-models/diveplannermodel.cpp @@ -397,6 +397,12 @@ void DivePlannerPointsModel::triggerGFLow() } } +void DivePlannerPointsModel::setConservatism(int level) +{ + prefs.conservatism_level = level; + emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, COLUMNS - 1)); +} + void DivePlannerPointsModel::setSurfacePressure(int pressure) { diveplan.surface_pressure = pressure; diff --git a/qt-models/diveplannermodel.h b/qt-models/diveplannermodel.h index a8524393a..b87ed84c3 100644 --- a/qt-models/diveplannermodel.h +++ b/qt-models/diveplannermodel.h @@ -65,6 +65,7 @@ slots: void triggerGFHigh(); void setGFLow(const int ghflow); void triggerGFLow(); + void setConservatism(int level); void setSurfacePressure(int pressure); void setSalinity(int salinity); int getSurfacePressure(); diff --git a/qt-ui/diveplanner.cpp b/qt-ui/diveplanner.cpp index efa75ddec..82ecb05dc 100644 --- a/qt-ui/diveplanner.cpp +++ b/qt-ui/diveplanner.cpp @@ -217,32 +217,37 @@ void PlannerSettingsWidget::decoSacChanged(const double decosac) plannerModel->setDecoSac(decosac); } -void PlannerSettingsWidget::disableDecoElements(bool value) +void PlannerSettingsWidget::disableDecoElements(int mode) { - if (prefs.deco_mode == RECREATIONAL) { - ui.lastStop->setDisabled(value); - ui.backgasBreaks->setDisabled(value); - ui.bottompo2->setDisabled(value); - ui.decopo2->setDisabled(value); - ui.reserve_gas->setDisabled(!value); + if (mode == RECREATIONAL) { + ui.gflow->setDisabled(false); + ui.gfhigh->setDisabled(false); + ui.lastStop->setDisabled(true); + ui.backgasBreaks->setDisabled(true); + ui.bottompo2->setDisabled(true); + ui.decopo2->setDisabled(true); + ui.reserve_gas->setDisabled(false); + ui.conservatism_lvl->setDisabled(true); } - else if (prefs.deco_mode == VPMB) { - ui.gflow->setDisabled(value); - ui.gfhigh->setDisabled(value); - ui.lastStop->setDisabled(!value); - ui.backgasBreaks->setDisabled(!value); - ui.bottompo2->setDisabled(!value); - ui.decopo2->setDisabled(!value); - ui.reserve_gas->setDisabled(value); + else if (mode == VPMB) { + ui.gflow->setDisabled(true); + ui.gfhigh->setDisabled(true); + ui.lastStop->setDisabled(false); + ui.backgasBreaks->setDisabled(false); + ui.bottompo2->setDisabled(false); + ui.decopo2->setDisabled(false); + ui.reserve_gas->setDisabled(true); + ui.conservatism_lvl->setDisabled(false); } - else if (prefs.deco_mode == BUEHLMANN) { - ui.gflow->setDisabled(!value); - ui.gfhigh->setDisabled(!value); - ui.lastStop->setDisabled(!value); - ui.backgasBreaks->setDisabled(!value); - ui.bottompo2->setDisabled(!value); - ui.decopo2->setDisabled(!value); - ui.reserve_gas->setDisabled(value); + else if (mode == BUEHLMANN) { + ui.gflow->setDisabled(false); + ui.gfhigh->setDisabled(false); + ui.lastStop->setDisabled(false); + ui.backgasBreaks->setDisabled(false); + ui.bottompo2->setDisabled(false); + ui.decopo2->setDisabled(false); + ui.reserve_gas->setDisabled(true); + ui.conservatism_lvl->setDisabled(true); } } @@ -279,6 +284,7 @@ PlannerSettingsWidget::PlannerSettingsWidget(QWidget *parent, Qt::WindowFlags f) prefs.drop_stone_mode = s.value("drop_stone_mode", prefs.drop_stone_mode).toBool(); prefs.bottomsac = s.value("bottomsac", prefs.bottomsac).toInt(); prefs.decosac = s.value("decosac", prefs.decosac).toInt(); + prefs.conservatism_level = s.value("conservatism", prefs.conservatism_level).toInt(); plannerModel->getDiveplan().bottomsac = prefs.bottomsac; plannerModel->getDiveplan().decosac = prefs.decosac; s.endGroup(); @@ -300,6 +306,8 @@ PlannerSettingsWidget::PlannerSettingsWidget(QWidget *parent, Qt::WindowFlags f) ui.recreational_deco->setChecked(prefs.deco_mode == RECREATIONAL); ui.buehlmann_deco->setChecked(prefs.deco_mode == BUEHLMANN); ui.vpmb_deco->setChecked(prefs.deco_mode == VPMB); + ui.conservatism_lvl->setValue(prefs.conservatism_level); + disableDecoElements((int) prefs.deco_mode); // should be the same order as in dive_comp_type! rebreather_modes << tr("Open circuit") << tr("CCR") << tr("pSCR"); @@ -341,11 +349,12 @@ PlannerSettingsWidget::PlannerSettingsWidget(QWidget *parent, Qt::WindowFlags f) connect(ui.gflow, SIGNAL(valueChanged(int)), plannerModel, SLOT(setGFLow(int))); connect(ui.gfhigh, SIGNAL(editingFinished()), plannerModel, SLOT(triggerGFHigh())); connect(ui.gflow, SIGNAL(editingFinished()), plannerModel, SLOT(triggerGFLow())); + connect(ui.conservatism_lvl, SIGNAL(valueChanged(int)), plannerModel, SLOT(setConservatism(int))); connect(ui.backgasBreaks, SIGNAL(toggled(bool)), this, SLOT(setBackgasBreaks(bool))); connect(ui.switch_at_req_stop, SIGNAL(toggled(bool)), plannerModel, SLOT(setSwitchAtReqStop(bool))); connect(ui.min_switch_duration, SIGNAL(valueChanged(int)), plannerModel, SLOT(setMinSwitchDuration(int))); connect(ui.rebreathermode, SIGNAL(currentIndexChanged(int)), plannerModel, SLOT(setRebreatherMode(int))); - connect(plannerModel, SIGNAL(recreationChanged(bool)), this, SLOT(disableDecoElements(bool))); + connect(modeMapper, SIGNAL(mapped(int)), this, SLOT(disableDecoElements(int))); settingsChanged(); ui.gflow->setValue(prefs.gflow); @@ -389,6 +398,7 @@ PlannerSettingsWidget::~PlannerSettingsWidget() s.setValue("bottomsac", prefs.bottomsac); s.setValue("decosac", prefs.decosac); s.setValue("deco_mode", int(prefs.deco_mode)); + s.setValue("conservatism", prefs.conservatism_level); s.endGroup(); } diff --git a/qt-ui/diveplanner.h b/qt-ui/diveplanner.h index c4210aadf..b2e03a97b 100644 --- a/qt-ui/diveplanner.h +++ b/qt-ui/diveplanner.h @@ -80,7 +80,7 @@ slots: void setBottomPo2(double po2); void setDecoPo2(double po2); void setBackgasBreaks(bool dobreaks); - void disableDecoElements(bool value); + void disableDecoElements(int mode); private: Ui::plannerSettingsWidget ui; diff --git a/qt-ui/plannerSettings.ui b/qt-ui/plannerSettings.ui index 3287b84fb..4ebc868af 100644 --- a/qt-ui/plannerSettings.ui +++ b/qt-ui/plannerSettings.ui @@ -255,165 +255,6 @@ 2 - - - - Min. switch duration - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - 6 - - - - - - - % - - - 1 - - - 150 - - - - - - - Drop to first depth - - - - - - - Last stop at 6m - - - - - - - Recreational mode - - - - - - - GF low - - - 26 - - - - - - - Plan backgas breaks - - - - - - - GF high - - - 25 - - - - - - - % - - - 1 - - - 150 - - - - - - - Postpone gas change if a stop is not required - - - Only switch at required stops - - - - - - - Qt::Vertical - - - - 20 - 20 - - - - - - - - Qt::Vertical - - - - 20 - 20 - - - - - - - - min - - - - - - 0 - - - 9 - - - 1 - - - @@ -460,6 +301,152 @@ + + + + % + + + 1 + + + 150 + + + + + + + Postpone gas change if a stop is not required + + + Only switch at required stops + + + + + + + Qt::Vertical + + + + 20 + 20 + + + + + + + + GF low + + + 26 + + + + + + + Plan backgas breaks + + + + + + + GF high + + + 25 + + + + + + + min + + + + + + 0 + + + 9 + + + 1 + + + + + + + Last stop at 6m + + + + + + + Recreational mode + + + + + + + + + + 6 + + + + + + + % + + + 1 + + + 150 + + + + + + + Drop to first depth + + + + + + + Min. switch duration + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + @@ -486,6 +473,33 @@ + + + + Qt::Vertical + + + + 20 + 20 + + + + + + + + Conservatism level + + + + + + + 4 + + + From ffe2884f72ace4d04158b72fc806823c87a62e4b Mon Sep 17 00:00:00 2001 From: Jan Darowski Date: Sat, 15 Aug 2015 15:55:46 +0200 Subject: [PATCH 7/7] VPM-B: Set radius constants to values reccomended by V-Planner. V-Planner reccomends smaller values for the VPM with the Boyles compensation. Also missing units comments were added. Signed-off-by: Jan Darowski --- deco.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/deco.c b/deco.c index 934818647..796bb9e5b 100644 --- a/deco.c +++ b/deco.c @@ -36,14 +36,14 @@ struct buehlmann_config buehlmann_config = { 1.0, 1.01, 0, 0.75, 0.35, 1.0, fals struct vpmb_config { double crit_radius_N2; //! Critical radius of N2 nucleon (microns). double crit_radius_He; //! Critical radius of He nucleon (microns). - double crit_volume_lambda; //! Constant corresponding to critical gas volume (bar-min). + double crit_volume_lambda; //! Constant corresponding to critical gas volume (bar * min). double gradient_of_imperm; //! Gradient after which bubbles become impermeable (bar). - double surface_tension_gamma; //! Nucleons surface tension constant. - double skin_compression_gammaC; //! Skin compression gammaC. + double surface_tension_gamma; //! Nucleons surface tension constant (N / 10m). + double skin_compression_gammaC; //! Skin compression gammaC (N / 10m). double regeneration_time; //! Time needed for the bubble to regenerate to the start radius (min). double other_gases_pressure; //! Always present pressure of other gasses in tissues (bar). }; -struct vpmb_config vpmb_config = { 0.8, 0.7, 230.284, 8.2, 0.179, 2.57, 20160, 0.1359888 }; +struct vpmb_config vpmb_config = { 0.55, 0.45, 230.284, 8.2, 0.179, 2.57, 20160, 0.1359888 }; const double buehlmann_N2_a[] = { 1.1696, 1.0, 0.8618, 0.7562, 0.62, 0.5043, 0.441, 0.4,