comparison Common/Src/decom.c @ 855:012f94ec2fe0 Evo_2_23

Redefine Deco gas creation function: The old function needed a lot of iteration to get through all gases. With the change to define the first gas in PSCR mode as deco gas for calculation (because the actual gas could be not breathable close to surface => deco planing would be based on > 80% nitrogen increasing the deco prediction higher than necessary) the need showed up to somehow define the first gas as deco gas. Instead of manipulating the gas attribute the deco list creation function was changed to create the list based on gas line pointer information instead of index lists. The new function needs less iterations for sorting and is more flexible regarding gas handling.
author Ideenmodellierer
date Mon, 18 Mar 2024 21:52:25 +0100
parents 9bc817e9e221
children
comparison
equal deleted inserted replaced
854:48b6a3b1f3f8 855:012f94ec2fe0
35 */ 35 */
36 36
37 #include "decom.h" 37 #include "decom.h"
38 38
39 #include <math.h> 39 #include <math.h>
40 #include <string.h>
40 #include "settings.h" 41 #include "settings.h"
41 #include "calc_crush.h" 42 #include "calc_crush.h"
42 43
43 # define FRACTION_N2_AIR 0.7902 44 #define FRACTION_N2_AIR 0.7902
44 45
45 const float helium_time_constant[16] = { 46 const float helium_time_constant[16] = {
46 3.68695308808482E-001, 47 3.68695308808482E-001,
47 2.29518933960247E-001, 48 2.29518933960247E-001,
48 1.46853216220327E-001, 49 1.46853216220327E-001,
575 } 576 }
576 return 0; 577 return 0;
577 } 578 }
578 579
579 580
581 void insertGasIntoList(SGasLine* pGas, SGasLine** pGasList, uint8_t gasInSettings, uint8_t* pGasInSettingsList, uint8_t GasListLength)
582 {
583 uint8_t localGasIndex = GasListLength;
584 if(pGas != 0)
585 {
586 while(localGasIndex != 0) /* first entry */
587 {
588 if(pGasList[localGasIndex-1]->depth_meter > pGas->depth_meter) /* switch depth of existing gas is deeper then new one => move down */
589 {
590 pGasList[localGasIndex] = pGasList[localGasIndex-1];
591 pGasInSettingsList[localGasIndex] = pGasInSettingsList[localGasIndex - 1];
592 localGasIndex--;
593 }
594 else
595 {
596 break;
597 }
598 }
599 pGasList[localGasIndex] = pGas;
600 pGasInSettingsList[localGasIndex] = gasInSettings;
601 }
602 }
580 603
581 void decom_CreateGasChangeList(SDiveSettings* pInput, const SLifeData* pLifeData) 604 void decom_CreateGasChangeList(SDiveSettings* pInput, const SLifeData* pLifeData)
582 { 605 {
583 int i=0, j = 0; 606 SGasLine localPSCRFirst;
584 int count = 0; 607 SGasLine *pLocalGasList[5] = {0,0,0,0,0};
585 for(i=0;i< 5;i++) 608 uint8_t localGasInSettingsList[5] = {0,0,0,0,0};
609
610 uint8_t gasStart = 1;
611 uint8_t gasIndex = 0;
612 uint8_t gasEntryCnt = 0;
613
614 int i=0;
615 for(i=0;i< 5;i++) /* reset list */
616 {
617 pInput->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero = 0;
618 pInput->decogaslist[i].GasIdInSettings = 255;
619 pInput->decogaslist[i].setPoint_cbar = 0;
620 pInput->decogaslist[i].helium_percentage = 0;
621 pInput->decogaslist[i].nitrogen_percentage = 0;
622 }
623 /* FirstGas
624 * 0 = special gas, 1 to 5 is OC gas, 6 to 10 is diluent
625 */
626 pInput->decogaslist[0] = pLifeData->actualGas;
627 /* Add Deco Gases
628 * special (gasId == 0) is never a deco/travel gas but actual gas only
629 */
630
631 if(pInput->diveMode != DIVEMODE_OC)
632 {
633 gasStart = 6; /* CCR or PSCR => CC gaslist */
634 }
635
636 if(pInput->diveMode == DIVEMODE_PSCR) /* Handle first gas as deco gas */
637 {
638 for(gasIndex = gasStart; gasIndex < gasStart + 5; gasIndex++)
639 {
640 if(pInput->gas[gasIndex].note.ub.first)
641 {
642 if (pLifeData->actualGas.GasIdInSettings != gasIndex)
586 { 643 {
587 //FirstGas 644 memcpy(&localPSCRFirst, &pInput->gas[gasIndex], sizeof(SGasLine));
588 645 localPSCRFirst.depth_meter = calc_MOD(gasIndex);
589 pInput->decogaslist[i].change_during_ascent_depth_meter_otherwise_zero = 0; 646 insertGasIntoList(&localPSCRFirst, pLocalGasList, gasIndex, localGasInSettingsList, gasEntryCnt);
590 pInput->decogaslist[i].GasIdInSettings = 255; 647 gasEntryCnt++;
591 pInput->decogaslist[i].setPoint_cbar = 0; 648 break;
592 pInput->decogaslist[i].helium_percentage = 0;
593 pInput->decogaslist[i].nitrogen_percentage = 0;
594 } 649 }
595 //pInput->liveData.dive_time_seconds = 0; 650 }
596 651 }
597 /* FirstGas 652 }
598 * 0 = special gas, 1 to 5 ist OC gas, 6 to 10 is diluent 653
599 */ 654
600 655 for(gasIndex = gasStart; gasIndex < gasStart + 5; gasIndex++)
601 656 {
602 657 if(((pInput->gas[gasIndex].note.ub.active) && (pInput->gas[gasIndex].depth_meter)) /* ready for deco calculation */
603 pInput->decogaslist[0] = pLifeData->actualGas; 658 && (pLifeData->actualGas.GasIdInSettings != gasIndex) /* not the actual gas */
604 659 && (pInput->gas[gasIndex].depth_meter < pLifeData->depth_meter )) /* a gas which is on the way to surface */
605 /* Add Deco Gases 660 {
606 * special (gasId == 0) is never a deco/travel gas but actual gas only 661 insertGasIntoList(&pInput->gas[gasIndex], pLocalGasList, gasIndex, localGasInSettingsList, gasEntryCnt);
607 */ 662 gasEntryCnt++;
608 if(pInput->diveMode == DIVEMODE_OC) 663 }
609 { 664 }
610 665 for(gasIndex = 1; gasIndex < gasEntryCnt+1; gasIndex++) /* move gasLine Information into deco List */
611 for(i=1;i<= 5;i++) 666 {
612 { 667 pInput->decogaslist[gasIndex].change_during_ascent_depth_meter_otherwise_zero = pLocalGasList[gasIndex-1]->depth_meter;
613 if(pInput->gas[i].note.ub.active && pInput->gas[i].depth_meter 668 pInput->decogaslist[gasIndex].nitrogen_percentage = 100;
614 && (pLifeData->actualGas.GasIdInSettings != i) 669 pInput->decogaslist[gasIndex].nitrogen_percentage -= pLocalGasList[gasIndex-1]->oxygen_percentage;
615 &&(pInput->gas[i].depth_meter < pLifeData->depth_meter ) ) 670 pInput->decogaslist[gasIndex].nitrogen_percentage -= pLocalGasList[gasIndex-1]->helium_percentage;
616 { 671 pInput->decogaslist[gasIndex].helium_percentage = pLocalGasList[gasIndex-1]->helium_percentage;
617 count = 1; 672 pInput->decogaslist[gasIndex].GasIdInSettings = localGasInSettingsList[gasIndex-1];
618 for(j=1;j<= 5;j++) 673 pInput->decogaslist[gasIndex].AppliedDiveMode = pInput->diveMode;
619 { 674 }
620 if( (pInput->gas[j].note.ub.active && pInput->gas[j].depth_meter > 0)
621 && (pLifeData->actualGas.GasIdInSettings != j) // new hw 160905
622 && (pInput->gas[j].depth_meter > pInput->gas[i].depth_meter))
623 count++;
624 }
625 pInput->decogaslist[count].change_during_ascent_depth_meter_otherwise_zero = pInput->gas[i].depth_meter;
626 pInput->decogaslist[count].nitrogen_percentage = 100;
627 pInput->decogaslist[count].nitrogen_percentage -= pInput->gas[i].oxygen_percentage;
628 pInput->decogaslist[count].nitrogen_percentage -= pInput->gas[i].helium_percentage;
629 pInput->decogaslist[count].helium_percentage = pInput->gas[i].helium_percentage;
630 pInput->decogaslist[count].GasIdInSettings = i;
631 pInput->decogaslist[count].AppliedDiveMode = DIVEMODE_OC;
632 }
633 }
634 }
635 else
636 {
637 //divmode CCR or PSCR
638 for(i=6; i <= 10; i++)
639 {
640 if((pInput->gas[i].note.ub.active) && (pInput->gas[i].depth_meter)
641 && (pLifeData->actualGas.GasIdInSettings != i)
642 && (pInput->gas[i].depth_meter < pLifeData->depth_meter ))
643 {
644 count = 1;
645 for(j=6;j<= 10;j++)
646 {
647 // if(pInput->gas[j].note.ub.active && pInput->gas[j].depth_meter > 0 &&pInput->gas[j].depth_meter > pInput->gas[i].depth_meter)
648 if(((pInput->gas[j].note.ub.active) && (pInput->gas[j].depth_meter > 0))
649 && (pLifeData->actualGas.GasIdInSettings != j) // new hw 160905
650 && (pInput->gas[j].depth_meter > pInput->gas[i].depth_meter))
651 count++;
652 }
653 pInput->decogaslist[count].change_during_ascent_depth_meter_otherwise_zero = pInput->gas[i].depth_meter;
654 pInput->decogaslist[count].nitrogen_percentage = 100;
655 if(pInput->diveMode == DIVEMODE_PSCR)
656 {
657 pInput->decogaslist[count].AppliedDiveMode = DIVEMODE_PSCR;
658 pInput->decogaslist[count].setPoint_cbar = decom_calc_SimppO2_O2based((float)(pInput->gas[i].depth_meter / 10.0 + 1.0), pInput->gas[i].oxygen_percentage, pInput->decogaslist[count].pscr_factor ) * 100;
659 pInput->decogaslist[count].nitrogen_percentage -= pInput->gas[i].oxygen_percentage;
660 }
661 else
662 {
663 pInput->decogaslist[count].nitrogen_percentage -= pInput->gas[i].oxygen_percentage;
664 pInput->decogaslist[count].AppliedDiveMode = DIVEMODE_CCR;
665 pInput->decogaslist[count].setPoint_cbar = pInput->decogaslist[0].setPoint_cbar; /* assume that current setpoint is kept till end of the dive */
666 }
667 pInput->decogaslist[count].nitrogen_percentage -= pInput->gas[i].helium_percentage;
668 pInput->decogaslist[count].helium_percentage = pInput->gas[i].helium_percentage;
669 pInput->decogaslist[count].GasIdInSettings = i;
670 }
671 }
672 }
673 } 675 }
674 void test_decom_CreateGasChangeList(void) 676 void test_decom_CreateGasChangeList(void)
675 { 677 {
676 SDiveSettings diveSetting; 678 SDiveSettings diveSetting;
677 SLifeData lifeData; 679 SLifeData lifeData;