summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--divelist.c65
-rw-r--r--dives/sac-test.xml19
2 files changed, 65 insertions, 19 deletions
diff --git a/divelist.c b/divelist.c
index 143f4d43c..501cf0487 100644
--- a/divelist.c
+++ b/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;
- if (!duration)
- return 0;
+
+ duration = calculate_duration(dive, dc, &meandepth);
/* find and eliminate long surface intervals */
+ if (!duration)
+ return 0;
- 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.. */
diff --git a/dives/sac-test.xml b/dives/sac-test.xml
index b5f0149bb..14ee3f17b 100644
--- a/dives/sac-test.xml
+++ b/dives/sac-test.xml
@@ -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>