mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Collect per tank SAC rate
This is a bit painful, but we basically walk the samples and pick the valid tank from the events. And then we do a simple discrete integration to figure out the mean depth per tank and duration per tank. And then we assemble all that into per tank statistics. Strangely the value calculated here seems slightly higher than one would expect from the overall SAC rate. This inconsistency should be investigated a bit further, but my guess it it's based on the assumption that the DC provided mean depth is possibly more accurate than what we can calculate from the profile. Fixes #284 Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
36cb50fb37
commit
0ca12c3601
4 changed files with 65 additions and 3 deletions
42
dive.c
42
dive.c
|
@ -5,6 +5,7 @@
|
|||
#include <limits.h>
|
||||
#include "gettext.h"
|
||||
#include "dive.h"
|
||||
#include "planner.h"
|
||||
|
||||
struct tag_entry *g_tag_list = NULL;
|
||||
|
||||
|
@ -339,6 +340,47 @@ static void fixup_dc_duration(struct divecomputer *dc)
|
|||
}
|
||||
}
|
||||
|
||||
void per_cylinder_mean_depth(struct dive *dive, struct divecomputer *dc, int *mean, int *duration)
|
||||
{
|
||||
int i;
|
||||
int depthtime[MAX_CYLINDERS] = {0,};
|
||||
int lasttime = 0, lastdepth = 0;
|
||||
int idx = 0;
|
||||
|
||||
for (i = 0; i < MAX_CYLINDERS; i++)
|
||||
mean[i] = duration[i] = 0;
|
||||
struct event *ev = get_next_event(dc->events, "gaschange");
|
||||
if (!ev) {
|
||||
// special case - no gas changes
|
||||
mean[0] = dc->meandepth.mm;
|
||||
duration[0] = dc->duration.seconds;
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < dc->samples; i++) {
|
||||
struct sample *sample = dc->sample + i;
|
||||
int time = sample->time.seconds;
|
||||
int depth = sample->depth.mm;
|
||||
if (ev && time >= ev->time.seconds) {
|
||||
int o2 = (ev->value & 0xFFFF) * 10;
|
||||
int he = (ev->value >> 16) * 10;
|
||||
idx = get_gasidx(dive, o2, he);
|
||||
ev = get_next_event(ev->next, "gaschange");
|
||||
}
|
||||
|
||||
/* We ignore segments at the surface */
|
||||
if (depth > SURFACE_THRESHOLD || lastdepth > SURFACE_THRESHOLD) {
|
||||
duration[idx] += time - lasttime;
|
||||
depthtime[idx] += (time - lasttime) * (depth + lastdepth) / 2;
|
||||
}
|
||||
lastdepth = depth;
|
||||
lasttime = time;
|
||||
}
|
||||
for (i = 0; i < MAX_CYLINDERS; i++) {
|
||||
if (duration[i])
|
||||
mean[i] = (depthtime[i] + duration[i] / 2) / duration[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void fixup_pressure(struct dive *dive, struct sample *sample)
|
||||
{
|
||||
unsigned int pressure, index;
|
||||
|
|
1
dive.h
1
dive.h
|
@ -661,6 +661,7 @@ extern void copy_samples(struct dive *s, struct dive *d);
|
|||
extern void fill_default_cylinder(cylinder_t *cyl);
|
||||
extern void add_gas_switch_event(struct dive *dive, struct divecomputer *dc, int time, int idx);
|
||||
extern void add_event(struct divecomputer *dc, int time, int type, int flags, int value, const char *name);
|
||||
extern void per_cylinder_mean_depth(struct dive *dive, struct divecomputer *dc, int *mean, int *duration);
|
||||
|
||||
/* UI related protopypes */
|
||||
|
||||
|
|
|
@ -353,8 +353,25 @@ void MainTab::updateDiveInfo(int dive)
|
|||
volume_t gases[MAX_CYLINDERS] = { 0 };
|
||||
get_gas_used(d, gases);
|
||||
QString volumes = get_volume_string(gases[0], TRUE);
|
||||
for(int i=1; i < MAX_CYLINDERS && gases[i].mliter != 0; i++)
|
||||
int mean[MAX_CYLINDERS], duration[MAX_CYLINDERS];
|
||||
per_cylinder_mean_depth(d, select_dc(&d->dc), mean, duration);
|
||||
volume_t sac;
|
||||
QString SACs;
|
||||
if (mean[0] && duration[0]) {
|
||||
sac.mliter = gases[0].mliter * 1000.0 / (depth_to_mbar(mean[0], d) * duration[0] / 60.0);
|
||||
SACs = get_volume_string(sac, TRUE).append(tr("/min"));
|
||||
} else {
|
||||
SACs = QString(tr("unknown"));
|
||||
}
|
||||
for(int i=1; i < MAX_CYLINDERS && gases[i].mliter != 0; i++) {
|
||||
volumes.append("\n" + get_volume_string(gases[i], TRUE));
|
||||
if (duration[i]) {
|
||||
sac.mliter = gases[i].mliter * 1000.0 / (depth_to_mbar(mean[i], d) * duration[i] / 60);
|
||||
SACs.append("\n" + get_volume_string(sac, TRUE).append(tr("/min")));
|
||||
} else {
|
||||
SACs.append("\n");
|
||||
}
|
||||
}
|
||||
ui.gasUsedText->setText(volumes);
|
||||
ui.oxygenHeliumText->setText(get_gaslist(d));
|
||||
ui.dateText->setText(get_short_dive_date_string(d->when));
|
||||
|
@ -363,8 +380,8 @@ void MainTab::updateDiveInfo(int dive)
|
|||
ui.surfaceIntervalText->setText(get_time_string(d->when - (prevd->when + prevd->duration.seconds), 4));
|
||||
else
|
||||
ui.surfaceIntervalText->clear();
|
||||
if ((sacVal.mliter = d->sac) > 0)
|
||||
ui.sacText->setText(get_volume_string(sacVal, TRUE).append(tr("/min")));
|
||||
if (mean[0])
|
||||
ui.sacText->setText(SACs);
|
||||
else
|
||||
ui.sacText->clear();
|
||||
if (d->surface_pressure.mbar)
|
||||
|
|
|
@ -437,12 +437,14 @@ void MainWindow::saveSplitterSizes(){
|
|||
void MainWindow::on_actionPreviousDC_triggered()
|
||||
{
|
||||
dc_number--;
|
||||
ui.InfoWidget->updateDiveInfo(selected_dive);
|
||||
redrawProfile();
|
||||
}
|
||||
|
||||
void MainWindow::on_actionNextDC_triggered()
|
||||
{
|
||||
dc_number++;
|
||||
ui.InfoWidget->updateDiveInfo(selected_dive);
|
||||
redrawProfile();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue