diff options
author | Robert C. Helling <helling@atdotde.de> | 2014-04-26 17:29:40 +0200 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2014-05-08 12:28:09 -0700 |
commit | c3a3c1a1e7d7eedc7aa09ba9842069e9933cb7b2 (patch) | |
tree | 0375e31c2e39e47944a2cf275f98e9a08493b611 | |
parent | 00e7ef2cf88e1a96bf14317af79ab2c9b3468ed2 (diff) | |
download | subsurface-c3a3c1a1e7d7eedc7aa09ba9842069e9933cb7b2.tar.gz |
Planner: Implement ascend rate according to GUE standard procedures
Signed-off-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r-- | dive.c | 20 | ||||
-rw-r--r-- | dive.h | 1 | ||||
-rw-r--r-- | planner.c | 22 |
3 files changed, 38 insertions, 5 deletions
@@ -2218,3 +2218,23 @@ void set_userid(char *rUserId) strcpy(prefs.userid, rUserId); } #undef MAX_USERID_SIZE + +int average_depth(struct diveplan *dive) +{ + int integral = 0; + int last_time = 0; + int last_depth = 0; + struct divedatapoint *dp = dive->dp; + + while (dp) { + if (dp->time) { + /* Ignore gas indication samples */ + integral += (dp->depth + last_depth) * (dp->time - last_time) / 2; + last_time = dp->time; + last_depth = dp->depth; + } + dp = dp->next; + } + + return integral / last_time; +} @@ -915,6 +915,7 @@ extern depth_t string_to_depth(const char *str); extern pressure_t string_to_pressure(const char *str); extern volume_t string_to_volume(const char *str, pressure_t workp); extern fraction_t string_to_fraction(const char *str); +extern int average_depth(struct diveplan *dive); #include "pref.h" @@ -576,10 +576,20 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive) } #endif -int ascend_velocity(int depth) +int ascend_velocity(int depth, int avg_depth, int bottom_time) { /* We need to make this configurable */ - return 10000/60; + + /* As an example (and possibly reasonable default) this is the Tech 1 provedure according + * to http://www.globalunderwaterexplorers.org/files/Standards_and_Procedures/SOP_Manual_Ver2.0.2.pdf */ + + if (depth <= 6000) + return 1000 / 60; + + if (depth * 4 > avg_depth *3) + return 9000 / 60; + else + return 6000 / 60; } void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, bool add_deco) @@ -599,6 +609,7 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, b bool stopping = false; bool clear_to_ascend; int clock, previous_point_time; + int avg_depth, bottom_time; set_gf(diveplan->gflow, diveplan->gfhigh, default_prefs.gf_low_at_maxdepth); if (!diveplan->surface_pressure) @@ -622,6 +633,7 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, b current_cylinder = 0; } depth = dive->dc.sample[dive->dc.samples - 1].depth.mm; + avg_depth = average_depth(diveplan); /* if all we wanted was the dive just get us back to the surface */ if (!add_deco) { @@ -655,7 +667,7 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, b stopidx += gaschangenr; /* Keep time during the ascend */ - clock = previous_point_time = dive->dc.sample[dive->dc.samples - 1].time.seconds; + bottom_time = clock = previous_point_time = dive->dc.sample[dive->dc.samples - 1].time.seconds; gi = gaschangenr - 1; while (1) { @@ -663,7 +675,7 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, b do { /* Ascend to next stop depth */ assert(deco_allowed_depth(tissue_tolerance, diveplan->surface_pressure / 1000.0, dive, 1) < depth); - int deltad = ascend_velocity(depth) * TIMESTEP; + int deltad = ascend_velocity(depth, avg_depth, bottom_time) * TIMESTEP; if (depth - deltad < stoplevels[stopidx]) deltad = depth - stoplevels[stopidx]; @@ -702,7 +714,7 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, b /* Check if ascending to next stop is clear, go back and wait if we hit the ceiling on the way */ clear_to_ascend = true; while (trial_depth > stoplevels[stopidx]) { - int deltad = ascend_velocity(trial_depth) * TIMESTEP; + int deltad = ascend_velocity(trial_depth, avg_depth, bottom_time) * TIMESTEP; tissue_tolerance = add_segment(depth_to_mbar(trial_depth, dive) / 1000.0, &dive->cylinder[current_cylinder].gasmix, TIMESTEP, po2, dive); if (deco_allowed_depth(tissue_tolerance, diveplan->surface_pressure / 1000.0, dive, 1) > trial_depth - deltad){ /* We should have stopped */ |