These patches add the planner option to postpone a gas switch to the next required stop. I haven't managed to make it do silly things, but please do check when you get a chance - no rush apply.
The option is ignored when the current gas is hypoxic. It's interesting to see what effect delaying the gas switch has until the next stop has on the calculated profile. It doesn't make much difference.
From 08e86c47a5cb42be59ae5b1a36103af9ae183e44 Mon Sep 17 00:00:00 2001 From: Rick Walsh <rickmwa...@gmail.com> Date: Mon, 22 Jun 2015 22:43:20 +1000 Subject: [PATCH] Implement planner option to switch only at required stops When option is enabled, if a stop is not otherwise required, a gas switch will be delayed until a stop is reached. This option is ignored if the current gas is hypoxic. Signed-off-by: Rick Walsh <rickmwa...@gmail.com> --- planner.c | 48 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/planner.c b/planner.c index e5aa19e..7199d15 100644 --- a/planner.c +++ b/planner.c @@ -869,6 +869,7 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool int gaschangenr; unsigned int *stoplevels = NULL; bool stopping = false; + bool pendinggaschange = false; bool clear_to_ascend; int clock, previous_point_time; int avg_depth, max_depth, bottom_time = 0; @@ -1034,7 +1035,7 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool if (depth <= 0) break; /* We are at the surface */ - if (gi >= 0 && stoplevels[stopidx] == gaschanges[gi].depth) { + if (gi >= 0 && stoplevels[stopidx] <= gaschanges[gi].depth) { /* We have reached a gas change. * Record this in the dive plan */ plan_add_segment(diveplan, clock - previous_point_time, depth, gas, po2, false); @@ -1042,21 +1043,29 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool stopping = true; /* Check we need to change cylinder. - * We might not if the cylinder was chosen by the user */ + * We might not if the cylinder was chosen by the user + * or user has selected only to switch only at required stops. + * If current gas is hypoxic, we want to switch asap */ if (current_cylinder != gaschanges[gi].gasidx) { - current_cylinder = gaschanges[gi].gasidx; - gas = displayed_dive.cylinder[current_cylinder].gasmix; + if (!prefs.switch_at_req_stop || + !trial_ascent(depth, stoplevels[stopidx - 1], avg_depth, bottom_time, tissue_tolerance, + &displayed_dive.cylinder[current_cylinder].gasmix, po2, diveplan->surface_pressure / 1000.0) || get_o2(&displayed_dive.cylinder[current_cylinder].gasmix) < 160) { + current_cylinder = gaschanges[gi].gasidx; + gas = displayed_dive.cylinder[current_cylinder].gasmix; #if DEBUG_PLAN & 16 - printf("switch to gas %d (%d/%d) @ %5.2lfm\n", gaschanges[gi].gasidx, - (get_o2(&gas) + 5) / 10, (get_he(&gas) + 5) / 10, gaschanges[gi].depth / 1000.0); + printf("switch to gas %d (%d/%d) @ %5.2lfm\n", gaschanges[gi].gasidx, + (get_o2(&gas) + 5) / 10, (get_he(&gas) + 5) / 10, gaschanges[gi].depth / 1000.0); #endif - /* Stop for the minimum duration to switch gas */ - tissue_tolerance = add_segment(depth_to_mbar(depth, &displayed_dive) / 1000.0, - &displayed_dive.cylinder[current_cylinder].gasmix, - prefs.min_switch_duration, po2, &displayed_dive, prefs.decosac); - clock += prefs.min_switch_duration; - } + /* Stop for the minimum duration to switch gas */ + tissue_tolerance = add_segment(depth_to_mbar(depth, &displayed_dive) / 1000.0, + &displayed_dive.cylinder[current_cylinder].gasmix, + prefs.min_switch_duration, po2, &displayed_dive, prefs.decosac); + clock += prefs.min_switch_duration; + } else { + pendinggaschange = true; + } gi--; + } } --stopidx; @@ -1078,6 +1087,21 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool stopping = true; } + if (pendinggaschange) { + current_cylinder = gaschanges[gi + 1].gasidx; + gas = displayed_dive.cylinder[current_cylinder].gasmix; +#if DEBUG_PLAN & 16 + printf("switch to gas %d (%d/%d) @ %5.2lfm\n", gaschanges[gi + 1].gasidx, + (get_o2(&gas) + 5) / 10, (get_he(&gas) + 5) / 10, gaschanges[gi + 1].depth / 1000.0); +#endif + /* Stop for the minimum duration to switch gas */ + tissue_tolerance = add_segment(depth_to_mbar(depth, &displayed_dive) / 1000.0, + &displayed_dive.cylinder[current_cylinder].gasmix, + prefs.min_switch_duration, po2, &displayed_dive, prefs.decosac); + clock += prefs.min_switch_duration; + pendinggaschange = false; + } + /* Deco stop should end when runtime is at a whole minute */ int this_decotimestep; this_decotimestep = DECOTIMESTEP - clock % DECOTIMESTEP; -- 2.4.3
From 3377675ab7dbb993550237398f0b4abe8c25c334 Mon Sep 17 00:00:00 2001 From: Rick Walsh <rickmwa...@gmail.com> Date: Mon, 22 Jun 2015 21:48:42 +1000 Subject: [PATCH] Add only switch at required stop option Add the option to only switch at required stop to the planner UI. This is not actually used yet. Signed-off-by: Rick Walsh <rickmwa...@gmail.com> --- pref.h | 1 + qt-models/diveplannermodel.cpp | 6 ++++++ qt-models/diveplannermodel.h | 1 + qt-ui/diveplanner.cpp | 4 ++++ qt-ui/plannerSettings.ui | 18 ++++++++++++++---- subsurfacestartup.c | 1 + 6 files changed, 27 insertions(+), 4 deletions(-) diff --git a/pref.h b/pref.h index ff5fd3d..90bfab9 100644 --- a/pref.h +++ b/pref.h @@ -83,6 +83,7 @@ struct preferences { bool display_transitions; bool recreational_mode; bool safetystop; + bool switch_at_req_stop; int reserve_gas; int min_switch_duration; // seconds int bottomsac; diff --git a/qt-models/diveplannermodel.cpp b/qt-models/diveplannermodel.cpp index a4ca147..adbcdba 100644 --- a/qt-models/diveplannermodel.cpp +++ b/qt-models/diveplannermodel.cpp @@ -490,6 +490,12 @@ void DivePlannerPointsModel::setDropStoneMode(bool value) emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, COLUMNS - 1)); } +void DivePlannerPointsModel::setSwitchAtReqStop(bool value) +{ + prefs.switch_at_req_stop = value; + emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, COLUMNS - 1)); +} + void DivePlannerPointsModel::setMinSwitchDuration(int duration) { prefs.min_switch_duration = duration * 60; diff --git a/qt-models/diveplannermodel.h b/qt-models/diveplannermodel.h index 883103f..4224990 100644 --- a/qt-models/diveplannermodel.h +++ b/qt-models/diveplannermodel.h @@ -90,6 +90,7 @@ slots: void emitDataChanged(); void setRebreatherMode(int mode); void setReserveGas(int reserve); + void setSwitchAtReqStop(bool value); void setMinSwitchDuration(int duration); signals: diff --git a/qt-ui/diveplanner.cpp b/qt-ui/diveplanner.cpp index 08ceba5..8b0e93c 100644 --- a/qt-ui/diveplanner.cpp +++ b/qt-ui/diveplanner.cpp @@ -254,6 +254,7 @@ PlannerSettingsWidget::PlannerSettingsWidget(QWidget *parent, Qt::WindowFlags f) prefs.bottompo2 = s.value("bottompo2", prefs.bottompo2).toInt(); prefs.decopo2 = s.value("decopo2", prefs.decopo2).toInt(); prefs.doo2breaks = s.value("doo2breaks", prefs.doo2breaks).toBool(); + prefs.switch_at_req_stop = s.value("switch_at_req_stop", prefs.switch_at_req_stop).toBool(); prefs.min_switch_duration = s.value("min_switch_duration", prefs.min_switch_duration).toInt(); prefs.drop_stone_mode = s.value("drop_stone_mode", prefs.drop_stone_mode).toBool(); prefs.bottomsac = s.value("bottomsac", prefs.bottomsac).toInt(); @@ -275,6 +276,7 @@ PlannerSettingsWidget::PlannerSettingsWidget(QWidget *parent, Qt::WindowFlags f) ui.decopo2->setValue(prefs.decopo2 / 1000.0); ui.backgasBreaks->setChecked(prefs.doo2breaks); ui.drop_stone_mode->setChecked(prefs.drop_stone_mode); + ui.switch_at_req_stop->setChecked(prefs.switch_at_req_stop); ui.min_switch_duration->setValue(prefs.min_switch_duration / 60); // should be the same order as in dive_comp_type! rebreater_modes << tr("Open circuit") << tr("CCR") << tr("pSCR"); @@ -308,6 +310,7 @@ PlannerSettingsWidget::PlannerSettingsWidget(QWidget *parent, Qt::WindowFlags f) connect(ui.gfhigh, SIGNAL(editingFinished()), plannerModel, SLOT(triggerGFHigh())); connect(ui.gflow, SIGNAL(editingFinished()), plannerModel, SLOT(triggerGFLow())); connect(ui.backgasBreaks, SIGNAL(toggled(bool)), this, SLOT(setBackgasBreaks(bool))); + connect(ui.switch_at_req_stop, SIGNAL(toggled(bool)), plannerModel, SLOT(setSwitchAtReqStop(bool))); connect(ui.min_switch_duration, SIGNAL(valueChanged(int)), plannerModel, SLOT(setMinSwitchDuration(int))); connect(ui.rebreathermode, SIGNAL(currentIndexChanged(int)), plannerModel, SLOT(setRebreatherMode(int))); connect(plannerModel, SIGNAL(recreationChanged(bool)), this, SLOT(disableDecoElements(bool))); @@ -350,6 +353,7 @@ PlannerSettingsWidget::~PlannerSettingsWidget() s.setValue("decopo2", prefs.decopo2); s.setValue("doo2breaks", prefs.doo2breaks); s.setValue("drop_stone_mode", prefs.drop_stone_mode); + s.setValue("switch_at_req_stop", prefs.switch_at_req_stop); s.setValue("min_switch_duration", prefs.min_switch_duration); s.setValue("bottomsac", prefs.bottomsac); s.setValue("decosac", prefs.decosac); diff --git a/qt-ui/plannerSettings.ui b/qt-ui/plannerSettings.ui index 9ca603b..55ca83a 100644 --- a/qt-ui/plannerSettings.ui +++ b/qt-ui/plannerSettings.ui @@ -308,7 +308,7 @@ </property> </widget> </item> - <item row="11" column="1"> + <item row="12" column="1"> <widget class="QComboBox" name="rebreathermode"> <property name="currentText"> <string/> @@ -338,7 +338,7 @@ </property> </widget> </item> - <item row="12" column="1"> + <item row="13" column="1"> <spacer name="verticalSpacer_2"> <property name="orientation"> <enum>Qt::Vertical</enum> @@ -401,14 +401,24 @@ </property> </widget> </item> - <item row="10" column="1"> + <item row="10" column="1" colspan="2"> + <widget class="QCheckBox" name="switch_at_req_stop"> + <property name="toolTip"> + <string>Postpone gas change if a stop is not required</string> + </property> + <property name="text"> + <string>Only switch at required stops</string> + </property> + </widget> + </item> + <item row="11" column="1"> <widget class="QLabel" name="label_4"> <property name="text"> <string>Min. switch duration</string> </property> </widget> </item> - <item row="10" column="2"> + <item row="11" column="2"> <widget class="QSpinBox" name="min_switch_duration"> <property name="suffix"> <string>min</string> diff --git a/subsurfacestartup.c b/subsurfacestartup.c index 7130f0f..e840ee2 100644 --- a/subsurfacestartup.c +++ b/subsurfacestartup.c @@ -47,6 +47,7 @@ struct preferences default_prefs = { .decopo2 = 1600, .doo2breaks = false, .drop_stone_mode = false, + .switch_at_req_stop = false, .min_switch_duration = 60, .last_stop = false, .verbatim_plan = false, -- 2.4.3
_______________________________________________ subsurface mailing list subsurface@subsurface-divelog.org http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface