[PATCH] Show MOD, EAD, END and EADD

Jan Schubert Jan.Schubert at GMX.li
Sun Jan 13 10:57:39 PST 2013


This is a approach to get more familar with the code by implementing
some basic stuff showing MOD, EAD, AND and EADD:

- MOD: Maximum Operation Depth based on a limit of 1.6bar as of now
(will think about to make this configurable soon)
- EAD: Equivalent Air Depth considering N2 and (!) O2 narcotic
- END: Equivalent Nitrogen (Narcotic) Depth considering just N2 narcotic
(ignoring O2)
- EADD: Equivalent Air Density Depth

Please note that some people and even diving organisations have opposite
definitions for EAD and END, but considering A stands for Air, I choosed
the above. And considerung N for Nitrogen it also fits in this scheme.

Some notes:

This patch moves N2_IN_AIR from deco.c to dive.h as this is already and
might be used in several places. It also respecifies N2_IN_AIR to a more
correct value of 78,084%, the former one also included all other gases
than oxygen appearing in air. If someone needs to use the former value
it would be more correct to use 1-O2_IN_AIR instead.
It took me some time to recognize that depth is always stored in mm
independent of using metric or imperial units and the conversion is not
done automatically when printing/displaying the graph.
All results rounded down to full meters. As the conversion to feet is
done afterwards the depth in feet might me 1 or 2 feet to shallow sometimes.

Signed-off-by: Jan Schubert / Jan.Schubert at GMX.li

diff --git a/deco.c b/deco.c
index 0005ba1..1a2d13a 100644
--- a/deco.c
+++ b/deco.c
@@ -78,7 +78,6 @@ const double buehlmann_He_factor_expositon_one_second[] = {
        1.00198406028040E-004, 7.83611475491108E-005, 6.13689891868496E-005, 4.81280465299827E-005};
 
 #define WV_PRESSURE 0.0627 /* water vapor pressure */
-#define N2_IN_AIR 0.7902
 #define DECO_STOPS_MULTIPLIER_MM 3000.0
 
 #define GF_LOW_AT_MAXDEPTH 0
diff --git a/dive.h b/dive.h
index b80e6bf..be637e5 100644
--- a/dive.h
+++ b/dive.h
@@ -11,6 +11,13 @@
 #include <libxml/tree.h>
 #include <openssl/sha.h>
 
