diff options
author | willem ferguson <willemferguson@zoology.up.ac.za> | 2014-08-30 17:46:47 +0200 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2014-09-11 08:32:10 -0700 |
commit | d1c521ce5ef6521c762a6e343c6fa9e878859cfd (patch) | |
tree | 507aa575e87d72ce6d6c95febfb50678f6492d97 | |
parent | 7bf65e3f0bad9a2c2c1c55d0999dfeabfae922d2 (diff) | |
download | subsurface-d1c521ce5ef6521c762a6e343c6fa9e878859cfd.tar.gz |
CCR patch: adapt code for diluent cylinder pressures (3)
This patch implements the cylinder pressure calculations for diluent
gas in CCR dive computers. This is the third patch for achieving this.
The following were performed:
1) Add two lines to try_to_fill_sample() in parse-xml so that
diluent cylinder pressures are stored from XML dive log file
into structures of sample.
2) Add one line to populate_plot_entries() in profile.c so that
the diluent cylinder pressures are copied from structures of
sample to structures of plot_info.
3) add three constant #defines in profile.h
4) change populate_pressure_information() in gaspressures.c in
order to take into account pressure calculations for the
diluent cylinder, calling subordinate functions in the
appropriate way.
5) change create_plot_info_new() in profile.c in order to initiate
the pressure calculations for the diluent cylinder.
6) Implement two debugging functions (one in profile.c, another
in gaspressures.c). These debugging functions are activated
by means of #defines.
Two function calls dealing with oxygen pressure are currently commented
out. They will be activated in the following patch that attends to CCR
oxygen partial pressure calculation.
[Dirk Hohndel: rather massive whitespace cleanup]
Signed-off-by: willem ferguson <willemferguson@zoology.up.ac.za>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r-- | gaspressures.c | 63 | ||||
-rw-r--r-- | parse-xml.c | 2 | ||||
-rw-r--r-- | profile.c | 70 | ||||
-rw-r--r-- | profile.h | 2 |
4 files changed, 109 insertions, 28 deletions
diff --git a/gaspressures.c b/gaspressures.c index be63f8714..3155a90ad 100644 --- a/gaspressures.c +++ b/gaspressures.c @@ -316,19 +316,46 @@ static inline int calc_pressure_time(struct dive *dive, struct divecomputer *dc, return depth_to_mbar(depth, dive) * time; } -void populate_pressure_information(struct dive *dive, struct divecomputer *dc, struct plot_info *pi) +#ifdef PRINT_PRESSURES_DEBUG +// A CCR debugging tool that prints the gas pressures in cylinder 0 and in the diluent cylinder, used in populate_pressure_information(): +static void debug_print_pressures(struct plot_info *pi) { - int i, cylinderindex; + int i; + for (i = 0; i < pi->nr; i++) { + struct plot_data *entry = pi->entry + i; + printf("%5d |%9d | %9d || %9d | %9d |\n", i, SENSOR_PRESSURE(entry), INTERPOLATED_PRESSURE(entry), DILUENT_PRESSURE(entry), INTERPOLATED_DILUENT_PRESSURE(entry)); + } +} +#endif + +/* This function goes through the list of tank pressures, either SENSOR_PRESSURE(entry) or DILUENT_PRESSURE(entry), + * of structure plot_info for the dive profile where each item in the list corresponds to one point (node) of the + * profile. It finds values for which there are no tank pressures (pressure==0). For each missing item (node) of + * tank pressure it creates a pr_track_alloc structure that represents a segment on the dive profile and that + * contains tank pressures. There is a linked list of pr_track_alloc structures for each cylinder. These pr_track_alloc + * structures ultimately allow for filling the missing tank pressure values on the dive profile using the depth_pressure + * of the dive. To do this, it calculates the summed pressure-time value for the duration of the dive and stores these + * in the pr_track_alloc structures. If diluent_flag = 1, then DILUENT_PRESSURE(entry) is used instead of SENSOR_PRESSURE. + * This function is called by create_plot_info_new() in profile.c + */ +void populate_pressure_information(struct dive *dive, struct divecomputer *dc, struct plot_info *pi, int diluent_flag) +{ + int i, cylinderid, cylinderindex = -1; pr_track_t *track_pr[MAX_CYLINDERS] = { NULL, }; - pr_track_t *current; + pr_track_t *current = NULL; bool missing_pr = false; - cylinderindex = -1; - current = NULL; for (i = 0; i < pi->nr; i++) { struct plot_data *entry = pi->entry + i; - int pressure = SENSOR_PRESSURE(entry); - + unsigned pressure; + if (diluent_flag) { // if this is a diluent cylinder: + pressure = DILUENT_PRESSURE(entry); + cylinderid = DILUENT_CYLINDER; + } else { + pressure = SENSOR_PRESSURE(entry); + cylinderid = entry->cylinderindex; + } + /* If track_pr structure already exists, then update it: */ /* discrete integration of pressure over time to get the SAC rate equivalent */ if (current) { entry->pressure_time = calc_pressure_time(dive, dc, entry - 1, entry); @@ -336,9 +363,13 @@ void populate_pressure_information(struct dive *dive, struct divecomputer *dc, s current->t_end = entry->sec; } + /* If 1st record or different cylinder: Create a new track_pr structure: */ /* track the segments per cylinder and their pressure/time integral */ - if (entry->cylinderindex != cylinderindex) { - cylinderindex = entry->cylinderindex; + if (cylinderid != cylinderindex) { + if (diluent_flag) // For CCR dives: + cylinderindex = DILUENT_CYLINDER; // indicate diluent cylinder + else + cylinderindex = entry->cylinderindex; current = pr_track_alloc(pressure, entry->sec); track_pr[cylinderindex] = list_add(track_pr[cylinderindex], current); continue; @@ -348,21 +379,27 @@ void populate_pressure_information(struct dive *dive, struct divecomputer *dc, s missing_pr = 1; continue; } - current->end = pressure; /* Was it continuous? */ - if (SENSOR_PRESSURE(entry - 1)) + if ((diluent_flag) && (DILUENT_PRESSURE(entry - 1))) // in the case of CCR diluent pressure + continue; + else if (SENSOR_PRESSURE(entry - 1)) // for all other cylinders continue; - /* transmitter changed its working status */ + /* transmitter stopped transmitting cylinder pressure data */ current = pr_track_alloc(pressure, entry->sec); track_pr[cylinderindex] = list_add(track_pr[cylinderindex], current); } if (missing_pr) { - fill_missing_tank_pressures(dive, pi, track_pr, 0); + fill_missing_tank_pressures(dive, pi, track_pr, diluent_flag); } + +#ifdef PRINT_PRESSURES_DEBUG + debug_print_pressures(pi); +#endif + for (i = 0; i < MAX_CYLINDERS; i++) list_free(track_pr[i]); } diff --git a/parse-xml.c b/parse-xml.c index 8e0099d3e..02cf9f771 100644 --- a/parse-xml.c +++ b/parse-xml.c @@ -835,6 +835,8 @@ static void try_to_fill_sample(struct sample *sample, const char *name, char *bu return; if (MATCH("cylpress.sample", pressure, &sample->cylinderpressure)) return; + if (MATCH("pdiluent.sample", pressure, &sample->diluentpressure)) + return; if (MATCH("cylinderindex.sample", get_cylinderindex, &sample->sensor)) return; if (MATCH("sensor.sample", get_sensor, &sample->sensor)) @@ -21,10 +21,10 @@ unsigned int dc_number = 0; static struct plot_data *last_pi_entry_new = NULL; -void fill_missing_segment_pressures(pr_track_t*); -struct pr_interpolate_struct get_pr_interpolate_data(pr_track_t*, struct plot_info*, int); -void fill_missing_tank_pressures(struct dive*, struct plot_info*, pr_track_t**); -void populate_pressure_information(struct dive*, struct divecomputer*, struct plot_info*); +void fill_missing_segment_pressures(pr_track_t *); +struct pr_interpolate_struct get_pr_interpolate_data(pr_track_t *, struct plot_info *, int); +void fill_missing_tank_pressures(struct dive *, struct plot_info *, pr_track_t **, int); +void populate_pressure_information(struct dive *, struct divecomputer *, struct plot_info *, int); #ifdef DEBUG_PI /* debugging tool - not normally used */ @@ -554,6 +554,7 @@ struct plot_data *populate_plot_entries(struct dive *dive, struct divecomputer * /* FIXME! sensor index -> cylinder index translation! */ entry->cylinderindex = sample->sensor; SENSOR_PRESSURE(entry) = sample->cylinderpressure.mbar; + DILUENT_PRESSURE(entry) = sample->diluentpressure.mbar; if (sample->temperature.mkelvin) entry->temperature = lasttemp = sample->temperature.mkelvin; else @@ -839,15 +840,15 @@ static void calculate_gas_information_new(struct dive *dive, struct plot_info *p * so there is no difference in calculating between OC and CC * END takes O₂ + N₂ (air) into account ("Narcotic" for trimix dives) * EAD just uses N₂ ("Air" for nitrox dives) */ - pressure_t modpO2 = { .mbar = (int) (prefs.modpO2 * 1000) }; - entry->mod = (double) gas_mod(&dive->cylinder[cylinderindex].gasmix, modpO2, 1).mm; + pressure_t modpO2 = { .mbar = (int)(prefs.modpO2 * 1000) }; + entry->mod = (double)gas_mod(&dive->cylinder[cylinderindex].gasmix, modpO2, 1).mm; entry->end = (entry->depth + 10000) * (1000 - fhe) / 1000.0 - 10000; entry->ead = (entry->depth + 10000) * (1000 - fo2 - fhe) / (double)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) * 1000 - 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) * 1000 - 10000; if (entry->mod < 0) entry->mod = 0; if (entry->ead < 0) @@ -858,6 +859,31 @@ static void calculate_gas_information_new(struct dive *dive, struct plot_info *p entry->eadd = 0; } } + +#ifdef DEBUG_GAS +/* A CCR debug function that writes the cylinder pressure and the oxygen values to the file debug_print_profiledata.dat: + * Called in create_plot_info_new() + */ +static void debug_print_profiledata(struct plot_info *pi) +{ + FILE *f1; + struct plot_data *entry; + int i; + if (!(f1 = fopen("debug_print_profiledata.dat", "w"))) + printf("File open error for: debug_print_profiledata.dat\n"); + else { + fprintf(f1, "id t1 gas gasint t2 t3 dil dilint t4 t5 setpoint sensor1 sensor2 sensor3 t6 po2 fo2\n"); + for (i = 0; i < pi->nr; i++) { + entry = pi->entry + i; + fprintf(f1, "%d gas=%8d %8d ; dil=%8d %8d ; o2_sp= %f %f %f %f PO2= %f\n", i, SENSOR_PRESSURE(entry), + INTERPOLATED_PRESSURE(entry), DILUENT_PRESSURE(entry), INTERPOLATED_DILUENT_PRESSURE(entry), + entry->o2setpoint, entry->o2sensor[0], entry->o2sensor[1], entry->o2sensor[2], entry->po2); + } + fclose(f1); + } +} +#endif + /* * Create a plot-info with smoothing and ranged min/max * @@ -867,10 +893,13 @@ static void calculate_gas_information_new(struct dive *dive, struct plot_info *p */ void create_plot_info_new(struct dive *dive, struct divecomputer *dc, struct plot_info *pi) { - int o2, he, o2low; + FILE *f1; + int i, o2, he, o2low; + struct plot_data *entry; init_decompression(dive); /* Create the new plot data */ free((void *)last_pi_entry_new); + get_dive_gas(dive, &o2, &he, &o2low); if (he > 0) { pi->dive_type = TRIMIX; @@ -881,12 +910,23 @@ void create_plot_info_new(struct dive *dive, struct divecomputer *dc, struct plo pi->dive_type = AIR; } last_pi_entry_new = populate_plot_entries(dive, dc, pi); - check_gas_change_events(dive, dc, pi); /* Populate the gas index from the gas change events */ - setup_gas_sensor_pressure(dive, dc, pi); /* Try to populate our gas pressure knowledge */ - populate_pressure_information(dive, dc, pi); /* .. calculate missing pressure entries */ - calculate_sac(dive, pi); /* Calculate sac */ + + check_gas_change_events(dive, dc, pi); /* Populate the gas index from the gas change events */ + setup_gas_sensor_pressure(dive, dc, pi); /* Try to populate our gas pressure knowledge */ + populate_pressure_information(dive, dc, pi, NONDILUENT); /* .. calculate missing pressure entries for all gasses except diluent */ + if (dc->dctype == CCR) { /* For CCR dives.. */ + printf("REBREATHER; %d O2 sensors\n", dc->no_o2sensors); + populate_pressure_information(dive, dc, pi, DILUENT); /* .. calculate missing diluent gas pressure entries */ +// fill_o2_values(dc, pi); /* .. and insert the O2 sensor data having 0 values. */ + } + calculate_sac(dive, pi); /* Calculate sac */ calculate_deco_information(dive, dc, pi, false); calculate_gas_information_new(dive, pi); /* And finaly calculate gas partial pressures */ + +#ifdef DEBUG_GAS + debug_print_profiledata(pi); +#endif + pi->meandepth = dive->dc.meandepth.mm; analyze_plot_info(pi); } @@ -86,6 +86,8 @@ int get_maxtime(struct plot_info *pi); int get_maxdepth(struct plot_info *pi); #define DILUENT_CYLINDER 1 +#define DILUENT 1 +#define NONDILUENT 0 #define SENSOR_PR 0 #define INTERPOLATED_PR 1 #define SENSOR_PRESSURE(_entry) (_entry)->pressure[SENSOR_PR] |