Advertisement
agmike

Код схемы ВР483 (WIP)

Dec 3rd, 2012
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 13.68 KB | None | 0 0
  1. /*
  2. SPAirDistributor483.airscheme.txt:
  3. ## двухкамерный резервуар ##
  4.  
  5. V tm 0 0.1
  6. V zr 0 0.1
  7. V tc 0 0.1
  8. V rk 0 6
  9. V zk 0 6
  10.  
  11.  
  12. ## магистральная часть ##
  13.  
  14. V mk 0 0.5     # MK
  15. C tm mk 12mm   #
  16.  
  17. V s1 0 0.1     # камера в седле C1
  18. V kdr 0 0.1    # КДР
  19. V k 0 0.01      # режимная камера
  20.  
  21. C mk_s1_p mk s1 2mm 0  # 2d1.0 в хвостовике плунжера (соединяют МК с ЗК при отпуске)
  22.  
  23. C kp s1 zk 3.6mm 0  # клапан плунжера (соединяет ЗК и С1 при торможении)
  24.  
  25. C s1_zk_p s1 zk 0.7mm 0  # верхнее отверстие в плунжере (соединяет С1 с ЗК или К)
  26. C s1_k_p  s1 k  0.7mm 0  
  27.  
  28. C k_zk_p k zk 0.7mm 0  # нижнее отверстие в плунжере (соединяет ЗК и К)
  29.  
  30. C chm mk s1 12mm 0  # челночная манжета (соединяет МК с С1 при торможении)
  31.  
  32. C dr s1 kdr 4mm 0  # клапан доп. разрядки
  33.  
  34. C ak kdr at 0.9mm 0  # атмосферный клапан
  35.  
  36. C km mk zk 0.9mm 0  # клапан мягкости
  37.  
  38. C rd rk k 0.6mm 0  # режимная диафрагма (соединение РК с К)
  39.  
  40.  
  41. ## главная часть ##
  42.  
  43. C tm_zr tm zr 1.3mm 0  #  дроссельное отверстие для зарядки ЗР
  44.  
  45. C rk_zk rk zk 0.5mm 1  #  дроссельное отверстие, соединяющее ЗК и РК
  46.  
  47. C zr_tc zr tc 1 0       #  отверстие (4d3.0 или d1.7) для наполнения ТЦ
  48. C kdr_tc kdr tc 12mm 1  #  канал КДР - ТЦ - Ат
  49. C tc_at tc at 2.3mm 1   #  ниппель в уравнительном поршне для соединения ТЦ с атмосферой
  50.  
  51. C vk rk at 1.5mm 0  # выпускной вентиль (выпуск воздуха из РК и отпуск тормоза)
  52. */
  53.  
  54. class SPAirDistributor483 : SPAirObject
  55. {
  56.     static readonly public int ModeR = 0;
  57.     static readonly public int ModeG = 1;
  58.     public int Mode = ModeR;
  59.  
  60.     static readonly public int LoadModeP = 0;
  61.     static readonly public int LoadModeS = 1;
  62.     static readonly public int LoadModeG = 2;
  63.     public int LoadMode = LoadModeG;
  64.  
  65.     public bool chmOpen = false;
  66.     public bool rdOpen = false;
  67.     public float mdPosition = 4.5f;
  68.     public float gpPosition = 0.0f;
  69.     public float upPosition = 5.0f;
  70.  
  71.     int vTM;
  72.     int vRK;
  73.     int vZK;
  74.     int vZR;
  75.     int vTC;
  76.     int vMK;
  77.     int vS1;
  78.     int vKDR;
  79.     int vK;
  80.     int cMK_S1_P;
  81.     int cKP;
  82.     int cS1_ZK_P;
  83.     int cS1_K_P;
  84.     int cK_ZK_P;
  85.     int cChM;
  86.     int cDR;
  87.     int cAK;
  88.     int cKM;
  89.     int cRD;
  90.     int cTM_ZR;
  91.     int cRK_ZK;
  92.     int cZR_TC;
  93.     int cKDR_TC;
  94.     int cTC_AT;
  95.  
  96.     public override void Init(SPAirScheme scheme, string objectName)
  97.     {
  98.         vTM = scheme.GetObjectReservoirIndex(".tm");
  99.         vRK = scheme.GetObjectReservoirIndex(".rk");
  100.         vZK = scheme.GetObjectReservoirIndex(".zk");
  101.         vZR = scheme.GetObjectReservoirIndex(".zr");
  102.         vTC = scheme.GetObjectReservoirIndex(".tc");
  103.  
  104.         vMK = scheme.GetObjectReservoirIndex(".mk");
  105.         vS1 = scheme.GetObjectReservoirIndex(".s1");
  106.         vKDR = scheme.GetObjectReservoirIndex(".kdr");
  107.         vK = scheme.GetObjectReservoirIndex(".k");
  108.  
  109.         cMK_S1_P = scheme.GetObjectConnectionIndex(".mk_s1_p");
  110.         cKP = scheme.GetObjectConnectionIndex(".kp");
  111.         cS1_ZK_P = scheme.GetObjectConnectionIndex(".s1_zk_p");
  112.         cS1_K_P = scheme.GetObjectConnectionIndex(".s1_k_p");
  113.         cK_ZK_P = scheme.GetObjectConnectionIndex(".k_zk_p");
  114.         cChM = scheme.GetObjectConnectionIndex(".chm");
  115.         cDR = scheme.GetObjectConnectionIndex(".dr");
  116.         cAK = scheme.GetObjectConnectionIndex(".ak");
  117.         cKM = scheme.GetObjectConnectionIndex(".km");
  118.         cRD = scheme.GetObjectConnectionIndex(".rd");
  119.  
  120.         cTM_ZR = scheme.GetObjectConnectionIndex(".tm_zr");
  121.         cRK_ZK = scheme.GetObjectConnectionIndex(".rk_zk");
  122.         cZR_TC = scheme.GetObjectConnectionIndex(".zr_tc");
  123.         cKDR_TC = scheme.GetObjectConnectionIndex(".kdr_tc");
  124.         cTC_AT = scheme.GetObjectConnectionIndex(".tc_at");
  125.     }
  126.  
  127.     public override void Update(SPAirScheme scheme, float dt)
  128.     {
  129.         float openMK_S1_P = 0.0f;
  130.         float openKP = 0.0f;
  131.         float openS1_ZK_P = 0.0f;
  132.         float openS1_K_P = 0.0f;
  133.         float openK_ZK = 0.0f;
  134.         float openChM = 0.0f;
  135.         float openDR = 0.0f;
  136.         float openAK = 0.0f;
  137.         float openKM = 0.0f;
  138.         float openRD = 0.0f;
  139.         float openTM_ZR = 0.0f;
  140.         float openRK_ZK = 0.0f;
  141.         float openZR_TC = 0.0f;
  142.         float openKDR_TC = 0.0f;
  143.         float openTC_AT = 0.0f;
  144.  
  145.         float kdrPressure = scheme.GetPressure(vKDR);
  146.         float mkPressure = scheme.GetPressure(vMK);
  147.         float zkPressure = scheme.GetPressure(vZK);
  148.         float s1Pressure = scheme.GetPressure(vS1);
  149.         float kPressure = scheme.GetPressure(vK);
  150.         float tmPressure = scheme.GetPressure(vTM);
  151.         float zrPressure = scheme.GetPressure(vZR);
  152.         float rkPressure = scheme.GetPressure(vRK);
  153.         float tcPressure = scheme.GetPressure(vTC);
  154.  
  155.         // клапан мягкости
  156.         const float kmOpenPressure = 400.0f;
  157.         if (kdrPressure < 40.0f && zkPressure >= kmOpenPressure)
  158.             openKM = 1.0f;
  159.  
  160.         // челночная манжета
  161.         float chmPressure = mkPressure - s1Pressure;
  162.         const float chmOpenSensivity = 150.0f;
  163.         const float chmCloseSensivity = 10.0f;
  164.         const float chmMinOpenDelta = 10.0f;
  165.         const float chmFullOpenDelta = 60.0f;
  166.         if (chmPressure > chmOpenSensivity)
  167.             chmOpen = true;
  168.         else if (chmPressure < chmCloseSensivity)
  169.             chmOpen = false;
  170.         if (chmOpen) {
  171.             openChM = (chmPressure - chmMinOpenDelta) / chmFullOpenDelta;
  172.             if (openChM > 1.0f)
  173.                 openChM = 1.0f;
  174.         }
  175.  
  176.         // магистральная диафрагма
  177.         float mdTargetPosition = 4.5f;
  178.         float mdPressure = zkPressure - mkPressure;
  179.  
  180.         // расчет положения МД
  181.         const float mdReleaseMax = 10.0f;
  182.         const float mdBrakeFirstStage = 5.0f;
  183.         const float mdBrakeSecondStage = 10.0f;
  184.         const float mdBrakeThirdStage = 20.0f;
  185.         const float mdBrakeMax = 30.0f;
  186.         if (mdPressure >= mdBrakeMax)
  187.             mdTargetPosition = 0.0f;
  188.         else if (mdPressure < -mdReleaseMax)
  189.             mdTargetPosition = 11.0f;
  190.         else if (mdPressure >= mdBrakeThirdStage) {
  191.             float a = (mdPressure - mdBrakeThirdStage) / (mdBrakeMax - mdBrakeThirdStage);
  192.             mdTargetPosition = 1.5f * a;
  193.         }
  194.         else if (mdPressure >= mdBrakeSecondStage) {
  195.             float a = (mdPressure - mdBrakeSecondStage) / (mdBrakeThirdStage - mdBrakeSecondStage);
  196.             mdTargetPosition = 1.5f * a + (1.0f - a) * 3.0f;
  197.         }
  198.         else if (mdPressure >= mdBrakeFirstStage) {
  199.             float a = (mdPressure - mdBrakeFirstStage)/ (mdBrakeSecondStage - mdBrakeFirstStage);
  200.             mdTargetPosition = 3.0f * a + (1.0f - a) * 4.5f;
  201.         }
  202.         else if (mdPressure < 0.0f) {
  203.             float a = -mdPressure / mdReleaseMax;
  204.             mdTargetPosition = 11.0f * a + (1.0f - a) * 4.5f;
  205.         }
  206.  
  207.         float mdSpeed = 3.0f ;
  208.         float mdPositionDelta = mdTargetPosition - mdPosition;
  209.         if (mdPositionDelta >= 0.0f) {
  210.             mdPosition = mdPosition + mdSpeed * (float)Math.Sqrt(mdPositionDelta) * dt;
  211.             if (mdPosition > mdTargetPosition)
  212.                 mdPosition = mdTargetPosition;
  213.         }
  214.         else {
  215.             mdPosition = mdPosition - mdSpeed * (float)Math.Sqrt(-mdPositionDelta) * dt;
  216.             if (mdPosition < mdTargetPosition)
  217.                 mdPosition = mdTargetPosition;
  218.         }
  219.  
  220.         // открытие клапанов МД
  221.         if (mdPosition < 4.5f) {
  222.             openDR = (4.5f - mdPosition) / 1.5f;
  223.             if (mdPosition < 3.0f) {
  224.                 openDR = 1.0f;
  225.                 openAK = 1.0f;
  226.                 if (mdPosition < 1.5f) {
  227.                     openKP = (1.5f - mdPosition) / 1.5f;
  228.                 }
  229.             }
  230.         }
  231.         else if (mdPosition >= 6.0f) {
  232.             openK_ZK = 1.0f;
  233.             if (mdPosition >= 6.2f) {
  234.                 openMK_S1_P = 1.0f;
  235.                 if (mdPosition >= 6.5f) {
  236.                     openS1_K_P = 1.0f;
  237.                 }
  238.             }
  239.         }
  240.         openS1_ZK_P = 1.0f - openS1_K_P;
  241.  
  242.         // режимная камера (Р и Г режим отпуска)
  243.         if (Mode == ModeR) {
  244.             const float rdRatioRK = 0.4f;
  245.             const float rdRatioK = 0.6f;
  246.             const float rdOpenPressure = rdRatioK * 350.0f + rdRatioRK * 250.0f;
  247.             const float rdFullOpenDelta = 20.0f;
  248.             float rdPressure = rdRatioK * kPressure + rdRatioRK * rkPressure;
  249.             float rdDelta = rdPressure - rdOpenPressure;
  250.             if (rdDelta > 0.0f) {
  251.                 openRD = rdDelta / rdFullOpenDelta;
  252.                 if (openRD > 1.0f)
  253.                     openRD = 1.0f;
  254.             }
  255.         }
  256.  
  257.         // главная часть
  258.  
  259.         // ОК зарядки ЗР
  260.         const float okSensivity = 2.0f;
  261.         if (tmPressure - zrPressure > okSensivity)
  262.             openTM_ZR = 1.0f;
  263.        
  264.         // положение главного поршня
  265.         const float gpSpeed = 7.0f / 1.0f;
  266.         const float gpMaxPressure = 60.0f;
  267.         const float gpMaxPosition = 23.0f;
  268.         const float gpSpring = gpMaxPressure / gpMaxPosition;
  269.         const float gpSensivity = 2.0f;
  270.         float gpSpringPressure = 15.0f + gpPosition * gpSpring;
  271.         float gpPressure = rkPressure - (zkPressure + gpSpringPressure);
  272.         if (gpPressure > gpSensivity) {
  273.             gpPosition = gpPosition + gpSpeed * (gpPressure - gpSensivity) * dt;
  274.             if (gpPosition > gpMaxPosition)
  275.                 gpPosition = gpMaxPosition;
  276.         }
  277.         else if (gpPressure < -gpSensivity) {
  278.             gpPosition = gpPosition + gpSpeed * (gpPressure + gpSensivity) * dt;
  279.             if (gpPosition < 0.0f)
  280.                 gpPosition = 0.0f;
  281.         }
  282.  
  283.         // увеличение объема РК из-за движения главного поршня
  284.         const float gpMaxAddVolume = 0.3f;
  285.         const float rkBaseVolume = 6.0f;
  286.         float rkVolume = scheme.GetVolume(vRK);
  287.         float rkAir = rkPressure * rkVolume;
  288.         rkVolume = rkBaseVolume + gpPosition * gpMaxAddVolume / gpMaxPosition;
  289.         rkPressure = rkAir / rkVolume;
  290.         scheme.SetPressure(vRK, rkPressure);
  291.         scheme.SetVolume(vRK, rkVolume);
  292.  
  293.         // положение уравнительного поршня
  294.         const float upMinPosition = 5.0f;
  295.         const float upMaxPosition = 23.0f;
  296.         const float upPositionRange = upMaxPosition - upMinPosition;
  297.         const float upMinPressure = 40.0f;
  298.         const float upMaxPressureG = 430.0f;
  299.         const float upMaxPressureP = 170.0f;
  300.         const float upPressureSP = 120.0f;
  301.         float upPressure = tcPressure - upMinPressure;
  302.         if (upPressure > 0.0f) {
  303.             if (LoadMode == LoadModeG)
  304.                 upPosition = upMinPosition + upPositionRange * (upPressure / upMaxPressureG);
  305.             else if (LoadMode == LoadModeS) {
  306.                 float pressureG = 0.0f;
  307.                 float pressureS = upPressure;
  308.                 if (pressureS > upPressureSP) {
  309.                     pressureG = upPressure - upPressureSP;
  310.                     pressureS = upPressureSP;
  311.                 }
  312.                 upPosition = upMinPosition + upPositionRange * (pressureS / upMaxPressureP + pressureG / upMaxPressureG);
  313.             }
  314.             else
  315.                 upPosition = upMinPosition + upPositionRange * (upPressure / upMaxPressureP);
  316.             if (upPosition > upMaxPosition)
  317.                 upPosition = upMaxPosition;
  318.         }
  319.         else
  320.             upPosition = upMinPosition;
  321.  
  322.         // каналы, управляемые главным поршнем
  323.         if (gpPosition < 5.0f) {
  324.             openRK_ZK = 1.0f;
  325.             openKDR_TC = 1.0f;
  326.         }
  327.  
  328.         // тормозной клапан
  329.         const float tkSensivity = 0.3f;
  330.         float tkDelta = gpPosition - upPosition;
  331.         if (tkDelta > tkSensivity) {
  332.             const float tkFullOpenDelta = 2.0f;
  333.             float tkHole = 12.0f;
  334.             if (gpPosition > 15.0f)
  335.                 tkHole = 1.7f;
  336.             float open = (tkDelta - tkSensivity) / tkFullOpenDelta;
  337.             if (open > 1.0f)
  338.                 open = 1.0f;
  339.             openZR_TC = open * SPAirHelper.HoleFlow(tkHole);
  340.         }
  341.         else if (tkDelta < -tkSensivity) {
  342.             const float tkFullOpenDelta = 0.5f;
  343.             openTC_AT = (-tkDelta - tkSensivity) / tkFullOpenDelta;
  344.         }
  345.  
  346.         scheme.SetFlowRate(cMK_S1_P, openMK_S1_P);
  347.         scheme.SetFlowRate(cKP, openKP);
  348.         scheme.SetFlowRate(cS1_ZK_P, openS1_ZK_P);
  349.         scheme.SetFlowRate(cS1_K_P, openS1_K_P);
  350.         scheme.SetFlowRate(cK_ZK_P, openK_ZK);
  351.         scheme.SetFlowRate(cChM, openChM);
  352.         scheme.SetFlowRate(cDR, openDR);
  353.         scheme.SetFlowRate(cAK, openAK);
  354.         scheme.SetFlowRate(cKM, openKM);
  355.         scheme.SetFlowRate(cRD, openRD);
  356.         scheme.SetFlowRate(cTM_ZR, openTM_ZR);
  357.         scheme.SetFlowRate(cRK_ZK, openRK_ZK);
  358.         scheme.SetFlowRate(cZR_TC, openZR_TC);
  359.         scheme.SetFlowRate(cKDR_TC, openKDR_TC);
  360.         scheme.SetFlowRate(cTC_AT, openTC_AT);
  361.     }
  362. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement