[PATCH] Use the improved duration and average depth for everything

Linus Torvalds torvalds at linux-foundation.org
Sun Feb 24 11:46:34 PST 2013


From: Linus Torvalds <torvalds at linux-foundation.org>
Date: Sun, 24 Feb 2013 11:39:51 -0800
Subject: [PATCH] Use the improved duration and average depth for everything

The code was written to get the SAC rate correct, but we probably do
want to have the duration and mean depth of the dive always be shown for
the non-surface-time.

So move the code from the sac-rate calculation to the generic dive fixup
part.  This makes the dive list and statistics all show the duration as
the under-water duration, which is not necessarily the same as
"difference between beginning and end of dive".

Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
---

This is conceptually independent of the whole SAC calculation issue, 
although it obviously depends on the patches, since it just moves that 
code around.

It also entirely removes the calculation of some average depth from the 
max depth. We don't know, and we can't know. Just don't do it.

Basically, it replaces all our old duration code with the new one that was 
written for the SAC calculation. And then makes the SAC calculations once 
more just use the dive computer duration and average depth directly.

 dive.c     | 72 ++++++++++++++++++++++++++++++++------------------------------
 divelist.c | 48 +++++------------------------------------
 2 files changed, 42 insertions(+), 78 deletions(-)

diff --git a/dive.c b/dive.c
index c07912ebd8d4..798de357cf99 100644
--- a/dive.c
+++ b/dive.c
@@ -213,12 +213,6 @@ static void update_depth(depth_t *depth, int new)
 	}
 }
 
-static void update_duration(duration_t *duration, int new)
-{
-	if (new)
-		duration->seconds = new;
-}
-
 static void update_temperature(temperature_t *temperature, int new)
 {
 	if (new) {
@@ -229,6 +223,40 @@ static void update_temperature(temperature_t *temperature, int new)
 	}
 }
 
+/*
+ * 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 void fixup_dc_duration(struct divecomputer *dc)
+{
+	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) {
+		dc->duration.seconds = duration;
+		dc->meandepth.mm = (depthtime + duration/2) / duration;
+	}
+}
+
 static void fixup_pressure(struct dive *dive, struct sample *sample)
 {
 	unsigned int pressure, index;
@@ -566,12 +594,14 @@ static void fixup_dive_dc(struct dive *dive, struct divecomputer *dc)
 	double depthtime = 0;
 	int lasttime = 0;
 	int lastindex = -1;
-	int start = -1, end = -1;
 	int maxdepth = 0, mintemp = 0;
 	int lastdepth = 0;
 	int lasttemp = 0, lastpressure = 0;
 	int pressure_delta[MAX_CYLINDERS] = {INT_MAX, };
 
+	/* Fixup duration and mean depth */
+	fixup_dc_duration(dc);
+
 	update_min_max_temperatures(dive, dc->watertemp);
 	for (i = 0; i < dc->samples; i++) {
 		struct sample *sample = dc->sample + i;
@@ -603,13 +633,7 @@ static void fixup_dive_dc(struct dive *dive, struct divecomputer *dc)
 		lastindex = index;
 		lastpressure = pressure;
 
-		if (lastdepth > SURFACE_THRESHOLD)
-			end = time;
-
 		if (depth > SURFACE_THRESHOLD) {
-			end = time;
-			if (start < 0)
-				start = lasttime;
 			if (depth > maxdepth)
 				maxdepth = depth;
 		}
@@ -666,29 +690,7 @@ static void fixup_dive_dc(struct dive *dive, struct divecomputer *dc)
 			cyl->sample_end.mbar = 0;
 		}
 	}
-	if (end < 0) {
-		/* Assume an ascent/descent rate of 9 m/min */
-		int depth = dc->maxdepth.mm;
-		int asc_desc_time = depth*60/9000;
-		int duration = dc->duration.seconds;
-
-		/* Some sanity checks against insane dives */
-		if (duration < 2)
-			duration = 2;
-		if (asc_desc_time * 2 >= duration)
-			asc_desc_time = duration/2;
-
-		if (!dc->meandepth.mm)
-			dc->meandepth.mm = depth*(duration-asc_desc_time)/duration;
-		if (depth > maxdepth)
-			maxdepth = depth;
-	} else {
-		update_duration(&dc->duration, end - start);
-		if (start != end)
-			depthtime /= (end - start);
 
-		update_depth(&dc->meandepth, depthtime);
-	}
 	update_temperature(&dc->watertemp, mintemp);
 	update_depth(&dc->maxdepth, maxdepth);
 	if (maxdepth > dive->maxdepth.mm)
diff --git a/divelist.c b/divelist.c
index 501cf0487b60..952b03bb222c 100644
--- a/divelist.c
+++ b/divelist.c
@@ -719,46 +719,6 @@ 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)
 {
@@ -770,12 +730,14 @@ static int calculate_sac(struct dive *dive)
 	if (!airuse)
 		return 0;
 
-	duration = calculate_duration(dive, dc, &meandepth);
-
-	/* find and eliminate long surface intervals */
+	duration = dc->duration.seconds;
 	if (!duration)
 		return 0;
 
+	meandepth = dc->meandepth.mm;
+	if (!meandepth)
+		return 0;
+
 	/* Mean pressure in ATM (SAC calculations are in atm*l/min) */
 	pressure = (double) depth_to_mbar(meandepth, dive) / SURFACE_PRESSURE;
 	sac = airuse / pressure * 60 / duration;
-- 
1.8.2.rc0.16.g20a599e



More information about the subsurface mailing list