mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Some gas handling improvements
Add a time linear gas interpolation strategy. Some minor changes. Signed-off-by: Robert C. Helling <helling@atdotde.de> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
5034f76072
commit
84dc8b8962
5 changed files with 38 additions and 25 deletions
4
dive.c
4
dive.c
|
@ -1062,8 +1062,8 @@ unsigned int dc_airtemp(struct divecomputer *dc)
|
||||||
|
|
||||||
static void fixup_cylinder_use(struct dive *dive) // for CCR dives, store the indices
|
static void fixup_cylinder_use(struct dive *dive) // for CCR dives, store the indices
|
||||||
{ // of the oxygen and diluent cylinders
|
{ // of the oxygen and diluent cylinders
|
||||||
dive->oxygen_cylinder_index = get_cylinder_use(dive, oxygen);
|
dive->oxygen_cylinder_index = get_cylinder_use(dive, OXYGEN);
|
||||||
dive->diluent_cylinder_index = get_cylinder_use(dive, diluent);
|
dive->diluent_cylinder_index = get_cylinder_use(dive, DILUENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fixup_airtemp(struct dive *dive)
|
static void fixup_airtemp(struct dive *dive)
|
||||||
|
|
2
dive.h
2
dive.h
|
@ -48,7 +48,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum dive_comp_type {OC, CCR, PSCR}; // Flags (Open-circuit and Closed-circuit-rebreather) for setting dive computer type
|
enum dive_comp_type {OC, CCR, PSCR}; // Flags (Open-circuit and Closed-circuit-rebreather) for setting dive computer type
|
||||||
enum cylinderuse {oxygen, diluent, bailout}; // The different uses for cylinders in CCR dives
|
enum cylinderuse {OC_GAS, DILUENT, OXYGEN}; // The different uses for cylinders
|
||||||
|
|
||||||
struct gasmix {
|
struct gasmix {
|
||||||
fraction_t o2;
|
fraction_t o2;
|
||||||
|
|
4
file.c
4
file.c
|
@ -507,14 +507,14 @@ int parse_txt_file(const char *filename, const char *csv)
|
||||||
dive->dc.dctype = CCR;
|
dive->dc.dctype = CCR;
|
||||||
dive->dc.no_o2sensors = 2;
|
dive->dc.no_o2sensors = 2;
|
||||||
|
|
||||||
dive->cylinder[cur_cylinder_index].cylinder_use = oxygen;
|
dive->cylinder[cur_cylinder_index].cylinder_use = OXYGEN;
|
||||||
dive->cylinder[cur_cylinder_index].type.size.mliter = 3000;
|
dive->cylinder[cur_cylinder_index].type.size.mliter = 3000;
|
||||||
dive->cylinder[cur_cylinder_index].type.workingpressure.mbar = 200000;
|
dive->cylinder[cur_cylinder_index].type.workingpressure.mbar = 200000;
|
||||||
dive->cylinder[cur_cylinder_index].type.description = strdup("3l Mk6");
|
dive->cylinder[cur_cylinder_index].type.description = strdup("3l Mk6");
|
||||||
dive->cylinder[cur_cylinder_index].gasmix.o2.permille = 1000;
|
dive->cylinder[cur_cylinder_index].gasmix.o2.permille = 1000;
|
||||||
cur_cylinder_index++;
|
cur_cylinder_index++;
|
||||||
|
|
||||||
dive->cylinder[cur_cylinder_index].cylinder_use = diluent;
|
dive->cylinder[cur_cylinder_index].cylinder_use = DILUENT;
|
||||||
dive->cylinder[cur_cylinder_index].type.size.mliter = 3000;
|
dive->cylinder[cur_cylinder_index].type.size.mliter = 3000;
|
||||||
dive->cylinder[cur_cylinder_index].type.workingpressure.mbar = 200000;
|
dive->cylinder[cur_cylinder_index].type.workingpressure.mbar = 200000;
|
||||||
dive->cylinder[cur_cylinder_index].type.description = strdup("3l Mk6");
|
dive->cylinder[cur_cylinder_index].type.description = strdup("3l Mk6");
|
||||||
|
|
|
@ -97,7 +97,7 @@ static void dump_pr_track(pr_track_t **track_pr)
|
||||||
* segments according to how big of a time_pressure area
|
* segments according to how big of a time_pressure area
|
||||||
* they have.
|
* they have.
|
||||||
*/
|
*/
|
||||||
static void fill_missing_segment_pressures(pr_track_t *list)
|
static void fill_missing_segment_pressures(pr_track_t *list, enum interpolation_strategy strategy)
|
||||||
{
|
{
|
||||||
while (list) {
|
while (list) {
|
||||||
int start = list->start, end;
|
int start = list->start, end;
|
||||||
|
@ -128,17 +128,29 @@ static void fill_missing_segment_pressures(pr_track_t *list)
|
||||||
*/
|
*/
|
||||||
list->start = start;
|
list->start = start;
|
||||||
tmp->end = end;
|
tmp->end = end;
|
||||||
for (;;) {
|
switch (strategy) {
|
||||||
int pressure;
|
case SAC:
|
||||||
pt += list->pressure_time;
|
for (;;) {
|
||||||
pressure = start;
|
int pressure;
|
||||||
if (pt_sum)
|
pt += list->pressure_time;
|
||||||
pressure -= (start - end) * (double)pt / pt_sum;
|
pressure = start;
|
||||||
list->end = pressure;
|
if (pt_sum)
|
||||||
if (list == tmp)
|
pressure -= (start - end) * (double)pt / pt_sum;
|
||||||
break;
|
list->end = pressure;
|
||||||
list = list->next;
|
if (list == tmp)
|
||||||
list->start = pressure;
|
break;
|
||||||
|
list = list->next;
|
||||||
|
list->start = pressure;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TIME:
|
||||||
|
if (list->t_end && (tmp->t_start - tmp->t_end))
|
||||||
|
list->end = start - (start - end) * (list->t_end - tmp->t_end) / (tmp->t_start - tmp->t_end);
|
||||||
|
else
|
||||||
|
list->end = start;
|
||||||
|
break;
|
||||||
|
case CONSTANT:
|
||||||
|
list->end = start;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ok, we've done that set of segments */
|
/* Ok, we've done that set of segments */
|
||||||
|
@ -155,12 +167,11 @@ void dump_pr_interpolate(int i, pr_interpolate_t interpolate_pr)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static struct pr_interpolate_struct get_pr_interpolate_data(pr_track_t *segment, struct plot_info *pi, int cur, int diluent_flag)
|
static struct pr_interpolate_struct get_pr_interpolate_data(pr_track_t *segment, struct plot_info *pi, int cur, int pressure)
|
||||||
{ // cur = index to pi->entry corresponding to t_end of segment; diluent_flag=1 indicates diluent cylinder
|
{ // cur = index to pi->entry corresponding to t_end of segment; diluent_flag=1 indicates diluent cylinder
|
||||||
struct pr_interpolate_struct interpolate;
|
struct pr_interpolate_struct interpolate;
|
||||||
int i;
|
int i;
|
||||||
struct plot_data *entry;
|
struct plot_data *entry;
|
||||||
int pressure;
|
|
||||||
|
|
||||||
interpolate.start = segment->start;
|
interpolate.start = segment->start;
|
||||||
interpolate.end = segment->end;
|
interpolate.end = segment->end;
|
||||||
|
@ -169,10 +180,6 @@ static struct pr_interpolate_struct get_pr_interpolate_data(pr_track_t *segment,
|
||||||
|
|
||||||
for (i = 0; i < pi->nr; i++) {
|
for (i = 0; i < pi->nr; i++) {
|
||||||
entry = pi->entry + i;
|
entry = pi->entry + i;
|
||||||
if (diluent_flag)
|
|
||||||
pressure = DILUENT_PRESSURE(entry);
|
|
||||||
else
|
|
||||||
pressure = SENSOR_PRESSURE(entry);
|
|
||||||
|
|
||||||
if (entry->sec < segment->t_start)
|
if (entry->sec < segment->t_start)
|
||||||
continue;
|
continue;
|
||||||
|
@ -219,12 +226,17 @@ static void fill_missing_tank_pressures(struct dive *dive, struct plot_info *pi,
|
||||||
int cur_pr[MAX_CYLINDERS]; // cur_pr[MAX_CYLINDERS] is the CCR diluent cylinder
|
int cur_pr[MAX_CYLINDERS]; // cur_pr[MAX_CYLINDERS] is the CCR diluent cylinder
|
||||||
|
|
||||||
for (cyl = 0; cyl < MAX_CYLINDERS; cyl++) {
|
for (cyl = 0; cyl < MAX_CYLINDERS; cyl++) {
|
||||||
|
enum interpolation_strategy strategy;
|
||||||
if (!track_pr[cyl]) {
|
if (!track_pr[cyl]) {
|
||||||
/* no segment where this cylinder is used */
|
/* no segment where this cylinder is used */
|
||||||
cur_pr[cyl] = -1;
|
cur_pr[cyl] = -1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
fill_missing_segment_pressures(track_pr[cyl]); // Interpolate the missing tank pressure values ..
|
if (dive->cylinder[cyl].cylinder_use == OC_GAS)
|
||||||
|
strategy = SAC;
|
||||||
|
else
|
||||||
|
strategy = TIME;
|
||||||
|
fill_missing_segment_pressures(track_pr[cyl], strategy); // Interpolate the missing tank pressure values ..
|
||||||
cur_pr[cyl] = track_pr[cyl]->start; // in the pr_track_t lists of structures
|
cur_pr[cyl] = track_pr[cyl]->start; // in the pr_track_t lists of structures
|
||||||
} // and keep the starting pressure for each cylinder.
|
} // and keep the starting pressure for each cylinder.
|
||||||
|
|
||||||
|
@ -279,7 +291,7 @@ static void fill_missing_tank_pressures(struct dive *dive, struct plot_info *pi,
|
||||||
continue; // and skip to next point.
|
continue; // and skip to next point.
|
||||||
}
|
}
|
||||||
// If there is a valid segment but no tank pressure ..
|
// If there is a valid segment but no tank pressure ..
|
||||||
interpolate = get_pr_interpolate_data(segment, pi, i, diluent_flag); // Set up an interpolation structure
|
interpolate = get_pr_interpolate_data(segment, pi, i, pressure); // Set up an interpolation structure
|
||||||
|
|
||||||
/* if this segment has pressure_time, then calculate a new interpolated pressure */
|
/* if this segment has pressure_time, then calculate a new interpolated pressure */
|
||||||
if (interpolate.pressure_time) {
|
if (interpolate.pressure_time) {
|
||||||
|
|
|
@ -27,6 +27,7 @@ struct pr_interpolate_struct {
|
||||||
int acc_pressure_time;
|
int acc_pressure_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum interpolation_strategy {SAC, TIME, CONSTANT};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue