Hi,

From bc5f5d53d533a1a1e790af9fd0391a8453e6cb89 Mon Sep 17 00:00:00 2001
From: "Robert C. Helling" <[email protected]>
Date: Sat, 4 Apr 2015 18:38:56 +0200
Subject: [PATCH 1/2] Take gas consumption into account for recreational mode

If there is valid gas information (cylinder size and starting pressure),
also ascent before gas runs out (taking a 40bar reserve into account).

Signed-off-by: Robert C. Helling <[email protected]>
---
 planner.c | 34 ++++++++++++++++++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/planner.c b/planner.c
index d30bc1a..b1d7d30 100644
--- a/planner.c
+++ b/planner.c
@@ -17,6 +17,8 @@
 #define TIMESTEP 3 /* second */
 #define DECOTIMESTEP 60 /* seconds. Unit of deco stop times */
 
+#define RESERVE 40000 /* Remaining gas in recreational mode */
+
 int decostoplevels[] = { 0, 3000, 6000, 9000, 12000, 15000, 18000, 21000, 
24000, 27000,
                                  30000, 33000, 36000, 39000, 42000, 45000, 
48000, 51000, 54000, 57000,
                                  60000, 63000, 66000, 69000, 72000, 75000, 
78000, 81000, 84000, 87000,
@@ -800,6 +802,17 @@ int ascend_velocity(int depth, int avg_depth, int 
bottom_time)
        }
 }
 
+void track_ascent_gas(int depth, cylinder_t *cylinder, int avg_depth, int 
bottom_time)
+{
+       while (depth > 0) {
+               int deltad = ascend_velocity(depth, avg_depth, bottom_time) * 
TIMESTEP;
+               if (deltad > depth)
+                       deltad = depth;
+               update_cylinder_pressure(&displayed_dive, depth, depth - 
deltad, TIMESTEP, prefs.bottomsac, cylinder, true);
+               depth -= deltad;
+       }
+}
+
 bool trial_ascent(int trial_depth, int stoplevel, int avg_depth, int 
bottom_time, double tissue_tolerance, struct gasmix *gasmix, int po2, double 
surface_pressure)
 {
 
@@ -825,6 +838,20 @@ bool trial_ascent(int trial_depth, int stoplevel, int 
avg_depth, int bottom_time
        return clear_to_ascend;
 }
 
+bool enough_gas(int current_cylinder)
+{
+       cylinder_t *cyl;
+
+       cyl = &displayed_dive.cylinder[current_cylinder];
+
+       if (!cyl->start.mbar)
+               return true;
+       if (cyl->type.size.mliter)
+               return (float) (cyl->end.mbar - RESERVE)         * 
cyl->type.size.mliter / 1000.0 > (float) cyl->deco_gas_used.mliter;
+       else
+               return true;
+}
+
 int plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool 
show_disclaimer)
 {
        struct sample *sample;
@@ -906,16 +933,19 @@ int plan(struct diveplan *diveplan, char **cached_datap, 
bool is_planner, bool s
        gi = gaschangenr - 1;
        if(prefs.recreational_mode) {
                bool safety_stop = prefs.safetystop && max_depth >= 10000;
+               track_ascent_gas(depth, 
&displayed_dive.cylinder[current_cylinder], avg_depth, bottom_time);
                // How long can we stay at the current depth and still directly 
ascent to the surface?
                while (trial_ascent(depth, 0, avg_depth, bottom_time, 
tissue_tolerance, &displayed_dive.cylinder[current_cylinder].gasmix,
-                                 po2, diveplan->surface_pressure / 1000.0)) {
+                                 po2, diveplan->surface_pressure / 1000.0) &&
+                      enough_gas(current_cylinder)) {
                        tissue_tolerance = add_segment(depth_to_mbar(depth, 
&displayed_dive) / 1000.0,
                                                       
&displayed_dive.cylinder[current_cylinder].gasmix,
                                                       DECOTIMESTEP, po2, 
&displayed_dive, prefs.bottomsac);
+                       update_cylinder_pressure(&displayed_dive, depth, depth, 
DECOTIMESTEP, prefs.bottomsac, &displayed_dive.cylinder[current_cylinder], 
false);
                        clock += DECOTIMESTEP;
                }
                clock -= DECOTIMESTEP;
-               plan_add_segment(diveplan, clock - previous_point_time, depth, 
gas, po2, false);
+               plan_add_segment(diveplan, clock - previous_point_time, depth, 
gas, po2, true);
                previous_point_time = clock;
                do {
                        /* Ascend to surface */
-- 
1.9.5 (Apple Git-50.3)

From 3d9dcc28003d3ef0ec916a8c5622210cf0004e72 Mon Sep 17 00:00:00 2001
From: "Robert C. Helling" <[email protected]>
Date: Sat, 4 Apr 2015 18:41:09 +0200
Subject: [PATCH 2/2] Spelling corrected

Signed-off-by: Robert C. Helling <[email protected]>
---
 planner.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/planner.c b/planner.c
index b1d7d30..11bf2a5 100644
--- a/planner.c
+++ b/planner.c
@@ -781,7 +781,7 @@ static void add_plan_to_notes(struct diveplan *diveplan, 
struct dive *dive, bool
        dive->notes = strdup(buffer);
 }
 
-int ascend_velocity(int depth, int avg_depth, int bottom_time)
+int ascent_velocity(int depth, int avg_depth, int bottom_time)
 {
        /* We need to make this configurable */
 
@@ -805,7 +805,7 @@ int ascend_velocity(int depth, int avg_depth, int 
bottom_time)
 void track_ascent_gas(int depth, cylinder_t *cylinder, int avg_depth, int 
bottom_time)
 {
        while (depth > 0) {
-               int deltad = ascend_velocity(depth, avg_depth, bottom_time) * 
TIMESTEP;
+               int deltad = ascent_velocity(depth, avg_depth, bottom_time) * 
TIMESTEP;
                if (deltad > depth)
                        deltad = depth;
                update_cylinder_pressure(&displayed_dive, depth, depth - 
deltad, TIMESTEP, prefs.bottomsac, cylinder, true);
@@ -821,7 +821,7 @@ bool trial_ascent(int trial_depth, int stoplevel, int 
avg_depth, int bottom_time
 
        cache_deco_state(tissue_tolerance, &trial_cache);
        while (trial_depth > stoplevel) {
-               int deltad = ascend_velocity(trial_depth, avg_depth, 
bottom_time) * TIMESTEP;
+               int deltad = ascent_velocity(trial_depth, avg_depth, 
bottom_time) * TIMESTEP;
                if (deltad > trial_depth) /* don't test against depth above 
surface */
                        deltad = trial_depth;
                tissue_tolerance = add_segment(depth_to_mbar(trial_depth, 
&displayed_dive) / 1000.0,
@@ -893,7 +893,7 @@ int plan(struct diveplan *diveplan, char **cached_datap, 
bool is_planner, bool s
        }
        depth = displayed_dive.dc.sample[displayed_dive.dc.samples - 
1].depth.mm;
        average_max_depth(diveplan, &avg_depth, &max_depth);
-       last_ascend_rate = ascend_velocity(depth, avg_depth, bottom_time);
+       last_ascend_rate = ascent_velocity(depth, avg_depth, bottom_time);
 
        /* if all we wanted was the dive just get us back to the surface */
        if (!is_planner) {
@@ -949,11 +949,11 @@ int plan(struct diveplan *diveplan, char **cached_datap, 
bool is_planner, bool s
                previous_point_time = clock;
                do {
                        /* Ascend to surface */
-                       int deltad = ascend_velocity(depth, avg_depth, 
bottom_time) * TIMESTEP;
-                       if (ascend_velocity(depth, avg_depth, bottom_time) != 
last_ascend_rate) {
+                       int deltad = ascent_velocity(depth, avg_depth, 
bottom_time) * TIMESTEP;
+                       if (ascent_velocity(depth, avg_depth, bottom_time) != 
last_ascend_rate) {
                                plan_add_segment(diveplan, clock - 
previous_point_time, depth, gas, po2, false);
                                previous_point_time = clock;
-                               last_ascend_rate = ascend_velocity(depth, 
avg_depth, bottom_time);
+                               last_ascend_rate = ascent_velocity(depth, 
avg_depth, bottom_time);
                        }
                        if (depth - deltad < 0)
                                deltad = depth;
@@ -998,12 +998,12 @@ int plan(struct diveplan *diveplan, char **cached_datap, 
bool is_planner, bool s
                /* We will break out when we hit the surface */
                do {
                        /* Ascend to next stop depth */
-                       int deltad = ascend_velocity(depth, avg_depth, 
bottom_time) * TIMESTEP;
-                       if (ascend_velocity(depth, avg_depth, bottom_time) != 
last_ascend_rate) {
+                       int deltad = ascent_velocity(depth, avg_depth, 
bottom_time) * TIMESTEP;
+                       if (ascent_velocity(depth, avg_depth, bottom_time) != 
last_ascend_rate) {
                                plan_add_segment(diveplan, clock - 
previous_point_time, depth, gas, po2, false);
                                previous_point_time = clock;
                                stopping = false;
-                               last_ascend_rate = ascend_velocity(depth, 
avg_depth, bottom_time);
+                               last_ascend_rate = ascent_velocity(depth, 
avg_depth, bottom_time);
                        }
                        if (depth - deltad < stoplevels[stopidx])
                                deltad = depth - stoplevels[stopidx];
-- 
1.9.5 (Apple Git-50.3)


this adds a gas use calculation to recreational mode. Now, we also ascent when 
we would run out of gas (using a reserve of 40bar and taking buddy breathing 
for the ascent into account).

This is only calculated if there is valid cylinder info (in particular cylinder 
volume and starting pressure). So, if the user wants to calculate with true 
NDL, the cylinder volume or the working pressure should be set to 0. (This 
remark is for the manual…)

And I fix an embarrassing typo.

Best
Robert

_______________________________________________
subsurface mailing list
[email protected]
http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface

Reply via email to