Two patches attached to enhance CCR data processing:
(1) Subject: [PATCH] Correct the adjustment of cylinder end pressures for CCR
In order to effect deco calculations for CCR, value of first_cylinder in dive.c is forced to the cylinder index of the diluent cylinder. This causes a malfunction in the assignment of end pressures of CCR dives (function fixup_pressures() in dive.c). This patch does two things: 1) It modifies fixup_pressures() to be compatible with calling parameters for processing CCR dives. 2) Function fixup_dive_dc() in dive.c is changed to provide for an alternative processing path in the case of CCR dives. Because of the correct initialisation of cylinder end pressures for CCR dives, the value displayed for the diluent cylinder end pressure in the Equipment tab is correct. Signed-off-by: willem ferguson <[email protected]> (2) Subject: [PATCH] Adapt cylinder pressure interpolation for CCR This patch is necessitated by the change in code that now, for CCR dives, causes explicit_first_cylinder() in dive.c to force the first cylinder to be the diluent cylinder. There is now a need to change the assignment of cylinder index values so that the three cases: a) Oxygen cylinder b) Diluent cylinder c) Open-circuit cylinder are treated correctly in the code that interpolates the cylinder pressures. This is achieved as follows: 1) in file.c, for Poseidon input, ensure that the cylinder index is hard-coded by setting sample->sensor to 0. 2) For the three cases above, ensure that function populate_pressure_information() in gaspressures.c assigns the correct cylinder indices. This is performed by using a small lookup-table, rather than using complex if--else constructs. 3) For the function fill_missing_tank_pressures() in gaspressures.c provide the appropriate cylinder index, depending on which of the three cases mentioned above. The descriptive comments for these functions have heen edited. Signed-off-by: willem ferguson <[email protected]>
>From a552fcf77be7feaa845b7c59423738f652c1ebf2 Mon Sep 17 00:00:00 2001 From: willem ferguson <[email protected]> Date: Sat, 8 Nov 2014 11:31:43 +0200 Subject: [PATCH] Correct the adjustment of cylinder end pressures for CCR In order to effect deco calculations for CCR, value of first_cylinder in dive.c is forced to the cylinder index of the diluent cylinder. This causes a malfunction in the assignment of end pressures of CCR dives (function fixup_pressures() in dive.c). This patch does two things: 1) It modifies fixup_pressures() to be compatible with calling parameters for processing CCR dives. 2) Function fixup_dive_dc() in dive.c is changed to provide for an alternative processing path in the case of CCR dives. Because of the correct initialisation of cylinder end pressures for CCR dives, the value displayed for the diluent cylinder end pressure in the Equipment tab is correct. Signed-off-by: willem ferguson <[email protected]> --- dive.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/dive.c b/dive.c index ccd071c..c8b5ef9 100644 --- a/dive.c +++ b/dive.c @@ -728,23 +728,16 @@ void per_cylinder_mean_depth(struct dive *dive, struct divecomputer *dc, int *me } } -static void fixup_pressure(struct dive *dive, struct sample *sample) +/* If the start or end pressures of a cylinder are undefined, then initialise them */ +static void fixup_pressure(struct dive *dive, int cylinder_index, int pressure) { - int pressure, index; cylinder_t *cyl; - - pressure = sample->cylinderpressure.mbar; - if (!pressure) - return; - index = sample->sensor; - - /* FIXME! sensor -> cylinder mapping? */ - if (index >= MAX_CYLINDERS) - return; - cyl = dive->cylinder + index; - if (!cyl->sample_start.mbar) - cyl->sample_start.mbar = pressure; - cyl->sample_end.mbar = pressure; + if ((pressure) && (cylinder_index < MAX_CYLINDERS)) { + cyl = dive->cylinder + cylinder_index; + if (!cyl->sample_start.mbar) + cyl->sample_start.mbar = pressure; + cyl->sample_end.mbar = pressure; + } } static void update_min_max_temperatures(struct dive *dive, temperature_t temperature) @@ -806,7 +799,8 @@ int explicit_first_cylinder(struct dive *dive, struct divecomputer *dc) if (ev && dc && dc->sample && ev->time.seconds == dc->sample[0].time.seconds) return get_cylinder_index(dive, ev); else - return 0; +// return 0; + return dc->dctype == CCR ? get_cylinder_use(dive, diluent) : 0; } void sanitize_gasmix(struct gasmix *mix) @@ -1184,7 +1178,13 @@ static void fixup_dive_dc(struct dive *dive, struct divecomputer *dc) maxdepth = depth; } - fixup_pressure(dive, sample); + // Ensure the begin and end pressures of each cylinder contains sensible values + if (dc->dctype != CCR) { // Open Circuit dives: + fixup_pressure(dive, sample->sensor, sample->cylinderpressure.mbar); + } else { // CCR dives: + fixup_pressure(dive, get_cylinder_use(dive, oxygen), sample->cylinderpressure.mbar); + fixup_pressure(dive, get_cylinder_use(dive, diluent), sample->diluentpressure.mbar); + } if (temp) { if (!mintemp || temp < mintemp) -- 1.9.1
>From 06c8d3aeac60e8d173c3865bdb1a485a79ff74c9 Mon Sep 17 00:00:00 2001 From: willem ferguson <[email protected]> Date: Sat, 8 Nov 2014 14:01:38 +0200 Subject: [PATCH] Adapt cylinder pressure interpolation for CCR This patch is necessitated by the change in code that now, for CCR dives, causes explicit_first_cylinder() in dive.c to force the first cylinder to be the diluent cylinder. There is now a need to change the assignment of cylinder index values so that the three cases: a) Oxygen cylinder b) Diluent cylinder c) Open-circuit cylinder are treated correctly in the code that interpolates the cylinder pressures. This is achieved as follows: 1) in file.c, for Poseidon input, ensure that the cylinder index is hard-coded by setting sample->sensor to 0. 2) For the three cases above, ensure that function populate_pressure_information() in gaspressures.c assigns the correct cylinder indices. Ths is performed by using a small lookup-table, rather than using complex if--else constructs. 3) For the function fill_missing_tank_pressures() in gaspressures.c provide the appropriate cylinder index, depending on which of the three cases mentioned above. The descriptive comments for these functions have heen edited. Signed-off-by: willem ferguson <[email protected]> --- file.c | 1 + gaspressures.c | 91 ++++++++++++++++++++++++++++++++-------------------------- profile.c | 2 +- 3 files changed, 53 insertions(+), 41 deletions(-) diff --git a/file.c b/file.c index dfc21e9..c5918ff 100644 --- a/file.c +++ b/file.c @@ -530,6 +530,7 @@ int parse_txt_file(const char *filename, const char *csv) has_setpoint = false; sample = prepare_sample(dc); sample->time.seconds = cur_sampletime; + sample->sensor = 0; do { int i = sscanf(lineptr, "%d,%d,%d", &sampletime, &type, &value); diff --git a/gaspressures.c b/gaspressures.c index 3155a90..ffed03b 100644 --- a/gaspressures.c +++ b/gaspressures.c @@ -22,6 +22,8 @@ #include "profile.h" #include "gaspressures.h" +//#define DEBUG_PR_TRACK 1 + static pr_track_t *pr_track_alloc(int start, int t_start) { pr_track_t *pt = malloc(sizeof(pr_track_t)); @@ -212,19 +214,21 @@ static struct pr_interpolate_struct get_pr_interpolate_data(pr_track_t *segment, return interpolate; } + static void fill_missing_tank_pressures(struct dive *dive, struct plot_info *pi, pr_track_t **track_pr, int diluent_flag) { int cyl, i; struct plot_data *entry; - int cur_pr[MAX_CYLINDERS]; // cur_pr[MAX_CYLINDERS] is the CCR diluent cylinder + int cur_pr[MAX_CYLINDERS]; + enum dive_comp_type dc_type = dive->dc.dctype; + int cyl_index_lookup[2][2] = { { 0, 0 }, { get_cylinder_use(dive, oxygen) , get_cylinder_use(dive, diluent)} }; for (cyl = 0; cyl < MAX_CYLINDERS; cyl++) { - if (!track_pr[cyl]) { - /* no segment where this cylinder is used */ - cur_pr[cyl] = -1; + if (!track_pr[cyl]) { // Mark the cur_pr for cylinders with no + cur_pr[cyl] = -1; // data or no empty pressure values with a -1. continue; } - fill_missing_segment_pressures(track_pr[cyl]); // Interpolate the missing tank pressure values .. + fill_missing_segment_pressures(track_pr[cyl]); // Interpolate the end tank pressure values .. cur_pr[cyl] = track_pr[cyl]->start; // in the pr_track_t lists of structures } // and keep the starting pressure for each cylinder. @@ -242,7 +246,7 @@ static void fill_missing_tank_pressures(struct dive *dive, struct plot_info *pi, * to the plot_info structure, allowing us to plot the tank pressure. * * The first two pi structures are "fillers", but in case we don't have a sample - * at time 0 we need to process the second of them here, therefore i=1 */ + * at time 0 we need to process the second of them here, therefore below, i=1 */ for (i = 1; i < pi->nr; i++) { // For each point on the profile: double magic; pr_track_t *segment; @@ -251,17 +255,20 @@ static void fill_missing_tank_pressures(struct dive *dive, struct plot_info *pi, int *save_pressure, *save_interpolated; entry = pi->entry + i; + cyl_index_lookup[0][0] = entry->cylinderindex; - if (diluent_flag) { // Find the cylinder index (cyl) .. - cyl = DILUENT_CYLINDER; // .. as well as the cylinder pressure + /* Perform a table lookup to find the appropriate cylinder index, using the + * array cyl_index_lookup[2][2] */ + cyl = cyl_index_lookup[dc_type][diluent_flag]; + + if (diluent_flag) { // for CCR diluent gas pressure = DILUENT_PRESSURE(entry); save_pressure = &(entry->diluentpressure[SENSOR_PR]); save_interpolated = &(entry->diluentpressure[INTERPOLATED_PR]); - } else { + } else { // Open Circuit and for CCR oxygen pressure = SENSOR_PRESSURE(entry); save_pressure = &(entry->pressure[SENSOR_PR]); save_interpolated = &(entry->pressure[INTERPOLATED_PR]); - cyl = entry->cylinderindex; } if (pressure) { // If there is a valid pressure value, @@ -293,7 +300,6 @@ static void fill_missing_tank_pressures(struct dive *dive, struct plot_info *pi, } } - /* * What's the pressure-time between two plot data entries? * We're calculating the integral of pressure over time by @@ -329,13 +335,13 @@ static void debug_print_pressures(struct plot_info *pi) #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. + * within 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 stretch of the dive log + * for which there are no pressures, it creates a pr_track_t structure which contains 1) the tank pressure at the + * start of the gap and at the end of the gap; 2) the times at the beginning and end of the gap; 3) the summed + * time-pressure values (based on depth) for all the segments in the gap with no cylinder pressure data. These pr_track_t + * structures ultimately allow for filling the missing tank pressure values on the dive profile using the depth_pressures + * of the dive. 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) @@ -344,55 +350,60 @@ void populate_pressure_information(struct dive *dive, struct divecomputer *dc, s pr_track_t *track_pr[MAX_CYLINDERS] = { NULL, }; pr_track_t *current = NULL; bool missing_pr = false; + enum dive_comp_type dc_type = dc->dctype; + + /* This lookup table allows lookup of appropriate cylinder IDs. It uses dc->dctype and diluent_flag as + * indices and asumes that the mumeric assignments of these two variables will not change. The table + * avoids the need for complex if-else constructs.*/ + int cyl_index_lookup[2][2] = { { 0, 0 }, { get_cylinder_use(dive, oxygen) , get_cylinder_use(dive, diluent)} }; +// int (*lookup_cyl_ptr)[2][2] = &cyl_index_lookup; for (i = 0; i < pi->nr; i++) { struct plot_data *entry = pi->entry + i; unsigned pressure; - if (diluent_flag) { // if this is a diluent cylinder: + cyl_index_lookup[0][0] = entry->cylinderindex; + + cylinderid = cyl_index_lookup[dc_type][diluent_flag]; + if (diluent_flag) pressure = DILUENT_PRESSURE(entry); - cylinderid = DILUENT_CYLINDER; - } else { + 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); current->pressure_time += entry->pressure_time; - current->t_end = entry->sec; + current->t_end = entry->sec; // Store the pressure-time data } - /* If 1st record or different cylinder: Create a new track_pr structure: */ - /* track the segments per cylinder and their pressure/time integral */ + /* If 1st record or different cylinder: Create a new track_pr structure */ + /* ..and initialise the start pressure and time for this new linked list*/ if (cylinderid != cylinderindex) { - if (diluent_flag) // For CCR dives: - cylinderindex = DILUENT_CYLINDER; // indicate diluent cylinder - else - cylinderindex = entry->cylinderindex; + cylinderindex = cyl_index_lookup[dc_type][diluent_flag]; current = pr_track_alloc(pressure, entry->sec); track_pr[cylinderindex] = list_add(track_pr[cylinderindex], current); continue; } - if (!pressure) { - missing_pr = 1; + if (!pressure) { // If no pressure data then do not add another struct to linked list + missing_pr = 1; // ..and proceed to next sample continue; } current->end = pressure; - - /* Was it continuous? */ - if ((diluent_flag) && (DILUENT_PRESSURE(entry - 1))) // in the case of CCR diluent pressure - continue; + /* Are the pressure data continuous? */ + if (diluent_flag) { + if (DILUENT_PRESSURE(entry - 1)) // in the case of CCR diluent pressure + continue; + } else if (SENSOR_PRESSURE(entry - 1)) // for all other cylinders continue; - - /* transmitter stopped transmitting cylinder pressure data */ - current = pr_track_alloc(pressure, entry->sec); + /* If there is a gap in the pressure data recorded into the track_pr structures */ + current = pr_track_alloc(pressure, entry->sec); // add a new track_pr struct to the list track_pr[cylinderindex] = list_add(track_pr[cylinderindex], current); } - if (missing_pr) { + if (missing_pr) { // if there are missing pressures then do interpolation fill_missing_tank_pressures(dive, pi, track_pr, diluent_flag); } diff --git a/profile.c b/profile.c index 5bfe7b9..7aa45f7 100644 --- a/profile.c +++ b/profile.c @@ -18,7 +18,7 @@ #include "membuffer.h" -//#define DEBUG_GAS 1 +//#define DEBUG_GAS 1 int selected_dive = -1; /* careful: 0 is a valid value */ unsigned int dc_number = 0; -- 1.9.1
_______________________________________________ subsurface mailing list [email protected] http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface
