mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-30 22:20:21 +00:00
Correctly calculate SAC rate in the presense of surface events
This assumes that you are not breathing your cylinders while at the surface, which may or may not be correct, but is usually the right thing. Regardless, we're better off giving a conservative (higher) SAC rate estimate for a diver that breathes his cylinder at the surface too than giving an artificially low one because the diver ended up using his snorkel and we didn't take that into account. NOTE! This basically calculates a better duration and average depth than the ones we end up showing in the dive list. Maybe we should actually show this "no-surface-time" duration and average depth instead of the ones we do show? That's a separate question, though. Added a test-case for the surface case to the sac-test.xml dives. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
f4bf16d5db
commit
6d548d2028
2 changed files with 65 additions and 19 deletions
65
divelist.c
65
divelist.c
|
@ -719,38 +719,65 @@ static double calculate_airuse(struct dive *dive)
|
|||
return airuse;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate how long we were actually under water, and the average
|
||||
* depth while under water.
|
||||
*
|
||||
* This ignores any surface time in the middle of the dive.
|
||||
*/
|
||||
static int calculate_duration(struct dive *dive, struct divecomputer *dc, int *meandepth)
|
||||
{
|
||||
int duration, i;
|
||||
int lasttime, lastdepth, depthtime;
|
||||
|
||||
duration = 0;
|
||||
lasttime = 0;
|
||||
lastdepth = 0;
|
||||
depthtime = 0;
|
||||
for (i = 0; i < dc->samples; i++) {
|
||||
struct sample *sample = dc->sample + i;
|
||||
int time = sample->time.seconds;
|
||||
int depth = sample->depth.mm;
|
||||
|
||||
/* We ignore segments at the surface */
|
||||
if (depth > SURFACE_THRESHOLD || lastdepth > SURFACE_THRESHOLD) {
|
||||
duration += time - lasttime;
|
||||
depthtime += (time - lasttime)*(depth+lastdepth)/2;
|
||||
}
|
||||
lastdepth = depth;
|
||||
lasttime = time;
|
||||
}
|
||||
if (duration) {
|
||||
if (meandepth)
|
||||
*meandepth = depthtime / duration;
|
||||
return duration;
|
||||
}
|
||||
|
||||
/* No samples? */
|
||||
if (meandepth)
|
||||
*meandepth = dive->meandepth.mm;
|
||||
return dive->duration.seconds;
|
||||
}
|
||||
|
||||
/* this only uses the first divecomputer to calculate the SAC rate */
|
||||
static int calculate_sac(struct dive *dive)
|
||||
{
|
||||
struct divecomputer *dc = &dive->dc;
|
||||
double airuse, pressure, sac;
|
||||
int duration, i;
|
||||
int duration, meandepth;
|
||||
|
||||
airuse = calculate_airuse(dive);
|
||||
if (!airuse)
|
||||
return 0;
|
||||
duration = dc->duration.seconds;
|
||||
|
||||
duration = calculate_duration(dive, dc, &meandepth);
|
||||
|
||||
/* find and eliminate long surface intervals */
|
||||
if (!duration)
|
||||
return 0;
|
||||
|
||||
/* find and eliminate long surface intervals */
|
||||
|
||||
for (i = 0; i < dc->samples; i++) {
|
||||
if (dc->sample[i].depth.mm < 100) { /* less than 10cm */
|
||||
int end = i + 1;
|
||||
while (end < dc->samples && dc->sample[end].depth.mm < 100)
|
||||
end++;
|
||||
/* we only want the actual surface time during a dive */
|
||||
if (end < dc->samples) {
|
||||
end--;
|
||||
duration -= dc->sample[end].time.seconds -
|
||||
dc->sample[i].time.seconds;
|
||||
i = end + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Mean pressure in ATM (SAC calculations are in atm*l/min) */
|
||||
pressure = (double) depth_to_mbar(dc->meandepth.mm, dive) / SURFACE_PRESSURE;
|
||||
pressure = (double) depth_to_mbar(meandepth, dive) / SURFACE_PRESSURE;
|
||||
sac = airuse / pressure * 60 / duration;
|
||||
|
||||
/* milliliters per minute.. */
|
||||
|
|
|
@ -46,5 +46,24 @@ We have exactly 100 ATM of gas in 15l of cylinder, average 20m for 25min</notes>
|
|||
<sample time='25:00 min' depth='0.0 m' />
|
||||
</divecomputer>
|
||||
</dive>
|
||||
<dive number='4' date='2013-02-24' time='12:26:04' duration='25:00 min'>
|
||||
<location>SAC test dive 3</location>
|
||||
<notes>SAC should be 20l/min (0.7063 cuft/min)
|
||||
This adds a 5-minute surface time to the middle of the dive.
|
||||
We have exactly 100 ATM of gas in 15l of cylinder, average 20m for 25min</notes>
|
||||
<cylinder size='10 l' description='10l' start='202.6 bar' end='101.3 bar' />
|
||||
<cylinder size='5 l' description='10l' start='202.6 bar' end='101.3 bar' />
|
||||
<divecomputer>
|
||||
<event time='22:00 min' name='gaschange' />
|
||||
<depth max='20.0 m' mean='10.0 m' />
|
||||
<sample time='0:00 min' depth='0.0 m' />
|
||||
<sample time='5:00 min' depth='20.0 m' />
|
||||
<sample time='10:00 min' depth='40.0 m' />
|
||||
<sample time='15:00 min' depth='0.0 m' />
|
||||
<sample time='20:00 min' depth='0.0 m' />
|
||||
<sample time='25:00 min' depth='40.0 m' />
|
||||
<sample time='30:00 min' depth='0.0 m' />
|
||||
</divecomputer>
|
||||
</dive>
|
||||
</dives>
|
||||
</divelog>
|
||||
|
|
Loading…
Reference in a new issue