Change fake profile behavior

If no average depth is known the current fake profile behavior is rather
unintuitive (we make up an average depth).

Instead we should assume that this is a PADI style dive log and give the
user a "rectangular" profile (actually, it's a trapecoid as we at least
try to enforce a sane ascent / descent speed). If the dive is somewhat
longer or deeper (10 min / 10 m) we even add a 3m safety stop at 5m.

Added a new dives/test0b that tries to capture the typical cases to test
this.

Fixes #398

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Dirk Hohndel 2014-01-08 21:46:27 +08:00
parent 262bc9c84b
commit 0d93470c50
3 changed files with 52 additions and 5 deletions

View file

@ -12,10 +12,10 @@
* To do that, we generate a 6-point profile: * To do that, we generate a 6-point profile:
* *
* (0, 0) * (0, 0)
* (t0, max_d)
* (t1, max_d) * (t1, max_d)
* (t2, d) * (t2, max_d)
* (t3, d) * (t3, d)
* (t4, d)
* (max_t, 0) * (max_t, 0)
* *
* with the same ascent/descent rates between the * with the same ascent/descent rates between the
@ -80,6 +80,28 @@ static int fill_samples(struct sample *s, int max_d, int avg_d, int max_t, doubl
return 1; return 1;
} }
/* we have no average depth; instead of making up a random average depth
* we should assume either a PADI recrangular profile (for short and/or
* shallow dives) or more reasonably a six point profile with a 3 minute
* safety stop at 5m */
static void fill_samples_no_avg(struct sample *s, int max_d, int max_t, double slope)
{
// shallow or short dives are just trapecoids based on the given slope
if (max_d < 10000 || max_t < 600) {
s[1].time.seconds = max_d / slope; s[1].depth.mm = max_d;
s[2].time.seconds = max_t - max_d / slope; s[2].depth.mm = max_d;
} else {
s[1].time.seconds = max_d / slope;
s[1].depth.mm = max_d;
s[2].time.seconds = max_t - max_d / slope - 180;
s[2].depth.mm = max_d;
s[3].time.seconds = max_t - 5000 / slope - 180;
s[3].depth.mm = 5000;
s[4].time.seconds = max_t - 5000 / slope;
s[4].depth.mm = 5000;
}
}
struct divecomputer* fake_dc(struct divecomputer* dc) struct divecomputer* fake_dc(struct divecomputer* dc)
{ {
static struct sample fake[6]; static struct sample fake[6];
@ -105,7 +127,17 @@ struct divecomputer* fake_dc(struct divecomputer* dc)
* a reasonable average, let's just make something * a reasonable average, let's just make something
* up. Note that 'avg_d == max_d' is _not_ a reasonable * up. Note that 'avg_d == max_d' is _not_ a reasonable
* average. * average.
*/ * We explicitly treat avg_d == 0 differently */
if (avg_d == 0) {
/* we try for a sane slope, but bow to the insanity of
* the user supplied data */
fill_samples_no_avg(fake, max_d, max_t, MAX(2.0 * max_d / max_t, 5000.0 / 60));
if(fake[3].time.seconds == 0) { // just a 4 point profile
fakedc.samples = 4;
fake[3].time.seconds = max_t;
}
return &fakedc;
}
if (avg_d < max_d / 10 || avg_d >= max_d) { if (avg_d < max_d / 10 || avg_d >= max_d) {
avg_d = (max_d+10000)/3; avg_d = (max_d+10000)/3;
if (avg_d > max_d) if (avg_d > max_d)

View file

@ -1,6 +1,6 @@
<dives> <dives>
<program name='subsurface' version='1'></program> <program name='subsurface' version='1'></program>
<dive number='0' date='2011-01-01' time='08:00:00' duration='30:00 min'> <dive number='0' date='2011-01-01' time='07:00:00' duration='30:00 min'>
<depth max='30.00 m' mean='15.00 m' /> <depth max='30.00 m' mean='15.00 m' />
</dive> </dive>
</dives> </dives>

15
dives/test0b.xml Normal file
View file

@ -0,0 +1,15 @@
<dives>
<program name='subsurface' version='1'></program>
<dive number='0' date='2011-01-01' time='08:00:00' duration='20:00 min'>
<depth max='30.00 m' />
</dive>
<dive number='0' date='2011-01-01' time='08:25:00' duration='8:00 min'>
<depth max='11.00 m' />
</dive>
<dive number='0' date='2011-01-01' time='08:35:00' duration='10:00 min'>
<depth max='8.00 m' />
</dive>
<dive number='0' date='2011-01-01' time='08:50:00' duration='3:00 min'>
<depth max='20.00 m' />
</dive>
</dives>