comparison Discovery/Src/check_warning.c @ 788:4abfb8a2a435

Define explicit setpoints for low / high / deco. Add an option to delay the switch to SPlow until all decompression has been cleared. (mikeller)
author heinrichsweikamp
date Tue, 04 Jul 2023 14:39:06 +0200
parents 2c243233c999
children da632300e7d4
comparison
equal deleted inserted replaced
787:aeb72882f30a 788:4abfb8a2a435
37 #include "data_exchange.h" 37 #include "data_exchange.h"
38 #include "check_warning.h" 38 #include "check_warning.h"
39 #include "settings.h" 39 #include "settings.h"
40 #include "decom.h" 40 #include "decom.h"
41 #include "tCCR.h" 41 #include "tCCR.h"
42 #include "tHome.h"
42 43
43 44
44 #define DEBOUNCE_FALLBACK_TIME_MS (5000u) /* set warning after 5 seconds of pending error condition */ 45 #define DEBOUNCE_FALLBACK_TIME_MS (5000u) /* set warning after 5 seconds of pending error condition */
45 46
47 #define SETPOINT_DECO_START_RANGE_M 3.0
48 #define SWITCH_DEPTH_LOW_MINIMUM_M 1.0
46 49
47 /* Private variables with access ----------------------------------------------*/ 50 /* Private variables with access ----------------------------------------------*/
48 static uint8_t betterGasId = 0; 51 static uint8_t betterGasId = 0;
49 static uint8_t betterBailoutGasId = 0; 52 static uint8_t betterBailoutGasId = 0;
50 static uint8_t betterSetpointId = 1; 53 static uint8_t betterSetpointId = 1;
287 } 290 }
288 291
289 292
290 uint8_t getSetpointLowId(void) 293 uint8_t getSetpointLowId(void)
291 { 294 {
295 SSettings *settings = settingsGetPointer();
296
297 if (settings->autoSetpoint) {
298 return SETPOINT_INDEX_AUTO_LOW;
299 }
300
292 uint8_t setpointLowId = 0; 301 uint8_t setpointLowId = 0;
293 uint8_t setpointLowDepthM = UINT8_MAX; 302 uint8_t setpointLowDepthM = UINT8_MAX;
294 for (unsigned i = 1; i <= NUM_GASES; i++) { 303 for (unsigned i = 1; i <= NUM_GASES; i++) {
295 if (stateUsed->diveSettings.setpoint[i].depth_meter && stateUsed->diveSettings.setpoint[i].depth_meter < setpointLowDepthM) { 304 if (stateUsed->diveSettings.setpoint[i].depth_meter && stateUsed->diveSettings.setpoint[i].depth_meter < setpointLowDepthM) {
296 setpointLowId = i; 305 setpointLowId = i;
302 } 311 }
303 312
304 313
305 uint8_t getSetpointHighId(void) 314 uint8_t getSetpointHighId(void)
306 { 315 {
316 SSettings *settings = settingsGetPointer();
317
318 if (settings->autoSetpoint) {
319 return SETPOINT_INDEX_AUTO_HIGH;
320 }
321
307 uint8_t setpointHighId = 0; 322 uint8_t setpointHighId = 0;
308 uint8_t setpointHighDepthM = 0; 323 uint8_t setpointHighDepthM = 0;
309 for (unsigned i = 1; i <= NUM_GASES; i++) { 324 for (unsigned i = 1; i <= NUM_GASES; i++) {
310 if (stateUsed->diveSettings.setpoint[i].depth_meter && stateUsed->diveSettings.setpoint[i].depth_meter >= setpointHighDepthM) { 325 if (stateUsed->diveSettings.setpoint[i].depth_meter && stateUsed->diveSettings.setpoint[i].depth_meter >= setpointHighDepthM) {
311 setpointHighId = i; 326 setpointHighId = i;
315 330
316 return setpointHighId; 331 return setpointHighId;
317 } 332 }
318 333
319 334
335 uint8_t getSetpointDecoId(void)
336 {
337 SSettings *settings = settingsGetPointer();
338
339 if (settings->autoSetpoint && stateUsed->diveSettings.setpoint[SETPOINT_INDEX_AUTO_DECO].note.ub.active) {
340 return SETPOINT_INDEX_AUTO_DECO;
341 }
342
343 return 0;
344 }
345
346
320 /* check for better travel!!! setpoint hw 151210 347 /* check for better travel!!! setpoint hw 151210
321 */ 348 */
322 static int8_t check_BetterSetpoint(SDiveState *diveState) 349 static int8_t check_BetterSetpoint(SDiveState *diveState)
323 { 350 {
324 diveState->warnings.betterSetpoint = 0; 351 diveState->warnings.betterSetpoint = 0;
330 } 357 }
331 358
332 SSettings *settings = settingsGetPointer(); 359 SSettings *settings = settingsGetPointer();
333 360
334 float currentDepthM = diveState->lifeData.depth_meter; 361 float currentDepthM = diveState->lifeData.depth_meter;
335 if (settings->dive_mode == DIVEMODE_CCR && diveState->lifeData.lastSetpointChangeDepthM != currentDepthM) { 362 float lastChangeDepthM = diveState->lifeData.lastSetpointChangeDepthM;
336 float lastChangeDepthM = diveState->lifeData.lastSetpointChangeDepthM; 363 if (settings->dive_mode == DIVEMODE_CCR && lastChangeDepthM != currentDepthM) {
337 bool descending = currentDepthM > lastChangeDepthM; 364 bool descending = currentDepthM > lastChangeDepthM;
338 uint8_t setpointLowId = getSetpointLowId();
339 uint8_t setpointHighId = getSetpointHighId();
340 uint8_t betterSetpointIdLocal = 0; 365 uint8_t betterSetpointIdLocal = 0;
341 uint8_t betterSetpointSwitchDepthM = descending ? 0 : UINT8_MAX; 366
342 367 if (settings->autoSetpoint) {
343 for (unsigned i = 1; i <= NUM_GASES; i++) { 368 bool decoSetpointEnabled = diveState->diveSettings.setpoint[SETPOINT_INDEX_AUTO_DECO].note.ub.active;
344 uint8_t switchDepthM = diveState->diveSettings.setpoint[i].depth_meter; 369 const SDecoinfo *decoInfo = getDecoInfo();
345 if (!switchDepthM || (descending && i == setpointLowId) || (!descending && i == setpointHighId)) { 370 uint8_t nextDecoStopDepthM;
346 continue; 371 uint16_t nextDecoStopTimeRemainingS;
347 } 372 tHome_findNextStop(decoInfo->output_stop_length_seconds, &nextDecoStopDepthM, &nextDecoStopTimeRemainingS);
348 373
349 if ((descending && lastChangeDepthM < switchDepthM && switchDepthM < currentDepthM && switchDepthM > betterSetpointSwitchDepthM) 374 if (decoSetpointEnabled && nextDecoStopDepthM && currentDepthM < nextDecoStopDepthM + SETPOINT_DECO_START_RANGE_M && !diveState->lifeData.setpointDecoActivated) {
350 || (!descending && lastChangeDepthM > switchDepthM && switchDepthM > currentDepthM && switchDepthM <= betterSetpointSwitchDepthM)) { 375 betterSetpointIdLocal = SETPOINT_INDEX_AUTO_DECO;
351 betterSetpointIdLocal = i; 376 diveState->lifeData.setpointDecoActivated = true;
352 betterSetpointSwitchDepthM = switchDepthM; 377 }
378
379 if (descending) {
380 uint8_t switchDepthHighM = diveState->diveSettings.setpoint[SETPOINT_INDEX_AUTO_HIGH].depth_meter;
381
382 if (lastChangeDepthM < switchDepthHighM && switchDepthHighM < currentDepthM && !diveState->lifeData.setpointDecoActivated) {
383 betterSetpointIdLocal = SETPOINT_INDEX_AUTO_HIGH;
384 }
385 } else {
386 uint8_t switchDepthLowM = diveState->diveSettings.setpoint[SETPOINT_INDEX_AUTO_LOW].depth_meter;
387
388 if (lastChangeDepthM > SWITCH_DEPTH_LOW_MINIMUM_M && SWITCH_DEPTH_LOW_MINIMUM_M > currentDepthM) {
389 // Avoid draining the oxygen supply by surfacing with a setpoint >= 1.0
390 betterSetpointIdLocal = SETPOINT_INDEX_AUTO_LOW;
391 diveState->lifeData.setpointLowDelayed = false;
392 } else if (lastChangeDepthM > switchDepthLowM && switchDepthLowM > currentDepthM) {
393 if (nextDecoStopDepthM && settings->delaySetpointLow) {
394 diveState->lifeData.setpointLowDelayed = true;
395 } else {
396 betterSetpointIdLocal = SETPOINT_INDEX_AUTO_LOW;
397 }
398 }
399 }
400
401 if (!nextDecoStopDepthM) {
402 // Update the state when the decompression obligation ends
403 diveState->lifeData.setpointDecoActivated = false;
404
405 if (diveState->lifeData.setpointLowDelayed) {
406 betterSetpointIdLocal = SETPOINT_INDEX_AUTO_LOW;
407 diveState->lifeData.setpointLowDelayed = false;
408 }
409 }
410 } else {
411 uint8_t setpointLowId = getSetpointLowId();
412 uint8_t setpointHighId = getSetpointHighId();
413 uint8_t betterSetpointSwitchDepthM = descending ? 0 : UINT8_MAX;
414
415 for (unsigned i = 1; i <= NUM_GASES; i++) {
416 uint8_t switchDepthM = diveState->diveSettings.setpoint[i].depth_meter;
417 if (!switchDepthM || (descending && i == setpointLowId) || (!descending && i == setpointHighId)) {
418 continue;
419 }
420
421 if ((descending && lastChangeDepthM < switchDepthM && switchDepthM < currentDepthM && switchDepthM > betterSetpointSwitchDepthM)
422 || (!descending && lastChangeDepthM > switchDepthM && switchDepthM > currentDepthM && switchDepthM <= betterSetpointSwitchDepthM)) {
423 betterSetpointIdLocal = i;
424 betterSetpointSwitchDepthM = switchDepthM;
425 }
353 } 426 }
354 } 427 }
355 428
356 if (betterSetpointIdLocal) { 429 if (betterSetpointIdLocal) {
357 betterSetpointId = betterSetpointIdLocal; 430 betterSetpointId = betterSetpointIdLocal;