Hi,

Here are two patches to set a minimum stop duration for any gas change.
The first patch adds a spinbox so the user can select what the duration
should be - up to 9 minutes, with 0 giving the previous behaviour.  The
second patch enforces the minimum stop for gas changes.

The notes output logic isn't affected by these patches, but I'll keep
trying to tackle that and this will help sort out what to do with gas
changes.

Cheers,

Rick
From 962d81b98eb16fd8738d19cb00c9056c4c8f1404 Mon Sep 17 00:00:00 2001
From: Rick Walsh <[email protected]>
Date: Fri, 19 Jun 2015 20:25:03 +1000
Subject: [PATCH 1/2] Add planner minimum gas switch duration option

Add the option for a minimum gas switch duration to the planner UI.  This is not actually used yet.

Signed-off-by: Rick Walsh <[email protected]>
---
 pref.h                         |  1 +
 qt-models/diveplannermodel.cpp |  6 ++++++
 qt-models/diveplannermodel.h   |  1 +
 qt-ui/diveplanner.cpp          |  4 ++++
 qt-ui/plannerSettings.ui       | 30 ++++++++++++++++++++++++++++--
 subsurfacestartup.c            |  1 +
 6 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/pref.h b/pref.h
index c657cf2..ff5fd3d 100644
--- a/pref.h
+++ b/pref.h
@@ -84,6 +84,7 @@ struct preferences {
 	bool recreational_mode;
 	bool safetystop;
 	int reserve_gas;
+	int min_switch_duration; // seconds
 	int bottomsac;
 	int decosac;
 	int o2consumption; // ml per min
diff --git a/qt-models/diveplannermodel.cpp b/qt-models/diveplannermodel.cpp
index bace54e..655f1bd 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::setMinSwitchDuration(int duration)
+{
+	prefs.min_switch_duration = duration * 60;
+	emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, COLUMNS - 1));
+}
+
 void DivePlannerPointsModel::setStartDate(const QDate &date)
 {
 	startTime.setDate(date);
diff --git a/qt-models/diveplannermodel.h b/qt-models/diveplannermodel.h
index 4d1ef32..883103f 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 setMinSwitchDuration(int duration);
 
 signals:
 	void planCreated();
diff --git a/qt-ui/diveplanner.cpp b/qt-ui/diveplanner.cpp
index e2a604b..08ceba5 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.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();
 	prefs.decosac = s.value("decosac", prefs.decosac).toInt();
@@ -274,6 +275,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.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");
 	ui.rebreathermode->insertItems(0, rebreater_modes);
@@ -306,6 +308,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.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)));
 
@@ -347,6 +350,7 @@ PlannerSettingsWidget::~PlannerSettingsWidget()
 	s.setValue("decopo2", prefs.decopo2);
 	s.setValue("doo2breaks", prefs.doo2breaks);
 	s.setValue("drop_stone_mode", prefs.drop_stone_mode);
+	s.setValue("min_switch_duration", prefs.min_switch_duration);
 	s.setValue("bottomsac", prefs.bottomsac);
 	s.setValue("decosac", prefs.decosac);
 	s.endGroup();
diff --git a/qt-ui/plannerSettings.ui b/qt-ui/plannerSettings.ui
index 9283bcd..9ca603b 100644
--- a/qt-ui/plannerSettings.ui
+++ b/qt-ui/plannerSettings.ui
@@ -308,7 +308,7 @@
             </property>
            </widget>
           </item>
-          <item row="10" column="1">
+          <item row="11" column="1">
            <widget class="QComboBox" name="rebreathermode">
             <property name="currentText">
              <string/>
@@ -338,7 +338,7 @@
             </property>
            </widget>
           </item>
-          <item row="11" column="1">
+          <item row="12" column="1">
            <spacer name="verticalSpacer_2">
             <property name="orientation">
              <enum>Qt::Vertical</enum>
@@ -401,6 +401,32 @@
             </property>
            </widget>
           </item>
+          <item row="10" column="1">
+           <widget class="QLabel" name="label_4">
+            <property name="text">
+             <string>Min. switch duration</string>
+            </property>
+           </widget>
+          </item>
+          <item row="10" column="2">
+           <widget class="QSpinBox" name="min_switch_duration">
+            <property name="suffix">
+             <string>min</string>
+            </property>
+            <property name="prefix">
+             <string/>
+            </property>
+            <property name="minimum">
+             <number>0</number>
+            </property>
+            <property name="maximum">
+             <number>9</number>
+            </property>
+            <property name="value">
+             <number>1</number>
+            </property>
+           </widget>
+          </item>
          </layout>
         </widget>
        </item>
diff --git a/subsurfacestartup.c b/subsurfacestartup.c
index a64c817..7130f0f 100644
--- a/subsurfacestartup.c
+++ b/subsurfacestartup.c
@@ -47,6 +47,7 @@ struct preferences default_prefs = {
 	.decopo2 = 1600,
 	.doo2breaks = false,
 	.drop_stone_mode = false,
+	.min_switch_duration = 60,
 	.last_stop = false,
 	.verbatim_plan = false,
 	.display_runtime = true,
-- 
2.4.3

From 2b102df6c268e9c9b5e6e30eb520bc1ec76c0aa2 Mon Sep 17 00:00:00 2001
From: Rick Walsh <[email protected]>
Date: Sat, 20 Jun 2015 00:02:38 +1000
Subject: [PATCH 2/2] Enforce planner minimum gas switch duration

Enforce a minimum duration for gas switching in the planner.

Signed-off-by: Rick Walsh <[email protected]>
---
 planner.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/planner.c b/planner.c
index 9b2d355..63f1f63 100644
--- a/planner.c
+++ b/planner.c
@@ -1040,12 +1040,21 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool
 			previous_point_time = clock;
 			stopping = true;
 
-			current_cylinder = gaschanges[gi].gasidx;
-			gas = displayed_dive.cylinder[current_cylinder].gasmix;
+			/* Check we need to change cylinder.
+			 * We might not if the cylinder was chosen by the user */
+			if (current_cylinder != gaschanges[gi].gasidx) {
+				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;
+			}
 			gi--;
 		}
 
-- 
2.4.3

_______________________________________________
subsurface mailing list
[email protected]
http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface

Reply via email to