So far, add_segment() returned a tissue tolerance (i.e. ceiling)
computed just in its return statement. This tissue_tolerance
needed to be dragged around until it was needed or be dropped
if not needed at all.
As for VPM-B, this ceiling computation is a bit expensive, this patch
calls the computation function tissue_tolerance_calc() when the
value is actually needed and not before.
This changes the signature of some functions.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
and not some time before and store the result in a global variable.
This stores only the bottom gradients and computes the Boyle compensation
when computing the allowed ambient pressure.
As the Boyle compensation needs a reference ambient pressure, to find the ceiling,
we have to iterate this computation until the reference pressure is close enough to
the ceiling.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We now do the first_ceiling_pressure calculation at the start of the CVA loop.
We don't need to do it before.
Signed-off-by: Rick Walsh <rickmwalsh@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We should run clear_deco as early as we can. We should calculate the nuclear
regeneration and start gradient after calculating tissue tolerance. We don't
need to redo nuclear regeration and start gradient after that.
Signed-off-by: Rick Walsh <rickmwalsh@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
By calculating crushing pressure after the manually entered phase, we were doing
it wrong for multi-level dives.
Signed-off-by: Rick Walsh <rickmwalsh@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The pressure for the Boyle compensation is of the first ceiling,
i.e. the ceiling seen from the bottom rather than the first
stop.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Otherwise, the results of the calculations tend to be rather
random and irreproducible...
Signed-off-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The Boyle's law compensation depends on first_stop_pressure. To produce
profiles similar to other VPM-B implementations, we should calculate it as the
ceiling before starting the ascent.
Commit 159c9eb2c1, Compare ceiling to next stop
rather than try to ascent for VPM-B, changed (VPM-B) to consider the current
ceiling rather than an incremental ascent between one stop level and the next.
However, the initial ascent generally steps through several stop levels, so
first_stop_pressure was still not calculated as the ceiling prior to commencing
the calculated ascent.
Signed-off-by: Rick Walsh <rickmwalsh@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
otherwise VPM-B planned profiles seem to violate the ceiling. This needs
the first_stop_pressure to be available also in the profile, so I made
it global in planner.c
Important lesson: If you want to use deco_allowed_depth on a tissue_tolerance
that comes from a VPM-B planned dive, you have to call boyles_law() before
add_segment()!
Signed-off-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Since a8ce8, that made deco_allowed_depth work for VPM-B as well, this
function became obsolete but was reintroduced by one of Jan's latest patches.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
For VPM-B, to stay within the reference implementation, to decide if we
need to stop we check if the current ceiling is above the next stop depth
rather than trying to ascent and check if we violate a ceiling. This
leads to more conservative profiles.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Previously we were calculating the compensation only on the deco
stops, gas change stops appearing before the first deco stop were
ommited.
Signed-off-by: Jan Darowski <jan.darowski@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Usually, we try to ascent to the next stop and check if we break the
ceiling while doing that. This patch adds a preference value to rather
check if the ceiling is above the next stop before attempting to ascent.
The difference if off-gasing during the ascent is taken into account.
Logically, it does not sound like it could be relevant to ignore that
off-gasing but it leads to more conservative schedules and it seems
the original Fortran VPM-B implementation does just this. So one could
argue it is part of that model (if it makes sense or not), so we should
at least give users the possibility to turn this on.
Maybe we should even make this the default for VPM-B.
This patch just addes the code to have the value in the preferences and
the planner to act accordingly. There is no UI for it, yet. To test, you
have to set it in the code. There could be a later patch with a UI if people
like to have it.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This patch makes deco_allowed_depth() work both for Buehlmann as well as
VPM-B (as long as the VPM-B internal variable total_gradient[] is valid).
As a bonus, in VPM-B mode, in the planner, the ceilings are VPM-B ceilings
and not Buehlmann GF.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Now, we calculate the volume of free gas not only based on the deco
time but also time on the surface, needed for the full desaturation.
Signed-off-by: Jan Darowski <jan.darowski@gmail.com>
The default stack size on Windows per thread is 1024kb.
Using the heap prevents a stack overflow in add_plan_to_notes().
The alternative is to tell the linker to use N bytes of stack:
-Wl,--stack,N
Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This fixes a bug where we would not do any gas changes at all if at the end of
bottom time we were deeper than the MOD of the bottom mix. Instead we would
constantly try to switch to that gas and find we are already breathing it.
A test case would be a dive with air and EAN50 to more than 66m. That would
have never switched to EAN50.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The purpose of parts of the planner code is not not always obvious. This is
especially true of the conditional statements in the add_plan_to_notes function.
Annotate the code with comments to explain the logic.
Signed-off-by: Rick Walsh <rickmwalsh@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
In commit 156ad42a3c ("snprintf is happier if it has an explicit string
literal format argument") I got a little too aggressive making sure there
are string literal format strings...
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
If display transitions in deco isn't selected, then we shouldn't show the
transition segment between two deco stops, even if there is a gas change. We
should still show the ascent segment up to the first deco stop. The
(gaschange_after && !isascent) condition is necessary to pick up backgas breaks.
An example plan is shown below.
Previously:
depth duration runtime gas
40m 1min 1min air
40m 34min 35min
21m 2min 37min <--meaningful ascent segment
21m 1min 38min EAN50
18m 1min 39min
15m 3min 42min
12m 4min 46min
9m 5min 51min
6m 0min 51min <--unnecessary ascent segment
6m 13min 64min oxygen
6m 6min 70min air
6m 2min 72min oxygen
0m 1min 73min
depth duration runtime gas
40m 1min 1min air
40m 34min 35min
21m 2min 37min <--meaningful ascent segment
21m 1min 38min EAN50
18m 1min 39min
15m 3min 42min
12m 4min 46min
9m 5min 51min
6m 13min 64min oxygen
6m 6min 70min air
6m 2min 72min oxygen
0m 1min 73min
Signed-off-by: Rick Walsh <rickmwalsh@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
When the last stop at 6m/20ft option is selected, replace the 3m/10ft stop with
zero depth, rather than doubling up on the 6m/20ft stop. This removes the need
to differentiate between 6m (=6000mm) and 20ft (=6096mm) and saves calling a
helper function. It does not alter the calculated profile at all.
Signed-off-by: Rick Walsh <rickmwalsh@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Previously we used strncat to output VPM mode without correctly defining the
length of the string, and didn't do anything for recreational mode. This
resulted in the output being junk recycled from the previous temp string.
We could use strncat if the string length were defined, but using snprintf will
make it simpler to include the VPM conservatism when that has been implemented.
Signed-off-by: Rick Walsh <rickmwalsh@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Update the disclamer text to reflect which algorithm where used.
[Dirk Hohndel: cleaned up coding style & replaced snprintf with strncat]
Signed-off-by: Joakim Bygdell <j.bygdell@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Make precedence of && over || explicit.
Explicitly convert between char * and unsigned char *.
Don't assign potentially negative return code to an unsigend variable.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
For the proper calculation, we need to take salinity and surface pressure
into account (rather than depth = bar * 10 - 10)
Signed-off-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This sets up a standard dive scenario (30 minutes at 260ft/79m, EAN36 and
Oxygen as deco gases, last stop at 20ft/6m) and calls the planner to set
up a dive plan given certain standard gases.
Instead of trying to verify the complete plans it checks that we switch to
the deco gases at the right depth and the complete duration of the dive
matches our expectation.
The test intentionally fails right now for imperial as we have the wrong
switch depth for Oxygen. See how useful tests are?
On the downside, the test does NOT produce the same plan as Subsurface
when I try to create a consistent setup for both - and I have not been
able to figure out why. There must be some other parameters that I'm not
setting, but I haven't identified them, yet. It's very small differences,
for example in the metric case the stops at 21m, 9m, and 6m are each one
minute shorter in the test than it what Subsurface calculates.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
When using feet as depth unit, deco stop levels should be at 10 ft rather
than 3 m increments.
For shallow stops, rounding means the difference is not apparent. However,
with stops deeper than 30 feet, using 3 m increments leads stops at 39ft,
49ft, ..., 98ft, etc.
Apart from making plans look messy, the old behaviour makes it harder to
benchmark the planner against published profiles in imperial units.
This revised patch uses the help macro M_OR_FT(6, 20) to set the last stop
at the correct depth.
Signed-off-by: Rick Walsh <rickmwalsh@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Read and use the last_stop preference in the plan function.
Read the plan notes preferences and set variables (plan_verbatim,
plan_display_runtime, plan_display_duration, and plan_display_transitions)
in the add_plan_to_notes function. Don't read the preferences and set
variables otherwise. Both plan and add_plan_to_notes functions are called
on data change.
Previous behaviour was:
- Set variables on declaration
- Reset variables in plan function (even variables that only relate to
planner notes output)
- Changing a preference triggered set_xxx function which sets variable,
then plan function, which sets variable again.
Apart from being inefficient, the previous behaviour made it difficult to
track down where and when variables were set.
Signed-off-by: Rick Walsh <rickmwalsh@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Added keeping bottom dive state and every deco's time, so we can
run multiple deco simulations with different gradients until they
converge to some optimal value.
Some improvements on the deco time calculation may be needed.
Signed-off-by: Jan Darowski <jan.darowski@gmail.com>
Add call of initial calculation of critical radius and start gradient,
so the VPM could work.
Currently without CVA, so the gradient isn't improved.
Only one iteration is run.
Signed-off-by: Jan Darowski <jan.darowski@gmail.com>
Check during the trial_ascent() if existing pressure gradient is
smaller than previously calculated max gradient. If not, ascent
is impossible from the vpm-b's point of view.
Signed-off-by: Jan Darowski <jan.darowski@gmail.com>
Removed recreational mode from ui and pref and replaced it with
new deco_mode enum.
Added radio button ui selection.
Set default deco_mode to Buehlmann algorithm.
Signed-off-by: Jan Darowski <jan.darowski@gmail.com>
When option is enabled, if a stop is not otherwise required, a gas switch will be delayed until a stop is reached. This option is ignored if the current gas is hypoxic.
Signed-off-by: Rick Walsh <rickmwalsh@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This is required so they work in the test for /* do we want to skip this leg as it is devoid of anything useful? */
We were already trying to use gaschange_after (and previously gaschange), but it was duplicating an existing condition (now removed).
Signed-off-by: Rick Walsh <rickmwalsh@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Previously gaschange_after was never being set back to false. Now it will be.
Signed-off-by: Rick Walsh <rickmwalsh@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>