mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-30 22:20:21 +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)
|
static void fixup_dive_dc(struct dive *dive, struct divecomputer *dc)
|
||||||
{
|
{
|
||||||
int i, j;
|
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 o2_pressure = sample->o2cylinderpressure.mbar;
|
||||||
int index;
|
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 we have an explicit first cylinder */
|
||||||
if (sample->sensor == 0 && first_cylinder != 0)
|
if (sample->sensor == 0 && first_cylinder != 0)
|
||||||
sample->sensor = first_cylinder;
|
sample->sensor = first_cylinder;
|
||||||
|
|
|
@ -231,7 +231,6 @@ static void handle_event(struct divecomputer *dc, struct sample *sample, dc_samp
|
||||||
void
|
void
|
||||||
sample_cb(dc_sample_type_t type, dc_sample_value_t value, void *userdata)
|
sample_cb(dc_sample_type_t type, dc_sample_value_t value, void *userdata)
|
||||||
{
|
{
|
||||||
unsigned int mm;
|
|
||||||
static unsigned int nsensor = 0;
|
static unsigned int nsensor = 0;
|
||||||
struct divecomputer *dc = userdata;
|
struct divecomputer *dc = userdata;
|
||||||
struct sample *sample;
|
struct sample *sample;
|
||||||
|
@ -252,7 +251,10 @@ sample_cb(dc_sample_type_t type, dc_sample_value_t value, void *userdata)
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case DC_SAMPLE_TIME:
|
case DC_SAMPLE_TIME:
|
||||||
nsensor = 0;
|
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) {
|
if (sample) {
|
||||||
sample->in_deco = in_deco;
|
sample->in_deco = in_deco;
|
||||||
sample->ndl.seconds = ndl;
|
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->stopdepth.mm = stopdepth;
|
||||||
sample->setpoint.mbar = po2;
|
sample->setpoint.mbar = po2;
|
||||||
sample->cns = cns;
|
sample->cns = cns;
|
||||||
mm = sample->depth.mm;
|
|
||||||
}
|
}
|
||||||
|
// Create a new sample.
|
||||||
|
// Mark depth as negative
|
||||||
sample = prepare_sample(dc);
|
sample = prepare_sample(dc);
|
||||||
sample->time.seconds = value.time;
|
sample->time.seconds = value.time;
|
||||||
sample->depth.mm = mm;
|
sample->depth.mm = -1;
|
||||||
finish_sample(dc);
|
finish_sample(dc);
|
||||||
break;
|
break;
|
||||||
case DC_SAMPLE_DEPTH:
|
case DC_SAMPLE_DEPTH:
|
||||||
|
|
Loading…
Reference in a new issue