VPM-B: add CVA to the deco planner.

Added keeping bottom dive state and every deco's time, so we can
run multiple deco simulations with different gradients until they
converge to some optimal value.

Some improvements on the deco time calculation may be needed.

Signed-off-by: Jan Darowski <jan.darowski@gmail.com>
This commit is contained in:
Jan Darowski 2015-07-04 00:13:34 +02:00
parent bfb9f19080
commit ddfd046c8d

View file

@ -869,6 +869,14 @@ bool enough_gas(int current_cylinder)
bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool show_disclaimer)
{
int bottom_depth;
int bottom_gi;
int bottom_stopidx;
bool is_final_plan = true;
int deco_time;
int previous_deco_time;
char *bottom_cache = NULL;
struct sample *sample;
int po2;
int transitiontime, gi;
@ -886,7 +894,7 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool
int avg_depth, max_depth, bottom_time = 0;
int last_ascend_rate;
int best_first_ascend_cylinder;
struct gasmix gas;
struct gasmix gas, bottom_gas;
int o2time = 0;
int breaktime = -1;
int breakcylinder = 0;
@ -1008,7 +1016,6 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool
free(stoplevels);
free(gaschanges);
return(false);
}
@ -1027,6 +1034,35 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool
// VPM-B or Buehlmann Deco
nuclear_regeneration(clock);
vpmb_start_gradient();
previous_deco_time = 100000000;
deco_time = 10000000;
cache_deco_state(tissue_tolerance, &bottom_cache); // Lets us make several iterations
bottom_depth = depth;
bottom_gi = gi;
bottom_gas = gas;
bottom_stopidx = stopidx;
//CVA
do {
is_final_plan = (prefs.deco_mode == BUEHLMANN) || (previous_deco_time - deco_time < 10); // CVA time converges
previous_deco_time = deco_time;
restore_deco_state(bottom_cache);
depth = bottom_depth;
gi = bottom_gi;
clock = previous_point_time = bottom_time;
gas = bottom_gas;
stopping = false;
decodive = false;
stopidx = bottom_stopidx;
breaktime = -1;
breakcylinder = 0;
o2time = 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 */
@ -1034,6 +1070,7 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool
/* Ascend to next stop depth */
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, gas, po2, false);
previous_point_time = clock;
stopping = false;
@ -1055,6 +1092,7 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool
if (gi >= 0 && stoplevels[stopidx] <= gaschanges[gi].depth) {
/* We have reached a gas change.
* Record this in the dive plan */
if (is_final_plan)
plan_add_segment(diveplan, clock - previous_point_time, depth, gas, po2, false);
previous_point_time = clock;
stopping = true;
@ -1084,7 +1122,6 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool
gi--;
}
}
--stopidx;
/* Save the current state and try to ascend to the next stopdepth */
@ -1099,11 +1136,11 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool
if (!stopping) {
/* The last segment was an ascend segment.
* Add a waypoint for start of this deco stop */
if (is_final_plan)
plan_add_segment(diveplan, clock - previous_point_time, depth, gas, po2, false);
previous_point_time = clock;
stopping = true;
}
if (pendinggaschange) {
current_cylinder = gaschanges[gi + 1].gasidx;
gas = displayed_dive.cylinder[current_cylinder].gasmix;
@ -1138,6 +1175,7 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool
if (o2time >= 12 * 60) {
breaktime = 0;
breakcylinder = current_cylinder;
if (is_final_plan)
plan_add_segment(diveplan, clock - previous_point_time, depth, gas, po2, false);
previous_point_time = clock;
current_cylinder = 0;
@ -1148,6 +1186,7 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool
breaktime += DECOTIMESTEP;
if (breaktime >= 6 * 60) {
o2time = 0;
if (is_final_plan)
plan_add_segment(diveplan, clock - previous_point_time, depth, gas, po2, false);
previous_point_time = clock;
current_cylinder = breakcylinder;
@ -1160,15 +1199,16 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool
}
if (stopping) {
/* Next we will ascend again. Add a waypoint if we have spend deco time */
if (is_final_plan)
plan_add_segment(diveplan, clock - previous_point_time, depth, gas, po2, false);
previous_point_time = clock;
stopping = false;
}
}
/* We made it to the surface
* Create the final dive, add the plan to the notes and fixup some internal
* data that we need to be there when plotting the dive */
deco_time = clock - bottom_time;
} while (!is_final_plan);
plan_add_segment(diveplan, clock - previous_point_time, 0, gas, po2, false);
create_dive_from_plan(diveplan, is_planner);
add_plan_to_notes(diveplan, &displayed_dive, show_disclaimer, error);