changeset 902:d4622533271d Evo_2_23 tip

VPM table mode: Because of the model maths, usage of float data type and so on it may happen that the TTS decreases during ascent and continues calculation of the vpm. To keep the values stable the vpm table mode has been introduces. Instead of continously calculation of the stops the stop time is decreased if the diver is close to a deco stop. If the table is violated (e.g. by not doing gas change) the table will be updated to the new, longer runtime. The table will not be switch back to a shorter version in case e.g. the missed gas change is performed
author Ideenmodellierer
date Wed, 02 Oct 2024 22:18:19 +0200
parents e4e9acfde839
children
files Common/Inc/data_central.h Discovery/Inc/tStructure.h Discovery/Inc/text_multilanguage.h Discovery/Inc/vpm.h Discovery/Src/data_central.c Discovery/Src/tMenuDecoParameter.c Discovery/Src/tMenuEditDecoParameter.c Discovery/Src/text_multilanguage.c Discovery/Src/vpm.c
diffstat 9 files changed, 130 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/Common/Inc/data_central.h	Wed Oct 02 22:07:13 2024 +0200
+++ b/Common/Inc/data_central.h	Wed Oct 02 22:18:19 2024 +0200
@@ -337,6 +337,10 @@
 	 */
 	uint8_t vpm_conservatism;
 
+	/* VPM table mode, do not change during dive!!!
+	 */
+	uint8_t vpm_tableMode;
+
 	/* B�hlmann GF
 	 * and a variable that is used by Buehlmann during the dive
 	 * to remember the position of GF low during ascend
--- a/Discovery/Inc/tStructure.h	Wed Oct 02 22:07:13 2024 +0200
+++ b/Discovery/Inc/tStructure.h	Wed Oct 02 22:18:19 2024 +0200
@@ -253,10 +253,11 @@
 #define StMDECOP	_MB(2,6,0,0,0)
 
 #define StMDECOP1_Algorithm		_MB(2,6,1,1,0)
-#define StMDECOP2_VPM					_MB(2,6,2,1,0)
-#define StMDECOP3_GF					_MB(2,6,3,1,0)
-#define StMDECOP4_AltGF				_MB(2,6,4,1,0)
+#define StMDECOP2_VPM			_MB(2,6,2,1,0)
+#define StMDECOP3_GF			_MB(2,6,3,1,0)
+#define StMDECOP4_AltGF			_MB(2,6,4,1,0)
 #define StMDECOP5_LASTSTOP		_MB(2,6,5,1,0)
+#define StMDECOP6_VPMTable		_MB(2,6,6,1,0)
 
 #define StMDECOP7_ActiveGF		_MB(2,6,7,1,0)
 #define StMDECOP8_ActiveVPM		_MB(2,6,8,1,0)
--- a/Discovery/Inc/text_multilanguage.h	Wed Oct 02 22:07:13 2024 +0200
+++ b/Discovery/Inc/text_multilanguage.h	Wed Oct 02 22:18:19 2024 +0200
@@ -382,6 +382,7 @@
         TXT2BYTE_Finished,
 
 		TXT2BYTE_Position,
+		TXT2BYTE_VpmTable,
         TXT2BYTE_Page,
 
 		TXT2BYTE_END,
--- a/Discovery/Inc/vpm.h	Wed Oct 02 22:07:13 2024 +0200
+++ b/Discovery/Inc/vpm.h	Wed Oct 02 22:18:19 2024 +0200
@@ -43,5 +43,7 @@
 
 float vpm_get_CNS(void);
 
+void vpm_table_init(void);
+
 
 #endif /* VPM_H */
