summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2013-01-08 08:52:48 -0800
committerGravatar Dirk Hohndel <dirk@hohndel.org>2013-01-08 08:52:48 -0800
commite3bdbb7c0f686050a68bbab1b1123c1ed3617d52 (patch)
tree7727b32d0a492506b9b69369eb4e13b65ee14130
parentbf395ebf45626eece9163dd387bce3dbbeb56a68 (diff)
downloadsubsurface-e3bdbb7c0f686050a68bbab1b1123c1ed3617d52.tar.gz
Fix gas handling in the planner
The dive will start with gas 0. If things change during the planned part of the dive, this will be represented by an event. Use the last gas for the ascent. Obviously this still doesn't handle deco gases, but at least we now no longer switch back to the first gas after the planned part of the dive. This also adds quite a bit of debugging code to be able to trace what's happening in the planner. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r--planner.c40
1 files changed, 35 insertions, 5 deletions
diff --git a/planner.c b/planner.c
index 0066bbcec..c00c8a791 100644
--- a/planner.c
+++ b/planner.c
@@ -128,11 +128,14 @@ struct dive *create_dive_from_plan(struct diveplan *diveplan)
if (!diveplan || !diveplan->dp)
return NULL;
+#if DEBUG_PLAN & 4
+ dump_plan(diveplan);
+#endif
dive = alloc_dive();
dive->when = diveplan->when;
dive->surface_pressure.mbar = diveplan->surface_pressure;
dc = &dive->dc;
- dc->model = "Simulated Dive";
+ dc->model = strdup("Simulated Dive");
dp = diveplan->dp;
/* let's start with the gas given on the first segment */
@@ -257,6 +260,18 @@ void plan_add_segment(struct diveplan *diveplan, int duration, int depth, int o2
add_to_end_of_diveplan(diveplan, dp);
}
+void get_gas_from_events(struct divecomputer *dc, int time, int *o2, int *he)
+{
+ struct event *event = dc->events;
+ while (event && event->time.seconds <= time) {
+ if (!strcmp(event->name, "gaschange")) {
+ *o2 = 10 * event->value & 0xffff;
+ *he = 10 * event->value >> 16;
+ }
+ event = event->next;
+ }
+}
+
void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep)
{
struct dive *dive;
@@ -276,16 +291,25 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep)
record_dive(dive);
sample = &dive->dc.sample[dive->dc.samples - 1];
- o2 = dive->cylinder[sample->sensor].gasmix.o2.permille;
- he = dive->cylinder[sample->sensor].gasmix.he.permille;
-
+ /* we start with gas 0, then check if that was changed */
+ o2 = dive->cylinder[0].gasmix.o2.permille;
+ he = dive->cylinder[0].gasmix.he.permille;
+ get_gas_from_events(&dive->dc, sample->time.seconds, &o2, &he);
+#if DEBUG_PLAN & 2
+ printf("gas %d/%d\n", o2, he);
+#endif
tissue_tolerance = tissue_at_end(dive, cached_datap);
ceiling = deco_allowed_depth(tissue_tolerance, diveplan->surface_pressure / 1000.0, dive, 1);
-
+#if DEBUG_PLAN & 2
+ printf("ceiling %5.2lfm\n", ceiling / 1000.0);
+#endif
for (stopidx = 1; stopidx < sizeof(stoplevels) / sizeof(int); stopidx++)
if (stoplevels[stopidx] >= ceiling)
break;
+#if DEBUG_PLAN & 2
+ printf("first stop at %5.2lfm\n", stoplevels[stopidx] / 1000.0);
+#endif
while (stopidx > 0) {
depth = dive->dc.sample[dive->dc.samples - 1].depth.mm;
if (depth > stoplevels[stopidx]) {
@@ -297,9 +321,15 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep)
record_dive(dive);
}
wait_time = time_at_last_depth(dive, stoplevels[stopidx - 1], cached_datap);
+#if DEBUG_PLAN & 2
+ printf("waittime %d:%2d\n", FRACTION(wait_time, 60));
+#endif
if (wait_time)
plan_add_segment(diveplan, wait_time, stoplevels[stopidx], o2, he);
transitiontime = (stoplevels[stopidx] - stoplevels[stopidx - 1]) / 150;
+#if DEBUG_PLAN & 2
+ printf("transitiontime %d:%2d to depth %5.2lfm\n", FRACTION(wait_time, 60), stoplevels[stopidx - 1] / 1000.0);
+#endif
plan_add_segment(diveplan, transitiontime, stoplevels[stopidx - 1], o2, he);
/* re-create the dive */
delete_single_dive(dive_table.nr - 1);