diff options
-rw-r--r-- | divelist.c | 65 | ||||
-rw-r--r-- | dives/sac-test.xml | 19 |
2 files changed, 65 insertions, 19 deletions
diff --git a/divelist.c b/divelist.c index 143f4d43c..501cf0487 100644 --- a/divelist.c +++ b/divelist.c @@ -719,38 +719,65 @@ static double calculate_airuse(struct dive *dive) return airuse; } +/* + * Calculate how long we were actually under water, and the average + * depth while under water. + * + * This ignores any surface time in the middle of the dive. + */ +static int calculate_duration(struct dive *dive, struct divecomputer *dc, int *meandepth) +{ + int duration, i; + int lasttime, lastdepth, depthtime; + + duration = 0; + lasttime = 0; + lastdepth = 0; + depthtime = 0; + for (i = 0; i < dc->samples; i++) { + struct sample *sample = dc->sample + i; + int time = sample->time.seconds; + int depth = sample->depth.mm; + + /* We ignore segments at the surface */ + if (depth > SURFACE_THRESHOLD || lastdepth > SURFACE_THRESHOLD) { + duration += time - lasttime; + depthtime += (time - lasttime)*(depth+lastdepth)/2; + } + lastdepth = depth; + lasttime = time; + } + if (duration) { + if (meandepth) + *meandepth = depthtime / duration; + return duration; + } + + /* No samples? */ + if (meandepth) + *meandepth = dive->meandepth.mm; + return dive->duration.seconds; +} + /* this only uses the first divecomputer to calculate the SAC rate */ static int calculate_sac(struct dive *dive) { struct divecomputer *dc = &dive->dc; double airuse, pressure, sac; - int duration, i; + int duration, meandepth; airuse = calculate_airuse(dive); if (!airuse) return 0; - duration = dc->duration.seconds; - if (!duration) - return 0; + + duration = calculate_duration(dive, dc, &meandepth); /* find and eliminate long surface intervals */ + if (!duration) + return 0; - for (i = 0; i < dc->samples; i++) { - if (dc->sample[i].depth.mm < 100) { /* less than 10cm */ - int end = i + 1; - while (end < dc->samples && dc->sample[end].depth.mm < 100) - end++; - /* we only want the actual surface time during a dive */ - if (end < dc->samples) { - end--; - duration -= dc->sample[end].time.seconds - - dc->sample[i].time.seconds; - i = end + 1; - } - } - } /* Mean pressure in ATM (SAC calculations are in atm*l/min) */ - pressure = (double) depth_to_mbar(dc->meandepth.mm, dive) / SURFACE_PRESSURE; + pressure = (double) depth_to_mbar(meandepth, dive) / SURFACE_PRESSURE; sac = airuse / pressure * 60 / duration; /* milliliters per minute.. */ diff --git a/dives/sac-test.xml b/dives/sac-test.xml index b5f0149bb..14ee3f17b 100644 --- a/dives/sac-test.xml +++ b/dives/sac-test.xml @@ -46,5 +46,24 @@ We have exactly 100 ATM of gas in 15l of cylinder, average 20m for 25min</notes> <sample time='25:00 min' depth='0.0 m' /> </divecomputer> </dive> +<dive number='4' date='2013-02-24' time='12:26:04' duration='25:00 min'> + <location>SAC test dive 3</location> + <notes>SAC should be 20l/min (0.7063 cuft/min) +This adds a 5-minute surface time to the middle of the dive. +We have exactly 100 ATM of gas in 15l of cylinder, average 20m for 25min</notes> + <cylinder size='10 l' description='10l' start='202.6 bar' end='101.3 bar' /> + <cylinder size='5 l' description='10l' start='202.6 bar' end='101.3 bar' /> + <divecomputer> + <event time='22:00 min' name='gaschange' /> + <depth max='20.0 m' mean='10.0 m' /> + <sample time='0:00 min' depth='0.0 m' /> + <sample time='5:00 min' depth='20.0 m' /> + <sample time='10:00 min' depth='40.0 m' /> + <sample time='15:00 min' depth='0.0 m' /> + <sample time='20:00 min' depth='0.0 m' /> + <sample time='25:00 min' depth='40.0 m' /> + <sample time='30:00 min' depth='0.0 m' /> + </divecomputer> +</dive> </dives> </divelog> |