]> git.tdb.fi Git - ext/subsurface.git/commitdiff
Calculate OTUs for every dive
authorDirk Hohndel <dirk@hohndel.org>
Thu, 22 Sep 2011 20:45:53 +0000 (13:45 -0700)
committerDirk Hohndel <dirk@hohndel.org>
Thu, 22 Sep 2011 23:26:38 +0000 (16:26 -0700)
The calculation assumes that the cylinderindex in each sample tells us
which PO2 the dive was breathing at that time. This needs to be verified
with dives where there is an actual gas switch.

No idea where to display them, yet. Far fewer people will care about this
than care about SAC - does this still rate a spot in the dive_list?
I guess I could make it part of the dive_info - but it's not editable.
It doesn't seem to fit with the equipment page (even though this is the
one editable field that is related - nitrox %)

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
dive.h
divelist.c
parse-xml.c

diff --git a/dive.h b/dive.h
index e1a5bc007e69fe76d032a2c81ce80dcb80897034..1766cff8203ef2cb38a465f6f90aa403709b97d8 100644 (file)
--- a/dive.h
+++ b/dive.h
@@ -134,6 +134,11 @@ static inline int to_PSI(pressure_t pressure)
        return pressure.mbar * 0.0145037738 + 0.5;
 }
 
+static inline double to_ATM(pressure_t pressure)
+{
+       return pressure.mbar / 1013.25;
+}
+
 struct sample {
        duration_t time;
        depth_t depth;
@@ -156,6 +161,7 @@ struct dive {
        depth_t visibility;
        temperature_t airtemp, watertemp;
        cylinder_t cylinder[MAX_CYLINDERS];
+       double otu;
        int samples, alloc_samples;
        struct sample sample[];
 };
index 51646c460f7b05761134227d94e604c761ac1a15..c2194bbec06b52ddfe7d3888e65bc53ef19274fe 100644 (file)
@@ -14,6 +14,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
+#include <math.h>
 
 #include "divelist.h"
 #include "dive.h"
@@ -222,6 +223,25 @@ static void sac_data_func(GtkTreeViewColumn *col,
        g_object_set(renderer, "text", buffer, NULL);
 }
 
+/* calculate OTU for a dive */
+static double calculate_otu(struct dive *dive)
+{
+       int i;
+       double otu = 0.0;
+
+       for (i = 1; i < dive->samples; i++) {
+               int t;
+               double po2;
+               struct sample *sample = dive->sample + i;
+               struct sample *psample = sample - 1;
+               t = sample->time.seconds - psample->time.seconds;
+               po2 = dive->cylinder[sample->cylinderindex].gasmix.o2.permille / 1000.0 *
+                       (sample->depth.mm + 10000) / 10000.0;
+               if (po2 >= 0.5)
+                       otu += pow(po2 - 0.5, 0.83) * t / 30.0;
+       }
+       return otu;
+}
 /*
  * Return air usage (in liters).
  */
@@ -389,6 +409,7 @@ static void fill_dive_list(void)
        for (i = 0; i < dive_table.nr; i++) {
                struct dive *dive = dive_table.dives[i];
 
+               dive->otu = calculate_otu(dive);
                gtk_list_store_append(store, &iter);
                gtk_list_store_set(store, &iter,
                        DIVE_INDEX, i,
index 1eb6e95fdd1007aff73d326c7d6b073c7fe36f36..8f916b09aea3ed02b2d7ebb7c927263eb2bd7a83 100644 (file)
@@ -1051,7 +1051,7 @@ static void match_standard_cylinder(cylinder_type_t *type)
                return;
 
        cuft = type->size.mliter / 28317.0;
-       cuft *= type->workingpressure.mbar / 1013.25;
+       cuft *= to_ATM(type->workingpressure);
        psi = type->workingpressure.mbar / 68.95;
 
        switch (psi) {
@@ -1106,7 +1106,7 @@ static void sanitize_cylinder_type(cylinder_type_t *type)
 
        if (input_units.volume == CUFT || import_source == SUUNTO) {
                volume_of_air = type->size.mliter * 28.317;     /* milli-cu ft to milliliter */
-               atm = type->workingpressure.mbar / 1013.25;     /* working pressure in atm */
+               atm = to_ATM(type->workingpressure);            /* working pressure in atm */
                volume = volume_of_air / atm;                   /* milliliters at 1 atm: "true size" */
                type->size.mliter = volume + 0.5;
        }