mirror of
https://github.com/subsurface/subsurface.git
synced 2024-12-03 15:43:09 +00:00
Comments added to planner
Signed-off-by: Robert C. Helling <helling@atdotde.de> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
e871169e4c
commit
cb4daa85c3
2 changed files with 40 additions and 15 deletions
45
planner.c
45
planner.c
|
@ -13,6 +13,9 @@
|
||||||
#include "planner.h"
|
#include "planner.h"
|
||||||
#include "gettext.h"
|
#include "gettext.h"
|
||||||
|
|
||||||
|
#define TIMESTEP 1 /* second */
|
||||||
|
#define DECOTIMESTEP 60 /* seconds. Unit of deco stop times */
|
||||||
|
|
||||||
int decostoplevels[] = { 0, 3000, 6000, 9000, 12000, 15000, 18000, 21000, 24000, 27000,
|
int decostoplevels[] = { 0, 3000, 6000, 9000, 12000, 15000, 18000, 21000, 24000, 27000,
|
||||||
30000, 33000, 36000, 39000, 42000, 45000, 48000, 51000, 54000, 57000,
|
30000, 33000, 36000, 39000, 42000, 45000, 48000, 51000, 54000, 57000,
|
||||||
60000, 63000, 66000, 69000, 72000, 75000, 78000, 81000, 84000, 87000,
|
60000, 63000, 66000, 69000, 72000, 75000, 78000, 81000, 84000, 87000,
|
||||||
|
@ -603,6 +606,7 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, b
|
||||||
return;
|
return;
|
||||||
record_dive(dive);
|
record_dive(dive);
|
||||||
|
|
||||||
|
/* Let's start at the last 'sample', i.e. the last manually entered waypoint. */
|
||||||
sample = &dive->dc.sample[dive->dc.samples - 1];
|
sample = &dive->dc.sample[dive->dc.samples - 1];
|
||||||
/* we start with gas 0, then check if that was changed */
|
/* we start with gas 0, then check if that was changed */
|
||||||
o2 = dive->cylinder[0].gasmix.o2.permille;
|
o2 = dive->cylinder[0].gasmix.o2.permille;
|
||||||
|
@ -634,28 +638,33 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, b
|
||||||
printf("depth %5.2lfm ceiling %5.2lfm\n", depth / 1000.0, ceiling / 1000.0);
|
printf("depth %5.2lfm ceiling %5.2lfm\n", depth / 1000.0, ceiling / 1000.0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Find the gases available for deco */
|
||||||
gaschanges = analyze_gaslist(diveplan, dive, &gaschangenr, depth);
|
gaschanges = analyze_gaslist(diveplan, dive, &gaschangenr, depth);
|
||||||
|
/* Find the first potential decostopdepth above current depth */
|
||||||
for (stopidx = 0; stopidx < sizeof(decostoplevels) / sizeof(int); stopidx++)
|
for (stopidx = 0; stopidx < sizeof(decostoplevels) / sizeof(int); stopidx++)
|
||||||
if (decostoplevels[stopidx] >= depth)
|
if (decostoplevels[stopidx] >= depth)
|
||||||
break;
|
break;
|
||||||
if (stopidx > 0)
|
if (stopidx > 0)
|
||||||
stopidx--;
|
stopidx--;
|
||||||
|
/* Stoplevels are either depths of gas changes or potential deco stop depths. */
|
||||||
stoplevels = sort_stops(decostoplevels, stopidx + 1, gaschanges, gaschangenr);
|
stoplevels = sort_stops(decostoplevels, stopidx + 1, gaschanges, gaschangenr);
|
||||||
stopidx += gaschangenr;
|
stopidx += gaschangenr;
|
||||||
|
|
||||||
|
/* Keep time during the ascend */
|
||||||
clock = previous_point_time = dive->dc.sample[dive->dc.samples - 1].time.seconds;
|
clock = previous_point_time = dive->dc.sample[dive->dc.samples - 1].time.seconds;
|
||||||
gi = gaschangenr - 1;
|
gi = gaschangenr - 1;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
/* We will break out when we hit the surface */
|
/* We will break out when we hit the surface */
|
||||||
do {
|
do {
|
||||||
/* Ascend in one second steps to next stop depth */
|
/* Ascend to next stop depth */
|
||||||
int deltad = ascend_velocity(depth);
|
assert(deco_allowed_depth(tissue_tolerance, diveplan->surface_pressure / 1000.0, dive, 1) < depth);
|
||||||
|
int deltad = ascend_velocity(depth) * TIMESTEP;
|
||||||
if (depth - deltad < stoplevels[stopidx])
|
if (depth - deltad < stoplevels[stopidx])
|
||||||
deltad = depth - stoplevels[stopidx];
|
deltad = depth - stoplevels[stopidx];
|
||||||
|
|
||||||
tissue_tolerance = add_segment(depth_to_mbar(depth, dive) / 1000.0, &dive->cylinder[current_cylinder].gasmix, 1, po2, dive);
|
tissue_tolerance = add_segment(depth_to_mbar(depth, dive) / 1000.0, &dive->cylinder[current_cylinder].gasmix, TIMESTEP, po2, dive);
|
||||||
++clock;
|
clock += TIMESTEP;
|
||||||
depth -= deltad;
|
depth -= deltad;
|
||||||
} while (depth > stoplevels[stopidx]);
|
} while (depth > stoplevels[stopidx]);
|
||||||
|
|
||||||
|
@ -664,6 +673,8 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, b
|
||||||
|
|
||||||
|
|
||||||
if (gi >= 0 && stoplevels[stopidx] == gaschanges[gi].depth) {
|
if (gi >= 0 && stoplevels[stopidx] == gaschanges[gi].depth) {
|
||||||
|
/* We have reached a gas change.
|
||||||
|
* Record this in the dive plan */
|
||||||
plan_add_segment(diveplan, clock - previous_point_time, depth, o2, he, po2, false);
|
plan_add_segment(diveplan, clock - previous_point_time, depth, o2, he, po2, false);
|
||||||
previous_point_time = clock;
|
previous_point_time = clock;
|
||||||
stopping = true;
|
stopping = true;
|
||||||
|
@ -678,16 +689,17 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, b
|
||||||
gi--;
|
gi--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* trial ascend */
|
|
||||||
--stopidx;
|
--stopidx;
|
||||||
|
|
||||||
|
/* Save the current state and try to ascend to the next stopdepth */
|
||||||
int trial_depth = depth;
|
int trial_depth = depth;
|
||||||
cache_deco_state(tissue_tolerance, &trial_cache);
|
cache_deco_state(tissue_tolerance, &trial_cache);
|
||||||
while(1) {
|
while(1) {
|
||||||
/* Try to ascend to next stop, go back and wait if we hit the ceiling on the way */
|
/* Check if ascending to next stop is clear, go back and wait if we hit the ceiling on the way */
|
||||||
clear_to_ascend = true;
|
clear_to_ascend = true;
|
||||||
while (trial_depth > stoplevels[stopidx]) {
|
while (trial_depth > stoplevels[stopidx]) {
|
||||||
int deltad = ascend_velocity(trial_depth);
|
int deltad = ascend_velocity(trial_depth) * TIMESTEP;
|
||||||
tissue_tolerance = add_segment(depth_to_mbar(trial_depth, dive) / 1000.0, &dive->cylinder[current_cylinder].gasmix, 1, po2, dive);
|
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){
|
if (deco_allowed_depth(tissue_tolerance, diveplan->surface_pressure / 1000.0, dive, 1) > trial_depth - deltad){
|
||||||
/* We should have stopped */
|
/* We should have stopped */
|
||||||
clear_to_ascend = false;
|
clear_to_ascend = false;
|
||||||
|
@ -696,28 +708,33 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, b
|
||||||
trial_depth -= deltad;
|
trial_depth -= deltad;
|
||||||
}
|
}
|
||||||
restore_deco_state(trial_cache);
|
restore_deco_state(trial_cache);
|
||||||
/* The next stop is clear */
|
|
||||||
if(clear_to_ascend)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Wait a minute */
|
if(clear_to_ascend)
|
||||||
|
break; /* We did not hit the ceiling */
|
||||||
|
|
||||||
|
/* Add a minute of deco time and then try again */
|
||||||
if (!stopping) {
|
if (!stopping) {
|
||||||
|
/* The last segment was an ascend segment.
|
||||||
|
* Add a waypoint for start of this deco stop */
|
||||||
plan_add_segment(diveplan, clock - previous_point_time, depth, o2, he, po2, false);
|
plan_add_segment(diveplan, clock - previous_point_time, depth, o2, he, po2, false);
|
||||||
previous_point_time = clock;
|
previous_point_time = clock;
|
||||||
stopping = true;
|
stopping = true;
|
||||||
}
|
}
|
||||||
tissue_tolerance = add_segment(depth_to_mbar(depth, dive) / 1000.0, &dive->cylinder[current_cylinder].gasmix, 60, po2, dive);
|
tissue_tolerance = add_segment(depth_to_mbar(depth, dive) / 1000.0, &dive->cylinder[current_cylinder].gasmix, DECOTIMESTEP, po2, dive);
|
||||||
cache_deco_state(tissue_tolerance, &trial_cache);
|
cache_deco_state(tissue_tolerance, &trial_cache);
|
||||||
clock += 60;
|
clock += DECOTIMESTEP;
|
||||||
trial_depth = depth;
|
trial_depth = depth;
|
||||||
}
|
}
|
||||||
if (stopping) {
|
if (stopping) {
|
||||||
|
/* Next we will ascend again. Add a waypoint if we have spend deco time */
|
||||||
plan_add_segment(diveplan, clock - previous_point_time, depth, o2, he, po2, false);
|
plan_add_segment(diveplan, clock - previous_point_time, depth, o2, he, po2, false);
|
||||||
previous_point_time = clock;
|
previous_point_time = clock;
|
||||||
stopping = false;
|
stopping = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We made it to the surface */
|
||||||
plan_add_segment(diveplan, clock - previous_point_time, 0, o2, he, po2, false);
|
plan_add_segment(diveplan, clock - previous_point_time, 0, o2, he, po2, false);
|
||||||
delete_single_dive(dive_table.nr - 1);
|
delete_single_dive(dive_table.nr - 1);
|
||||||
*divep = dive = create_dive_from_plan(diveplan);
|
*divep = dive = create_dive_from_plan(diveplan);
|
||||||
|
|
|
@ -1044,6 +1044,9 @@ bool DivePlannerPointsModel::isPlanner()
|
||||||
return mode == PLAN;
|
return mode == PLAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* When the planner adds deco stops to the model, adding those should not trigger a new deco calculation.
|
||||||
|
* We thus start the planner only when recalc is true. */
|
||||||
|
|
||||||
bool DivePlannerPointsModel::setRecalc(bool rec)
|
bool DivePlannerPointsModel::setRecalc(bool rec)
|
||||||
{
|
{
|
||||||
bool old = recalc;
|
bool old = recalc;
|
||||||
|
@ -1245,6 +1248,8 @@ bool DivePlannerPointsModel::addGas(int o2, int he)
|
||||||
fill_default_cylinder(cyl);
|
fill_default_cylinder(cyl);
|
||||||
cyl->gasmix.o2.permille = o2;
|
cyl->gasmix.o2.permille = o2;
|
||||||
cyl->gasmix.he.permille = he;
|
cyl->gasmix.he.permille = he;
|
||||||
|
/* The depth to change to that gas is given by the depth where its pO2 is 1.6 bar.
|
||||||
|
* The user should be able to change this depth manually. */
|
||||||
if (!o2)
|
if (!o2)
|
||||||
cyl->depth.mm = 1600 * 1000 / O2_IN_AIR * 10 - 10000;
|
cyl->depth.mm = 1600 * 1000 / O2_IN_AIR * 10 - 10000;
|
||||||
else
|
else
|
||||||
|
@ -1326,6 +1331,8 @@ int DivePlannerPointsModel::addStop(int milimeters, int seconds, int o2, int he,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get rid of deco stops before adding waypoints
|
||||||
bool oldRecalc = setRecalc(false);
|
bool oldRecalc = setRecalc(false);
|
||||||
if (oldRecalc) {
|
if (oldRecalc) {
|
||||||
QVector<int> computedPoints;
|
QVector<int> computedPoints;
|
||||||
|
@ -1582,7 +1589,8 @@ void DivePlannerPointsModel::createPlan()
|
||||||
int consumption = ((depth_to_mbar(mean[i], tempDive) * duration[i] / 60) * sac) / (cyl->type.size.mliter / 1000);
|
int consumption = ((depth_to_mbar(mean[i], tempDive) * duration[i] / 60) * sac) / (cyl->type.size.mliter / 1000);
|
||||||
cyl->end.mbar = cyl->start.mbar - consumption;
|
cyl->end.mbar = cyl->start.mbar - consumption;
|
||||||
} else {
|
} else {
|
||||||
/* Cylider without a proper size are easily emptied */
|
// Cylinders without a proper size are easily emptied.
|
||||||
|
// Don't attempt to to calculate the infinite pressure drop.
|
||||||
cyl->end.mbar = 0;
|
cyl->end.mbar = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue