diff options
author | Dirk Hohndel <dirk@hohndel.org> | 2013-01-08 08:52:48 -0800 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2013-01-08 08:52:48 -0800 |
commit | e3bdbb7c0f686050a68bbab1b1123c1ed3617d52 (patch) | |
tree | 7727b32d0a492506b9b69369eb4e13b65ee14130 | |
parent | bf395ebf45626eece9163dd387bce3dbbeb56a68 (diff) | |
download | subsurface-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.c | 40 |
1 files changed, 35 insertions, 5 deletions
@@ -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); |