mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-28 05:00:20 +00:00
Interpolate depth for samples that have no depth
When downloading from libdivecomputer, we used to initialize the depth of a sample to the previous depth. However, at least for the Suunto EON Steel, you can get sample times without any actual depth reading - the time might be associated with some ranbdom event rather than a new depth sample. Rather than initialize these samples to have the same depth as the previous one (and then perhaps getting a very sudden jump when the *real* depth event comes in a second later), initialize the depth samples to -1, and if that sample doesn't get a real depth, we'll create an interpolated depth. It is possible that we should just carry the sample around as not actually having a depth, and instead just interpolate in the plot_info generation, but at least right now we have a ton of code that "knows" that every sample has a depth. Not the least of which is our own save format. So generating an interpolated depth seems the path of least resistance, and at least makes the graph look correct - no odd staircase effect from other events that happen in between depth samples. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
cd1884b29c
commit
2b1017c986
2 changed files with 29 additions and 4 deletions
22
dive.c
22
dive.c
|
@ -1243,6 +1243,23 @@ static void fixup_dc_events(struct divecomputer *dc)
|
|||
}
|
||||
}
|
||||
|
||||
static int interpolate_depth(struct divecomputer *dc, int idx, int lastdepth, int lasttime, int now)
|
||||
{
|
||||
int i;
|
||||
int nextdepth = lastdepth;
|
||||
int nexttime = now;
|
||||
|
||||
for (i = idx+1; i < dc->samples; i++) {
|
||||
struct sample *sample = dc->sample + i;
|
||||
if (sample->depth.mm < 0)
|
||||
continue;
|
||||
nextdepth = sample->depth.mm;
|
||||
nexttime = sample->time.seconds;
|
||||
break;
|
||||
}
|
||||
return interpolate(lastdepth, nextdepth, now-lasttime, nexttime-lasttime);
|
||||
}
|
||||
|
||||
static void fixup_dive_dc(struct dive *dive, struct divecomputer *dc)
|
||||
{
|
||||
int i, j;
|
||||
|
@ -1276,6 +1293,11 @@ static void fixup_dive_dc(struct dive *dive, struct divecomputer *dc)
|
|||
int o2_pressure = sample->o2cylinderpressure.mbar;
|
||||
int index;
|
||||
|
||||
if (depth < 0) {
|
||||
depth = interpolate_depth(dc, i, lastdepth, lasttime, time);
|
||||
sample->depth.mm = depth;
|
||||
}
|
||||
|
||||
/* if we have an explicit first cylinder */
|
||||
if (sample->sensor == 0 && first_cylinder != 0)
|
||||
sample->sensor = first_cylinder;
|
||||
|
|
|
@ -231,7 +231,6 @@ static void handle_event(struct divecomputer *dc, struct sample *sample, dc_samp
|
|||
void
|
||||
sample_cb(dc_sample_type_t type, dc_sample_value_t value, void *userdata)
|
||||
{
|
||||
unsigned int mm;
|
||||
static unsigned int nsensor = 0;
|
||||
struct divecomputer *dc = userdata;
|
||||
struct sample *sample;
|
||||
|
@ -252,7 +251,10 @@ sample_cb(dc_sample_type_t type, dc_sample_value_t value, void *userdata)
|
|||
switch (type) {
|
||||
case DC_SAMPLE_TIME:
|
||||
nsensor = 0;
|
||||
mm = 0;
|
||||
|
||||
// The previous sample gets some sticky values
|
||||
// that may have been around from before, even
|
||||
// if there was no new data
|
||||
if (sample) {
|
||||
sample->in_deco = in_deco;
|
||||
sample->ndl.seconds = ndl;
|
||||
|
@ -260,11 +262,12 @@ sample_cb(dc_sample_type_t type, dc_sample_value_t value, void *userdata)
|
|||
sample->stopdepth.mm = stopdepth;
|
||||
sample->setpoint.mbar = po2;
|
||||
sample->cns = cns;
|
||||
mm = sample->depth.mm;
|
||||
}
|
||||
// Create a new sample.
|
||||
// Mark depth as negative
|
||||
sample = prepare_sample(dc);
|
||||
sample->time.seconds = value.time;
|
||||
sample->depth.mm = mm;
|
||||
sample->depth.mm = -1;
|
||||
finish_sample(dc);
|
||||
break;
|
||||
case DC_SAMPLE_DEPTH:
|
||||
|
|
Loading…
Reference in a new issue