--- a/Discovery/Src/data_central.c	Wed Oct 02 22:07:13 2024 +0200
+++ b/Discovery/Src/data_central.c	Wed Oct 02 22:18:19 2024 +0200
@@ -347,6 +347,7 @@
 	stateReal.diveSettings.input_next_stop_increment_depth_bar = ((float)pSettings->stop_increment_depth_meter) / 10.0f;
 	stateReal.diveSettings.last_stop_depth_bar = ((float)pSettings->last_stop_depth_meter) / 10.0f;
 	stateReal.diveSettings.vpm_conservatism = pSettings->VPM_conservatism.ub.standard;
+	stateReal.diveSettings.vpm_tableMode = pSettings->VPM_conservatism.ub.alternative;
 	stateReal.diveSettings.deco_type.uw = pSettings->deco_type.uw;
 	stateReal.diveSettings.fallbackOption = pSettings->fallbackToFixedSetpoint;
 	stateReal.diveSettings.ppo2sensors_deactivated = pSettings->ppo2sensors_deactivated;
--- a/Discovery/Src/tMenuDecoParameter.c	Wed Oct 02 22:07:13 2024 +0200
+++ b/Discovery/Src/tMenuDecoParameter.c	Wed Oct 02 22:18:19 2024 +0200
@@ -147,7 +147,7 @@
 
         textPointer += snprintf(&text[textPointer], 60,\
             "%c"
-            "\t"
+            "\t          "
             "%c"
             , TXT_DecoAlgorithm
             , decotypeTxtId
@@ -160,7 +160,7 @@
     {
         textPointer += snprintf(&text[textPointer], 60,\
             "VPM"
-            "\t"
+        	"\t          "
             "+"
             "%u"
             , VpmConsveratism
@@ -176,7 +176,7 @@
             "\016\016"
             "low/high"
             "\017"
-            "\t"
+        	"\t          "
             "%u"
             "/"
             "%u"
@@ -193,7 +193,7 @@
             "\016\016"
             "low/high"
             "\017"
-            "\t"
+            "\t          "
             "%u"
             "/"
             "%u"
@@ -207,7 +207,7 @@
     {
         textPointer += snprintf(&text[textPointer], 60,\
             "%c"
-            "\t"
+            "\t          "
             "%u"
             "\016\016"
             " %c%c"
@@ -220,6 +220,17 @@
     }
     strcpy(&text[textPointer],"\n\r");
     textPointer += 2;
+    if((line == 0) || (line == 6))
+    {
+    	textPointer+= snprintf(&text[textPointer], 60, "%c%c\t          ",TXT_2BYTE,TXT2BYTE_VpmTable);
+        if(settingsGetPointer()->VPM_conservatism.ub.alternative)
+            text[textPointer++] = '\005';
+        else
+            text[textPointer++] = '\006';
+        text[textPointer] = 0;
+    }
+    strcpy(&text[textPointer],"\n\r");
+    textPointer += 2;
 
     return StMDECOP;
 }
--- a/Discovery/Src/tMenuEditDecoParameter.c	Wed Oct 02 22:07:13 2024 +0200
+++ b/Discovery/Src/tMenuEditDecoParameter.c	Wed Oct 02 22:18:19 2024 +0200
@@ -33,7 +33,7 @@
 #include "tMenuEdit.h"
 #include "unit.h" // last stop in meter and feet
 
-#define MEDP_TAB (380)
+#define MEDP_TAB (525)
 
 /* Private function prototypes -----------------------------------------------*/
 static void openEdit_DecoAlgorithm(void);
@@ -41,6 +41,7 @@
 static void openEdit_DecoAltGF(void);
 static void openEdit_DecoVPM(void);
 static void openEdit_DecoLastStop(void);
+static void openEdit_DecoVpmTable(void);
 static void openEdit_DM_SwitchAlgorithm(uint8_t line);
 
 //void openEdit_DecoGasUsage(void);
@@ -81,6 +82,7 @@
             openEdit_DecoLastStop();
             break;
         case 6:
+        	openEdit_DecoVpmTable();
             break;
         }
     }
@@ -231,6 +233,21 @@
     startEdit();
 }
 