+#define O2_IN_AIR 0.20942
+#define N2_IN_AIR 0.78084 // has been set to 0.7902 before to ignore other components of air
+#define O2_DENSITY 1.429  // Gramm/Liter
+#define N2_DENSITY 1.25
+#define HE_DENSITY 0.178
+
+
 /*
  * Some silly typedefs to make our units very explicit.
  *
diff --git a/gtk-gui.c b/gtk-gui.c
index 1bc3388..a26fad8 100644
--- a/gtk-gui.c
+++ b/gtk-gui.c
@@ -439,6 +439,7 @@ OPTIONCALLBACK(cylinder_toggle, prefs.visible_cols.cylinder)
 OPTIONCALLBACK(po2_toggle, prefs.pp_graphs.po2)
 OPTIONCALLBACK(pn2_toggle, prefs.pp_graphs.pn2)
 OPTIONCALLBACK(phe_toggle, prefs.pp_graphs.phe)                                                                                                                                                           
+OPTIONCALLBACK(mod_toggle, prefs.mod)                                                                                                                                                                     
 OPTIONCALLBACK(red_ceiling_toggle, prefs.profile_red_ceiling)                                                                                                                                             
 OPTIONCALLBACK(calc_ceiling_toggle, prefs.profile_calc_ceiling)                                                                                                                                           
 OPTIONCALLBACK(calc_ceiling_3m_toggle, prefs.calc_ceiling_3m_incr)                                                                                                                                        
@@ -529,7 +530,7 @@ static void preferences_dialog(GtkWidget *w, gpointer data)                                                                                                                            
 {                                                                                                                                                                                                         
        int result;                                                                                                                                                                                        
        GtkWidget *dialog, *notebook, *font, *frame, *box, *vbox, *button, *xmlfile_button;                                                                                                                
-       GtkWidget *entry_po2, *entry_pn2, *entry_phe, *entry_gflow, *entry_gfhigh;                                                                                                                         
+       GtkWidget *entry_po2, *entry_pn2, *entry_phe, *entry_mod, *entry_gflow, *entry_gfhigh;                                                                                                             
        const char *current_default, *new_default;                                                                                                                                                         
        char threshold_text[10], utf8_buf[128];                                                                                                                                                            
        struct preferences oldprefs = prefs;                                                                                                                                                               
@@ -722,6 +723,14 @@ static void preferences_dialog(GtkWidget *w, gpointer data)                                                                                                                           
        box = gtk_hbox_new(FALSE, 6);                                                                                                                                                                      
        gtk_container_add(GTK_CONTAINER(vbox), box);                                                                                                                                                       
                                                                                                                                                                                                           
+       button = gtk_check_button_new_with_label(_("Show MOD, EAD, END, EADD"));                                                                                                                           
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), prefs.mod);                                                                                                                                
+       gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 6);                                                                                                                                         
+       g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(mod_toggle), NULL);                                                                                                                       
+
+       box = gtk_hbox_new(FALSE, 6);
+       gtk_container_add(GTK_CONTAINER(vbox), box);
+
        button = gtk_check_button_new_with_label(_("Show dc reported ceiling in red"));
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), prefs.profile_red_ceiling);
        gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 6);
diff --git a/main.c b/main.c
index a0cd313..c88551d 100644
--- a/main.c
+++ b/main.c
@@ -27,6 +27,7 @@ struct preferences default_prefs = {
                .pn2_threshold =  4.0,
                .phe_threshold = 13.0,
        },
+       .mod  = FALSE,
        .profile_red_ceiling  = FALSE,
        .profile_calc_ceiling = FALSE,
        .calc_ceiling_3m_incr = FALSE,
diff --git a/planner.c b/planner.c
index c1b0fb4..9494d51 100644
--- a/planner.c
+++ b/planner.c
@@ -125,7 +125,7 @@ int time_at_last_depth(struct dive *dive, int next_stop, char **cached_data_p)
        depth = sample->depth.mm;
        get_gas_from_events(&dive->dc, sample->time.seconds, &o2, &he);
        gasidx = get_gasidx(dive, o2, he);
-       while (deco_allowed_depth(tissue_tolerance, surface_pressure, dive, 1) > next_stop) {
+       while (deco_allowed_depth(tissue_tolerance, surface_pressure, dive, 1) > next_stop + 200) {
                wait++;
                tissue_tolerance = add_segment(depth_to_mbar(depth, dive) / 1000.0,
                                               &dive->cylinder[gasidx].gasmix, 1, sample->po2, dive);
diff --git a/pref.h b/pref.h
index 342c9f6..2c656fd 100644
--- a/pref.h
+++ b/pref.h
@@ -25,6 +25,7 @@ struct preferences {
        struct units units;
        visible_cols_t visible_cols;
        partial_pressure_graphs_t pp_graphs;
+       gboolean mod;
        gboolean profile_red_ceiling;
        gboolean profile_calc_ceiling;
        gboolean calc_ceiling_3m_incr;
diff --git a/prefs.c b/prefs.c
index b6ae4ee..4b6b5d8 100644
--- a/prefs.c
+++ b/prefs.c
@@ -85,6 +85,7 @@ void save_preferences(void)
        SAVE_DOUBLE("pn2threshold", pp_graphs.pn2_threshold);
        SAVE_DOUBLE("phethreshold", pp_graphs.phe_threshold);
 
+       SAVE_BOOL("mod", mod);
        SAVE_BOOL("redceiling", profile_red_ceiling);
        SAVE_BOOL("calcceiling", profile_calc_ceiling);
        SAVE_BOOL("calcceiling3m", calc_ceiling_3m_incr);
@@ -149,6 +150,7 @@ void load_preferences(void)
                sscanf(conf_value, "%lf", &prefs.pp_graphs.phe_threshold);
                free((void *)conf_value);
        }
+       GET_BOOL("mod", mod);
        GET_BOOL("redceiling", profile_red_ceiling);
        GET_BOOL("calcceiling", profile_calc_ceiling);
        GET_BOOL("calcceiling3m", calc_ceiling_3m_incr);
diff --git a/profile.c b/profile.c
index ccca599..50f27de 100644
--- a/profile.c
+++ b/profile.c
@@ -46,6 +46,7 @@ struct plot_data {
        int cns;
        int smoothed;
        double po2, pn2, phe;
+       int mod, ead, end, eadd;
        velocity_t velocity;
        struct plot_data *min[3];
        struct plot_data *max[3];
@@ -1820,6 +1821,7 @@ static void calculate_deco_information(struct dive *dive, struct divecomputer *d
        int i;
        double amb_pressure;
        double surface_pressure = (dive->surface_pressure.mbar ? dive->surface_pressure.mbar : 1013) / 1000.0;
+       const char *depth_unit;
 
        for (i = 1; i < pi->nr; i++) {
                int fo2, fhe, j, t0, t1;
@@ -1840,11 +1842,31 @@ static void calculate_deco_information(struct dive *dive, struct divecomputer *d
                        entry->phe = (amb_pressure - po2) * ratio;
                        entry->pn2 = amb_pressure - po2 - entry->phe;
                        entry->po2 = po2;
+
+                        entry->ead  = (entry->depth/1000 + 10) * (entry->po2+(amb_pressure-entry->po2)*(1-ratio))/amb_pressure - 10; // no rounding! (equla to -9.5)
+                        entry->end  = (entry->depth/1000 + 10) * (amb_pressure-entry->po2)*(1-ratio)/amb_pressure/N2_IN_AIR - 10;
+                        entry->eadd = (entry->depth/1000 + 10) * (entry->po2/amb_pressure * O2_DENSITY + entry->pn2/amb_pressure * N2_DENSITY + entry->phe/amb_pressure * HE_DENSITY) / (O2_IN_AIR * O2_DENSITY + N2_IN_AIR * N2_DENSITY) -10;
                } else {
                        entry->po2 = fo2 / 1000.0 * amb_pressure;
                        entry->phe = fhe / 1000.0 * amb_pressure;
                        entry->pn2 = (1000 - fo2 - fhe) / 1000.0 * amb_pressure;
+
+                        entry->ead = (entry->depth/1000 + 10) * (1000 - fhe) / 1000.0 - 10;
+                        entry->end = (entry->depth/1000 + 10) * (1000 - fo2 - fhe) / 1000.0 / N2_IN_AIR - 10;
+                        entry->eadd = (entry->depth/1000 + 10) * (fo2 * O2_DENSITY + (1-fo2-fhe) * N2_DENSITY + fhe * HE_DENSITY) / (O2_IN_AIR * O2_DENSITY + N2_IN_AIR * N2_DENSITY) -10;
+               }
+               entry->mod = (1.6/fo2*1000 -1) * (strcmp(depth_unit, "m") ? 33 : 10);
+
+               // Convert to Feet if necessary
+               get_depth_units(entry->depth, NULL, &depth_unit);
+               if(strcmp(depth_unit, "m"))
+               {
+                 entry->ead = mm_to_feet(entry->ead*1000);
+                 entry->end = mm_to_feet(entry->end*1000);
+                 entry->eadd = mm_to_feet(entry->eadd*1000);
+                 entry->mod = mm_to_feet(entry->mod*1000);
                }
+
                if (entry->po2 > pi->maxpp)
                        pi->maxpp = entry->po2;
                if (entry->phe > pi->maxpp)
@@ -2141,6 +2163,10 @@ static void plot_string(struct plot_data *entry, char *buf, size_t bufsize,
                memcpy(buf2, buf, bufsize);
                snprintf(buf, bufsize, "%s\npHe:%.2f", buf2, entry->phe);
        }
+       if (prefs.mod) {
+               memcpy(buf2, buf, bufsize);
+               snprintf(buf, bufsize, "%s\nMOD1.6:%d%s\nEAD:%d%s\nEND:%d%s\nEADD:%d%s", buf2, entry->mod, depth_unit, entry->ead, depth_unit, entry->end, depth_unit, entry->eadd, depth_unit);
+       }
        free(buf2);
 }



More information about the subsurface mailing list