X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=dive.c;h=7fe6eb17b863f0ceeef887d81636fcb77991a3e8;hb=85921592b052e2be867f049306abd28e69c978ae;hp=2ecd10cb0be418f524736c0ab227930d343abc6c;hpb=1e75ceac0dbbf6a6eef1e13f076c3ae6a7af4c55;p=ext%2Fsubsurface.git diff --git a/dive.c b/dive.c index 2ecd10c..7fe6eb1 100644 --- a/dive.c +++ b/dive.c @@ -3,6 +3,58 @@ #include "dive.h" +/* + * So when we re-calculate maxdepth and meandepth, we will + * not override the old numbers if they are close to the + * new ones. + * + * Why? Because a dive computer may well actually track the + * max depth and mean depth at finer granularity than the + * samples it stores. So it's possible that the max and mean + * have been reported more correctly originally. + * + * Only if the values calculated from the samples are clearly + * different do we override the normal depth values. + * + * This considers 1m to be "clearly different". That's + * a totally random number. + */ +static void update_depth(depth_t *depth, int new) +{ + if (new) { + int old = depth->mm; + + if (abs(old - new) > 1000) + depth->mm = new; + } +} + +static void update_pressure(pressure_t *pressure, int new) +{ + if (new) { + int old = pressure->mbar; + + if (abs(old - new) > 1000) + pressure->mbar = new; + } +} + +static void update_duration(duration_t *duration, int new) +{ + if (new) + duration->seconds = new; +} + +static void update_temperature(temperature_t *temperature, int new) +{ + if (new) { + int old = temperature->mkelvin; + + if (abs(old - new) > 1000) + temperature->mkelvin = new; + } +} + struct dive *fixup_dive(struct dive *dive) { int i; @@ -10,15 +62,16 @@ struct dive *fixup_dive(struct dive *dive) int lasttime = 0; int start = -1, end = -1; int startpress = 0, endpress = 0; - int starttemp = 0, endtemp = 0; int maxdepth = 0, mintemp = 0; int lastdepth = 0; + int lasttemp = 0; + temperature_t *redundant_temp = NULL; for (i = 0; i < dive->samples; i++) { struct sample *sample = dive->sample + i; int time = sample->time.seconds; int depth = sample->depth.mm; - int press = sample->tankpressure.mbar; + int press = sample->cylinderpressure.mbar; int temp = sample->temperature.mkelvin; if (lastdepth) @@ -36,9 +89,21 @@ struct dive *fixup_dive(struct dive *dive) startpress = press; } if (temp) { - endtemp = temp; - if (!starttemp) - starttemp = temp; + /* + * If we have consecutive identical + * temperature readings, throw away + * the redundant ones. We care about + * the "edges" only. + */ + if (lasttemp == temp) { + if (redundant_temp) + redundant_temp->mkelvin = 0; + redundant_temp = &sample->temperature; + } else { + redundant_temp = NULL; + lasttemp = temp; + } + if (!mintemp || temp < mintemp) mintemp = temp; } @@ -48,17 +113,16 @@ struct dive *fixup_dive(struct dive *dive) } if (end < 0) return dive; - dive->duration.seconds = end - start; + + update_duration(&dive->duration, end - start); if (start != end) - dive->meandepth.mm = depthtime / (end - start); - if (startpress) - dive->beginning_pressure.mbar = startpress; - if (endpress) - dive->end_pressure.mbar = endpress; - if (mintemp) - dive->watertemp.mkelvin = mintemp; - if (maxdepth) - dive->maxdepth.mm = maxdepth; + depthtime /= (end - start); + + update_depth(&dive->meandepth, depthtime); + update_pressure(&dive->beginning_pressure, startpress); + update_pressure(&dive->end_pressure, endpress); + update_temperature(&dive->watertemp, mintemp); + update_depth(&dive->maxdepth, maxdepth); return dive; } @@ -143,10 +207,10 @@ add_sample_b: sample.depth = as->depth; if (as->temperature.mkelvin) sample.temperature = as->temperature; - if (as->tankpressure.mbar) - sample.tankpressure = as->tankpressure; - if (as->tankindex) - sample.tankindex = as->tankindex; + if (as->cylinderpressure.mbar) + sample.cylinderpressure = as->cylinderpressure; + if (as->cylinderindex) + sample.cylinderindex = as->cylinderindex; res = add_sample(&sample, at, res); @@ -174,6 +238,27 @@ static char *merge_text(const char *a, const char *b) return res; } +/* Pick whichever has any info (if either). Prefer 'a' */ +static void merge_cylinder_type(cylinder_type_t *res, cylinder_type_t *a, cylinder_type_t *b) +{ + if (a->size.mliter) + b = a; + *res = *b; +} + +static void merge_cylinder_mix(gasmix_t *res, gasmix_t *a, gasmix_t *b) +{ + if (a->o2.permille) + b = a; + *res = *b; +} + +static void merge_cylinder_info(cylinder_t *res, cylinder_t *a, cylinder_t *b) +{ + merge_cylinder_type(&res->type, &a->type, &b->type); + merge_cylinder_mix(&res->gasmix, &a->gasmix, &b->gasmix); +} + /* * This could do a lot more merging. Right now it really only * merges almost exact duplicates - something that happens easily @@ -194,7 +279,6 @@ struct dive *try_to_merge(struct dive *a, struct dive *b) memset(res, 0, dive_size(alloc_samples)); res->when = a->when; - res->name = merge_text(a->name, b->name); res->location = merge_text(a->location, b->location); res->notes = merge_text(a->notes, b->notes); MERGE_MAX(res, a, b, maxdepth.mm); @@ -205,12 +289,8 @@ struct dive *try_to_merge(struct dive *a, struct dive *b) MERGE_MIN(res, a, b, watertemp.mkelvin); MERGE_MAX(res, a, b, beginning_pressure.mbar); MERGE_MAX(res, a, b, end_pressure.mbar); - for (i = 0; i < MAX_MIXES; i++) { - if (a->gasmix[i].o2.permille) { - res->gasmix[i] = a->gasmix[i]; - continue; - } - res->gasmix[i] = b->gasmix[i]; - } + for (i = 0; i < MAX_CYLINDERS; i++) + merge_cylinder_info(res->cylinder+i, a->cylinder + i, b->cylinder + i); + return merge_samples(res, a, b, 0); }