+static void openEdit_DecoVpmTable(void)
+{
+	SSettings *pSettings = settingsGetPointer();
+
+	if(pSettings->VPM_conservatism.ub.alternative == 0)
+	{
+	   pSettings->VPM_conservatism.ub.alternative = 1;
+	}
+    else
+    {
+    	pSettings->VPM_conservatism.ub.alternative = 0;
+    }
+	exitEditWithUpdate();
+}
+
 uint8_t OnAction_VPM(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
 {
     SSettings *pSettings;
--- a/Discovery/Src/text_multilanguage.c	Wed Oct 02 22:07:13 2024 +0200
+++ b/Discovery/Src/text_multilanguage.c	Wed Oct 02 22:18:19 2024 +0200
@@ -1944,6 +1944,12 @@
 static uint8_t text_IT_Position[] = "";
 static uint8_t text_ES_Position[] = "";
 
+static uint8_t text_EN_VpmTable[] = "VPM table mode";
+static uint8_t text_DE_VpmTable[] = "VPM Tabellenmodus";
+static uint8_t text_FR_VpmTable[] = "";
+static uint8_t text_IT_VpmTable[] = "";
+static uint8_t text_ES_VpmTable[] = "";
+
 static uint8_t text_EN_Page[] = "Page";
 static uint8_t text_DE_Page[] = "Blättern";
 static uint8_t text_FR_Page[] = "Défiler";
@@ -2247,6 +2253,7 @@
 	{(uint8_t)TXT2BYTE_Finished, 	{text_EN_Finished, text_DE_Finished, text_FR_Finished, text_IT_Finished, text_ES_Finished}},
 
 	{(uint8_t)TXT2BYTE_Position, 	{text_EN_Position, text_DE_Position, text_FR_Position, text_IT_Position, text_ES_Position}},
+	{(uint8_t)TXT2BYTE_VpmTable, 	{text_EN_VpmTable, text_DE_VpmTable, text_FR_VpmTable, text_IT_VpmTable, text_ES_VpmTable}},
 
 	{(uint8_t)TXT2BYTE_Page, 	{text_EN_Page, text_DE_Page, text_FR_Page, text_IT_Page, text_ES_Page}},
 };
--- a/Discovery/Src/vpm.c	Wed Oct 02 22:07:13 2024 +0200
+++ b/Discovery/Src/vpm.c	Wed Oct 02 22:18:19 2024 +0200
@@ -132,6 +132,8 @@
 
 static const _Bool vpm_b = true;
 
+static SDecoinfo vpmTable;
+
 extern const float float_buehlmann_N2_factor_expositon_20_seconds[];
 extern const float float_buehlmann_He_factor_expositon_20_seconds[];
 extern const float float_buehlmann_N2_factor_expositon_one_minute[];
@@ -219,6 +221,44 @@
     return gCNS_VPM;
 }
 
