diff options
-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] |