diff options
author | Dirk Hohndel <dirk@hohndel.org> | 2013-01-13 16:24:58 -0800 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2013-01-13 16:26:35 -0800 |
commit | 23ce727e62c5670ca30c487fc9fd52eb25883de5 (patch) | |
tree | 4e04981e3d7d6da34be745894a7b20116b871006 | |
parent | 53dbccb87a81313395fa6d3d48325389a070439b (diff) | |
download | subsurface-23ce727e62c5670ca30c487fc9fd52eb25883de5.tar.gz |
Add support for MOD, EAD, AND and EADD in the mouse over display
- MOD: Maximum Operation Depth based on a configurable limit
- 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. Considering A stands for Air, lets choose the
above. And considering N for Nitrogen it also fits in this scheme.
This patch moves N2_IN_AIR from deco.c to dive.h as this is already used
in several places and might be useful for future use also. 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.
Signed-off-by: Jan Schubert / Jan.Schubert@GMX.li
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r-- | deco.c | 1 | ||||
-rw-r--r-- | dive.h | 7 | ||||
-rw-r--r-- | gtk-gui.c | 35 | ||||
-rw-r--r-- | main.c | 3 | ||||
-rw-r--r-- | pref.h | 3 | ||||
-rw-r--r-- | prefs.c | 10 | ||||
-rw-r--r-- | profile.c | 36 |
7 files changed, 90 insertions, 5 deletions
@@ -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 @@ -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.251 +#define HE_DENSITY 0.1786 + + /* * Some silly typedefs to make our units very explicit. * @@ -439,6 +439,8 @@ 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(ead_toggle, prefs.ead) 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,9 +531,9 @@ 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_ead, *entry_gflow, *entry_gfhigh; const char *current_default, *new_default; - char threshold_text[10], utf8_buf[128]; + char threshold_text[10], mod_text[10], utf8_buf[128]; struct preferences oldprefs = prefs; dialog = gtk_dialog_new_with_buttons(_("Preferences"), @@ -722,6 +724,31 @@ 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")); + 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), &entry_mod); + + frame = gtk_frame_new(_("max ppO2")); + gtk_box_pack_start(GTK_BOX(box), frame, FALSE, FALSE, 6); + entry_mod = gtk_entry_new(); + gtk_entry_set_max_length(GTK_ENTRY(entry_mod), 4); + snprintf(mod_text, sizeof(mod_text), "%.1f", prefs.mod_ppO2); + gtk_entry_set_text(GTK_ENTRY(entry_mod), mod_text); + gtk_widget_set_sensitive(entry_mod, prefs.mod); + gtk_container_add(GTK_CONTAINER(frame), entry_mod); + + box = gtk_hbox_new(FALSE, 6); + gtk_container_add(GTK_CONTAINER(vbox), box); + + button = gtk_check_button_new_with_label(_("Show EAD, END, EADD")); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), prefs.ead); + gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 6); + g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(ead_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); @@ -766,7 +793,7 @@ static void preferences_dialog(GtkWidget *w, gpointer data) gtk_widget_show_all(dialog); result = gtk_dialog_run(GTK_DIALOG(dialog)); if (result == GTK_RESPONSE_ACCEPT) { - const char *po2_threshold_text, *pn2_threshold_text, *phe_threshold_text, *gflow_text, *gfhigh_text; + const char *po2_threshold_text, *pn2_threshold_text, *phe_threshold_text, *mod_text, *gflow_text, *gfhigh_text; /* Make sure to flush any modified old dive data with old units */ update_dive(NULL); @@ -778,6 +805,8 @@ static void preferences_dialog(GtkWidget *w, gpointer data) sscanf(pn2_threshold_text, "%lf", &prefs.pp_graphs.pn2_threshold); phe_threshold_text = gtk_entry_get_text(GTK_ENTRY(entry_phe)); sscanf(phe_threshold_text, "%lf", &prefs.pp_graphs.phe_threshold); + mod_text = gtk_entry_get_text(GTK_ENTRY(entry_mod)); + sscanf(mod_text, "%lf", &prefs.mod_ppO2); gflow_text = gtk_entry_get_text(GTK_ENTRY(entry_gflow)); sscanf(gflow_text, "%lf", &prefs.gflow); gfhigh_text = gtk_entry_get_text(GTK_ENTRY(entry_gfhigh)); @@ -27,6 +27,9 @@ struct preferences default_prefs = { .pn2_threshold = 4.0, .phe_threshold = 13.0, }, + .mod = FALSE, + .mod_ppO2 = 1.6, + .ead = FALSE, .profile_red_ceiling = FALSE, .profile_calc_ceiling = FALSE, .calc_ceiling_3m_incr = FALSE, @@ -25,6 +25,9 @@ struct preferences { struct units units; visible_cols_t visible_cols; partial_pressure_graphs_t pp_graphs; + gboolean mod; + double mod_ppO2; + gboolean ead; gboolean profile_red_ceiling; gboolean profile_calc_ceiling; gboolean calc_ceiling_3m_incr; @@ -85,6 +85,9 @@ void save_preferences(void) SAVE_DOUBLE("pn2threshold", pp_graphs.pn2_threshold); SAVE_DOUBLE("phethreshold", pp_graphs.phe_threshold); + SAVE_BOOL("mod", mod); + SAVE_DOUBLE("modppO2", mod_ppO2); + SAVE_BOOL("ead", ead); SAVE_BOOL("redceiling", profile_red_ceiling); SAVE_BOOL("calcceiling", profile_calc_ceiling); SAVE_BOOL("calcceiling3m", calc_ceiling_3m_incr); @@ -149,6 +152,13 @@ void load_preferences(void) sscanf(conf_value, "%lf", &prefs.pp_graphs.phe_threshold); free((void *)conf_value); } + GET_BOOL("mod", mod); + conf_value = subsurface_get_conf("modppO2"); + if (conf_value) { + sscanf(conf_value, "%lf", &prefs.mod_ppO2); + free((void *)conf_value); + } + GET_BOOL("ead", ead); GET_BOOL("redceiling", profile_red_ceiling); GET_BOOL("calcceiling", profile_calc_ceiling); GET_BOOL("calcceiling3m", calc_ceiling_3m_incr); @@ -46,6 +46,7 @@ struct plot_data { int cns; int smoothed; double po2, pn2, phe; + double mod, ead, end, eadd; velocity_t velocity; struct plot_data *min[3]; struct plot_data *max[3]; @@ -1835,11 +1836,32 @@ 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 + 10000) * + (entry->po2+(amb_pressure-entry->po2)*(1-ratio))/amb_pressure - 10000; + entry->end = (entry->depth + 10000) * + (amb_pressure-entry->po2)*(1-ratio)/amb_pressure/N2_IN_AIR - 10000; + entry->eadd = (entry->depth + 10000) * + (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) -10000; } 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 + 10000) * (1000 - fhe) / 1000.0 - 10000; + entry->end = (entry->depth + 10000) * (1000 - fo2 - fhe) / 1000.0 / N2_IN_AIR - 10000; + entry->eadd = (entry->depth + 10000) * (fo2 * O2_DENSITY + (1-fo2-fhe) * N2_DENSITY + fhe * HE_DENSITY) / (O2_IN_AIR * O2_DENSITY + N2_IN_AIR * N2_DENSITY) -10000; } + entry->mod = (prefs.mod_ppO2/fo2*1000 - 1) * 10000; + if(entry->mod <0) + entry->mod=0; + if(entry->ead <0) + entry->ead=0; + if(entry->end <0) + entry->end=0; + if(entry->eadd <0) + entry->eadd=0; if (entry->po2 > pi->maxpp && prefs.pp_graphs.po2) pi->maxpp = entry->po2; if (entry->phe > pi->maxpp && prefs.pp_graphs.phe) @@ -2070,7 +2092,7 @@ void plot(struct graphics_context *gc, struct dive *dive, scale_mode_t scale) static void plot_string(struct plot_data *entry, char *buf, size_t bufsize, int depth, int pressure, int temp, gboolean has_ndl) { - int pressurevalue; + int pressurevalue, mod, ead, end, eadd; const char *depth_unit, *pressure_unit, *temp_unit; char *buf2 = malloc(bufsize); double depthvalue, tempvalue; @@ -2136,6 +2158,18 @@ 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) { + mod = (int)get_depth_units(entry->mod, NULL, &depth_unit); + memcpy(buf2, buf, bufsize); + snprintf(buf, bufsize, "%s\nMOD:%d%s", buf2, mod, depth_unit); + } + if (prefs.ead) { + ead = (int)get_depth_units(entry->ead, NULL, &depth_unit); + end = (int)get_depth_units(entry->end, NULL, &depth_unit); + eadd = (int)get_depth_units(entry->eadd, NULL, &depth_unit); + memcpy(buf2, buf, bufsize); + snprintf(buf, bufsize, "%s\nEAD:%d%s\nEND:%d%s\nEADD:%d%s", buf2, ead, depth_unit, end, depth_unit, eadd, depth_unit); + } free(buf2); } |