summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Robert C. Helling <helling@atdotde.de>2015-08-12 12:06:52 +0200
committerGravatar Dirk Hohndel <dirk@hohndel.org>2015-08-15 09:10:29 -0700
commita8ce8c3ef1562559508c77c63ca2d101b3bdcce6 (patch)
tree311b7177db81583ca27a4331e3b91c0c80ead79a
parent2455a5dec70d1baa2d0009e602db6b4f19941b56 (diff)
downloadsubsurface-a8ce8c3ef1562559508c77c63ca2d101b3bdcce6.tar.gz
Some unification between Buehlmann and VPM-B
This patch makes deco_allowed_depth() work both for Buehlmann as well as VPM-B (as long as the VPM-B internal variable total_gradient[] is valid). As a bonus, in VPM-B mode, in the planner, the ceilings are VPM-B ceilings and not Buehlmann GF. Signed-off-by: Robert C. Helling <helling@atdotde.de> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r--deco.c94
-rw-r--r--dive.h1
-rw-r--r--planner.c14
-rw-r--r--planner.h2
-rw-r--r--qt-ui/mainwindow.cpp2
5 files changed, 58 insertions, 55 deletions
diff --git a/deco.c b/deco.c
index a8012213c..7b0aa54c1 100644
--- a/deco.c
+++ b/deco.c
@@ -19,6 +19,7 @@
#include <string.h>
#include "dive.h"
#include <assert.h>
+#include <planner.h>
//! Option structure for Buehlmann decompression.
struct buehlmann_config {
@@ -125,43 +126,55 @@ static double tissue_tolerance_calc(const struct dive *dive)
double lowest_ceiling = 0.0;
double tissue_lowest_ceiling[16];
- for (ci = 0; ci < 16; ci++) {
- tissue_inertgas_saturation[ci] = tissue_n2_sat[ci] + tissue_he_sat[ci];
- buehlmann_inertgas_a[ci] = ((buehlmann_N2_a[ci] * tissue_n2_sat[ci]) + (buehlmann_He_a[ci] * tissue_he_sat[ci])) / tissue_inertgas_saturation[ci];
- buehlmann_inertgas_b[ci] = ((buehlmann_N2_b[ci] * tissue_n2_sat[ci]) + (buehlmann_He_b[ci] * tissue_he_sat[ci])) / tissue_inertgas_saturation[ci];
+ if (prefs.deco_mode != VPMB || !in_planner) {
+ for (ci = 0; ci < 16; ci++) {
+ tissue_inertgas_saturation[ci] = tissue_n2_sat[ci] + tissue_he_sat[ci];
+ buehlmann_inertgas_a[ci] = ((buehlmann_N2_a[ci] * tissue_n2_sat[ci]) + (buehlmann_He_a[ci] * tissue_he_sat[ci])) / tissue_inertgas_saturation[ci];
+ buehlmann_inertgas_b[ci] = ((buehlmann_N2_b[ci] * tissue_n2_sat[ci]) + (buehlmann_He_b[ci] * tissue_he_sat[ci])) / tissue_inertgas_saturation[ci];
- /* tolerated = (tissue_inertgas_saturation - buehlmann_inertgas_a) * buehlmann_inertgas_b; */
+ /* tolerated = (tissue_inertgas_saturation - buehlmann_inertgas_a) * buehlmann_inertgas_b; */
- tissue_lowest_ceiling[ci] = (buehlmann_inertgas_b[ci] * tissue_inertgas_saturation[ci] - gf_low * buehlmann_inertgas_a[ci] * buehlmann_inertgas_b[ci]) /
- ((1.0 - buehlmann_inertgas_b[ci]) * gf_low + buehlmann_inertgas_b[ci]);
- if (tissue_lowest_ceiling[ci] > lowest_ceiling)
- lowest_ceiling = tissue_lowest_ceiling[ci];
- if (!buehlmann_config.gf_low_at_maxdepth) {
- if (lowest_ceiling > gf_low_pressure_this_dive)
- gf_low_pressure_this_dive = lowest_ceiling;
+ tissue_lowest_ceiling[ci] = (buehlmann_inertgas_b[ci] * tissue_inertgas_saturation[ci] - gf_low * buehlmann_inertgas_a[ci] * buehlmann_inertgas_b[ci]) /
+ ((1.0 - buehlmann_inertgas_b[ci]) * gf_low + buehlmann_inertgas_b[ci]);
+ if (tissue_lowest_ceiling[ci] > lowest_ceiling)
+ lowest_ceiling = tissue_lowest_ceiling[ci];
+ if (!buehlmann_config.gf_low_at_maxdepth) {
+ if (lowest_ceiling > gf_low_pressure_this_dive)
+ gf_low_pressure_this_dive = lowest_ceiling;
+ }
}
- }
- for (ci = 0; ci <16; ci++) {
- double tolerated;
-
- if ((surface / buehlmann_inertgas_b[ci] + buehlmann_inertgas_a[ci] - surface) * gf_high + surface <
- (gf_low_pressure_this_dive / buehlmann_inertgas_b[ci] + buehlmann_inertgas_a[ci] - gf_low_pressure_this_dive) * gf_low + gf_low_pressure_this_dive)
- tolerated = (-buehlmann_inertgas_a[ci] * buehlmann_inertgas_b[ci] * (gf_high * gf_low_pressure_this_dive - gf_low * surface) -
- (1.0 - buehlmann_inertgas_b[ci]) * (gf_high - gf_low) * gf_low_pressure_this_dive * surface +
- buehlmann_inertgas_b[ci] * (gf_low_pressure_this_dive - surface) * tissue_inertgas_saturation[ci]) /
- (-buehlmann_inertgas_a[ci] * buehlmann_inertgas_b[ci] * (gf_high - gf_low) +
- (1.0 - buehlmann_inertgas_b[ci]) * (gf_low * gf_low_pressure_this_dive - gf_high * surface) +
- buehlmann_inertgas_b[ci] * (gf_low_pressure_this_dive - surface));
- else
- tolerated = ret_tolerance_limit_ambient_pressure;
-
-
- tolerated_by_tissue[ci] = tolerated;
-
- if (tolerated >= ret_tolerance_limit_ambient_pressure) {
- ci_pointing_to_guiding_tissue = ci;
- ret_tolerance_limit_ambient_pressure = tolerated;
+ for (ci = 0; ci < 16; ci++) {
+ double tolerated;
+
+ if ((surface / buehlmann_inertgas_b[ci] + buehlmann_inertgas_a[ci] - surface) * gf_high + surface <
+ (gf_low_pressure_this_dive / buehlmann_inertgas_b[ci] + buehlmann_inertgas_a[ci] - gf_low_pressure_this_dive) * gf_low + gf_low_pressure_this_dive)
+ tolerated = (-buehlmann_inertgas_a[ci] * buehlmann_inertgas_b[ci] * (gf_high * gf_low_pressure_this_dive - gf_low * surface) -
+ (1.0 - buehlmann_inertgas_b[ci]) * (gf_high - gf_low) * gf_low_pressure_this_dive * surface +
+ buehlmann_inertgas_b[ci] * (gf_low_pressure_this_dive - surface) * tissue_inertgas_saturation[ci]) /
+ (-buehlmann_inertgas_a[ci] * buehlmann_inertgas_b[ci] * (gf_high - gf_low) +
+ (1.0 - buehlmann_inertgas_b[ci]) * (gf_low * gf_low_pressure_this_dive - gf_high * surface) +
+ buehlmann_inertgas_b[ci] * (gf_low_pressure_this_dive - surface));
+ else
+ tolerated = ret_tolerance_limit_ambient_pressure;
+
+
+ tolerated_by_tissue[ci] = tolerated;
+
+ if (tolerated >= ret_tolerance_limit_ambient_pressure) {
+ ci_pointing_to_guiding_tissue = ci;
+ ret_tolerance_limit_ambient_pressure = tolerated;
+ }
+ }
+ } else {
+ // VPM-B ceiling
+ for (ci = 0; ci < 16; ci++) {
+ double tolerated = tissue_n2_sat[ci] + tissue_he_sat[ci] + vpmb_config.other_gases_pressure - total_gradient[ci];
+ if (tolerated >= ret_tolerance_limit_ambient_pressure) {
+ ci_pointing_to_guiding_tissue = ci;
+ ret_tolerance_limit_ambient_pressure = tolerated;
+ }
+ tolerated_by_tissue[ci] = tolerated;
}
}
return ret_tolerance_limit_ambient_pressure;
@@ -210,21 +223,6 @@ double he_factor(int period_in_seconds, int ci)
return cache[ci].last_factor;
}
-bool is_vpmb_ok(double pressure)
-{
- int ci;
- double gradient;
- double gas_tension;
-
- for (ci = 0; ci < 16; ++ci) {
- gas_tension = tissue_n2_sat[ci] + tissue_he_sat[ci] + vpmb_config.other_gases_pressure;
- gradient = gas_tension - pressure;
- if (gradient > total_gradient[ci])
- return false;
- }
- return true;
-}
-
void vpmb_start_gradient()
{
int ci;
diff --git a/dive.h b/dive.h
index 69a01125e..d0ef47ded 100644
--- a/dive.h
+++ b/dive.h
@@ -801,7 +801,6 @@ 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 bool is_vpmb_ok(double pressure);
/* this should be converted to use our types */
struct divedatapoint {
diff --git a/planner.c b/planner.c
index 9c0c95f45..3c09a610a 100644
--- a/planner.c
+++ b/planner.c
@@ -33,6 +33,14 @@ int decostoplevels_imperial[] = { 0, 3048, 6096, 9144, 12192, 15240, 18288, 2133
double plangflow, plangfhigh;
bool plan_verbatim, plan_display_runtime, plan_display_duration, plan_display_transitions;
+/* This is a bit round about: Currently, we only support VPM-B in the planner,
+ * so, when we compute ceilings we have to know if we are in planning mode since
+ * the maximally allowed gradient in the tissues is determined by the critical volume algorithm for
+ * which we currently have no version for logged dives. But the information about the application state
+ * is only available in the C++/Qt part. So this global variable is a way to leak this info. */
+
+bool in_planner = false;
+
const char *disclaimer;
#if DEBUG_PLAN
@@ -879,15 +887,11 @@ bool trial_ascent(int trial_depth, int stoplevel, int avg_depth, int bottom_time
tissue_tolerance = add_segment(depth_to_mbar(trial_depth, &displayed_dive) / 1000.0,
gasmix,
TIMESTEP, po2, &displayed_dive, prefs.decosac);
- if (prefs.deco_mode != VPMB && deco_allowed_depth(tissue_tolerance, surface_pressure, &displayed_dive, 1) > trial_depth - deltad) {
+ if (deco_allowed_depth(tissue_tolerance, surface_pressure, &displayed_dive, 1) > trial_depth - deltad) {
/* We should have stopped */
clear_to_ascend = false;
break;
}
- if (prefs.deco_mode == VPMB && (!is_vpmb_ok(depth_to_mbar(trial_depth, &displayed_dive) / 1000.0))){
- clear_to_ascend = false;
- break;
- }
trial_depth -= deltad;
}
restore_deco_state(trial_cache);
diff --git a/planner.h b/planner.h
index ac146055d..20aff89ad 100644
--- a/planner.h
+++ b/planner.h
@@ -25,7 +25,7 @@ extern struct dive *planned_dive;
extern char *cache_data;
extern const char *disclaimer;
extern double plangflow, plangfhigh;
-
+extern bool in_planner;
#ifdef __cplusplus
}
diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp
index db1d8c8b7..f22884a84 100644
--- a/qt-ui/mainwindow.cpp
+++ b/qt-ui/mainwindow.cpp
@@ -1716,6 +1716,8 @@ void MainWindow::setApplicationState(const QByteArray& state) {
return;
currentApplicationState = state;
+ in_planner = (state == "PlanDive" || state == "EditPlannedDive");
+
#define SET_CURRENT_INDEX( X ) \
if (applicationState[state].X) { \
ui.X->setCurrentWidget( applicationState[state].X); \