+
+void vpm_maintainTable(SLifeData* pLifeData,SDecoinfo* pDecoInfo)
+{
+	static uint32_t lastDiveSecond = 0;
+	uint8_t actual_deco_stop = 0;
+	int8_t index = 0;
+	uint8_t decreaseStopTime = 1;
+
+	if(lastDiveSecond < pLifeData->dive_time_seconds)
+	{
+		lastDiveSecond = pLifeData->dive_time_seconds;
+		actual_deco_stop = decom_get_actual_deco_stop((SDiveState*)stateUsed);
+
+		pDecoInfo->output_time_to_surface_seconds = 0;
+		for(index = DECOINFO_STRUCT_MAX_STOPS -1 ;index >= 0; index--)
+		{
+			if(pDecoInfo->output_stop_length_seconds[index] > 0)
+			{
+				if(decreaseStopTime)
+				{
+					if((pLifeData->depth_meter > (float)(actual_deco_stop - 0.5))
+						&& (pLifeData->depth_meter < (float)actual_deco_stop + 1.5))
+					{
+						pDecoInfo->output_stop_length_seconds[index]--;
+						decreaseStopTime = 0;
+					}
+				}
+				pDecoInfo->output_time_to_surface_seconds += pDecoInfo->output_stop_length_seconds[index];
+			}
+		}
+		pDecoInfo->output_time_to_surface_seconds += pLifeData->depth_meter / 10.0 * 60.0;
+	}
+	else if(lastDiveSecond > pLifeData->dive_time_seconds)
+	{
+		lastDiveSecond = pLifeData->dive_time_seconds;
+	}
+}
+
 int  vpm_calc(SLifeData* pINPUT,
               SDiveSettings* pSettings,
               SVpm* pVPM,
@@ -226,10 +266,17 @@
               pDECOINFO,
               int calc_what)
 {
+	static uint8_t vpmTableActive = 0;
+
     vpm_init_1();
     //decom_CreateGasChangeList(pSettings, pINPUT);
     vpm_calc_what = calc_what;
     /**clear decoInfo*/
+
+    if((vpmTableActive) && (vpm_calc_what == DECOSTOPS))
+    {
+    	memcpy(&vpmTable, pDECOINFO, sizeof(SDecoinfo));	/* save changes done by e.g. the simulator */
+    }
     pDECOINFO->output_time_to_surface_seconds = 0;
     pDECOINFO->output_ndl_seconds = 0;
     pDECOINFO->output_ceiling_meter = 0;
@@ -280,7 +327,26 @@
 
     //Only Decostops not futute stops
     if(vpm_calc_what == DECOSTOPS)
+    {
         vpm_calc_status = tmp_calc_status;
+        if(pSettings->vpm_tableMode)		/* store the most conservative deco plan and stick to it. */
+        {
+			if((int16_t)(pDECOINFO->output_time_to_surface_seconds - vpmTable.output_time_to_surface_seconds) > 60)
+			{
+				memcpy(&vpmTable, pDECOINFO, sizeof(SDecoinfo));
+				vpmTableActive = 1;
+			}
+			else
+			{
+				if(vpmTable.output_time_to_surface_seconds > 0)
+				{
+					vpm_maintainTable(pINPUT, &vpmTable);
+					vpmTable.output_ceiling_meter = pDECOINFO->output_ceiling_meter;
+					memcpy(pDECOINFO, &vpmTable, sizeof(SDecoinfo));
+				}
+			}
+        }
+    }
     return vpm_calc_status;
 }
 
@@ -1005,8 +1071,9 @@
     static int dp_max;
     static float surfacetime;
     _Bool first_stop = false;
+    float roundingValue = 0.0;
 
-    short stop_time_seconds;
+    uint16_t stop_time_seconds;
 
     max_first_stop_depth = fmaxf(first_stop_depth,max_first_stop_depth);
     if(begin)
@@ -1106,7 +1173,8 @@
             }
             else
             {
-                dp = 1 + (short)((deco_stop_depth - (pDiveSettings->input_second_to_last_stop_depth_bar * 10.0)) / step_size);
+            	roundingValue = (deco_stop_depth - (pDiveSettings->input_second_to_last_stop_depth_bar * 10.0)) / step_size;
+            	dp = 1 + r_nint(&roundingValue);
             }
 
             //dp_max = (int)fmaxf(dp_max,dp);
@@ -1116,7 +1184,7 @@
             }
             if(dp < DECOINFO_STRUCT_MAX_STOPS)
             {
-                stop_time_seconds = (short) fminf((999.9 * 60.0), (stop_time *60.0));
+                stop_time_seconds = (uint16_t)(fminf((999.9 * 60.0), (stop_time *60.0)));
                 //
 
                 //if(vpm_calc_what == DECOSTOPS)
@@ -2417,3 +2485,9 @@
     else
         return CALC_BEGIN;
 }
+
+void vpm_table_init()
+{
+	vpmTable.output_time_to_surface_seconds = 0;
+}
+