mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
core: pass depth_t to depth_to_* functions
This is a drop in the ocean. Make the usage of the unit-types a bit more consistent throughout the code base. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
661ce3f9c7
commit
da17f6a08c
13 changed files with 216 additions and 212 deletions
|
@ -544,21 +544,20 @@ void deco_state_cache::restore(struct deco_state *target, bool keep_vpmb_state)
|
||||||
*target = *data;
|
*target = *data;
|
||||||
}
|
}
|
||||||
|
|
||||||
int deco_allowed_depth(double tissues_tolerance, double surface_pressure, const struct dive *dive, bool smooth)
|
depth_t deco_allowed_depth(double tissues_tolerance, double surface_pressure, const struct dive *dive, bool smooth)
|
||||||
{
|
{
|
||||||
int depth;
|
|
||||||
double pressure_delta;
|
double pressure_delta;
|
||||||
|
|
||||||
/* Avoid negative depths */
|
/* Avoid negative depths */
|
||||||
pressure_delta = tissues_tolerance > surface_pressure ? tissues_tolerance - surface_pressure : 0.0;
|
pressure_delta = tissues_tolerance > surface_pressure ? tissues_tolerance - surface_pressure : 0.0;
|
||||||
|
|
||||||
depth = dive->rel_mbar_to_depth(lrint(pressure_delta * 1000));
|
depth_t depth = dive->rel_mbar_to_depth(lrint(pressure_delta * 1000));
|
||||||
|
|
||||||
if (!smooth)
|
if (!smooth)
|
||||||
depth = lrint(ceil(depth / DECO_STOPS_MULTIPLIER_MM) * DECO_STOPS_MULTIPLIER_MM);
|
depth.mm = lrint(ceil(depth.mm / DECO_STOPS_MULTIPLIER_MM) * DECO_STOPS_MULTIPLIER_MM);
|
||||||
|
|
||||||
if (depth > 0 && depth < buehlmann_config.last_deco_stop_in_mtr * 1000)
|
if (depth.mm > 0 && depth.mm < buehlmann_config.last_deco_stop_in_mtr * 1000)
|
||||||
depth = buehlmann_config.last_deco_stop_in_mtr * 1000;
|
depth.mm = buehlmann_config.last_deco_stop_in_mtr * 1000;
|
||||||
|
|
||||||
return depth;
|
return depth;
|
||||||
}
|
}
|
||||||
|
@ -631,12 +630,13 @@ void update_regression(struct deco_state *ds, const struct dive *dive)
|
||||||
ds->sumx += ds->plot_depth;
|
ds->sumx += ds->plot_depth;
|
||||||
ds->sumxx += (long)ds->plot_depth * ds->plot_depth;
|
ds->sumxx += (long)ds->plot_depth * ds->plot_depth;
|
||||||
double n2_gradient, he_gradient, total_gradient;
|
double n2_gradient, he_gradient, total_gradient;
|
||||||
n2_gradient = update_gradient(ds, dive->depth_to_bar(ds->plot_depth), ds->bottom_n2_gradient[ds->ci_pointing_to_guiding_tissue]);
|
depth_t plot_depth { .mm = ds->plot_depth };
|
||||||
he_gradient = update_gradient(ds, dive->depth_to_bar(ds->plot_depth), ds->bottom_he_gradient[ds->ci_pointing_to_guiding_tissue]);
|
n2_gradient = update_gradient(ds, dive->depth_to_bar(plot_depth), ds->bottom_n2_gradient[ds->ci_pointing_to_guiding_tissue]);
|
||||||
|
he_gradient = update_gradient(ds, dive->depth_to_bar(plot_depth), ds->bottom_he_gradient[ds->ci_pointing_to_guiding_tissue]);
|
||||||
total_gradient = ((n2_gradient * ds->tissue_n2_sat[ds->ci_pointing_to_guiding_tissue]) + (he_gradient * ds->tissue_he_sat[ds->ci_pointing_to_guiding_tissue]))
|
total_gradient = ((n2_gradient * ds->tissue_n2_sat[ds->ci_pointing_to_guiding_tissue]) + (he_gradient * ds->tissue_he_sat[ds->ci_pointing_to_guiding_tissue]))
|
||||||
/ (ds->tissue_n2_sat[ds->ci_pointing_to_guiding_tissue] + ds->tissue_he_sat[ds->ci_pointing_to_guiding_tissue]);
|
/ (ds->tissue_n2_sat[ds->ci_pointing_to_guiding_tissue] + ds->tissue_he_sat[ds->ci_pointing_to_guiding_tissue]);
|
||||||
|
|
||||||
double buehlmann_gradient = (1.0 / ds->buehlmann_inertgas_b[ds->ci_pointing_to_guiding_tissue] - 1.0) * dive->depth_to_bar(ds->plot_depth) + ds->buehlmann_inertgas_a[ds->ci_pointing_to_guiding_tissue];
|
double buehlmann_gradient = (1.0 / ds->buehlmann_inertgas_b[ds->ci_pointing_to_guiding_tissue] - 1.0) * dive->depth_to_bar(plot_depth) + ds->buehlmann_inertgas_a[ds->ci_pointing_to_guiding_tissue];
|
||||||
double gf = (total_gradient - vpmb_config.other_gases_pressure) / buehlmann_gradient;
|
double gf = (total_gradient - vpmb_config.other_gases_pressure) / buehlmann_gradient;
|
||||||
ds->sumxy += gf * ds->plot_depth;
|
ds->sumxy += gf * ds->plot_depth;
|
||||||
ds->sumy += gf;
|
ds->sumy += gf;
|
||||||
|
|
|
@ -46,7 +46,7 @@ struct deco_state {
|
||||||
|
|
||||||
extern const double buehlmann_N2_t_halflife[];
|
extern const double buehlmann_N2_t_halflife[];
|
||||||
|
|
||||||
extern int deco_allowed_depth(double tissues_tolerance, double surface_pressure, const struct dive *dive, bool smooth);
|
extern depth_t deco_allowed_depth(double tissues_tolerance, double surface_pressure, const struct dive *dive, bool smooth);
|
||||||
|
|
||||||
double get_gf(struct deco_state *ds, double ambpressure_bar, const struct dive *dive);
|
double get_gf(struct deco_state *ds, double ambpressure_bar, const struct dive *dive);
|
||||||
extern void clear_deco(struct deco_state *ds, double surface_pressure, bool in_planner);
|
extern void clear_deco(struct deco_state *ds, double surface_pressure, bool in_planner);
|
||||||
|
|
|
@ -472,7 +472,7 @@ static int same_rounded_pressure(pressure_t a, pressure_t b)
|
||||||
return abs((a - b).mbar) <= 500;
|
return abs((a - b).mbar) <= 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double calculate_depth_to_mbarf(int depth, pressure_t surface_pressure, int salinity);
|
static double calculate_depth_to_mbarf(depth_t depth, pressure_t surface_pressure, int salinity);
|
||||||
|
|
||||||
/* this gets called when the dive mode has changed (so OC vs. CC)
|
/* this gets called when the dive mode has changed (so OC vs. CC)
|
||||||
* there are two places we might have setpoints... events or in the samples
|
* there are two places we might have setpoints... events or in the samples
|
||||||
|
@ -496,7 +496,7 @@ void update_setpoint_events(const struct dive *dive, struct divecomputer *dc)
|
||||||
gasmix_loop loop(*dive, *dc);
|
gasmix_loop loop(*dive, *dc);
|
||||||
for (auto &sample: dc->samples) {
|
for (auto &sample: dc->samples) {
|
||||||
struct gasmix gasmix = loop.at(sample.time.seconds).first;
|
struct gasmix gasmix = loop.at(sample.time.seconds).first;
|
||||||
gas_pressures pressures = fill_pressures(lrint(calculate_depth_to_mbarf(sample.depth.mm, dc->surface_pressure, 0)), gasmix ,0, dc->divemode);
|
gas_pressures pressures = fill_pressures(lrint(calculate_depth_to_mbarf(sample.depth, dc->surface_pressure, 0)), gasmix ,0, dc->divemode);
|
||||||
if (abs(sample.setpoint.mbar - (int)(1000 * pressures.o2)) <= 50)
|
if (abs(sample.setpoint.mbar - (int)(1000 * pressures.o2)) <= 50)
|
||||||
sample.setpoint = 0_baro2;
|
sample.setpoint = 0_baro2;
|
||||||
}
|
}
|
||||||
|
@ -2329,7 +2329,7 @@ fraction_t dive::best_o2(depth_t depth, bool in_planner) const
|
||||||
fraction_t fo2;
|
fraction_t fo2;
|
||||||
int po2 = in_planner ? prefs.bottompo2 : (int)(prefs.modpO2 * 1000.0);
|
int po2 = in_planner ? prefs.bottompo2 : (int)(prefs.modpO2 * 1000.0);
|
||||||
|
|
||||||
fo2.permille = (po2 * 100 / depth_to_mbar(depth.mm)) * 10; //use integer arithmetic to round down to nearest percent
|
fo2.permille = (po2 * 100 / depth_to_mbar(depth)) * 10; //use integer arithmetic to round down to nearest percent
|
||||||
// Don't permit >100% O2
|
// Don't permit >100% O2
|
||||||
// TODO: use std::min, once we have comparison
|
// TODO: use std::min, once we have comparison
|
||||||
if (fo2.permille > 1000)
|
if (fo2.permille > 1000)
|
||||||
|
@ -2342,8 +2342,8 @@ fraction_t dive::best_he(depth_t depth, bool o2narcotic, fraction_t fo2) const
|
||||||
{
|
{
|
||||||
fraction_t fhe;
|
fraction_t fhe;
|
||||||
int pnarcotic, ambient;
|
int pnarcotic, ambient;
|
||||||
pnarcotic = depth_to_mbar(prefs.bestmixend.mm);
|
pnarcotic = depth_to_mbar(prefs.bestmixend);
|
||||||
ambient = depth_to_mbar(depth.mm);
|
ambient = depth_to_mbar(depth);
|
||||||
if (o2narcotic) {
|
if (o2narcotic) {
|
||||||
fhe.permille = (100 - 100 * pnarcotic / ambient) * 10; //use integer arithmetic to round up to nearest percent
|
fhe.permille = (100 - 100 * pnarcotic / ambient) * 10; //use integer arithmetic to round up to nearest percent
|
||||||
} else {
|
} else {
|
||||||
|
@ -2384,7 +2384,7 @@ static double salinity_to_specific_weight(int salinity)
|
||||||
/* Pa = N/m^2 - so we determine the weight (in N) of the mass of 10m
|
/* Pa = N/m^2 - so we determine the weight (in N) of the mass of 10m
|
||||||
* of water (and use standard salt water at 1.03kg per liter if we don't know salinity)
|
* of water (and use standard salt water at 1.03kg per liter if we don't know salinity)
|
||||||
* and add that to the surface pressure (or to 1013 if that's unknown) */
|
* and add that to the surface pressure (or to 1013 if that's unknown) */
|
||||||
static double calculate_depth_to_mbarf(int depth, pressure_t surface_pressure, int salinity)
|
static double calculate_depth_to_mbarf(depth_t depth, pressure_t surface_pressure, int salinity)
|
||||||
{
|
{
|
||||||
if (!surface_pressure.mbar)
|
if (!surface_pressure.mbar)
|
||||||
surface_pressure = 1_atm;
|
surface_pressure = 1_atm;
|
||||||
|
@ -2393,15 +2393,15 @@ static double calculate_depth_to_mbarf(int depth, pressure_t surface_pressure, i
|
||||||
if (salinity < 500)
|
if (salinity < 500)
|
||||||
salinity += FRESHWATER_SALINITY;
|
salinity += FRESHWATER_SALINITY;
|
||||||
double specific_weight = salinity_to_specific_weight(salinity);
|
double specific_weight = salinity_to_specific_weight(salinity);
|
||||||
return surface_pressure.mbar + depth * specific_weight;
|
return surface_pressure.mbar + depth.mm * specific_weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dive::depth_to_mbar(int depth) const
|
int dive::depth_to_mbar(depth_t depth) const
|
||||||
{
|
{
|
||||||
return lrint(depth_to_mbarf(depth));
|
return lrint(depth_to_mbarf(depth));
|
||||||
}
|
}
|
||||||
|
|
||||||
double dive::depth_to_mbarf(int depth) const
|
double dive::depth_to_mbarf(depth_t depth) const
|
||||||
{
|
{
|
||||||
// For downloaded and planned dives, use DC's values
|
// For downloaded and planned dives, use DC's values
|
||||||
int salinity = dcs[0].salinity;
|
int salinity = dcs[0].salinity;
|
||||||
|
@ -2414,12 +2414,12 @@ double dive::depth_to_mbarf(int depth) const
|
||||||
return calculate_depth_to_mbarf(depth, surface_pressure, salinity);
|
return calculate_depth_to_mbarf(depth, surface_pressure, salinity);
|
||||||
}
|
}
|
||||||
|
|
||||||
double dive::depth_to_bar(int depth) const
|
double dive::depth_to_bar(depth_t depth) const
|
||||||
{
|
{
|
||||||
return depth_to_mbar(depth) / 1000.0;
|
return depth_to_mbar(depth) / 1000.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double dive::depth_to_atm(int depth) const
|
double dive::depth_to_atm(depth_t depth) const
|
||||||
{
|
{
|
||||||
return mbar_to_atm(depth_to_mbar(depth));
|
return mbar_to_atm(depth_to_mbar(depth));
|
||||||
}
|
}
|
||||||
|
@ -2428,7 +2428,7 @@ double dive::depth_to_atm(int depth) const
|
||||||
* (that's the one that some dive computers like the Uemis Zurich
|
* (that's the one that some dive computers like the Uemis Zurich
|
||||||
* provide - for the other models that do this libdivecomputer has to
|
* provide - for the other models that do this libdivecomputer has to
|
||||||
* take care of this, but the Uemis we support natively */
|
* take care of this, but the Uemis we support natively */
|
||||||
int dive::rel_mbar_to_depth(int mbar) const
|
depth_t dive::rel_mbar_to_depth(int mbar) const
|
||||||
{
|
{
|
||||||
// For downloaded and planned dives, use DC's salinity. Manual dives, use user's salinity
|
// For downloaded and planned dives, use DC's salinity. Manual dives, use user's salinity
|
||||||
int salinity = is_dc_manually_added_dive(&dcs[0]) ? user_salinity : dcs[0].salinity;
|
int salinity = is_dc_manually_added_dive(&dcs[0]) ? user_salinity : dcs[0].salinity;
|
||||||
|
@ -2437,10 +2437,11 @@ int dive::rel_mbar_to_depth(int mbar) const
|
||||||
|
|
||||||
/* whole mbar gives us cm precision */
|
/* whole mbar gives us cm precision */
|
||||||
double specific_weight = salinity_to_specific_weight(salinity);
|
double specific_weight = salinity_to_specific_weight(salinity);
|
||||||
return int_cast<int>(mbar / specific_weight);
|
depth_t res { .mm = int_cast<int>(mbar / specific_weight) };
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dive::mbar_to_depth(int mbar) const
|
depth_t dive::mbar_to_depth(int mbar) const
|
||||||
{
|
{
|
||||||
// For downloaded and planned dives, use DC's pressure. Manual dives, use user's pressure
|
// For downloaded and planned dives, use DC's pressure. Manual dives, use user's pressure
|
||||||
pressure_t surface_pressure = is_dc_manually_added_dive(&dcs[0])
|
pressure_t surface_pressure = is_dc_manually_added_dive(&dcs[0])
|
||||||
|
@ -2456,7 +2457,7 @@ int dive::mbar_to_depth(int mbar) const
|
||||||
/* MOD rounded to multiples of roundto mm */
|
/* MOD rounded to multiples of roundto mm */
|
||||||
depth_t dive::gas_mod(struct gasmix mix, pressure_t po2_limit, int roundto) const
|
depth_t dive::gas_mod(struct gasmix mix, pressure_t po2_limit, int roundto) const
|
||||||
{
|
{
|
||||||
double depth = (double) mbar_to_depth(po2_limit.mbar * 1000 / get_o2(mix));
|
double depth = (double) mbar_to_depth(po2_limit.mbar * 1000 / get_o2(mix)).mm;
|
||||||
// Rounding should be towards lower=safer depths but we give a bit
|
// Rounding should be towards lower=safer depths but we give a bit
|
||||||
// of fudge to all to switch to o2 at 6m. So from .9 we round up.
|
// of fudge to all to switch to o2 at 6m. So from .9 we round up.
|
||||||
return depth_t { .mm = (int)(depth / roundto + 0.1) * roundto };
|
return depth_t { .mm = (int)(depth / roundto + 0.1) * roundto };
|
||||||
|
@ -2465,7 +2466,7 @@ depth_t dive::gas_mod(struct gasmix mix, pressure_t po2_limit, int roundto) cons
|
||||||
/* Maximum narcotic depth rounded to multiples of roundto mm */
|
/* Maximum narcotic depth rounded to multiples of roundto mm */
|
||||||
depth_t dive::gas_mnd(struct gasmix mix, depth_t end, int roundto) const
|
depth_t dive::gas_mnd(struct gasmix mix, depth_t end, int roundto) const
|
||||||
{
|
{
|
||||||
pressure_t ppo2n2 { .mbar = depth_to_mbar(end.mm) };
|
pressure_t ppo2n2 { .mbar = depth_to_mbar(end) };
|
||||||
|
|
||||||
int maxambient = prefs.o2narcotic ?
|
int maxambient = prefs.o2narcotic ?
|
||||||
int_cast<int>(ppo2n2.mbar / (1 - get_he(mix) / 1000.0))
|
int_cast<int>(ppo2n2.mbar / (1 - get_he(mix) / 1000.0))
|
||||||
|
@ -2475,7 +2476,8 @@ depth_t dive::gas_mnd(struct gasmix mix, depth_t end, int roundto) const
|
||||||
:
|
:
|
||||||
// Actually: Infinity
|
// Actually: Infinity
|
||||||
1000000;
|
1000000;
|
||||||
return depth_t { .mm = int_cast<int>(((double)mbar_to_depth(maxambient)) / roundto) * roundto };
|
double depth = static_cast<double>(mbar_to_depth(maxambient).mm);
|
||||||
|
return depth_t { .mm = int_cast<int>(depth / roundto) * roundto };
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string dive::get_country() const
|
std::string dive::get_country() const
|
||||||
|
|
12
core/dive.h
12
core/dive.h
|
@ -116,12 +116,12 @@ struct dive {
|
||||||
std::string get_country() const;
|
std::string get_country() const;
|
||||||
std::string get_location() const;
|
std::string get_location() const;
|
||||||
|
|
||||||
int depth_to_mbar(int depth) const;
|
int depth_to_mbar(depth_t depth) const;
|
||||||
double depth_to_mbarf(int depth) const;
|
double depth_to_mbarf(depth_t depth) const;
|
||||||
double depth_to_bar(int depth) const;
|
double depth_to_bar(depth_t depth) const;
|
||||||
double depth_to_atm(int depth) const;
|
double depth_to_atm(depth_t depth) const;
|
||||||
int rel_mbar_to_depth(int mbar) const;
|
depth_t rel_mbar_to_depth(int mbar) const;
|
||||||
int mbar_to_depth(int mbar) const;
|
depth_t mbar_to_depth(int mbar) const;
|
||||||
|
|
||||||
pressure_t calculate_surface_pressure() const;
|
pressure_t calculate_surface_pressure() const;
|
||||||
pressure_t un_fixup_surface_pressure() const;
|
pressure_t un_fixup_surface_pressure() const;
|
||||||
|
|
|
@ -116,16 +116,18 @@ static int get_sample_o2(const struct dive &dive, const struct divecomputer *dc,
|
||||||
{
|
{
|
||||||
int po2i, po2f, po2;
|
int po2i, po2f, po2;
|
||||||
// Use sensor[0] if available
|
// Use sensor[0] if available
|
||||||
|
depth_t depth = sample.depth;
|
||||||
|
depth_t pdepth = psample.depth;
|
||||||
if ((dc->divemode == CCR || dc->divemode == PSCR) && sample.o2sensor[0].mbar) {
|
if ((dc->divemode == CCR || dc->divemode == PSCR) && sample.o2sensor[0].mbar) {
|
||||||
po2i = psample.o2sensor[0].mbar;
|
po2i = psample.o2sensor[0].mbar;
|
||||||
po2f = sample.o2sensor[0].mbar; // then use data from the first o2 sensor
|
po2f = sample.o2sensor[0].mbar; // then use data from the first o2 sensor
|
||||||
po2 = (po2f + po2i) / 2;
|
po2 = (po2f + po2i) / 2;
|
||||||
} else if (sample.setpoint.mbar > 0) {
|
} else if (sample.setpoint.mbar > 0) {
|
||||||
po2 = std::min((int) sample.setpoint.mbar,
|
po2 = std::min((int) sample.setpoint.mbar,
|
||||||
dive.depth_to_mbar(sample.depth.mm));
|
dive.depth_to_mbar(depth));
|
||||||
} else {
|
} else {
|
||||||
double amb_presure = dive.depth_to_bar(sample.depth.mm);
|
double amb_presure = dive.depth_to_bar(depth);
|
||||||
double pamb_pressure = dive.depth_to_bar(psample.depth.mm );
|
double pamb_pressure = dive.depth_to_bar(pdepth);
|
||||||
if (dc->divemode == PSCR) {
|
if (dc->divemode == PSCR) {
|
||||||
po2i = pscr_o2(pamb_pressure, dive.get_gasmix_at_time(*dc, psample.time));
|
po2i = pscr_o2(pamb_pressure, dive.get_gasmix_at_time(*dc, psample.time));
|
||||||
po2f = pscr_o2(amb_presure, dive.get_gasmix_at_time(*dc, sample.time));
|
po2f = pscr_o2(amb_presure, dive.get_gasmix_at_time(*dc, sample.time));
|
||||||
|
@ -154,6 +156,8 @@ static int calculate_otu(const struct dive &dive)
|
||||||
int po2i, po2f;
|
int po2i, po2f;
|
||||||
double pm;
|
double pm;
|
||||||
int t = (sample.time - psample.time).seconds;
|
int t = (sample.time - psample.time).seconds;
|
||||||
|
depth_t depth = sample.depth;
|
||||||
|
depth_t pdepth = psample.depth;
|
||||||
// if there is sensor data use sensor[0]
|
// if there is sensor data use sensor[0]
|
||||||
if ((dc->divemode == CCR || dc->divemode == PSCR) && sample.o2sensor[0].mbar) {
|
if ((dc->divemode == CCR || dc->divemode == PSCR) && sample.o2sensor[0].mbar) {
|
||||||
po2i = psample.o2sensor[0].mbar;
|
po2i = psample.o2sensor[0].mbar;
|
||||||
|
@ -161,15 +165,15 @@ static int calculate_otu(const struct dive &dive)
|
||||||
} else {
|
} else {
|
||||||
if (sample.setpoint.mbar > 0) {
|
if (sample.setpoint.mbar > 0) {
|
||||||
po2f = std::min((int) sample.setpoint.mbar,
|
po2f = std::min((int) sample.setpoint.mbar,
|
||||||
dive.depth_to_mbar(sample.depth.mm));
|
dive.depth_to_mbar(depth));
|
||||||
if (psample.setpoint.mbar > 0)
|
if (psample.setpoint.mbar > 0)
|
||||||
po2i = std::min((int) psample.setpoint.mbar,
|
po2i = std::min((int) psample.setpoint.mbar,
|
||||||
dive.depth_to_mbar(psample.depth.mm));
|
dive.depth_to_mbar(pdepth));
|
||||||
else
|
else
|
||||||
po2i = po2f;
|
po2i = po2f;
|
||||||
} else { // For OC and rebreather without o2 sensor/setpoint
|
} else { // For OC and rebreather without o2 sensor/setpoint
|
||||||
double amb_presure = dive.depth_to_bar(sample.depth.mm);
|
double amb_presure = dive.depth_to_bar(depth);
|
||||||
double pamb_pressure = dive.depth_to_bar(psample.depth.mm);
|
double pamb_pressure = dive.depth_to_bar(pdepth);
|
||||||
if (dc->divemode == PSCR) {
|
if (dc->divemode == PSCR) {
|
||||||
po2i = pscr_o2(pamb_pressure, dive.get_gasmix_at_time(*dc, psample.time));
|
po2i = pscr_o2(pamb_pressure, dive.get_gasmix_at_time(*dc, psample.time));
|
||||||
po2f = pscr_o2(amb_presure, dive.get_gasmix_at_time(*dc, sample.time));
|
po2f = pscr_o2(amb_presure, dive.get_gasmix_at_time(*dc, sample.time));
|
||||||
|
@ -394,7 +398,7 @@ static int calculate_sac(const struct dive &dive)
|
||||||
{
|
{
|
||||||
const struct divecomputer *dc = &dive.dcs[0];
|
const struct divecomputer *dc = &dive.dcs[0];
|
||||||
double airuse, pressure, sac;
|
double airuse, pressure, sac;
|
||||||
int duration, meandepth;
|
int duration;
|
||||||
|
|
||||||
airuse = calculate_airuse(dive);
|
airuse = calculate_airuse(dive);
|
||||||
if (!airuse)
|
if (!airuse)
|
||||||
|
@ -404,12 +408,11 @@ static int calculate_sac(const struct dive &dive)
|
||||||
if (!duration)
|
if (!duration)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
meandepth = dc->meandepth.mm;
|
if (!dc->meandepth.mm)
|
||||||
if (!meandepth)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Mean pressure in ATM (SAC calculations are in atm*l/min) */
|
/* Mean pressure in ATM (SAC calculations are in atm*l/min) */
|
||||||
pressure = dive.depth_to_atm(meandepth);
|
pressure = dive.depth_to_atm(dc->meandepth);
|
||||||
sac = airuse / pressure * 60 / duration;
|
sac = airuse / pressure * 60 / duration;
|
||||||
|
|
||||||
/* milliliters per minute.. */
|
/* milliliters per minute.. */
|
||||||
|
@ -429,7 +432,7 @@ static void add_dive_to_deco(struct deco_state *ds, const struct dive &dive, boo
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
for (j = t0; j < t1; j++) {
|
for (j = t0; j < t1; j++) {
|
||||||
int depth = interpolate(psample.depth.mm, sample.depth.mm, j - t0, t1 - t0);
|
depth_t depth = { .mm = interpolate(psample.depth.mm, sample.depth.mm, j - t0, t1 - t0) };
|
||||||
auto gasmix = loop.at(j).first;
|
auto gasmix = loop.at(j).first;
|
||||||
add_segment(ds, dive.depth_to_bar(depth), gasmix, 1, sample.setpoint.mbar,
|
add_segment(ds, dive.depth_to_bar(depth), gasmix, 1, sample.setpoint.mbar,
|
||||||
loop_d.at(j), dive.sac,
|
loop_d.at(j), dive.sac,
|
||||||
|
|
|
@ -280,9 +280,9 @@ static void fill_missing_tank_pressures(const struct dive *dive, struct plot_inf
|
||||||
static inline int calc_pressure_time(const struct dive *dive, const struct plot_data &a, const struct plot_data &b)
|
static inline int calc_pressure_time(const struct dive *dive, const struct plot_data &a, const struct plot_data &b)
|
||||||
{
|
{
|
||||||
int time = b.sec - a.sec;
|
int time = b.sec - a.sec;
|
||||||
int depth = (a.depth + b.depth) / 2;
|
depth_t depth { .mm = (a.depth + b.depth) / 2 };
|
||||||
|
|
||||||
if (depth <= SURFACE_THRESHOLD)
|
if (depth.mm <= SURFACE_THRESHOLD)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return dive->depth_to_mbar(depth) * time;
|
return dive->depth_to_mbar(depth) * time;
|
||||||
|
|
189
core/planner.cpp
189
core/planner.cpp
|
@ -29,18 +29,19 @@
|
||||||
|
|
||||||
static constexpr int base_timestep = 2; // seconds
|
static constexpr int base_timestep = 2; // seconds
|
||||||
|
|
||||||
static int decostoplevels_metric[] = { 0, 3000, 6000, 9000, 12000, 15000, 18000, 21000, 24000, 27000,
|
static std::vector<depth_t> decostoplevels_metric = { 0_m, 3_m, 6_m, 9_m, 12_m, 15_m, 18_m, 21_m, 24_m, 27_m,
|
||||||
30000, 33000, 36000, 39000, 42000, 45000, 48000, 51000, 54000, 57000,
|
30_m, 33_m, 36_m, 39_m, 42_m, 45_m, 48_m, 51_m, 54_m, 57_m,
|
||||||
60000, 63000, 66000, 69000, 72000, 75000, 78000, 81000, 84000, 87000,
|
60_m, 63_m, 66_m, 69_m, 72_m, 75_m, 78_m, 81_m, 84_m, 87_m,
|
||||||
90000, 100000, 110000, 120000, 130000, 140000, 150000, 160000, 170000,
|
90_m, 100_m, 110_m, 120_m, 130_m, 140_m, 150_m, 160_m, 170_m,
|
||||||
180000, 190000, 200000, 220000, 240000, 260000, 280000, 300000,
|
180_m, 190_m, 200_m, 220_m, 240_m, 260_m, 280_m, 300_m,
|
||||||
320000, 340000, 360000, 380000 };
|
320_m, 340_m, 360_m, 380_m };
|
||||||
static int decostoplevels_imperial[] = { 0, 3048, 6096, 9144, 12192, 15240, 18288, 21336, 24384, 27432,
|
// Note: for fractional feet (e.g. 333.33 ft), we use mm, since currently our custom depth literals only support integers.
|
||||||
30480, 33528, 36576, 39624, 42672, 45720, 48768, 51816, 54864, 57912,
|
static std::vector<depth_t> decostoplevels_imperial = { 0_ft, 10_ft, 20_ft, 30_ft, 40_ft, 50_ft, 60_ft, 70_ft, 80_ft, 90_ft,
|
||||||
60960, 64008, 67056, 70104, 73152, 76200, 79248, 82296, 85344, 88392,
|
100_ft, 110_ft, 120_ft, 130_ft, 140_ft, 150_ft, 160_ft, 170_ft, 180_ft, 190_ft,
|
||||||
91440, 101600, 111760, 121920, 132080, 142240, 152400, 162560, 172720,
|
200_ft, 210_ft, 220_ft, 230_ft, 240_ft, 250_ft, 260_ft, 270_ft, 280_ft, 290_ft,
|
||||||
182880, 193040, 203200, 223520, 243840, 264160, 284480, 304800,
|
300_ft, 101600_mm, 111760_mm, 400_ft, 132080_mm, 142240_mm, 500_ft, 162560_mm, 172720_mm,
|
||||||
325120, 345440, 365760, 386080 };
|
600_ft, 193040_mm, 203200_mm, 223520_mm, 800_ft, 264160_mm, 284480_mm, 1000_ft,
|
||||||
|
325120_mm, 345440_mm, 1200_ft, 386080_mm };
|
||||||
|
|
||||||
#if DEBUG_PLAN
|
#if DEBUG_PLAN
|
||||||
void dump_plan(struct diveplan *diveplan)
|
void dump_plan(struct diveplan *diveplan)
|
||||||
|
@ -103,11 +104,11 @@ static void interpolate_transition(struct deco_state *ds, struct dive *dive, dur
|
||||||
int32_t j;
|
int32_t j;
|
||||||
|
|
||||||
for (j = t0.seconds; j < t1.seconds; j++) {
|
for (j = t0.seconds; j < t1.seconds; j++) {
|
||||||
int depth = interpolate(d0.mm, d1.mm, j - t0.seconds, t1.seconds - t0.seconds);
|
depth_t depth = depth_t { .mm = interpolate(d0.mm, d1.mm, j - t0.seconds, t1.seconds - t0.seconds) };
|
||||||
add_segment(ds, dive->depth_to_bar(depth), gasmix, 1, po2.mbar, divemode, prefs.bottomsac, true);
|
add_segment(ds, dive->depth_to_bar(depth), gasmix, 1, po2.mbar, divemode, prefs.bottomsac, true);
|
||||||
}
|
}
|
||||||
if (d1.mm > d0.mm)
|
if (d1.mm > d0.mm)
|
||||||
calc_crushing_pressure(ds, dive->depth_to_bar(d1.mm));
|
calc_crushing_pressure(ds, dive->depth_to_bar(d1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns the tissue tolerance at the end of this (partial) dive */
|
/* returns the tissue tolerance at the end of this (partial) dive */
|
||||||
|
@ -153,7 +154,7 @@ static int tissue_at_end(struct deco_state *ds, struct dive *dive, const struct
|
||||||
nuclear_regeneration(ds, t0.seconds);
|
nuclear_regeneration(ds, t0.seconds);
|
||||||
vpmb_start_gradient(ds);
|
vpmb_start_gradient(ds);
|
||||||
ceiling_pressure.mbar = dive->depth_to_mbar(deco_allowed_depth(tissue_tolerance_calc(ds, dive,
|
ceiling_pressure.mbar = dive->depth_to_mbar(deco_allowed_depth(tissue_tolerance_calc(ds, dive,
|
||||||
dive->depth_to_bar(lastdepth.mm), true),
|
dive->depth_to_bar(lastdepth), true),
|
||||||
dive->surface_pressure.mbar / 1000.0,
|
dive->surface_pressure.mbar / 1000.0,
|
||||||
dive,
|
dive,
|
||||||
1));
|
1));
|
||||||
|
@ -184,7 +185,7 @@ static void update_cylinder_pressure(struct dive *d, int old_depth, int new_dept
|
||||||
if (!cyl)
|
if (!cyl)
|
||||||
return;
|
return;
|
||||||
mean_depth.mm = (old_depth + new_depth) / 2;
|
mean_depth.mm = (old_depth + new_depth) / 2;
|
||||||
gas_used.mliter = lrint(d->depth_to_atm(mean_depth.mm) * sac / 60 * duration * factor / 1000);
|
gas_used.mliter = lrint(d->depth_to_atm(mean_depth) * sac / 60 * duration * factor / 1000);
|
||||||
cyl->gas_used += gas_used;
|
cyl->gas_used += gas_used;
|
||||||
if (in_deco)
|
if (in_deco)
|
||||||
cyl->deco_gas_used += gas_used;
|
cyl->deco_gas_used += gas_used;
|
||||||
|
@ -400,39 +401,39 @@ static std::vector<gaschanges> analyze_gaslist(const struct diveplan &diveplan,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sort all the stops into one ordered list */
|
/* sort all the stops into one ordered list */
|
||||||
static std::vector<int> sort_stops(int dstops[], size_t dnr, std::vector<gaschanges> gstops)
|
static std::vector<depth_t> sort_stops(const std::vector<depth_t> &dstops, size_t dnr, const std::vector<gaschanges> &gstops)
|
||||||
{
|
{
|
||||||
int total = dnr + gstops.size();
|
int total = static_cast<int>(dnr + gstops.size());
|
||||||
std::vector<int> stoplevels(total);
|
std::vector<depth_t> stoplevels(total);
|
||||||
|
|
||||||
/* Can't happen. */
|
/* Can't happen. */
|
||||||
if (dnr == 0)
|
if (dnr == 0)
|
||||||
return std::vector<int>();
|
return {};
|
||||||
|
|
||||||
/* no gaschanges */
|
/* no gaschanges */
|
||||||
if (gstops.empty()) {
|
if (gstops.empty()) {
|
||||||
std::copy(dstops, dstops + dnr, stoplevels.begin());
|
std::copy(dstops.begin(), dstops.begin() + dnr, stoplevels.begin());
|
||||||
return stoplevels;
|
return stoplevels;
|
||||||
}
|
}
|
||||||
int i = static_cast<int>(total) - 1;
|
int i = static_cast<int>(total) - 1;
|
||||||
int gi = static_cast<int>(gstops.size()) - 1;
|
int gi = static_cast<int>(gstops.size()) - 1;
|
||||||
int di = static_cast<int>(dnr) - 1;
|
int di = static_cast<int>(dnr) - 1;
|
||||||
while (i >= 0) {
|
while (i >= 0) {
|
||||||
if (dstops[di] > gstops[gi].depth) {
|
if (dstops[di].mm > gstops[gi].depth) {
|
||||||
stoplevels[i] = dstops[di];
|
stoplevels[i] = dstops[di];
|
||||||
di--;
|
di--;
|
||||||
} else if (dstops[di] == gstops[gi].depth) {
|
} else if (dstops[di].mm == gstops[gi].depth) {
|
||||||
stoplevels[i] = dstops[di];
|
stoplevels[i] = dstops[di];
|
||||||
di--;
|
di--;
|
||||||
gi--;
|
gi--;
|
||||||
} else {
|
} else {
|
||||||
stoplevels[i] = gstops[gi].depth;
|
stoplevels[i].mm = gstops[gi].depth;
|
||||||
gi--;
|
gi--;
|
||||||
}
|
}
|
||||||
i--;
|
i--;
|
||||||
if (di < 0) {
|
if (di < 0) {
|
||||||
while (gi >= 0)
|
while (gi >= 0)
|
||||||
stoplevels[i--] = gstops[gi--].depth;
|
stoplevels[i--].mm = gstops[gi--].depth;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (gi < 0) {
|
if (gi < 0) {
|
||||||
|
@ -442,33 +443,33 @@ static std::vector<int> sort_stops(int dstops[], size_t dnr, std::vector<gaschan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (i >= 0)
|
while (i >= 0)
|
||||||
stoplevels[i--] = 0;
|
stoplevels[i--].mm = 0;
|
||||||
|
|
||||||
#if DEBUG_PLAN & 16
|
#if DEBUG_PLAN & 16
|
||||||
int k;
|
int k;
|
||||||
for (k = static_cast<int>(gstops.size()) + dnr - 1; k >= 0; k--) {
|
for (k = static_cast<int>(gstops.size()) + dnr - 1; k >= 0; k--) {
|
||||||
printf("stoplevel[%d]: %5.2lfm\n", k, stoplevels[k] / 1000.0);
|
printf("stoplevel[%d]: %5.2lfm\n", k, stoplevels[k].mm / 1000.0);
|
||||||
if (stoplevels[k] == 0)
|
if (stoplevels[k].mm == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return stoplevels;
|
return stoplevels;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ascent_velocity(int depth, int avg_depth, int)
|
int ascent_velocity(depth_t depth, int avg_depth, int)
|
||||||
{
|
{
|
||||||
/* We need to make this configurable */
|
/* We need to make this configurable */
|
||||||
|
|
||||||
/* As an example (and possibly reasonable default) this is the Tech 1 provedure according
|
/* 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 */
|
* to http://www.globalunderwaterexplorers.org/files/Standards_and_Procedures/SOP_Manual_Ver2.0.2.pdf */
|
||||||
|
|
||||||
if (depth * 4 > avg_depth * 3) {
|
if (depth.mm * 4 > avg_depth * 3) {
|
||||||
return prefs.ascrate75;
|
return prefs.ascrate75;
|
||||||
} else {
|
} else {
|
||||||
if (depth * 2 > avg_depth) {
|
if (depth.mm * 2 > avg_depth) {
|
||||||
return prefs.ascrate50;
|
return prefs.ascrate50;
|
||||||
} else {
|
} else {
|
||||||
if (depth > 6000)
|
if (depth.mm > 6000)
|
||||||
return prefs.ascratestops;
|
return prefs.ascratestops;
|
||||||
else
|
else
|
||||||
return prefs.ascratelast6m;
|
return prefs.ascratelast6m;
|
||||||
|
@ -476,24 +477,24 @@ int ascent_velocity(int depth, int avg_depth, int)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void track_ascent_gas(int depth, struct dive *dive, int cylinder_id, int avg_depth, int bottom_time, bool safety_stop, enum divemode_t divemode)
|
static void track_ascent_gas(depth_t depth, struct dive *dive, int cylinder_id, int avg_depth, int bottom_time, bool safety_stop, enum divemode_t divemode)
|
||||||
{
|
{
|
||||||
cylinder_t *cylinder = dive->get_cylinder(cylinder_id);
|
cylinder_t *cylinder = dive->get_cylinder(cylinder_id);
|
||||||
while (depth > 0) {
|
while (depth.mm > 0) {
|
||||||
int deltad = ascent_velocity(depth, avg_depth, bottom_time) * base_timestep;
|
int deltad = ascent_velocity(depth, avg_depth, bottom_time) * base_timestep;
|
||||||
if (deltad > depth)
|
if (deltad > depth.mm)
|
||||||
deltad = depth;
|
deltad = depth.mm;
|
||||||
update_cylinder_pressure(dive, depth, depth - deltad, base_timestep, prefs.decosac, cylinder, true, divemode);
|
update_cylinder_pressure(dive, depth.mm, depth.mm - deltad, base_timestep, prefs.decosac, cylinder, true, divemode);
|
||||||
if (depth <= 5000 && depth >= (5000 - deltad) && safety_stop) {
|
if (depth.mm <= 5000 && depth.mm >= (5000 - deltad) && safety_stop) {
|
||||||
update_cylinder_pressure(dive, 5000, 5000, 180, prefs.decosac, cylinder, true, divemode);
|
update_cylinder_pressure(dive, 5000, 5000, 180, prefs.decosac, cylinder, true, divemode);
|
||||||
safety_stop = false;
|
safety_stop = false;
|
||||||
}
|
}
|
||||||
depth -= deltad;
|
depth.mm -= deltad;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine whether ascending to the next stop will break the ceiling. Return true if the ascent is ok, false if it isn't.
|
// Determine whether ascending to the next stop will break the ceiling. Return true if the ascent is ok, false if it isn't.
|
||||||
static bool trial_ascent(struct deco_state *ds, int wait_time, int trial_depth, int stoplevel, int avg_depth, int bottom_time, struct gasmix gasmix, int po2, double surface_pressure, struct dive *dive, enum divemode_t divemode)
|
static bool trial_ascent(struct deco_state *ds, int wait_time, depth_t trial_depth, depth_t stoplevel, int avg_depth, int bottom_time, struct gasmix gasmix, int po2, double surface_pressure, struct dive *dive, enum divemode_t divemode)
|
||||||
{
|
{
|
||||||
|
|
||||||
bool clear_to_ascend = true;
|
bool clear_to_ascend = true;
|
||||||
|
@ -510,29 +511,29 @@ static bool trial_ascent(struct deco_state *ds, int wait_time, int trial_depth,
|
||||||
if (decoMode(true) == VPMB) {
|
if (decoMode(true) == VPMB) {
|
||||||
double tolerance_limit = tissue_tolerance_calc(ds, dive, dive->depth_to_bar(stoplevel), true);
|
double tolerance_limit = tissue_tolerance_calc(ds, dive, dive->depth_to_bar(stoplevel), true);
|
||||||
update_regression(ds, dive);
|
update_regression(ds, dive);
|
||||||
if (deco_allowed_depth(tolerance_limit, surface_pressure, dive, 1) > stoplevel) {
|
if (deco_allowed_depth(tolerance_limit, surface_pressure, dive, 1).mm > stoplevel.mm) {
|
||||||
trial_cache.restore(ds, false);
|
trial_cache.restore(ds, false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (trial_depth > stoplevel) {
|
while (trial_depth.mm > stoplevel.mm) {
|
||||||
double tolerance_limit;
|
double tolerance_limit;
|
||||||
int deltad = ascent_velocity(trial_depth, avg_depth, bottom_time) * base_timestep;
|
int deltad = ascent_velocity(trial_depth, avg_depth, bottom_time) * base_timestep;
|
||||||
if (deltad > trial_depth) /* don't test against depth above surface */
|
if (deltad > trial_depth.mm) /* don't test against depth above surface */
|
||||||
deltad = trial_depth;
|
deltad = trial_depth.mm;
|
||||||
add_segment(ds, dive->depth_to_bar(trial_depth),
|
add_segment(ds, dive->depth_to_bar(trial_depth),
|
||||||
gasmix,
|
gasmix,
|
||||||
base_timestep, po2, divemode, prefs.decosac, true);
|
base_timestep, po2, divemode, prefs.decosac, true);
|
||||||
tolerance_limit = tissue_tolerance_calc(ds, dive, dive->depth_to_bar(trial_depth), true);
|
tolerance_limit = tissue_tolerance_calc(ds, dive, dive->depth_to_bar(trial_depth), true);
|
||||||
if (decoMode(true) == VPMB)
|
if (decoMode(true) == VPMB)
|
||||||
update_regression(ds, dive);
|
update_regression(ds, dive);
|
||||||
if (deco_allowed_depth(tolerance_limit, surface_pressure, dive, 1) > trial_depth - deltad) {
|
if (deco_allowed_depth(tolerance_limit, surface_pressure, dive, 1).mm > trial_depth.mm - deltad) {
|
||||||
/* We should have stopped */
|
/* We should have stopped */
|
||||||
clear_to_ascend = false;
|
clear_to_ascend = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
trial_depth -= deltad;
|
trial_depth.mm -= deltad;
|
||||||
}
|
}
|
||||||
trial_cache.restore(ds, false);
|
trial_cache.restore(ds, false);
|
||||||
return clear_to_ascend;
|
return clear_to_ascend;
|
||||||
|
@ -561,7 +562,7 @@ static bool enough_gas(const struct dive *dive, int current_cylinder)
|
||||||
* leap is a guess for the maximum but there is no guarantee that leap is an upper limit.
|
* leap is a guess for the maximum but there is no guarantee that leap is an upper limit.
|
||||||
* So we always test at the upper bundary, not in the middle!
|
* So we always test at the upper bundary, not in the middle!
|
||||||
*/
|
*/
|
||||||
static int wait_until(struct deco_state *ds, struct dive *dive, int clock, int min, int leap, int stepsize, int depth, int target_depth, int avg_depth, int bottom_time, struct gasmix gasmix, int po2, double surface_pressure, enum divemode_t divemode)
|
static int wait_until(struct deco_state *ds, struct dive *dive, int clock, int min, int leap, int stepsize, depth_t depth, depth_t target_depth, int avg_depth, int bottom_time, struct gasmix gasmix, int po2, double surface_pressure, enum divemode_t divemode)
|
||||||
{
|
{
|
||||||
// When a deco stop exceeds two days, there is something wrong...
|
// When a deco stop exceeds two days, there is something wrong...
|
||||||
if (min >= 48 * 3600)
|
if (min >= 48 * 3600)
|
||||||
|
@ -605,7 +606,6 @@ static void average_max_depth(const struct diveplan &dive, int *avg_depth, int *
|
||||||
std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, struct dive *dive, int dcNr, int timestep, deco_state_cache &cache, bool is_planner, bool show_disclaimer)
|
std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, struct dive *dive, int dcNr, int timestep, deco_state_cache &cache, bool is_planner, bool show_disclaimer)
|
||||||
{
|
{
|
||||||
|
|
||||||
int bottom_depth;
|
|
||||||
int bottom_gi;
|
int bottom_gi;
|
||||||
int bottom_stopidx;
|
int bottom_stopidx;
|
||||||
bool is_final_plan = true;
|
bool is_final_plan = true;
|
||||||
|
@ -616,10 +616,6 @@ std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, str
|
||||||
int transitiontime, gi;
|
int transitiontime, gi;
|
||||||
int current_cylinder, stop_cylinder;
|
int current_cylinder, stop_cylinder;
|
||||||
size_t stopidx;
|
size_t stopidx;
|
||||||
int depth;
|
|
||||||
int *decostoplevels;
|
|
||||||
size_t decostoplevelcount;
|
|
||||||
std::vector<int> stoplevels;
|
|
||||||
bool stopping = false;
|
bool stopping = false;
|
||||||
bool pendinggaschange = false;
|
bool pendinggaschange = false;
|
||||||
int clock, previous_point_time;
|
int clock, previous_point_time;
|
||||||
|
@ -631,7 +627,7 @@ std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, str
|
||||||
int break_cylinder = -1, breakfrom_cylinder = 0;
|
int break_cylinder = -1, breakfrom_cylinder = 0;
|
||||||
bool last_segment_min_switch = false;
|
bool last_segment_min_switch = false;
|
||||||
planner_error_t error = PLAN_OK;
|
planner_error_t error = PLAN_OK;
|
||||||
int first_stop_depth = 0;
|
depth_t first_stop_depth;
|
||||||
int laststoptime = timestep;
|
int laststoptime = timestep;
|
||||||
bool o2breaking = false;
|
bool o2breaking = false;
|
||||||
struct divecomputer *dc = dive->get_dc(dcNr);
|
struct divecomputer *dc = dive->get_dc(dcNr);
|
||||||
|
@ -656,22 +652,17 @@ std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, str
|
||||||
create_dive_from_plan(diveplan, dive, dc, is_planner);
|
create_dive_from_plan(diveplan, dive, dc, is_planner);
|
||||||
|
|
||||||
// Do we want deco stop array in metres or feet?
|
// Do we want deco stop array in metres or feet?
|
||||||
if (prefs.units.length == units::METERS ) {
|
auto &decostoplevels = prefs.units.length == units::METERS ?
|
||||||
decostoplevels = decostoplevels_metric;
|
decostoplevels_metric : decostoplevels_imperial;
|
||||||
decostoplevelcount = std::size(decostoplevels_metric);
|
|
||||||
} else {
|
|
||||||
decostoplevels = decostoplevels_imperial;
|
|
||||||
decostoplevelcount = std::size(decostoplevels_imperial);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If the user has selected last stop to be at 6m/20', we need to get rid of the 3m/10' stop.
|
/* If the user has selected last stop to be at 6m/20', we need to get rid of the 3m/10' stop.
|
||||||
* Otherwise reinstate the last stop 3m/10' stop.
|
* Otherwise reinstate the last stop 3m/10' stop.
|
||||||
* Remark: not reentrant, but the user probably won't change preferences while this is running.
|
* Remark: not reentrant, but the user probably won't change preferences while this is running.
|
||||||
*/
|
*/
|
||||||
if (prefs.last_stop)
|
if (prefs.last_stop)
|
||||||
*(decostoplevels + 1) = 0;
|
decostoplevels[1].mm = 0;
|
||||||
else
|
else
|
||||||
*(decostoplevels + 1) = M_OR_FT(3,10);
|
decostoplevels[1].mm = M_OR_FT(3,10);
|
||||||
|
|
||||||
/* Let's start at the last 'sample', i.e. the last manually entered waypoint. */
|
/* Let's start at the last 'sample', i.e. the last manually entered waypoint. */
|
||||||
const struct sample &sample = dc->samples.back();
|
const struct sample &sample = dc->samples.back();
|
||||||
|
@ -686,7 +677,7 @@ std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, str
|
||||||
gas = dive->get_cylinder(current_cylinder)->gasmix;
|
gas = dive->get_cylinder(current_cylinder)->gasmix;
|
||||||
|
|
||||||
po2 = sample.setpoint.mbar;
|
po2 = sample.setpoint.mbar;
|
||||||
depth = sample.depth.mm;
|
depth_t depth = sample.depth;
|
||||||
average_max_depth(diveplan, &avg_depth, &max_depth);
|
average_max_depth(diveplan, &avg_depth, &max_depth);
|
||||||
last_ascend_rate = ascent_velocity(depth, avg_depth, bottom_time);
|
last_ascend_rate = ascent_velocity(depth, avg_depth, bottom_time);
|
||||||
|
|
||||||
|
@ -695,7 +686,7 @@ std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, str
|
||||||
/* Attn: for manually entered dives, we depend on the last segment having the
|
/* Attn: for manually entered dives, we depend on the last segment having the
|
||||||
* same ascent rate as in fake_dc(). If you change it here, also change it there.
|
* same ascent rate as in fake_dc(). If you change it here, also change it there.
|
||||||
*/
|
*/
|
||||||
transitiontime = lrint(depth / (double)prefs.ascratelast6m);
|
transitiontime = lrint(depth.mm / (double)prefs.ascratelast6m);
|
||||||
plan_add_segment(diveplan, transitiontime, 0, current_cylinder, po2, false, divemode);
|
plan_add_segment(diveplan, transitiontime, 0, current_cylinder, po2, false, divemode);
|
||||||
create_dive_from_plan(diveplan, dive, dc, is_planner);
|
create_dive_from_plan(diveplan, dive, dc, is_planner);
|
||||||
return {};
|
return {};
|
||||||
|
@ -703,26 +694,26 @@ std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, str
|
||||||
|
|
||||||
#if DEBUG_PLAN & 4
|
#if DEBUG_PLAN & 4
|
||||||
printf("gas %s\n", gas.name().c_str());
|
printf("gas %s\n", gas.name().c_str());
|
||||||
printf("depth %5.2lfm \n", depth / 1000.0);
|
printf("depth %5.2lfm \n", depth.mm / 1000.0);
|
||||||
printf("current_cylinder %i\n", current_cylinder);
|
printf("current_cylinder %i\n", current_cylinder);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Find the gases available for deco */
|
/* Find the gases available for deco */
|
||||||
|
|
||||||
bool inappropriate_cylinder_use = false;
|
bool inappropriate_cylinder_use = false;
|
||||||
std::vector<gaschanges> gaschanges = analyze_gaslist(diveplan, dive, dcNr, depth, &best_first_ascend_cylinder, divemode == CCR && !prefs.dobailout, inappropriate_cylinder_use);
|
std::vector<gaschanges> gaschanges = analyze_gaslist(diveplan, dive, dcNr, depth.mm, &best_first_ascend_cylinder, divemode == CCR && !prefs.dobailout, inappropriate_cylinder_use);
|
||||||
if (inappropriate_cylinder_use) {
|
if (inappropriate_cylinder_use) {
|
||||||
error = PLAN_ERROR_INAPPROPRIATE_GAS;
|
error = PLAN_ERROR_INAPPROPRIATE_GAS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the first potential decostopdepth above current depth */
|
/* Find the first potential decostopdepth above current depth */
|
||||||
for (stopidx = 0; stopidx < decostoplevelcount; stopidx++)
|
for (stopidx = 0; stopidx < decostoplevels.size(); stopidx++)
|
||||||
if (decostoplevels[stopidx] > depth)
|
if (decostoplevels[stopidx].mm > depth.mm)
|
||||||
break;
|
break;
|
||||||
if (stopidx > 0)
|
if (stopidx > 0)
|
||||||
stopidx--;
|
stopidx--;
|
||||||
/* Stoplevels are either depths of gas changes or potential deco stop depths. */
|
/* Stoplevels are either depths of gas changes or potential deco stop depths. */
|
||||||
stoplevels = sort_stops(decostoplevels, stopidx + 1, gaschanges);
|
std::vector<depth_t> stoplevels = sort_stops(decostoplevels, stopidx + 1, gaschanges);
|
||||||
stopidx += gaschanges.size();
|
stopidx += gaschanges.size();
|
||||||
|
|
||||||
gi = static_cast<int>(gaschanges.size()) - 1;
|
gi = static_cast<int>(gaschanges.size()) - 1;
|
||||||
|
@ -739,9 +730,9 @@ std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, str
|
||||||
add_segment(ds, dive->depth_to_bar(depth),
|
add_segment(ds, dive->depth_to_bar(depth),
|
||||||
dive->get_cylinder(current_cylinder)->gasmix,
|
dive->get_cylinder(current_cylinder)->gasmix,
|
||||||
timestep, po2, divemode, prefs.bottomsac, true);
|
timestep, po2, divemode, prefs.bottomsac, true);
|
||||||
update_cylinder_pressure(dive, depth, depth, timestep, prefs.bottomsac, dive->get_cylinder(current_cylinder), false, divemode);
|
update_cylinder_pressure(dive, depth.mm, depth.mm, timestep, prefs.bottomsac, dive->get_cylinder(current_cylinder), false, divemode);
|
||||||
clock += timestep;
|
clock += timestep;
|
||||||
} while (trial_ascent(ds, 0, depth, 0, avg_depth, bottom_time, dive->get_cylinder(current_cylinder)->gasmix,
|
} while (trial_ascent(ds, 0, depth, 0_m, avg_depth, bottom_time, dive->get_cylinder(current_cylinder)->gasmix,
|
||||||
po2, diveplan.surface_pressure.mbar / 1000.0, dive, divemode) &&
|
po2, diveplan.surface_pressure.mbar / 1000.0, dive, divemode) &&
|
||||||
enough_gas(dive, current_cylinder) && clock < 6 * 3600);
|
enough_gas(dive, current_cylinder) && clock < 6 * 3600);
|
||||||
|
|
||||||
|
@ -749,24 +740,24 @@ std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, str
|
||||||
// In the best of all worlds, we would roll back also the last add_segment in terms of caching deco state, but
|
// In the best of all worlds, we would roll back also the last add_segment in terms of caching deco state, but
|
||||||
// let's ignore that since for the eventual ascent in recreational mode, nobody looks at the ceiling anymore,
|
// let's ignore that since for the eventual ascent in recreational mode, nobody looks at the ceiling anymore,
|
||||||
// so we don't really have to compute the deco state.
|
// so we don't really have to compute the deco state.
|
||||||
update_cylinder_pressure(dive, depth, depth, -timestep, prefs.bottomsac, dive->get_cylinder(current_cylinder), false, divemode);
|
update_cylinder_pressure(dive, depth.mm, depth.mm, -timestep, prefs.bottomsac, dive->get_cylinder(current_cylinder), false, divemode);
|
||||||
clock -= timestep;
|
clock -= timestep;
|
||||||
plan_add_segment(diveplan, clock - previous_point_time, depth, current_cylinder, po2, true, divemode);
|
plan_add_segment(diveplan, clock - previous_point_time, depth.mm, current_cylinder, po2, true, divemode);
|
||||||
previous_point_time = clock;
|
previous_point_time = clock;
|
||||||
do {
|
do {
|
||||||
/* Ascend to surface */
|
/* Ascend to surface */
|
||||||
int deltad = ascent_velocity(depth, avg_depth, bottom_time) * base_timestep;
|
int deltad = ascent_velocity(depth, avg_depth, bottom_time) * base_timestep;
|
||||||
if (ascent_velocity(depth, avg_depth, bottom_time) != last_ascend_rate) {
|
if (ascent_velocity(depth, avg_depth, bottom_time) != last_ascend_rate) {
|
||||||
plan_add_segment(diveplan, clock - previous_point_time, depth, current_cylinder, po2, false, divemode);
|
plan_add_segment(diveplan, clock - previous_point_time, depth.mm, current_cylinder, po2, false, divemode);
|
||||||
previous_point_time = clock;
|
previous_point_time = clock;
|
||||||
last_ascend_rate = ascent_velocity(depth, avg_depth, bottom_time);
|
last_ascend_rate = ascent_velocity(depth, avg_depth, bottom_time);
|
||||||
}
|
}
|
||||||
if (depth - deltad < 0)
|
if (depth.mm - deltad < 0)
|
||||||
deltad = depth;
|
deltad = depth.mm;
|
||||||
|
|
||||||
clock += base_timestep;
|
clock += base_timestep;
|
||||||
depth -= deltad;
|
depth.mm -= deltad;
|
||||||
if (depth <= 5000 && depth >= (5000 - deltad) && safety_stop) {
|
if (depth.mm <= 5000 && depth.mm >= (5000 - deltad) && safety_stop) {
|
||||||
plan_add_segment(diveplan, clock - previous_point_time, 5000, current_cylinder, po2, false, divemode);
|
plan_add_segment(diveplan, clock - previous_point_time, 5000, current_cylinder, po2, false, divemode);
|
||||||
previous_point_time = clock;
|
previous_point_time = clock;
|
||||||
clock += 180;
|
clock += 180;
|
||||||
|
@ -774,7 +765,7 @@ std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, str
|
||||||
previous_point_time = clock;
|
previous_point_time = clock;
|
||||||
safety_stop = false;
|
safety_stop = false;
|
||||||
}
|
}
|
||||||
} while (depth > 0);
|
} while (depth.mm > 0);
|
||||||
plan_add_segment(diveplan, clock - previous_point_time, 0, current_cylinder, po2, false, divemode);
|
plan_add_segment(diveplan, clock - previous_point_time, 0, current_cylinder, po2, false, divemode);
|
||||||
create_dive_from_plan(diveplan, dive, dc, is_planner);
|
create_dive_from_plan(diveplan, dive, dc, is_planner);
|
||||||
diveplan.add_plan_to_notes(*dive, show_disclaimer, error);
|
diveplan.add_plan_to_notes(*dive, show_disclaimer, error);
|
||||||
|
@ -789,7 +780,7 @@ std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, str
|
||||||
|
|
||||||
#if DEBUG_PLAN & 16
|
#if DEBUG_PLAN & 16
|
||||||
printf("switch to gas %d (%d/%d) @ %5.2lfm\n", best_first_ascend_cylinder,
|
printf("switch to gas %d (%d/%d) @ %5.2lfm\n", best_first_ascend_cylinder,
|
||||||
(get_o2(&gas) + 5) / 10, (get_he(&gas) + 5) / 10, gaschanges[best_first_ascend_cylinder].depth / 1000.0);
|
(get_o2(&gas) + 5) / 10, (get_he(&gas) + 5) / 10, gaschanges[best_first_ascend_cylinder].depth.mm / 1000.0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -802,13 +793,13 @@ std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, str
|
||||||
add_segment(ds, dive->depth_to_bar(depth),
|
add_segment(ds, dive->depth_to_bar(depth),
|
||||||
dive->get_cylinder(current_cylinder)->gasmix,
|
dive->get_cylinder(current_cylinder)->gasmix,
|
||||||
bailoutsegment, po2, divemode, prefs.bottomsac, true);
|
bailoutsegment, po2, divemode, prefs.bottomsac, true);
|
||||||
plan_add_segment(diveplan, bailoutsegment, depth, current_cylinder, po2, false, divemode);
|
plan_add_segment(diveplan, bailoutsegment, depth.mm, current_cylinder, po2, false, divemode);
|
||||||
bottom_time += bailoutsegment;
|
bottom_time += bailoutsegment;
|
||||||
}
|
}
|
||||||
previous_deco_time = 100000000;
|
previous_deco_time = 100000000;
|
||||||
ds->deco_time = 10000000;
|
ds->deco_time = 10000000;
|
||||||
bottom_cache.cache(ds); // Lets us make several iterations
|
bottom_cache.cache(ds); // Lets us make several iterations
|
||||||
bottom_depth = depth;
|
depth_t bottom_depth = depth;
|
||||||
bottom_gi = gi;
|
bottom_gi = gi;
|
||||||
bottom_gas = gas;
|
bottom_gas = gas;
|
||||||
bottom_stopidx = stopidx;
|
bottom_stopidx = stopidx;
|
||||||
|
@ -830,7 +821,7 @@ std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, str
|
||||||
gas = bottom_gas;
|
gas = bottom_gas;
|
||||||
stopping = false;
|
stopping = false;
|
||||||
bool decodive = false;
|
bool decodive = false;
|
||||||
first_stop_depth = 0;
|
first_stop_depth = 0_m;
|
||||||
stopidx = bottom_stopidx;
|
stopidx = bottom_stopidx;
|
||||||
ds->first_ceiling_pressure.mbar = dive->depth_to_mbar(
|
ds->first_ceiling_pressure.mbar = dive->depth_to_mbar(
|
||||||
deco_allowed_depth(tissue_tolerance_calc(ds, dive, dive->depth_to_bar(depth), true),
|
deco_allowed_depth(tissue_tolerance_calc(ds, dive, dive->depth_to_bar(depth), true),
|
||||||
|
@ -854,15 +845,15 @@ std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, str
|
||||||
/* We will break out when we hit the surface */
|
/* We will break out when we hit the surface */
|
||||||
do {
|
do {
|
||||||
/* Ascend to next stop depth */
|
/* Ascend to next stop depth */
|
||||||
int deltad = ascent_velocity(depth, avg_depth, bottom_time) * base_timestep;
|
depth_t deltad { .mm = ascent_velocity(depth, avg_depth, bottom_time) * base_timestep };
|
||||||
if (ascent_velocity(depth, avg_depth, bottom_time) != last_ascend_rate) {
|
if (ascent_velocity(depth, avg_depth, bottom_time) != last_ascend_rate) {
|
||||||
if (is_final_plan)
|
if (is_final_plan)
|
||||||
plan_add_segment(diveplan, clock - previous_point_time, depth, current_cylinder, po2, false, divemode);
|
plan_add_segment(diveplan, clock - previous_point_time, depth.mm, current_cylinder, po2, false, divemode);
|
||||||
previous_point_time = clock;
|
previous_point_time = clock;
|
||||||
stopping = false;
|
stopping = false;
|
||||||
last_ascend_rate = ascent_velocity(depth, avg_depth, bottom_time);
|
last_ascend_rate = ascent_velocity(depth, avg_depth, bottom_time);
|
||||||
}
|
}
|
||||||
if (depth - deltad < stoplevels[stopidx])
|
if (depth.mm - deltad.mm < stoplevels[stopidx].mm)
|
||||||
deltad = depth - stoplevels[stopidx];
|
deltad = depth - stoplevels[stopidx];
|
||||||
|
|
||||||
add_segment(ds, dive->depth_to_bar(depth),
|
add_segment(ds, dive->depth_to_bar(depth),
|
||||||
|
@ -873,13 +864,13 @@ std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, str
|
||||||
depth -= deltad;
|
depth -= deltad;
|
||||||
/* Print VPM-Gradient as gradient factor, this has to be done from within deco.cpp */
|
/* Print VPM-Gradient as gradient factor, this has to be done from within deco.cpp */
|
||||||
if (decodive)
|
if (decodive)
|
||||||
ds->plot_depth = depth;
|
ds->plot_depth = depth.mm;
|
||||||
} while (depth > 0 && depth > stoplevels[stopidx]);
|
} while (depth.mm > 0 && depth.mm > stoplevels[stopidx].mm);
|
||||||
|
|
||||||
if (depth <= 0)
|
if (depth.mm <= 0)
|
||||||
break; /* We are at the surface */
|
break; /* We are at the surface */
|
||||||
|
|
||||||
if (gi >= 0 && stoplevels[stopidx] <= gaschanges[gi].depth) {
|
if (gi >= 0 && stoplevels[stopidx].mm <= gaschanges[gi].depth) {
|
||||||
/* We have reached a gas change.
|
/* We have reached a gas change.
|
||||||
* Record this in the dive plan */
|
* Record this in the dive plan */
|
||||||
|
|
||||||
|
@ -893,7 +884,7 @@ std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, str
|
||||||
!trial_ascent(ds, 0, depth, stoplevels[stopidx - 1], avg_depth, bottom_time,
|
!trial_ascent(ds, 0, depth, stoplevels[stopidx - 1], avg_depth, bottom_time,
|
||||||
dive->get_cylinder(current_cylinder)->gasmix, po2, diveplan.surface_pressure.mbar / 1000.0, dive, divemode) || get_o2(dive->get_cylinder(current_cylinder)->gasmix) < 160) {
|
dive->get_cylinder(current_cylinder)->gasmix, po2, diveplan.surface_pressure.mbar / 1000.0, dive, divemode) || get_o2(dive->get_cylinder(current_cylinder)->gasmix) < 160) {
|
||||||
if (is_final_plan)
|
if (is_final_plan)
|
||||||
plan_add_segment(diveplan, clock - previous_point_time, depth, current_cylinder, po2, false, divemode);
|
plan_add_segment(diveplan, clock - previous_point_time, depth.mm, current_cylinder, po2, false, divemode);
|
||||||
stopping = true;
|
stopping = true;
|
||||||
previous_point_time = clock;
|
previous_point_time = clock;
|
||||||
current_cylinder = gaschanges[gi].gasidx;
|
current_cylinder = gaschanges[gi].gasidx;
|
||||||
|
@ -928,7 +919,7 @@ std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, str
|
||||||
/* Check if ascending to next stop is clear, 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 */
|
||||||
if (trial_ascent(ds, 0, depth, stoplevels[stopidx], avg_depth, bottom_time,
|
if (trial_ascent(ds, 0, depth, stoplevels[stopidx], avg_depth, bottom_time,
|
||||||
dive->get_cylinder(current_cylinder)->gasmix, po2, diveplan.surface_pressure.mbar / 1000.0, dive, divemode)) {
|
dive->get_cylinder(current_cylinder)->gasmix, po2, diveplan.surface_pressure.mbar / 1000.0, dive, divemode)) {
|
||||||
decostoptable.push_back( decostop { depth, 0 });
|
decostoptable.push_back( decostop { depth.mm, 0 });
|
||||||
break; /* We did not hit the ceiling */
|
break; /* We did not hit the ceiling */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -941,7 +932,7 @@ std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, str
|
||||||
/* The last segment was an ascend segment.
|
/* The last segment was an ascend segment.
|
||||||
* Add a waypoint for start of this deco stop */
|
* Add a waypoint for start of this deco stop */
|
||||||
if (is_final_plan)
|
if (is_final_plan)
|
||||||
plan_add_segment(diveplan, clock - previous_point_time, depth, current_cylinder, po2, false, divemode);
|
plan_add_segment(diveplan, clock - previous_point_time, depth.mm, current_cylinder, po2, false, divemode);
|
||||||
previous_point_time = clock;
|
previous_point_time = clock;
|
||||||
stopping = true;
|
stopping = true;
|
||||||
}
|
}
|
||||||
|
@ -972,7 +963,7 @@ std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, str
|
||||||
bottom_time, dive->get_cylinder(current_cylinder)->gasmix, po2, diveplan.surface_pressure.mbar / 1000.0, divemode);
|
bottom_time, dive->get_cylinder(current_cylinder)->gasmix, po2, diveplan.surface_pressure.mbar / 1000.0, divemode);
|
||||||
laststoptime = new_clock - clock;
|
laststoptime = new_clock - clock;
|
||||||
/* Finish infinite deco */
|
/* Finish infinite deco */
|
||||||
if (laststoptime >= 48 * 3600 && depth >= 6000) {
|
if (laststoptime >= 48 * 3600 && depth.mm >= 6000) {
|
||||||
error = PLAN_ERROR_TIMEOUT;
|
error = PLAN_ERROR_TIMEOUT;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -998,7 +989,7 @@ std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, str
|
||||||
o2break_next = true;
|
o2break_next = true;
|
||||||
breakfrom_cylinder = current_cylinder;
|
breakfrom_cylinder = current_cylinder;
|
||||||
if (is_final_plan)
|
if (is_final_plan)
|
||||||
plan_add_segment(diveplan, laststoptime, depth, current_cylinder, po2, false, divemode);
|
plan_add_segment(diveplan, laststoptime, depth.mm, current_cylinder, po2, false, divemode);
|
||||||
previous_point_time = clock + laststoptime;
|
previous_point_time = clock + laststoptime;
|
||||||
current_cylinder = break_cylinder;
|
current_cylinder = break_cylinder;
|
||||||
}
|
}
|
||||||
|
@ -1009,7 +1000,7 @@ std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, str
|
||||||
o2breaking = true;
|
o2breaking = true;
|
||||||
o2break_next = false;
|
o2break_next = false;
|
||||||
if (is_final_plan)
|
if (is_final_plan)
|
||||||
plan_add_segment(diveplan, laststoptime, depth, current_cylinder, po2, false, divemode);
|
plan_add_segment(diveplan, laststoptime, depth.mm, current_cylinder, po2, false, divemode);
|
||||||
previous_point_time = clock + laststoptime;
|
previous_point_time = clock + laststoptime;
|
||||||
current_cylinder = breakfrom_cylinder;
|
current_cylinder = breakfrom_cylinder;
|
||||||
}
|
}
|
||||||
|
@ -1018,7 +1009,7 @@ std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, str
|
||||||
add_segment(ds, dive->depth_to_bar(depth), dive->get_cylinder(stop_cylinder)->gasmix,
|
add_segment(ds, dive->depth_to_bar(depth), dive->get_cylinder(stop_cylinder)->gasmix,
|
||||||
laststoptime, po2, divemode, prefs.decosac, true);
|
laststoptime, po2, divemode, prefs.decosac, true);
|
||||||
last_segment_min_switch = false;
|
last_segment_min_switch = false;
|
||||||
decostoptable.push_back(decostop { depth, laststoptime } );
|
decostoptable.push_back(decostop { depth.mm, laststoptime } );
|
||||||
|
|
||||||
clock += laststoptime;
|
clock += laststoptime;
|
||||||
if (!o2breaking)
|
if (!o2breaking)
|
||||||
|
@ -1027,7 +1018,7 @@ std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, str
|
||||||
if (stopping) {
|
if (stopping) {
|
||||||
/* Next we will ascend again. Add a waypoint if we have spend deco time */
|
/* Next we will ascend again. Add a waypoint if we have spend deco time */
|
||||||
if (is_final_plan)
|
if (is_final_plan)
|
||||||
plan_add_segment(diveplan, clock - previous_point_time, depth, current_cylinder, po2, false, divemode);
|
plan_add_segment(diveplan, clock - previous_point_time, depth.mm, current_cylinder, po2, false, divemode);
|
||||||
previous_point_time = clock;
|
previous_point_time = clock;
|
||||||
stopping = false;
|
stopping = false;
|
||||||
}
|
}
|
||||||
|
@ -1042,7 +1033,7 @@ std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, str
|
||||||
plan_add_segment(diveplan, clock - previous_point_time, 0, current_cylinder, po2, false, divemode);
|
plan_add_segment(diveplan, clock - previous_point_time, 0, current_cylinder, po2, false, divemode);
|
||||||
if (decoMode(true) == VPMB) {
|
if (decoMode(true) == VPMB) {
|
||||||
diveplan.eff_gfhigh = lrint(100.0 * regressionb(ds));
|
diveplan.eff_gfhigh = lrint(100.0 * regressionb(ds));
|
||||||
diveplan.eff_gflow = lrint(100.0 * (regressiona(ds) * first_stop_depth + regressionb(ds)));
|
diveplan.eff_gflow = lrint(100.0 * (regressiona(ds) * first_stop_depth.mm + regressionb(ds)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prefs.surface_segment != 0) {
|
if (prefs.surface_segment != 0) {
|
||||||
|
|
|
@ -58,6 +58,7 @@ struct diveplan {
|
||||||
struct deco_state_cache;
|
struct deco_state_cache;
|
||||||
|
|
||||||
extern int get_cylinderid_at_time(struct dive *dive, struct divecomputer *dc, duration_t time);
|
extern int get_cylinderid_at_time(struct dive *dive, struct divecomputer *dc, duration_t time);
|
||||||
|
extern int ascent_velocity(depth_t depth, int avg_depth, int);
|
||||||
extern const char *get_planner_disclaimer();
|
extern const char *get_planner_disclaimer();
|
||||||
|
|
||||||
void plan_add_segment(struct diveplan &diveplan, int duration, int depth, int cylinderid, int po2, bool entered, enum divemode_t divemode);
|
void plan_add_segment(struct diveplan &diveplan, int duration, int depth, int cylinderid, int po2, bool entered, enum divemode_t divemode);
|
||||||
|
|
|
@ -346,7 +346,7 @@ void diveplan::add_plan_to_notes(struct dive &dive, bool show_disclaimer, planne
|
||||||
if (isobaric_counterdiffusion(lastprintgasmix, newgasmix, &icdvalues)) // Do icd calulations
|
if (isobaric_counterdiffusion(lastprintgasmix, newgasmix, &icdvalues)) // Do icd calulations
|
||||||
icdwarning = true;
|
icdwarning = true;
|
||||||
if (icdvalues.dN2 > 0) { // If the gas change involved helium as well as an increase in nitrogen..
|
if (icdvalues.dN2 > 0) { // If the gas change involved helium as well as an increase in nitrogen..
|
||||||
icdbuf += icd_entry(&icdvalues, icdtableheader, dp->time, dive.depth_to_mbar(dp->depth.mm), lastprintgasmix, newgasmix); // .. then print calculations to buffer.
|
icdbuf += icd_entry(&icdvalues, icdtableheader, dp->time, dive.depth_to_mbar(dp->depth), lastprintgasmix, newgasmix); // .. then print calculations to buffer.
|
||||||
icdtableheader = false;
|
icdtableheader = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -367,7 +367,7 @@ void diveplan::add_plan_to_notes(struct dive &dive, bool show_disclaimer, planne
|
||||||
if (isobaric_counterdiffusion(lastprintgasmix, gasmix, &icdvalues)) // Do icd calculations
|
if (isobaric_counterdiffusion(lastprintgasmix, gasmix, &icdvalues)) // Do icd calculations
|
||||||
icdwarning = true;
|
icdwarning = true;
|
||||||
if (icdvalues.dN2 > 0) { // If the gas change involved helium as well as an increase in nitrogen..
|
if (icdvalues.dN2 > 0) { // If the gas change involved helium as well as an increase in nitrogen..
|
||||||
icdbuf += icd_entry(&icdvalues, icdtableheader, lasttime, dive.depth_to_mbar(dp->depth.mm), lastprintgasmix, gasmix); // .. then print data to buffer.
|
icdbuf += icd_entry(&icdvalues, icdtableheader, lasttime, dive.depth_to_mbar(dp->depth), lastprintgasmix, gasmix); // .. then print data to buffer.
|
||||||
icdtableheader = false;
|
icdtableheader = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -398,7 +398,7 @@ void diveplan::add_plan_to_notes(struct dive &dive, bool show_disclaimer, planne
|
||||||
if (isobaric_counterdiffusion(lastprintgasmix, newgasmix, &icdvalues)) // Do icd calculations
|
if (isobaric_counterdiffusion(lastprintgasmix, newgasmix, &icdvalues)) // Do icd calculations
|
||||||
icdwarning = true;
|
icdwarning = true;
|
||||||
if (icdvalues.dN2 > 0) { // If the gas change involved helium as well as an increase in nitrogen..
|
if (icdvalues.dN2 > 0) { // If the gas change involved helium as well as an increase in nitrogen..
|
||||||
icdbuf += icd_entry(&icdvalues, icdtableheader, dp->time, dive.depth_to_mbar(dp->depth.mm), lastprintgasmix, newgasmix); // ... then print data to buffer.
|
icdbuf += icd_entry(&icdvalues, icdtableheader, dp->time, dive.depth_to_mbar(dp->depth), lastprintgasmix, newgasmix); // ... then print data to buffer.
|
||||||
icdtableheader = false;
|
icdtableheader = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -510,7 +510,7 @@ void diveplan::add_plan_to_notes(struct dive &dive, bool show_disclaimer, planne
|
||||||
/* Calculate minimum gas volume. */
|
/* Calculate minimum gas volume. */
|
||||||
volume_t mingasv;
|
volume_t mingasv;
|
||||||
mingasv.mliter = lrint(prefs.sacfactor / 100.0 * prefs.problemsolvingtime * prefs.bottomsac
|
mingasv.mliter = lrint(prefs.sacfactor / 100.0 * prefs.problemsolvingtime * prefs.bottomsac
|
||||||
* dive.depth_to_bar(lastbottomdp->depth.mm)
|
* dive.depth_to_bar(lastbottomdp->depth)
|
||||||
+ prefs.sacfactor / 100.0 * cyl.deco_gas_used.mliter);
|
+ prefs.sacfactor / 100.0 * cyl.deco_gas_used.mliter);
|
||||||
/* Calculate minimum gas pressure for cyclinder. */
|
/* Calculate minimum gas pressure for cyclinder. */
|
||||||
lastbottomdp->minimum_gas.mbar = lrint(isothermal_pressure(cyl.gasmix, 1.0,
|
lastbottomdp->minimum_gas.mbar = lrint(isothermal_pressure(cyl.gasmix, 1.0,
|
||||||
|
@ -589,7 +589,7 @@ void diveplan::add_plan_to_notes(struct dive &dive, bool show_disclaimer, planne
|
||||||
struct gasmix gasmix = dive.get_cylinder(dp.cylinderid)->gasmix;
|
struct gasmix gasmix = dive.get_cylinder(dp.cylinderid)->gasmix;
|
||||||
|
|
||||||
divemode_t current_divemode = loop.at(dp.time);
|
divemode_t current_divemode = loop.at(dp.time);
|
||||||
amb = dive.depth_to_atm(dp.depth.mm);
|
amb = dive.depth_to_atm(dp.depth);
|
||||||
gas_pressures pressures = fill_pressures(amb, gasmix, (current_divemode == OC) ? 0.0 : amb * gasmix.o2.permille / 1000.0, current_divemode);
|
gas_pressures pressures = fill_pressures(amb, gasmix, (current_divemode == OC) ? 0.0 : amb * gasmix.o2.permille / 1000.0, current_divemode);
|
||||||
|
|
||||||
if (pressures.o2 > (dp.entered ? prefs.bottompo2 : prefs.decopo2) / 1000.0) {
|
if (pressures.o2 > (dp.entered ? prefs.bottompo2 : prefs.decopo2) / 1000.0) {
|
||||||
|
|
100
core/profile.cpp
100
core/profile.cpp
|
@ -17,6 +17,7 @@
|
||||||
#include "sample.h"
|
#include "sample.h"
|
||||||
#include "subsurface-string.h"
|
#include "subsurface-string.h"
|
||||||
|
|
||||||
|
#include "planner.h"
|
||||||
#include "profile.h"
|
#include "profile.h"
|
||||||
#include "gaspressures.h"
|
#include "gaspressures.h"
|
||||||
#include "deco.h"
|
#include "deco.h"
|
||||||
|
@ -32,7 +33,6 @@
|
||||||
|
|
||||||
#define MAX_PROFILE_DECO 7200
|
#define MAX_PROFILE_DECO 7200
|
||||||
|
|
||||||
int ascent_velocity(int depth, int avg_depth, int bottom_time);
|
|
||||||
|
|
||||||
#ifdef DEBUG_PI
|
#ifdef DEBUG_PI
|
||||||
/* debugging tool - not normally used */
|
/* debugging tool - not normally used */
|
||||||
|
@ -46,6 +46,7 @@ static void dump_pi(const struct plot_info &pi)
|
||||||
pi.maxpressure, pi.mintemp, pi.maxtemp);
|
pi.maxpressure, pi.mintemp, pi.maxtemp);
|
||||||
for (i = 0; i < pi.nr; i++) {
|
for (i = 0; i < pi.nr; i++) {
|
||||||
struct plot_data &entry = pi.entry[i];
|
struct plot_data &entry = pi.entry[i];
|
||||||
|
depth_t depth { .mm = entry.depth };
|
||||||
printf(" entry[%d]:{cylinderindex:%d sec:%d pressure:{%d,%d}\n"
|
printf(" entry[%d]:{cylinderindex:%d sec:%d pressure:{%d,%d}\n"
|
||||||
" time:%d:%02d temperature:%d depth:%d stopdepth:%d stoptime:%d ndl:%d smoothed:%d po2:%lf phe:%lf pn2:%lf sum-pp %lf}\n",
|
" time:%d:%02d temperature:%d depth:%d stopdepth:%d stoptime:%d ndl:%d smoothed:%d po2:%lf phe:%lf pn2:%lf sum-pp %lf}\n",
|
||||||
i, entry.sensor[0], entry.sec,
|
i, entry.sensor[0], entry.sec,
|
||||||
|
@ -111,7 +112,6 @@ static int get_local_sac(struct plot_info &pi, int idx1, int idx2, struct dive *
|
||||||
struct plot_data &entry1 = pi.entry[idx1];
|
struct plot_data &entry1 = pi.entry[idx1];
|
||||||
struct plot_data &entry2 = pi.entry[idx2];
|
struct plot_data &entry2 = pi.entry[idx2];
|
||||||
int duration = entry2.sec - entry1.sec;
|
int duration = entry2.sec - entry1.sec;
|
||||||
int depth;
|
|
||||||
pressure_t a, b;
|
pressure_t a, b;
|
||||||
double atm;
|
double atm;
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ static int get_local_sac(struct plot_info &pi, int idx1, int idx2, struct dive *
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Mean pressure in ATM */
|
/* Mean pressure in ATM */
|
||||||
depth = (entry1.depth + entry2.depth) / 2;
|
depth_t depth {.mm = (entry1.depth + entry2.depth) / 2 };
|
||||||
atm = dive->depth_to_atm(depth);
|
atm = dive->depth_to_atm(depth);
|
||||||
|
|
||||||
cyl = dive->get_cylinder(index);
|
cyl = dive->get_cylinder(index);
|
||||||
|
@ -492,7 +492,7 @@ static int sac_between(const struct dive *dive, const struct plot_info &pi, int
|
||||||
do {
|
do {
|
||||||
const struct plot_data &entry = pi.entry[first];
|
const struct plot_data &entry = pi.entry[first];
|
||||||
const struct plot_data &next = pi.entry[first + 1];
|
const struct plot_data &next = pi.entry[first + 1];
|
||||||
int depth = (entry.depth + next.depth) / 2;
|
depth_t depth { .mm = (entry.depth + next.depth) / 2 };
|
||||||
int time = next.sec - entry.sec;
|
int time = next.sec - entry.sec;
|
||||||
double atm = dive->depth_to_atm(depth);
|
double atm = dive->depth_to_atm(depth);
|
||||||
|
|
||||||
|
@ -766,10 +766,10 @@ static void calculate_ndl_tts(struct deco_state *ds, const struct dive *dive, st
|
||||||
const int time_stepsize = 60;
|
const int time_stepsize = 60;
|
||||||
const int deco_stepsize = M_OR_FT(3, 10);
|
const int deco_stepsize = M_OR_FT(3, 10);
|
||||||
/* at what depth is the current deco-step? */
|
/* at what depth is the current deco-step? */
|
||||||
|
depth_t ascent_depth { .mm = entry.depth };
|
||||||
int next_stop = round_up(deco_allowed_depth(
|
int next_stop = round_up(deco_allowed_depth(
|
||||||
tissue_tolerance_calc(ds, dive, dive->depth_to_bar(entry.depth), in_planner),
|
tissue_tolerance_calc(ds, dive, dive->depth_to_bar(ascent_depth), in_planner),
|
||||||
surface_pressure, dive, 1), deco_stepsize);
|
surface_pressure, dive, 1).mm, deco_stepsize);
|
||||||
int ascent_depth = entry.depth;
|
|
||||||
/* at what time should we give up and say that we got enuff NDL? */
|
/* at what time should we give up and say that we got enuff NDL? */
|
||||||
/* If iterating through a dive, entry.tts_calc needs to be reset */
|
/* If iterating through a dive, entry.tts_calc needs to be reset */
|
||||||
entry.tts_calc = 0;
|
entry.tts_calc = 0;
|
||||||
|
@ -783,11 +783,11 @@ static void calculate_ndl_tts(struct deco_state *ds, const struct dive *dive, st
|
||||||
}
|
}
|
||||||
/* stop if the ndl is above max_ndl seconds, and call it plenty of time */
|
/* stop if the ndl is above max_ndl seconds, and call it plenty of time */
|
||||||
while (entry.ndl_calc < MAX_PROFILE_DECO &&
|
while (entry.ndl_calc < MAX_PROFILE_DECO &&
|
||||||
deco_allowed_depth(tissue_tolerance_calc(ds, dive, dive->depth_to_bar(entry.depth), in_planner),
|
deco_allowed_depth(tissue_tolerance_calc(ds, dive, dive->depth_to_bar(ascent_depth), in_planner),
|
||||||
surface_pressure, dive, 1) <= 0
|
surface_pressure, dive, 1).mm <= 0
|
||||||
) {
|
) {
|
||||||
entry.ndl_calc += time_stepsize;
|
entry.ndl_calc += time_stepsize;
|
||||||
add_segment(ds, dive->depth_to_bar(entry.depth),
|
add_segment(ds, dive->depth_to_bar(ascent_depth),
|
||||||
gasmix, time_stepsize, entry.o2pressure.mbar, divemode, prefs.bottomsac, in_planner);
|
gasmix, time_stepsize, entry.o2pressure.mbar, divemode, prefs.bottomsac, in_planner);
|
||||||
}
|
}
|
||||||
/* we don't need to calculate anything else */
|
/* we don't need to calculate anything else */
|
||||||
|
@ -798,13 +798,13 @@ static void calculate_ndl_tts(struct deco_state *ds, const struct dive *dive, st
|
||||||
entry.in_deco_calc = true;
|
entry.in_deco_calc = true;
|
||||||
|
|
||||||
/* Add segments for movement to stopdepth */
|
/* Add segments for movement to stopdepth */
|
||||||
for (; ascent_depth > next_stop; ascent_depth -= ascent_s_per_step * ascent_velocity(ascent_depth, entry.running_sum / entry.sec, 0), entry.tts_calc += ascent_s_per_step) {
|
for (; ascent_depth.mm > next_stop; ascent_depth.mm -= ascent_s_per_step * ascent_velocity(ascent_depth, entry.running_sum / entry.sec, 0), entry.tts_calc += ascent_s_per_step) {
|
||||||
add_segment(ds, dive->depth_to_bar(ascent_depth),
|
add_segment(ds, dive->depth_to_bar(ascent_depth),
|
||||||
gasmix, ascent_s_per_step, entry.o2pressure.mbar, divemode, prefs.decosac, in_planner);
|
gasmix, ascent_s_per_step, entry.o2pressure.mbar, divemode, prefs.decosac, in_planner);
|
||||||
next_stop = round_up(deco_allowed_depth(tissue_tolerance_calc(ds, dive, dive->depth_to_bar(ascent_depth), in_planner),
|
next_stop = round_up(deco_allowed_depth(tissue_tolerance_calc(ds, dive, dive->depth_to_bar(ascent_depth), in_planner),
|
||||||
surface_pressure, dive, 1), deco_stepsize);
|
surface_pressure, dive, 1).mm, deco_stepsize);
|
||||||
}
|
}
|
||||||
ascent_depth = next_stop;
|
ascent_depth.mm = next_stop;
|
||||||
|
|
||||||
/* And how long is the current deco-step? */
|
/* And how long is the current deco-step? */
|
||||||
entry.stoptime_calc = 0;
|
entry.stoptime_calc = 0;
|
||||||
|
@ -814,7 +814,7 @@ static void calculate_ndl_tts(struct deco_state *ds, const struct dive *dive, st
|
||||||
/* And how long is the total TTS */
|
/* And how long is the total TTS */
|
||||||
while (next_stop >= 0) {
|
while (next_stop >= 0) {
|
||||||
/* save the time for the first stop to show in the graph */
|
/* save the time for the first stop to show in the graph */
|
||||||
if (ascent_depth == entry.stopdepth_calc)
|
if (ascent_depth.mm == entry.stopdepth_calc)
|
||||||
entry.stoptime_calc += time_stepsize;
|
entry.stoptime_calc += time_stepsize;
|
||||||
|
|
||||||
entry.tts_calc += time_stepsize;
|
entry.tts_calc += time_stepsize;
|
||||||
|
@ -823,12 +823,12 @@ static void calculate_ndl_tts(struct deco_state *ds, const struct dive *dive, st
|
||||||
add_segment(ds, dive->depth_to_bar(ascent_depth),
|
add_segment(ds, dive->depth_to_bar(ascent_depth),
|
||||||
gasmix, time_stepsize, entry.o2pressure.mbar, divemode, prefs.decosac, in_planner);
|
gasmix, time_stepsize, entry.o2pressure.mbar, divemode, prefs.decosac, in_planner);
|
||||||
|
|
||||||
if (deco_allowed_depth(tissue_tolerance_calc(ds, dive, dive->depth_to_bar(ascent_depth), in_planner), surface_pressure, dive, 1) <= next_stop) {
|
if (deco_allowed_depth(tissue_tolerance_calc(ds, dive, dive->depth_to_bar(ascent_depth), in_planner), surface_pressure, dive, 1).mm <= next_stop) {
|
||||||
/* move to the next stop and add the travel between stops */
|
/* move to the next stop and add the travel between stops */
|
||||||
for (; ascent_depth > next_stop; ascent_depth -= ascent_s_per_deco_step * ascent_velocity(ascent_depth, entry.running_sum / entry.sec, 0), entry.tts_calc += ascent_s_per_deco_step)
|
for (; ascent_depth.mm > next_stop; ascent_depth.mm -= ascent_s_per_deco_step * ascent_velocity(ascent_depth, entry.running_sum / entry.sec, 0), entry.tts_calc += ascent_s_per_deco_step)
|
||||||
add_segment(ds, dive->depth_to_bar(ascent_depth),
|
add_segment(ds, dive->depth_to_bar(ascent_depth),
|
||||||
gasmix, ascent_s_per_deco_step, entry.o2pressure.mbar, divemode, prefs.decosac, in_planner);
|
gasmix, ascent_s_per_deco_step, entry.o2pressure.mbar, divemode, prefs.decosac, in_planner);
|
||||||
ascent_depth = next_stop;
|
ascent_depth.mm = next_stop;
|
||||||
next_stop -= deco_stepsize;
|
next_stop -= deco_stepsize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -862,7 +862,8 @@ static void calculate_deco_information(struct deco_state *ds, const struct deco_
|
||||||
* Set maximum number of iterations to 10 just in case */
|
* Set maximum number of iterations to 10 just in case */
|
||||||
|
|
||||||
while ((abs(prev_deco_time - ds->deco_time) >= 30) && (count_iteration < 10)) {
|
while ((abs(prev_deco_time - ds->deco_time) >= 30) && (count_iteration < 10)) {
|
||||||
int last_ndl_tts_calc_time = 0, first_ceiling = 0, current_ceiling, last_ceiling = 0, final_tts = 0 , time_clear_ceiling = 0;
|
depth_t first_ceiling, current_ceiling, last_ceiling;
|
||||||
|
int last_ndl_tts_calc_time = 0, final_tts = 0 , time_clear_ceiling = 0;
|
||||||
if (decoMode(in_planner) == VPMB)
|
if (decoMode(in_planner) == VPMB)
|
||||||
ds->first_ceiling_pressure.mbar = dive->depth_to_mbar(first_ceiling);
|
ds->first_ceiling_pressure.mbar = dive->depth_to_mbar(first_ceiling);
|
||||||
|
|
||||||
|
@ -871,12 +872,14 @@ static void calculate_deco_information(struct deco_state *ds, const struct deco_
|
||||||
for (i = 1; i < pi.nr; i++) {
|
for (i = 1; i < pi.nr; i++) {
|
||||||
struct plot_data &entry = pi.entry[i];
|
struct plot_data &entry = pi.entry[i];
|
||||||
struct plot_data &prev = pi.entry[i - 1];
|
struct plot_data &prev = pi.entry[i - 1];
|
||||||
int j, t0 = prev.sec, t1 = entry.sec;
|
int t0 = prev.sec, t1 = entry.sec;
|
||||||
int time_stepsize = 20, max_ceiling = -1;
|
int time_stepsize = 20;
|
||||||
|
depth_t max_ceiling;
|
||||||
|
depth_t depth { .mm = entry.depth };
|
||||||
|
|
||||||
divemode_t current_divemode = loop_d.at(entry.sec);
|
divemode_t current_divemode = loop_d.at(entry.sec);
|
||||||
struct gasmix gasmix = loop.at(t1).first;
|
struct gasmix gasmix = loop.at(t1).first;
|
||||||
entry.ambpressure = dive->depth_to_bar(entry.depth);
|
entry.ambpressure = dive->depth_to_bar(depth);
|
||||||
entry.gfline = get_gf(ds, entry.ambpressure, dive) * (100.0 - AMB_PERCENTAGE) + AMB_PERCENTAGE;
|
entry.gfline = get_gf(ds, entry.ambpressure, dive) * (100.0 - AMB_PERCENTAGE) + AMB_PERCENTAGE;
|
||||||
if (t0 > t1) {
|
if (t0 > t1) {
|
||||||
report_info("non-monotonous dive stamps %d %d", t0, t1);
|
report_info("non-monotonous dive stamps %d %d", t0, t1);
|
||||||
|
@ -884,9 +887,9 @@ static void calculate_deco_information(struct deco_state *ds, const struct deco_
|
||||||
}
|
}
|
||||||
if (t0 != t1 && t1 - t0 < time_stepsize)
|
if (t0 != t1 && t1 - t0 < time_stepsize)
|
||||||
time_stepsize = t1 - t0;
|
time_stepsize = t1 - t0;
|
||||||
for (j = t0 + time_stepsize; j <= t1; j += time_stepsize) {
|
for (int j = t0 + time_stepsize; j <= t1; j += time_stepsize) {
|
||||||
int depth = interpolate(prev.depth, entry.depth, j - t0, t1 - t0);
|
depth_t new_depth { .mm = interpolate(prev.depth, depth.mm, j - t0, t1 - t0) };
|
||||||
add_segment(ds, dive->depth_to_bar(depth),
|
add_segment(ds, dive->depth_to_bar(new_depth),
|
||||||
gasmix, time_stepsize, entry.o2pressure.mbar, current_divemode, entry.sac, in_planner);
|
gasmix, time_stepsize, entry.o2pressure.mbar, current_divemode, entry.sac, in_planner);
|
||||||
entry.icd_warning = ds->icd_warning;
|
entry.icd_warning = ds->icd_warning;
|
||||||
if ((t1 - j < time_stepsize) && (j < t1))
|
if ((t1 - j < time_stepsize) && (j < t1))
|
||||||
|
@ -896,23 +899,23 @@ static void calculate_deco_information(struct deco_state *ds, const struct deco_
|
||||||
entry.ceiling = prev.ceiling;
|
entry.ceiling = prev.ceiling;
|
||||||
} else {
|
} else {
|
||||||
/* Keep updating the VPM-B gradients until the start of the ascent phase of the dive. */
|
/* Keep updating the VPM-B gradients until the start of the ascent phase of the dive. */
|
||||||
if (decoMode(in_planner) == VPMB && last_ceiling >= first_ceiling && first_iteration == true) {
|
if (decoMode(in_planner) == VPMB && last_ceiling.mm >= first_ceiling.mm && first_iteration == true) {
|
||||||
nuclear_regeneration(ds, t1);
|
nuclear_regeneration(ds, t1);
|
||||||
vpmb_start_gradient(ds);
|
vpmb_start_gradient(ds);
|
||||||
/* For CVA iterations, calculate next gradient */
|
/* For CVA iterations, calculate next gradient */
|
||||||
if (!first_iteration || in_planner)
|
if (!first_iteration || in_planner)
|
||||||
vpmb_next_gradient(ds, ds->deco_time, surface_pressure / 1000.0, in_planner);
|
vpmb_next_gradient(ds, ds->deco_time, surface_pressure / 1000.0, in_planner);
|
||||||
}
|
}
|
||||||
entry.ceiling = deco_allowed_depth(tissue_tolerance_calc(ds, dive, dive->depth_to_bar(entry.depth), in_planner), surface_pressure, dive, !prefs.calcceiling3m);
|
entry.ceiling = deco_allowed_depth(tissue_tolerance_calc(ds, dive, dive->depth_to_bar(depth), in_planner), surface_pressure, dive, !prefs.calcceiling3m).mm;
|
||||||
if (prefs.calcceiling3m)
|
if (prefs.calcceiling3m)
|
||||||
current_ceiling = deco_allowed_depth(tissue_tolerance_calc(ds, dive, dive->depth_to_bar(entry.depth), in_planner), surface_pressure, dive, true);
|
current_ceiling = deco_allowed_depth(tissue_tolerance_calc(ds, dive, dive->depth_to_bar(depth), in_planner), surface_pressure, dive, true);
|
||||||
else
|
else
|
||||||
current_ceiling = entry.ceiling;
|
current_ceiling.mm = entry.ceiling;
|
||||||
last_ceiling = current_ceiling;
|
last_ceiling = current_ceiling;
|
||||||
/* If using VPM-B, take first_ceiling_pressure as the deepest ceiling */
|
/* If using VPM-B, take first_ceiling_pressure as the deepest ceiling */
|
||||||
if (decoMode(in_planner) == VPMB) {
|
if (decoMode(in_planner) == VPMB) {
|
||||||
if (current_ceiling >= first_ceiling ||
|
if (current_ceiling.mm >= first_ceiling.mm ||
|
||||||
(time_deep_ceiling == t0 && entry.depth == prev.depth)) {
|
(time_deep_ceiling == t0 && depth.mm == prev.depth)) {
|
||||||
time_deep_ceiling = t1;
|
time_deep_ceiling = t1;
|
||||||
first_ceiling = current_ceiling;
|
first_ceiling = current_ceiling;
|
||||||
ds->first_ceiling_pressure.mbar = dive->depth_to_mbar(first_ceiling);
|
ds->first_ceiling_pressure.mbar = dive->depth_to_mbar(first_ceiling);
|
||||||
|
@ -928,7 +931,7 @@ static void calculate_deco_information(struct deco_state *ds, const struct deco_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Use the point where the ceiling clears as the end of deco phase for CVA calculations
|
// Use the point where the ceiling clears as the end of deco phase for CVA calculations
|
||||||
if (current_ceiling > 0)
|
if (current_ceiling.mm > 0)
|
||||||
time_clear_ceiling = 0;
|
time_clear_ceiling = 0;
|
||||||
else if (time_clear_ceiling == 0 && t1 > time_deep_ceiling)
|
else if (time_clear_ceiling == 0 && t1 > time_deep_ceiling)
|
||||||
time_clear_ceiling = t1;
|
time_clear_ceiling = t1;
|
||||||
|
@ -936,12 +939,12 @@ static void calculate_deco_information(struct deco_state *ds, const struct deco_
|
||||||
}
|
}
|
||||||
entry.surface_gf = 0.0;
|
entry.surface_gf = 0.0;
|
||||||
entry.current_gf = 0.0;
|
entry.current_gf = 0.0;
|
||||||
for (j = 0; j < 16; j++) {
|
for (int j = 0; j < 16; j++) {
|
||||||
double m_value = ds->buehlmann_inertgas_a[j] + entry.ambpressure / ds->buehlmann_inertgas_b[j];
|
double m_value = ds->buehlmann_inertgas_a[j] + entry.ambpressure / ds->buehlmann_inertgas_b[j];
|
||||||
double surface_m_value = ds->buehlmann_inertgas_a[j] + surface_pressure / ds->buehlmann_inertgas_b[j];
|
double surface_m_value = ds->buehlmann_inertgas_a[j] + surface_pressure / ds->buehlmann_inertgas_b[j];
|
||||||
entry.ceilings[j] = deco_allowed_depth(ds->tolerated_by_tissue[j], surface_pressure, dive, 1);
|
entry.ceilings[j] = deco_allowed_depth(ds->tolerated_by_tissue[j], surface_pressure, dive, 1).mm;
|
||||||
if (entry.ceilings[j] > max_ceiling)
|
if (entry.ceilings[j] > max_ceiling.mm)
|
||||||
max_ceiling = entry.ceilings[j];
|
max_ceiling.mm = entry.ceilings[j];
|
||||||
double current_gf = (ds->tissue_inertgas_saturation[j] - entry.ambpressure) / (m_value - entry.ambpressure);
|
double current_gf = (ds->tissue_inertgas_saturation[j] - entry.ambpressure) / (m_value - entry.ambpressure);
|
||||||
entry.percentages[j] = ds->tissue_inertgas_saturation[j] < entry.ambpressure ?
|
entry.percentages[j] = ds->tissue_inertgas_saturation[j] < entry.ambpressure ?
|
||||||
lrint(ds->tissue_inertgas_saturation[j] / entry.ambpressure * AMB_PERCENTAGE) :
|
lrint(ds->tissue_inertgas_saturation[j] / entry.ambpressure * AMB_PERCENTAGE) :
|
||||||
|
@ -960,9 +963,9 @@ static void calculate_deco_information(struct deco_state *ds, const struct deco_
|
||||||
// marker should be handled differently!
|
// marker should be handled differently!
|
||||||
// Don't scream if we violate the ceiling by a few cm.
|
// Don't scream if we violate the ceiling by a few cm.
|
||||||
if (in_planner && !pi.waypoint_above_ceiling &&
|
if (in_planner && !pi.waypoint_above_ceiling &&
|
||||||
entry.depth < max_ceiling - 100 && entry.sec > 0) {
|
depth.mm < max_ceiling.mm - 100 && entry.sec > 0) {
|
||||||
struct dive *non_const_dive = (struct dive *)dive; // cast away const!
|
struct dive *non_const_dive = (struct dive *)dive; // cast away const!
|
||||||
add_event(&non_const_dive->dcs[0], entry.sec, SAMPLE_EVENT_CEILING, -1, max_ceiling / 1000,
|
add_event(&non_const_dive->dcs[0], entry.sec, SAMPLE_EVENT_CEILING, -1, max_ceiling.mm / 1000,
|
||||||
translate("gettextFromC", "planned waypoint above ceiling"));
|
translate("gettextFromC", "planned waypoint above ceiling"));
|
||||||
pi.waypoint_above_ceiling = true;
|
pi.waypoint_above_ceiling = true;
|
||||||
}
|
}
|
||||||
|
@ -1009,7 +1012,7 @@ static void calculate_deco_information(struct deco_state *ds, const struct deco_
|
||||||
vpmb_next_gradient(ds, ds->deco_time, surface_pressure / 1000.0, in_planner);
|
vpmb_next_gradient(ds, ds->deco_time, surface_pressure / 1000.0, in_planner);
|
||||||
final_tts = 0;
|
final_tts = 0;
|
||||||
last_ndl_tts_calc_time = 0;
|
last_ndl_tts_calc_time = 0;
|
||||||
first_ceiling = 0;
|
first_ceiling = 0_m;
|
||||||
first_iteration = false;
|
first_iteration = false;
|
||||||
count_iteration ++;
|
count_iteration ++;
|
||||||
this_deco_time = ds->deco_time;
|
this_deco_time = ds->deco_time;
|
||||||
|
@ -1109,16 +1112,17 @@ static void calculate_gas_information_new(const struct dive *dive, const struct
|
||||||
for (i = 1; i < pi.nr; i++) {
|
for (i = 1; i < pi.nr; i++) {
|
||||||
double fn2, fhe;
|
double fn2, fhe;
|
||||||
struct plot_data &entry = pi.entry[i];
|
struct plot_data &entry = pi.entry[i];
|
||||||
|
depth_t depth { .mm = entry.depth };
|
||||||
|
|
||||||
auto gasmix = loop.at(entry.sec).first;
|
auto gasmix = loop.at(entry.sec).first;
|
||||||
amb_pressure = dive->depth_to_bar(entry.depth);
|
amb_pressure = dive->depth_to_bar(depth);
|
||||||
divemode_t current_divemode = loop_d.at(entry.sec);
|
divemode_t current_divemode = loop_d.at(entry.sec);
|
||||||
entry.pressures = fill_pressures(amb_pressure, gasmix, (current_divemode == OC) ? 0.0 : entry.o2pressure.mbar / 1000.0, current_divemode);
|
entry.pressures = fill_pressures(amb_pressure, gasmix, (current_divemode == OC) ? 0.0 : entry.o2pressure.mbar / 1000.0, current_divemode);
|
||||||
fn2 = 1000.0 * entry.pressures.n2 / amb_pressure;
|
fn2 = 1000.0 * entry.pressures.n2 / amb_pressure;
|
||||||
fhe = 1000.0 * entry.pressures.he / amb_pressure;
|
fhe = 1000.0 * entry.pressures.he / amb_pressure;
|
||||||
if (dc->divemode == PSCR) { // OC pO2 is calulated for PSCR with or without external PO2 monitoring.
|
if (dc->divemode == PSCR) { // OC pO2 is calulated for PSCR with or without external PO2 monitoring.
|
||||||
struct gasmix gasmix2 = loop.at(entry.sec).first;
|
struct gasmix gasmix2 = loop.at(entry.sec).first;
|
||||||
entry.scr_OC_pO2.mbar = (int) dive->depth_to_mbar(entry.depth) * get_o2(gasmix2) / 1000;
|
entry.scr_OC_pO2.mbar = (int) dive->depth_to_mbar(depth) * get_o2(gasmix2) / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate MOD, EAD, END and EADD based on partial pressures calculated before
|
/* Calculate MOD, EAD, END and EADD based on partial pressures calculated before
|
||||||
|
@ -1127,13 +1131,13 @@ static void calculate_gas_information_new(const struct dive *dive, const struct
|
||||||
* EAD just uses N₂ ("Air" for nitrox dives) */
|
* EAD just uses N₂ ("Air" for nitrox dives) */
|
||||||
pressure_t modpO2 = { .mbar = (int)(prefs.modpO2 * 1000) };
|
pressure_t modpO2 = { .mbar = (int)(prefs.modpO2 * 1000) };
|
||||||
entry.mod = dive->gas_mod(gasmix, modpO2, 1).mm;
|
entry.mod = dive->gas_mod(gasmix, modpO2, 1).mm;
|
||||||
entry.end = dive->mbar_to_depth(lrint(dive->depth_to_mbarf(entry.depth) * (1000 - fhe) / 1000.0));
|
entry.end = dive->mbar_to_depth(lrint(dive->depth_to_mbarf(depth) * (1000 - fhe) / 1000.0)).mm;
|
||||||
entry.ead = dive->mbar_to_depth(lrint(dive->depth_to_mbarf(entry.depth) * fn2 / (double)N2_IN_AIR));
|
entry.ead = dive->mbar_to_depth(lrint(dive->depth_to_mbarf(depth) * fn2 / (double)N2_IN_AIR)).mm;
|
||||||
entry.eadd = dive->mbar_to_depth(lrint(dive->depth_to_mbarf(entry.depth) *
|
entry.eadd = dive->mbar_to_depth(lrint(dive->depth_to_mbarf(depth) *
|
||||||
(entry.pressures.o2 / amb_pressure * O2_DENSITY +
|
(entry.pressures.o2 / amb_pressure * O2_DENSITY +
|
||||||
entry.pressures.n2 / amb_pressure * N2_DENSITY +
|
entry.pressures.n2 / amb_pressure * N2_DENSITY +
|
||||||
entry.pressures.he / amb_pressure * HE_DENSITY) /
|
entry.pressures.he / amb_pressure * HE_DENSITY) /
|
||||||
(O2_IN_AIR * O2_DENSITY + N2_IN_AIR * N2_DENSITY) * 1000));
|
(O2_IN_AIR * O2_DENSITY + N2_IN_AIR * N2_DENSITY) * 1000)).mm;
|
||||||
entry.density = gas_density(entry.pressures);
|
entry.density = gas_density(entry.pressures);
|
||||||
if (entry.mod < 0)
|
if (entry.mod < 0)
|
||||||
entry.mod = 0;
|
entry.mod = 0;
|
||||||
|
@ -1162,6 +1166,7 @@ static void fill_o2_values(const struct dive *dive, const struct divecomputer *d
|
||||||
|
|
||||||
for (i = 0; i < pi.nr; i++) {
|
for (i = 0; i < pi.nr; i++) {
|
||||||
struct plot_data &entry = pi.entry[i];
|
struct plot_data &entry = pi.entry[i];
|
||||||
|
depth_t depth { .mm = entry.depth };
|
||||||
|
|
||||||
if (dc->divemode == CCR || (dc->divemode == PSCR && dc->no_o2sensors)) {
|
if (dc->divemode == CCR || (dc->divemode == PSCR && dc->no_o2sensors)) {
|
||||||
if (i == 0) { // For 1st iteration, initialise the last_sensor values
|
if (i == 0) { // For 1st iteration, initialise the last_sensor values
|
||||||
|
@ -1174,7 +1179,7 @@ static void fill_o2_values(const struct dive *dive, const struct divecomputer *d
|
||||||
else
|
else
|
||||||
entry.o2sensor[j] = last_sensor[j];
|
entry.o2sensor[j] = last_sensor[j];
|
||||||
} // having initialised the empty o2 sensor values for this point on the profile,
|
} // having initialised the empty o2 sensor values for this point on the profile,
|
||||||
amb_pressure.mbar = dive->depth_to_mbar(entry.depth);
|
amb_pressure.mbar = dive->depth_to_mbar(depth);
|
||||||
o2pressure.mbar = calculate_ccr_po2(entry, dc); // ...calculate the po2 based on the sensor data
|
o2pressure.mbar = calculate_ccr_po2(entry, dc); // ...calculate the po2 based on the sensor data
|
||||||
entry.o2pressure.mbar = std::min(o2pressure.mbar, amb_pressure.mbar);
|
entry.o2pressure.mbar = std::min(o2pressure.mbar, amb_pressure.mbar);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1265,9 +1270,10 @@ static std::vector<std::string> plot_string(const struct dive *d, const struct p
|
||||||
int decimals, cyl;
|
int decimals, cyl;
|
||||||
const char *unit;
|
const char *unit;
|
||||||
const struct plot_data &entry = pi.entry[idx];
|
const struct plot_data &entry = pi.entry[idx];
|
||||||
|
depth_t depth { .mm = entry.depth };
|
||||||
std::vector<std::string> res;
|
std::vector<std::string> res;
|
||||||
|
|
||||||
depthvalue = get_depth_units(entry.depth, NULL, &depth_unit);
|
depthvalue = get_depth_units(depth.mm, NULL, &depth_unit);
|
||||||
res.push_back(casprintf_loc(translate("gettextFromC", "@: %d:%02d"), FRACTION_TUPLE(entry.sec, 60)));
|
res.push_back(casprintf_loc(translate("gettextFromC", "@: %d:%02d"), FRACTION_TUPLE(entry.sec, 60)));
|
||||||
res.push_back(casprintf_loc(translate("gettextFromC", "D: %.1f%s"), depthvalue, depth_unit));
|
res.push_back(casprintf_loc(translate("gettextFromC", "D: %.1f%s"), depthvalue, depth_unit));
|
||||||
for (cyl = 0; cyl < pi.nr_cylinders; cyl++) {
|
for (cyl = 0; cyl < pi.nr_cylinders; cyl++) {
|
||||||
|
@ -1579,7 +1585,7 @@ std::vector<std::string> compare_samples(const struct dive *d, const struct plot
|
||||||
const char *volume_unit;
|
const char *volume_unit;
|
||||||
|
|
||||||
/* Mean pressure in ATM */
|
/* Mean pressure in ATM */
|
||||||
double atm = d->depth_to_atm(avg_depth);
|
double atm = d->depth_to_atm(depth_t { .mm = avg_depth });
|
||||||
|
|
||||||
/* milliliters per minute */
|
/* milliliters per minute */
|
||||||
int sac = lrint(total_volume_used / atm * 60 / delta_time);
|
int sac = lrint(total_volume_used / atm * 60 / delta_time);
|
||||||
|
|
|
@ -248,7 +248,7 @@ void uemis::event(struct dive *dive, struct divecomputer *dc, struct sample *sam
|
||||||
* flags[3].bit0 | flags[5].bit1 != 0 ==> in deco
|
* flags[3].bit0 | flags[5].bit1 != 0 ==> in deco
|
||||||
* flags[0].bit7 == 1 ==> Safety Stop
|
* flags[0].bit7 == 1 ==> Safety Stop
|
||||||
* otherwise NDL */
|
* otherwise NDL */
|
||||||
stopdepth = dive->rel_mbar_to_depth(u_sample->hold_depth);
|
stopdepth = dive->rel_mbar_to_depth(u_sample->hold_depth).mm;
|
||||||
if ((flags[3] & 1) | (flags[5] & 2)) {
|
if ((flags[3] & 1) | (flags[5] & 2)) {
|
||||||
/* deco */
|
/* deco */
|
||||||
sample->in_deco = true;
|
sample->in_deco = true;
|
||||||
|
@ -344,7 +344,7 @@ void uemis::parse_divelog_binary(std::string_view base64, struct dive *dive)
|
||||||
}
|
}
|
||||||
sample = prepare_sample(dc);
|
sample = prepare_sample(dc);
|
||||||
sample->time.seconds = u_sample->dive_time;
|
sample->time.seconds = u_sample->dive_time;
|
||||||
sample->depth.mm = dive->rel_mbar_to_depth(u_sample->water_pressure);
|
sample->depth = dive->rel_mbar_to_depth(u_sample->water_pressure);
|
||||||
sample->temperature.mkelvin = C_to_mkelvin(u_sample->dive_temperature / 10.0);
|
sample->temperature.mkelvin = C_to_mkelvin(u_sample->dive_temperature / 10.0);
|
||||||
add_sample_pressure(sample, active, (u_sample->tank_pressure_high * 256 + u_sample->tank_pressure_low) * 10);
|
add_sample_pressure(sample, active, (u_sample->tank_pressure_high * 256 + u_sample->tank_pressure_low) * 10);
|
||||||
sample->cns = u_sample->cns;
|
sample->cns = u_sample->cns;
|
||||||
|
|
|
@ -144,7 +144,8 @@ void TabDiveInformation::updateProfile()
|
||||||
continue;
|
continue;
|
||||||
volumes.append(get_volume_string(gases[i], true));
|
volumes.append(get_volume_string(gases[i], true));
|
||||||
if (duration[i]) {
|
if (duration[i]) {
|
||||||
sac.mliter = lrint(gases[i].mliter / (currentDive->depth_to_atm(mean[i]) * duration[i] / 60));
|
depth_t mean_depth = { .mm = mean[i] }; // Will be removed in upcoming commit
|
||||||
|
sac.mliter = lrint(gases[i].mliter / (currentDive->depth_to_atm(mean_depth) * duration[i] / 60));
|
||||||
SACs.append(get_volume_string(sac, true).append(tr("/min")));
|
SACs.append(get_volume_string(sac, true).append(tr("/min")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -578,7 +578,7 @@ void TestPlan::testVpmbMetric45m30minTx()
|
||||||
auto dp = std::find_if(testPlan.dp.begin(), testPlan.dp.end(), [](auto &dp) { return dp.minimum_gas.mbar != 0; });
|
auto dp = std::find_if(testPlan.dp.begin(), testPlan.dp.end(), [](auto &dp) { return dp.minimum_gas.mbar != 0; });
|
||||||
QCOMPARE(lrint(dp == testPlan.dp.end() ? 0.0 : dp->minimum_gas.mbar / 1000.0), 108l);
|
QCOMPARE(lrint(dp == testPlan.dp.end() ? 0.0 : dp->minimum_gas.mbar / 1000.0), 108l);
|
||||||
// print first ceiling
|
// print first ceiling
|
||||||
printf("First ceiling %.1f m\n", dive.mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar) * 0.001);
|
printf("First ceiling %.1f m\n", dive.mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar).mm * 0.001);
|
||||||
// check benchmark run time of 141 minutes, and known Subsurface runtime of 139 minutes
|
// check benchmark run time of 141 minutes, and known Subsurface runtime of 139 minutes
|
||||||
//QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 141u * 60u + 20u, 139u * 60u + 20u));
|
//QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 141u * 60u + 20u, 139u * 60u + 20u));
|
||||||
}
|
}
|
||||||
|
@ -604,7 +604,7 @@ void TestPlan::testVpmbMetric60m10minTx()
|
||||||
auto dp = std::find_if(testPlan.dp.begin(), testPlan.dp.end(), [](auto &dp) { return dp.minimum_gas.mbar != 0; });
|
auto dp = std::find_if(testPlan.dp.begin(), testPlan.dp.end(), [](auto &dp) { return dp.minimum_gas.mbar != 0; });
|
||||||
QCOMPARE(lrint(dp == testPlan.dp.end() ? 0.0 : dp->minimum_gas.mbar / 1000.0), 162l);
|
QCOMPARE(lrint(dp == testPlan.dp.end() ? 0.0 : dp->minimum_gas.mbar / 1000.0), 162l);
|
||||||
// print first ceiling
|
// print first ceiling
|
||||||
printf("First ceiling %.1f m\n", dive.mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar) * 0.001);
|
printf("First ceiling %.1f m\n", dive.mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar).mm * 0.001);
|
||||||
// check benchmark run time of 141 minutes, and known Subsurface runtime of 139 minutes
|
// check benchmark run time of 141 minutes, and known Subsurface runtime of 139 minutes
|
||||||
//QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 141u * 60u + 20u, 139u * 60u + 20u));
|
//QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 141u * 60u + 20u, 139u * 60u + 20u));
|
||||||
}
|
}
|
||||||
|
@ -630,7 +630,7 @@ void TestPlan::testVpmbMetric60m30minAir()
|
||||||
auto dp = std::find_if(testPlan.dp.begin(), testPlan.dp.end(), [](auto &dp) { return dp.minimum_gas.mbar != 0; });
|
auto dp = std::find_if(testPlan.dp.begin(), testPlan.dp.end(), [](auto &dp) { return dp.minimum_gas.mbar != 0; });
|
||||||
QCOMPARE(lrint(dp == testPlan.dp.end() ? 0.0 : dp->minimum_gas.mbar / 1000.0), 180l);
|
QCOMPARE(lrint(dp == testPlan.dp.end() ? 0.0 : dp->minimum_gas.mbar / 1000.0), 180l);
|
||||||
// print first ceiling
|
// print first ceiling
|
||||||
printf("First ceiling %.1f m\n", dive.mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar) * 0.001);
|
printf("First ceiling %.1f m\n", dive.mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar).mm * 0.001);
|
||||||
// check benchmark run time of 141 minutes, and known Subsurface runtime of 139 minutes
|
// check benchmark run time of 141 minutes, and known Subsurface runtime of 139 minutes
|
||||||
QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 141u * 60u + 20u, 139u * 60u + 20u));
|
QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 141u * 60u + 20u, 139u * 60u + 20u));
|
||||||
}
|
}
|
||||||
|
@ -656,7 +656,7 @@ void TestPlan::testVpmbMetric60m30minEan50()
|
||||||
auto dp = std::find_if(testPlan.dp.begin(), testPlan.dp.end(), [](auto &dp) { return dp.minimum_gas.mbar != 0; });
|
auto dp = std::find_if(testPlan.dp.begin(), testPlan.dp.end(), [](auto &dp) { return dp.minimum_gas.mbar != 0; });
|
||||||
QCOMPARE(lrint(dp == testPlan.dp.end() ? 0.0 : dp->minimum_gas.mbar / 1000.0), 155l);
|
QCOMPARE(lrint(dp == testPlan.dp.end() ? 0.0 : dp->minimum_gas.mbar / 1000.0), 155l);
|
||||||
// print first ceiling
|
// print first ceiling
|
||||||
printf("First ceiling %.1f m\n", dive.mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar) * 0.001);
|
printf("First ceiling %.1f m\n", dive.mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar).mm * 0.001);
|
||||||
QVERIFY(dive.dcs[0].events.size() >= 1);
|
QVERIFY(dive.dcs[0].events.size() >= 1);
|
||||||
// check first gas change to EAN50 at 21m
|
// check first gas change to EAN50 at 21m
|
||||||
struct event *ev = &dive.dcs[0].events[0];
|
struct event *ev = &dive.dcs[0].events[0];
|
||||||
|
@ -688,7 +688,7 @@ void TestPlan::testVpmbMetric60m30minTx()
|
||||||
auto dp = std::find_if(testPlan.dp.begin(), testPlan.dp.end(), [](auto &dp) { return dp.minimum_gas.mbar != 0; });
|
auto dp = std::find_if(testPlan.dp.begin(), testPlan.dp.end(), [](auto &dp) { return dp.minimum_gas.mbar != 0; });
|
||||||
QCOMPARE(lrint(dp == testPlan.dp.end() ? 0.0 : dp->minimum_gas.mbar / 1000.0), 159l);
|
QCOMPARE(lrint(dp == testPlan.dp.end() ? 0.0 : dp->minimum_gas.mbar / 1000.0), 159l);
|
||||||
// print first ceiling
|
// print first ceiling
|
||||||
printf("First ceiling %.1f m\n", dive.mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar) * 0.001);
|
printf("First ceiling %.1f m\n", dive.mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar).mm * 0.001);
|
||||||
// check first gas change to EAN50 at 21m
|
// check first gas change to EAN50 at 21m
|
||||||
QVERIFY(dive.dcs[0].events.size() >= 1);
|
QVERIFY(dive.dcs[0].events.size() >= 1);
|
||||||
struct event *ev = &dive.dcs[0].events[0];
|
struct event *ev = &dive.dcs[0].events[0];
|
||||||
|
@ -720,7 +720,7 @@ void TestPlan::testVpmbMetric100m60min()
|
||||||
auto dp = std::find_if(testPlan.dp.begin(), testPlan.dp.end(), [](auto &dp) { return dp.minimum_gas.mbar != 0; });
|
auto dp = std::find_if(testPlan.dp.begin(), testPlan.dp.end(), [](auto &dp) { return dp.minimum_gas.mbar != 0; });
|
||||||
QCOMPARE(lrint(dp == testPlan.dp.end() ? 0.0 : dp->minimum_gas.mbar / 1000.0), 157l);
|
QCOMPARE(lrint(dp == testPlan.dp.end() ? 0.0 : dp->minimum_gas.mbar / 1000.0), 157l);
|
||||||
// print first ceiling
|
// print first ceiling
|
||||||
printf("First ceiling %.1f m\n", dive.mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar) * 0.001);
|
printf("First ceiling %.1f m\n", dive.mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar).mm * 0.001);
|
||||||
QVERIFY(dive.dcs[0].events.size() >= 2);
|
QVERIFY(dive.dcs[0].events.size() >= 2);
|
||||||
// check first gas change to EAN50 at 21m
|
// check first gas change to EAN50 at 21m
|
||||||
struct event *ev = &dive.dcs[0].events[0];
|
struct event *ev = &dive.dcs[0].events[0];
|
||||||
|
@ -780,7 +780,7 @@ void TestPlan::testVpmbMetricMultiLevelAir()
|
||||||
auto dp = std::find_if(testPlan.dp.begin(), testPlan.dp.end(), [](auto &dp) { return dp.minimum_gas.mbar != 0; });
|
auto dp = std::find_if(testPlan.dp.begin(), testPlan.dp.end(), [](auto &dp) { return dp.minimum_gas.mbar != 0; });
|
||||||
QCOMPARE(lrint(dp == testPlan.dp.end() ? 0.0 : dp->minimum_gas.mbar / 1000.0), 101l);
|
QCOMPARE(lrint(dp == testPlan.dp.end() ? 0.0 : dp->minimum_gas.mbar / 1000.0), 101l);
|
||||||
// print first ceiling
|
// print first ceiling
|
||||||
printf("First ceiling %.1f m\n", dive.mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar) * 0.001);
|
printf("First ceiling %.1f m\n", dive.mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar).mm * 0.001);
|
||||||
// check benchmark run time of 167 minutes, and known Subsurface runtime of 169 minutes
|
// check benchmark run time of 167 minutes, and known Subsurface runtime of 169 minutes
|
||||||
QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 167u * 60u + 20u, 169u * 60u + 20u));
|
QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 167u * 60u + 20u, 169u * 60u + 20u));
|
||||||
}
|
}
|
||||||
|
@ -806,7 +806,7 @@ void TestPlan::testVpmbMetric100m10min()
|
||||||
auto dp = std::find_if(testPlan.dp.begin(), testPlan.dp.end(), [](auto &dp) { return dp.minimum_gas.mbar != 0; });
|
auto dp = std::find_if(testPlan.dp.begin(), testPlan.dp.end(), [](auto &dp) { return dp.minimum_gas.mbar != 0; });
|
||||||
QCOMPARE(lrint(dp == testPlan.dp.end() ? 0.0 : dp->minimum_gas.mbar / 1000.0), 175l);
|
QCOMPARE(lrint(dp == testPlan.dp.end() ? 0.0 : dp->minimum_gas.mbar / 1000.0), 175l);
|
||||||
// print first ceiling
|
// print first ceiling
|
||||||
printf("First ceiling %.1f m\n", dive.mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar) * 0.001);
|
printf("First ceiling %.1f m\n", dive.mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar).mm * 0.001);
|
||||||
QVERIFY(dive.dcs[0].events.size() >= 2);
|
QVERIFY(dive.dcs[0].events.size() >= 2);
|
||||||
// check first gas change to EAN50 at 21m
|
// check first gas change to EAN50 at 21m
|
||||||
struct event *ev = &dive.dcs[0].events[0];
|
struct event *ev = &dive.dcs[0].events[0];
|
||||||
|
@ -849,7 +849,7 @@ void TestPlan::testVpmbMetricRepeat()
|
||||||
auto dp = std::find_if(testPlan.dp.begin(), testPlan.dp.end(), [](auto &dp) { return dp.minimum_gas.mbar != 0; });
|
auto dp = std::find_if(testPlan.dp.begin(), testPlan.dp.end(), [](auto &dp) { return dp.minimum_gas.mbar != 0; });
|
||||||
QCOMPARE(lrint(dp == testPlan.dp.end() ? 0.0 : dp->minimum_gas.mbar / 1000.0), 61l);
|
QCOMPARE(lrint(dp == testPlan.dp.end() ? 0.0 : dp->minimum_gas.mbar / 1000.0), 61l);
|
||||||
// print first ceiling
|
// print first ceiling
|
||||||
printf("First ceiling %.1f m\n", dive.mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar) * 0.001);
|
printf("First ceiling %.1f m\n", dive.mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar).mm * 0.001);
|
||||||
// check benchmark run time of 27 minutes, and known Subsurface runtime of 28 minutes
|
// check benchmark run time of 27 minutes, and known Subsurface runtime of 28 minutes
|
||||||
QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 27u * 60u + 20u, 27u * 60u + 20u));
|
QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 27u * 60u + 20u, 27u * 60u + 20u));
|
||||||
|
|
||||||
|
@ -867,7 +867,7 @@ void TestPlan::testVpmbMetricRepeat()
|
||||||
dp = std::find_if(testPlan.dp.begin(), testPlan.dp.end(), [](auto &dp) { return dp.minimum_gas.mbar != 0; });
|
dp = std::find_if(testPlan.dp.begin(), testPlan.dp.end(), [](auto &dp) { return dp.minimum_gas.mbar != 0; });
|
||||||
QCOMPARE(lrint(dp == testPlan.dp.end() ? 0.0 : dp->minimum_gas.mbar / 1000.0), 85l);
|
QCOMPARE(lrint(dp == testPlan.dp.end() ? 0.0 : dp->minimum_gas.mbar / 1000.0), 85l);
|
||||||
// print first ceiling
|
// print first ceiling
|
||||||
printf("First ceiling %.1f m\n", dive.mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar) * 0.001);
|
printf("First ceiling %.1f m\n", dive.mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar).mm * 0.001);
|
||||||
QVERIFY(dive.dcs[0].events.size() >= 3);
|
QVERIFY(dive.dcs[0].events.size() >= 3);
|
||||||
// check first gas change to 21/35 at 63m
|
// check first gas change to 21/35 at 63m
|
||||||
struct event *ev = &dive.dcs[0].events[0];
|
struct event *ev = &dive.dcs[0].events[0];
|
||||||
|
@ -902,7 +902,7 @@ void TestPlan::testVpmbMetricRepeat()
|
||||||
dp = std::find_if(testPlan.dp.begin(), testPlan.dp.end(), [](auto &dp) { return dp.minimum_gas.mbar != 0; });
|
dp = std::find_if(testPlan.dp.begin(), testPlan.dp.end(), [](auto &dp) { return dp.minimum_gas.mbar != 0; });
|
||||||
QCOMPARE(lrint(dp == testPlan.dp.end() ? 0.0 : dp->minimum_gas.mbar / 1000.0), 61l);
|
QCOMPARE(lrint(dp == testPlan.dp.end() ? 0.0 : dp->minimum_gas.mbar / 1000.0), 61l);
|
||||||
// print first ceiling
|
// print first ceiling
|
||||||
printf("First ceiling %.1f m\n", dive.mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar) * 0.001);
|
printf("First ceiling %.1f m\n", dive.mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar).mm * 0.001);
|
||||||
|
|
||||||
// check runtime is exactly the same as the first time
|
// check runtime is exactly the same as the first time
|
||||||
int finalDiveRunTimeSeconds = dive.dcs[0].duration.seconds;
|
int finalDiveRunTimeSeconds = dive.dcs[0].duration.seconds;
|
||||||
|
|
Loading…
Add table
Reference in a new issue