diff options
author | Dirk Hohndel <dirk@hohndel.org> | 2013-01-03 20:45:20 -0800 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2013-01-03 20:45:20 -0800 |
commit | 2c336032568cd13bec23fce2500bde551141c3e3 (patch) | |
tree | 4d27fd5b219bacf147098549493fbe87207081d1 /divelist.c | |
parent | 5ba250bd48500c9f7aa206324272d40fd3064069 (diff) | |
download | subsurface-2c336032568cd13bec23fce2500bde551141c3e3.tar.gz |
Consider previous dives when calculating deco
This also initializes the N2 tissue saturations to correct numbers
(setting them to zero was clearly silly).
With this commit we walk back in the dive_table until we find a surface
intervall that's longer than 48h. Or a dive that comes after the last one
we looked at; that would indicate that this is a divelist that contains
dives from multiple divers or dives that for other reasons are not
ordered. In a sane environment one would assume that the dives that need
to be taken into account when doing deco calculations are organized as one
trip in the XML file and so this logic should work.
One major downside of the current implementation is that we recalculate
everything whenever the plot_info is recreated - which happens quite
frequently, for example when resizing the window or even when we go into
loup mode. While this isn't all that compute intensive, this is an utter
waste and we should at least cache the saturation inherited from previous
dives (and clear that number when the selected dive changes). We don't
want to cache all of it as the recreation of the plot_info may be
triggered by the user changing equipment (and most importantly, gasmix)
information. In that case the deco data for this dive does indeed have to
be recreated. But without changing the current dive the saturation after
the last surface intervall should stay the same.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'divelist.c')
-rw-r--r-- | divelist.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/divelist.c b/divelist.c index 5df8fbb57..32f5f44a3 100644 --- a/divelist.c +++ b/divelist.c @@ -818,6 +818,83 @@ static int calculate_sac(struct dive *dive, struct divecomputer *dc) return sac * 1000; } +/* for now we do this based on the first divecomputer */ +static void add_dive_to_deco(struct dive *dive) +{ + struct divecomputer *dc = &dive->dc; + int i; + + if (!dc) + return; + for (i = 1; i < dive->dc.samples; i++) { + struct sample *psample = dc->sample + i - 1; + struct sample *sample = dc->sample + i; + int t0 = psample->time.seconds; + int t1 = sample->time.seconds; + int j; + + for (j = t0; j < t1; j++) { + int depth = 0.5 + psample->depth.mm + (j - t0) * (sample->depth.mm - psample->depth.mm) / (t1 - t0); + (void) add_segment(depth_to_mbar(depth, dive) / 1000.0, &dive->cylinder[sample->sensor].gasmix, 1); + } + } +} + +static struct gasmix air = { .o2.permille = 209 }; + +/* take into account previous dives until there is a 48h gap between dives */ +void init_decompression(struct dive *dive) +{ + int i, divenr = -1; + timestamp_t when; + gboolean deco_init = FALSE; + + if (!dive) + return; + while (++divenr < dive_table.nr && get_dive(divenr) != dive) + ; + when = dive->when; + i = divenr; + while (--i) { + struct dive* pdive = get_dive(i); + if (!pdive || pdive->when > when || pdive->when + pdive->duration.seconds + 48 * 60 * 60 < when) + break; + when = pdive->when; + } + + while (++i < divenr) { + struct dive* pdive = get_dive(i); + double surface_pressure = pdive->surface_pressure.mbar ? pdive->surface_pressure.mbar / 1000.0 : 1.013; + unsigned int surface_time = get_dive(i+1)->when - pdive->when - pdive->duration.seconds; + + if (!deco_init) { + clear_deco(surface_pressure); + deco_init = TRUE; +#if DEBUG & 16 + dump_tissues(); +#endif + } + add_dive_to_deco(pdive); +#if DEBUG & 16 + printf("added dive #%d\n", pdive->number); + dump_tissues(); +#endif + add_segment(surface_pressure, &air, surface_time); +#if DEBUG & 16 + printf("after surface intervall of %d:%02u\n", FRACTION(surface_time,60)); + dump_tissues(); +#endif + } + if (!deco_init) { + double surface_pressure = dive->surface_pressure.mbar ? dive->surface_pressure.mbar / 1000.0 : 1.013; + clear_deco(surface_pressure); +#if DEBUG & 16 + printf("no previous dive\n"); + dump_tissues(); +#endif + } +} + void update_cylinder_related_info(struct dive *dive) { if (dive != NULL) { |