diff options
author | Rick Walsh <rickmwalsh@gmail.com> | 2017-11-03 07:32:28 +1100 |
---|---|---|
committer | Robert C. Helling <helling@atdotde.de> | 2017-11-08 15:22:32 +0100 |
commit | fe474ac266d952206f74b428e4d31e1f8531180d (patch) | |
tree | c721b95687a59cc8c701b18b78aecec486979382 /core | |
parent | e365cac54ec5e9bd00e97d6d977684c9cd7474ef (diff) | |
download | subsurface-fe474ac266d952206f74b428e4d31e1f8531180d.tar.gz |
VPMB profile: use deco_time rather bottom_time from planner
This makes the calculations in profile.c a little simpler, especially now we
adopt consistent final ascent rate to determine deco_time since d15779a27
Signed-off-by: Rick Walsh <rickmwalsh@gmail.com>
Diffstat (limited to 'core')
-rw-r--r-- | core/dive.h | 2 | ||||
-rw-r--r-- | core/planner.c | 44 | ||||
-rw-r--r-- | core/profile.c | 26 |
3 files changed, 35 insertions, 37 deletions
diff --git a/core/dive.h b/core/dive.h index 5a5edf145..ad0ad66bb 100644 --- a/core/dive.h +++ b/core/dive.h @@ -894,7 +894,7 @@ struct deco_state { pressure_t max_bottom_ceiling_pressure; int ci_pointing_to_guiding_tissue; double gf_low_pressure_this_dive; - int bottom_time; + int deco_time; }; extern void add_segment(double pressure, const struct gasmix *gasmix, int period_in_seconds, int setpoint, const struct dive *dive, int sac); diff --git a/core/planner.c b/core/planner.c index ab53dc0be..6632c76a4 100644 --- a/core/planner.c +++ b/core/planner.c @@ -652,7 +652,7 @@ bool plan(struct diveplan *diveplan, struct dive *dive, int timestep, struct dec int bottom_gi; int bottom_stopidx; bool is_final_plan = true; - int deco_time; + int bottom_time; int previous_deco_time; struct deco_state *bottom_cache = NULL; struct sample *sample; @@ -713,7 +713,7 @@ bool plan(struct diveplan *diveplan, struct dive *dive, int timestep, struct dec sample = &dive->dc.sample[dive->dc.samples - 1]; /* Keep time during the ascend */ - deco_state->bottom_time = 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; current_cylinder = get_cylinderid_at_time(dive, &dive->dc, sample->time); gas = dive->cylinder[current_cylinder].gasmix; @@ -721,7 +721,7 @@ bool plan(struct diveplan *diveplan, struct dive *dive, int timestep, struct dec po2 = sample->setpoint.mbar; depth = dive->dc.sample[dive->dc.samples - 1].depth.mm; average_max_depth(diveplan, &avg_depth, &max_depth); - last_ascend_rate = ascent_velocity(depth, avg_depth, deco_state->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) { @@ -765,7 +765,7 @@ bool plan(struct diveplan *diveplan, struct dive *dive, int timestep, struct dec if (decoMode() == RECREATIONAL) { bool safety_stop = prefs.safetystop && max_depth >= 10000; - track_ascent_gas(depth, &dive->cylinder[current_cylinder], avg_depth, deco_state->bottom_time, safety_stop); + track_ascent_gas(depth, &dive->cylinder[current_cylinder], avg_depth, bottom_time, safety_stop); // How long can we stay at the current depth and still directly ascent to the surface? do { add_segment(depth_to_bar(depth, dive), @@ -773,7 +773,7 @@ bool plan(struct diveplan *diveplan, struct dive *dive, int timestep, struct dec timestep, po2, dive, prefs.bottomsac); update_cylinder_pressure(dive, depth, depth, timestep, prefs.bottomsac, &dive->cylinder[current_cylinder], false); clock += timestep; - } while (trial_ascent(0, depth, 0, avg_depth, deco_state->bottom_time, &dive->cylinder[current_cylinder].gasmix, + } while (trial_ascent(0, depth, 0, avg_depth, bottom_time, &dive->cylinder[current_cylinder].gasmix, po2, diveplan->surface_pressure / 1000.0, dive) && enough_gas(current_cylinder)); @@ -787,11 +787,11 @@ bool plan(struct diveplan *diveplan, struct dive *dive, int timestep, struct dec previous_point_time = clock; do { /* Ascend to surface */ - int deltad = ascent_velocity(depth, avg_depth, deco_state->bottom_time) * TIMESTEP; - if (ascent_velocity(depth, avg_depth, deco_state->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, current_cylinder, po2, false); previous_point_time = clock; - last_ascend_rate = ascent_velocity(depth, avg_depth, deco_state->bottom_time); + last_ascend_rate = ascent_velocity(depth, avg_depth, bottom_time); } if (depth - deltad < 0) deltad = depth; @@ -830,7 +830,7 @@ bool plan(struct diveplan *diveplan, struct dive *dive, int timestep, struct dec // VPM-B or Buehlmann Deco tissue_at_end(dive, cached_datap); previous_deco_time = 100000000; - deco_time = 10000000; + deco_state->deco_time = 10000000; cache_deco_state(&bottom_cache); // Lets us make several iterations bottom_depth = depth; bottom_gi = gi; @@ -840,16 +840,16 @@ bool plan(struct diveplan *diveplan, struct dive *dive, int timestep, struct dec //CVA do { decostopcounter = 0; - is_final_plan = (decoMode() == BUEHLMANN) || (previous_deco_time - deco_time < 10); // CVA time converges - if (deco_time != 10000000) - vpmb_next_gradient(deco_time, diveplan->surface_pressure / 1000.0); + is_final_plan = (decoMode() == BUEHLMANN) || (previous_deco_time - deco_state->deco_time < 10); // CVA time converges + if (deco_state->deco_time != 10000000) + vpmb_next_gradient(deco_state->deco_time, diveplan->surface_pressure / 1000.0); - previous_deco_time = deco_time; + previous_deco_time = deco_state->deco_time; restore_deco_state(bottom_cache, true); depth = bottom_depth; gi = bottom_gi; - clock = previous_point_time = deco_state->bottom_time; + clock = previous_point_time = bottom_time; gas = bottom_gas; stopping = false; decodive = false; @@ -864,7 +864,7 @@ bool plan(struct diveplan *diveplan, struct dive *dive, int timestep, struct dec if (deco_state->max_bottom_ceiling_pressure.mbar > deco_state->first_ceiling_pressure.mbar) deco_state->first_ceiling_pressure.mbar = deco_state->max_bottom_ceiling_pressure.mbar; - last_ascend_rate = ascent_velocity(depth, avg_depth, deco_state->bottom_time); + last_ascend_rate = ascent_velocity(depth, avg_depth, bottom_time); /* Always prefer the best_first_ascend_cylinder if it has the right gasmix. * Otherwise take first cylinder from list with rightgasmix */ if (same_gasmix(&gas, &dive->cylinder[best_first_ascend_cylinder].gasmix)) @@ -880,13 +880,13 @@ bool plan(struct diveplan *diveplan, struct dive *dive, int timestep, struct dec /* We will break out when we hit the surface */ do { /* Ascend to next stop depth */ - int deltad = ascent_velocity(depth, avg_depth, deco_state->bottom_time) * TIMESTEP; - if (ascent_velocity(depth, avg_depth, deco_state->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) { if (is_final_plan) plan_add_segment(diveplan, clock - previous_point_time, depth, current_cylinder, po2, false); previous_point_time = clock; stopping = false; - last_ascend_rate = ascent_velocity(depth, avg_depth, deco_state->bottom_time); + last_ascend_rate = ascent_velocity(depth, avg_depth, bottom_time); } if (depth - deltad < stoplevels[stopidx]) deltad = depth - stoplevels[stopidx]; @@ -919,7 +919,7 @@ bool plan(struct diveplan *diveplan, struct dive *dive, int timestep, struct dec if (current_cylinder != gaschanges[gi].gasidx) { if (!prefs.switch_at_req_stop || - !trial_ascent(0, depth, stoplevels[stopidx - 1], avg_depth, deco_state->bottom_time, + !trial_ascent(0, depth, stoplevels[stopidx - 1], avg_depth, bottom_time, &dive->cylinder[current_cylinder].gasmix, po2, diveplan->surface_pressure / 1000.0, dive) || get_o2(&dive->cylinder[current_cylinder].gasmix) < 160) { current_cylinder = gaschanges[gi].gasidx; gas = dive->cylinder[current_cylinder].gasmix; @@ -948,7 +948,7 @@ bool plan(struct diveplan *diveplan, struct dive *dive, int timestep, struct dec /* Save the current state and try to ascend to the next stopdepth */ while (1) { /* Check if ascending to next stop is clear, go back and wait if we hit the ceiling on the way */ - if (trial_ascent(0, depth, stoplevels[stopidx], avg_depth, deco_state->bottom_time, + if (trial_ascent(0, depth, stoplevels[stopidx], avg_depth, bottom_time, &dive->cylinder[current_cylinder].gasmix, po2, diveplan->surface_pressure / 1000.0, dive)) { decostoptable[decostopcounter].depth = depth; decostoptable[decostopcounter].time = 0; @@ -990,7 +990,7 @@ bool plan(struct diveplan *diveplan, struct dive *dive, int timestep, struct dec pendinggaschange = false; } - int new_clock = wait_until(dive, clock, clock, laststoptime * 2 + 1, timestep, depth, stoplevels[stopidx], avg_depth, deco_state->bottom_time, &dive->cylinder[current_cylinder].gasmix, po2, diveplan->surface_pressure / 1000.0); + int new_clock = wait_until(dive, clock, clock, laststoptime * 2 + 1, timestep, depth, stoplevels[stopidx], avg_depth, bottom_time, &dive->cylinder[current_cylinder].gasmix, po2, diveplan->surface_pressure / 1000.0); laststoptime = new_clock - clock; /* Finish infinite deco */ if (clock >= 48 * 3600 && depth >= 6000) { @@ -1060,7 +1060,7 @@ bool plan(struct diveplan *diveplan, struct dive *dive, int timestep, struct dec * otherwise odd things can happen, such as CVA causing the final ascent to start *later* * if the ascent rate is slower, which is completely nonsensical. * Assume final ascent takes 20s, which is the time taken to ascend at 9m/min from 3m */ - deco_time = clock - deco_state->bottom_time - stoplevels[2] / last_ascend_rate + 20; + deco_state->deco_time = clock - bottom_time - stoplevels[2] / last_ascend_rate + 20; } while (!is_final_plan); decostoptable[decostopcounter].depth = 0; diff --git a/core/profile.c b/core/profile.c index 419c60584..32e2103af 100644 --- a/core/profile.c +++ b/core/profile.c @@ -954,14 +954,12 @@ static void calculate_ndl_tts(struct dive *dive, struct plot_data *entry, struct */ void calculate_deco_information(struct dive *dive, struct divecomputer *dc, struct plot_info *pi, bool print_mode) { - int i, count_iteration = 0, deco_time; + int i, count_iteration = 0; double surface_pressure = (dc->surface_pressure.mbar ? dc->surface_pressure.mbar : get_surface_pressure_in_mbar(dive, true)) / 1000.0; bool first_iteration = true; int prev_deco_time = 10000000, time_deep_ceiling = 0; - if (in_planner()) - deco_time = pi->maxtime - deco_state->bottom_time; - else - deco_time = 0; + if (!in_planner()) + deco_state->deco_time = 0; struct deco_state *cache_data_initial = NULL; /* For VPM-B outside the planner, cache the initial deco state for CVA iterations */ if (decoMode() == VPMB) { @@ -969,7 +967,7 @@ void calculate_deco_information(struct dive *dive, struct divecomputer *dc, stru } /* For VPM-B outside the planner, iterate until deco time converges (usually one or two iterations after the initial) * Set maximum number of iterations to 10 just in case */ - while ((abs(prev_deco_time - deco_time) >= 30) && (count_iteration < 10)) { + while ((abs(prev_deco_time - deco_state->deco_time) >= 30) && (count_iteration < 10)) { int last_ndl_tts_calc_time = 0, first_ceiling = 0, current_ceiling, last_ceiling, final_tts = 0 , time_clear_ceiling = 0; if (decoMode() == VPMB) deco_state->first_ceiling_pressure.mbar = depth_to_mbar(first_ceiling, dive); @@ -1009,7 +1007,7 @@ void calculate_deco_information(struct dive *dive, struct divecomputer *dc, stru vpmb_start_gradient(); /* For CVA iterations, calculate next gradient */ if (!first_iteration || in_planner()) - vpmb_next_gradient(deco_time, surface_pressure / 1000.0); + vpmb_next_gradient(deco_state->deco_time, surface_pressure / 1000.0); } entry->ceiling = deco_allowed_depth(tissue_tolerance_calc(dive, depth_to_bar(entry->depth, dive)), surface_pressure, dive, !prefs.calcceiling3m); if (prefs.calcceiling3m) @@ -1031,8 +1029,8 @@ void calculate_deco_information(struct dive *dive, struct divecomputer *dc, stru but we want to over-estimate deco_time for the first iteration so it converges correctly, so add 30min*/ if (!in_planner()) - deco_time = pi->maxtime - t1 + 1800; - vpmb_next_gradient(deco_time, surface_pressure / 1000.0); + deco_state->deco_time = pi->maxtime - t1 + 1800; + vpmb_next_gradient(deco_state->deco_time, surface_pressure / 1000.0); } } // Use the point where the ceiling clears as the end of deco phase for CVA calculations @@ -1079,17 +1077,17 @@ void calculate_deco_information(struct dive *dive, struct divecomputer *dc, stru } } if (decoMode() == VPMB && !in_planner()) { - prev_deco_time = deco_time; + prev_deco_time = deco_state->deco_time; // Do we need to update deco_time? if (final_tts > 0) - deco_time = pi->maxtime + final_tts - time_deep_ceiling; + deco_state->deco_time = pi->maxtime + final_tts - time_deep_ceiling; else if (time_clear_ceiling > 0) /* Consistent with planner, deco_time ends after ascending (20s @9m/min from 3m) * at end of whole minute after clearing ceiling. The deepest ceiling when planning a dive * comes typically 10-60s after the end of the bottom time, so add 20s to the calculated * deco time. */ - deco_time = ROUND_UP(time_clear_ceiling - time_deep_ceiling + 20, 60) + 20; - vpmb_next_gradient(deco_time, surface_pressure / 1000.0); + deco_state->deco_time = ROUND_UP(time_clear_ceiling - time_deep_ceiling + 20, 60) + 20; + vpmb_next_gradient(deco_state->deco_time, surface_pressure / 1000.0); final_tts = 0; last_ndl_tts_calc_time = 0; first_ceiling = 0; @@ -1098,7 +1096,7 @@ void calculate_deco_information(struct dive *dive, struct divecomputer *dc, stru restore_deco_state(cache_data_initial, true); } else { // With Buhlmann iterating isn't needed. This makes the while condition false. - prev_deco_time = deco_time = 0; + prev_deco_time = deco_state->deco_time = 0; } } free(cache_data_initial); |