aboutsummaryrefslogtreecommitdiffstats
path: root/subsurface-core
diff options
context:
space:
mode:
authorGravatar Linus Torvalds <torvalds@linux-foundation.org>2016-04-01 15:23:55 -0500
committerGravatar Dirk Hohndel <dirk@hohndel.org>2016-04-01 20:18:53 -0500
commita554c66fa39912ac82253741880a83a22bf574b4 (patch)
tree914939d6deff0219a52e306da352b3cc914eeec6 /subsurface-core
parentf92e2e752f6e16af518b3e2e5221bf401221751a (diff)
downloadsubsurface-a554c66fa39912ac82253741880a83a22bf574b4.tar.gz
Fix cylinder end pressure fixup from samples
This bug admittedly hits almost nobody, but if you had multiple cylinder pressure sensors on the same cylinder (attached to multiple dive computers, of course), we would take the beginning pressure from the first dive computer, and the ending pressure from the last dive computer. That came about because we'd just walk all the dive computer samples in order, and the first time we see a relevant sample and we don't have a beginning pressure, we'd take that pressure. So the beginning pressure was from the first dive computer, and once we'd seen a valid beginning pressure, that would never change. But as we're walking along, we'd continue to update the ending pressure from the last relevant sample we see, which means that as we go on to look at the other dive computers, we'd continue to update the ending pressure with data from them. And mixing beginning/ending pressures from two different sensors just does not make sense. This changes the logic to be the same for beginning and ending pressures: we only update it once, with the first relevant sample we see. But we walk the samples twice: forwards from the beginning to find the first beginning pressure, and backwards from the end to find the ending pressure. That means that as we move on to the second dive computer, we've now filled in the ending pressure from the first one, and will no longer update it any more. NOTE! We don't stop scanning the samples (or the dive computers) just because we've found a valid pressure value. We'll always walk all the samples because there might be multiple different cylinders that get pressure data from different samples (and different dive computers). We could have some early-out logic when we've filled in all relevant cylinders, but since this just runs once per dive it's not worth it. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'subsurface-core')
-rw-r--r--subsurface-core/dive.c94
1 files changed, 51 insertions, 43 deletions
diff --git a/subsurface-core/dive.c b/subsurface-core/dive.c
index 6ee002e1f..12154704f 100644
--- a/subsurface-core/dive.c
+++ b/subsurface-core/dive.c
@@ -798,45 +798,6 @@ void per_cylinder_mean_depth(struct dive *dive, struct divecomputer *dc, int *me
}
}
-static void fixup_pressure(struct dive *dive, struct sample *sample, enum cylinderuse cyl_use)
-{
- int pressure, index;
- cylinder_t *cyl;
-
- if (cyl_use != OXYGEN) {
- pressure = sample->cylinderpressure.mbar;
- index = sample->sensor;
- } else { // for the CCR oxygen cylinder:
- pressure = sample->o2cylinderpressure.mbar;
- index = get_cylinder_idx_by_use(dive, OXYGEN);
- }
- if (index < 0)
- return;
- if (!pressure)
- return;
-
- /*
- * Ignore surface samples for tank pressure information.
- *
- * At the beginning of the dive, let the cylinder cool down
- * if the diver starts off at the surface. And at the end
- * of the dive, there may be surface pressures where the
- * diver has already turned off the air supply (especially
- * for computers like the Uemis Zurich that end up saving
- * quite a bit of samples after the dive has ended).
- */
- if (sample->depth.mm < SURFACE_THRESHOLD)
- return;
-
- /* FIXME! sensor -> cylinder mapping? */
- if (index >= MAX_CYLINDERS)
- return;
- cyl = dive->cylinder + index;
- if (!cyl->sample_start.mbar)
- cyl->sample_start.mbar = pressure;
- cyl->sample_end.mbar = pressure;
-}
-
static void update_min_max_temperatures(struct dive *dive, temperature_t temperature)
{
if (temperature.mkelvin) {
@@ -1419,18 +1380,65 @@ static void simplify_dc_pressures(struct dive *dive, struct divecomputer *dc)
}
}
+/* FIXME! sensor -> cylinder mapping? */
+static void fixup_start_pressure(struct dive *dive, int idx, pressure_t p)
+{
+ if (idx >= 0 && idx < MAX_CYLINDERS) {
+ cylinder_t *cyl = dive->cylinder + idx;
+ if (p.mbar && !cyl->sample_start.mbar)
+ cyl->sample_start = p;
+ }
+}
+
+static void fixup_end_pressure(struct dive *dive, int idx, pressure_t p)
+{
+ if (idx >= 0 && idx < MAX_CYLINDERS) {
+ cylinder_t *cyl = dive->cylinder + idx;
+ if (p.mbar && !cyl->sample_end.mbar)
+ cyl->sample_end = p;
+ }
+}
+
/*
* Check the cylinder pressure sample information and fill in the
* overall cylinder pressures from those.
+ *
+ * We ignore surface samples for tank pressure information.
+ *
+ * At the beginning of the dive, let the cylinder cool down
+ * if the diver starts off at the surface. And at the end
+ * of the dive, there may be surface pressures where the
+ * diver has already turned off the air supply (especially
+ * for computers like the Uemis Zurich that end up saving
+ * quite a bit of samples after the dive has ended).
*/
static void fixup_dive_pressures(struct dive *dive, struct divecomputer *dc)
{
- int i;
+ int i, o2index = -1;
+
+ if (dive->dc.divemode == CCR)
+ o2index = get_cylinder_idx_by_use(dive, OXYGEN);
+
+ /* Walk the samples from the beginning to find starting pressures.. */
for (i = 0; i < dc->samples; i++) {
struct sample *sample = dc->sample + i;
- fixup_pressure(dive, sample, OC_GAS);
- if (dive->dc.divemode == CCR)
- fixup_pressure(dive, sample, OXYGEN);
+
+ if (sample->depth.mm < SURFACE_THRESHOLD)
+ continue;
+
+ fixup_start_pressure(dive, sample->sensor, sample->cylinderpressure);
+ fixup_start_pressure(dive, o2index, sample->o2cylinderpressure);
+ }
+
+ /* ..and from the end for ending pressures */
+ for (i = dc->samples; --i >= 0; ) {
+ struct sample *sample = dc->sample + i;
+
+ if (sample->depth.mm < SURFACE_THRESHOLD)
+ continue;
+
+ fixup_end_pressure(dive, sample->sensor, sample->cylinderpressure);
+ fixup_end_pressure(dive, o2index, sample->o2cylinderpressure);
}
simplify_dc_pressures(dive, dc);