X-Git-Url: http://git.tdb.fi/?p=ext%2Fsubsurface.git;a=blobdiff_plain;f=dive.c;h=9f57aed58146554969901198ac761fc888904e18;hp=3fa09bd10c05982a9972c0db8a58a76314543f59;hb=618a20ba5f2a9adc0e5a35117535f8eaa9fd34a4;hpb=95cc317b087e863f6e0a4ab4db7ab68f06a9d969 diff --git a/dive.c b/dive.c index 3fa09bd..9f57aed 100644 --- a/dive.c +++ b/dive.c @@ -160,7 +160,7 @@ struct sample *prepare_sample(struct dive **divep) return NULL; } -void finish_sample(struct dive *dive, struct sample *sample) +void finish_sample(struct dive *dive) { dive->samples++; } @@ -234,6 +234,122 @@ static int same_rounded_pressure(pressure_t a, pressure_t b) return abs(a.mbar - b.mbar) <= 500; } +static void sanitize_gasmix(struct gasmix *mix) +{ + unsigned int o2, he; + + o2 = mix->o2.permille; + he = mix->he.permille; + + /* Regular air: leave empty */ + if (!he) { + if (!o2) + return; + /* 20.9% or 21% O2 is just air */ + if (o2 >= 209 && o2 <= 210) { + mix->o2.permille = 0; + return; + } + } + + /* Sane mix? */ + if (o2 <= 1000 && he <= 1000 && o2+he <= 1000) + return; + fprintf(stderr, "Odd gasmix: %d O2 %d He\n", o2, he); + memset(mix, 0, sizeof(*mix)); +} + +/* + * See if the size/workingpressure looks like some standard cylinder + * size, eg "AL80". + */ +static void match_standard_cylinder(cylinder_type_t *type) +{ + double cuft; + int psi, len; + const char *fmt; + char buffer[20], *p; + + /* Do we already have a cylinder description? */ + if (type->description) + return; + + cuft = ml_to_cuft(type->size.mliter); + cuft *= to_ATM(type->workingpressure); + psi = to_PSI(type->workingpressure); + + switch (psi) { + case 2300 ... 2500: /* 2400 psi: LP tank */ + fmt = "LP%d"; + break; + case 2600 ... 2700: /* 2640 psi: LP+10% */ + fmt = "LP%d"; + break; + case 2900 ... 3100: /* 3000 psi: ALx tank */ + fmt = "AL%d"; + break; + case 3400 ... 3500: /* 3442 psi: HP tank */ + fmt = "HP%d"; + break; + case 3700 ... 3850: /* HP+10% */ + fmt = "HP%d+"; + break; + default: + return; + } + len = snprintf(buffer, sizeof(buffer), fmt, (int) (cuft+0.5)); + p = malloc(len+1); + if (!p) + return; + memcpy(p, buffer, len+1); + type->description = p; +} + + +/* + * There are two ways to give cylinder size information: + * - total amount of gas in cuft (depends on working pressure and physical size) + * - physical size + * + * where "physical size" is the one that actually matters and is sane. + * + * We internally use physical size only. But we save the workingpressure + * so that we can do the conversion if required. + */ +static void sanitize_cylinder_type(cylinder_type_t *type) +{ + double volume_of_air, atm, volume; + + /* If we have no working pressure, it had *better* be just a physical size! */ + if (!type->workingpressure.mbar) + return; + + /* No size either? Nothing to go on */ + if (!type->size.mliter) + return; + + if (input_units.volume == CUFT) { + /* confusing - we don't really start from ml but millicuft !*/ + volume_of_air = cuft_to_l(type->size.mliter); + atm = to_ATM(type->workingpressure); /* working pressure in atm */ + volume = volume_of_air / atm; /* milliliters at 1 atm: "true size" */ + type->size.mliter = volume + 0.5; + } + + /* Ok, we have both size and pressure: try to match a description */ + match_standard_cylinder(type); +} + +static void sanitize_cylinder_info(struct dive *dive) +{ + int i; + + for (i = 0; i < MAX_CYLINDERS; i++) { + sanitize_gasmix(&dive->cylinder[i].gasmix); + sanitize_cylinder_type(&dive->cylinder[i].type); + } +} + struct dive *fixup_dive(struct dive *dive) { int i,j; @@ -246,6 +362,7 @@ struct dive *fixup_dive(struct dive *dive) int lasttemp = 0, lastpressure = 0; int pressure_delta[MAX_CYLINDERS] = {INT_MAX, }; + sanitize_cylinder_info(dive); for (i = 0; i < dive->samples; i++) { struct sample *sample = dive->sample + i; int time = sample->time.seconds; @@ -373,7 +490,7 @@ static struct dive *add_sample(struct sample *sample, int time, struct dive *div return NULL; *p = *sample; p->time.seconds = time; - finish_sample(dive, p); + finish_sample(dive); return dive; }