void FGRocket::Calculate(void) { if (FDMExec->IntegrationSuspended()) return; RunPreFunctions(); PropellantFlowRate = (FuelExpended + OxidizerExpended)/in.TotalDeltaT; TotalPropellantExpended += FuelExpended + OxidizerExpended; // If Isp has been specified as a function, override the value of Isp to that, otherwise // assume a constant value is given. if (isp_function) Isp = isp_function->GetValue(); // If there is a thrust table, it is a function of propellant burned. The // engine is started when the throttle is advanced to 1.0. After that, it // burns without regard to throttle setting. if (ThrustTable != 0L) { // Thrust table given -> Solid fuel used if ((in.ThrottlePos[EngineNumber] == 1 || BurnTime > 0.0 ) && !Starved) { VacThrust = ThrustTable->GetValue(TotalPropellantExpended) * (ThrustVariation + 1) * (TotalIspVariation + 1); if (BurnTime <= BuildupTime && BuildupTime > 0.0) { VacThrust *= sin((BurnTime/BuildupTime)*M_PI/2.0); // VacThrust *= (1-cos((BurnTime/BuildupTime)*M_PI))/2.0; // 1 - cos approach } BurnTime += in.TotalDeltaT; // Increment burn time } else { VacThrust = 0.0; } } else { // liquid fueled rocket assumed if (in.ThrottlePos[EngineNumber] < MinThrottle || Starved) { // Combustion not supported PctPower = 0.0; // desired thrust Flameout = true; VacThrust = 0.0; } else { // Calculate thrust // PctPower = Throttle / MaxThrottle; // Min and MaxThrottle range from 0.0 to 1.0, normally. PctPower = in.ThrottlePos[EngineNumber]; Flameout = false; VacThrust = Isp * PropellantFlowRate; } } // End thrust calculations LoadThrusterInputs(); It += Thruster->Calculate(VacThrust) * in.TotalDeltaT; ItVac += VacThrust * in.TotalDeltaT; RunPostFunctions(); }
void FGPiston::Calculate(void) { // Input values. p_amb = in.Pressure * psftopa; double p = in.TotalPressure * psftopa; p_ram = (p - p_amb) * Ram_Air_Factor + p_amb; T_amb = RankineToKelvin(in.Temperature); RunPreFunctions(); TotalDeltaT = ( in.TotalDeltaT < 1e-9 ) ? 1.0 : in.TotalDeltaT; /* The thruster controls the engine RPM because it encapsulates the gear ratio and other transmission variables */ RPM = Thruster->GetEngineRPM(); MeanPistonSpeed_fps = ( RPM * Stroke) / (360); // AKA 2 * (RPM/60) * ( Stroke / 12) or 2NS IAS = in.Vc; doEngineStartup(); if (Boosted) doBoostControl(); doMAP(); doAirFlow(); doFuelFlow(); //Now that the fuel flow is done check if the mixture is too lean to run the engine //Assume lean limit at 22 AFR for now - thats a thi of 0.668 //This might be a bit generous, but since there's currently no audiable warning of impending //cutout in the form of misfiring and/or rough running its probably reasonable for now. // if (equivalence_ratio < 0.668) // Running = false; doEnginePower(); if (IndicatedHorsePower < 0.1250) Running = false; doEGT(); doCHT(); doOilTemperature(); doOilPressure(); if (Thruster->GetType() == FGThruster::ttPropeller) { ((FGPropeller*)Thruster)->SetAdvance(in.PropAdvance[EngineNumber]); ((FGPropeller*)Thruster)->SetFeather(in.PropFeather[EngineNumber]); } LoadThrusterInputs(); Thruster->Calculate(HP * hptoftlbssec); RunPostFunctions(); }
void FGElectric::Calculate(void) { RunPreFunctions(); if (Thruster->GetType() == FGThruster::ttPropeller) { ((FGPropeller*)Thruster)->SetAdvance(in.PropAdvance[EngineNumber]); ((FGPropeller*)Thruster)->SetFeather(in.PropFeather[EngineNumber]); } RPM = Thruster->GetRPM() * Thruster->GetGearRatio(); HP = PowerWatts * in.ThrottlePos[EngineNumber] / hptowatts; LoadThrusterInputs(); Thruster->Calculate(HP * hptoftlbssec); RunPostFunctions(); }
void FGTurboProp::Calculate(void) { RunPreFunctions(); TAT = in.TAT_c; ThrottlePos = in.ThrottlePos[EngineNumber]; /* The thruster controls the engine RPM because it encapsulates the gear ratio and other transmission variables */ RPM = Thruster->GetEngineRPM(); if (thrusterType == FGThruster::ttPropeller) { ((FGPropeller*)Thruster)->SetAdvance(in.PropAdvance[EngineNumber]); ((FGPropeller*)Thruster)->SetFeather(in.PropFeather[EngineNumber]); ((FGPropeller*)Thruster)->SetReverse(Reversed); if (Reversed) { ((FGPropeller*)Thruster)->SetReverseCoef(ThrottlePos); } else { ((FGPropeller*)Thruster)->SetReverseCoef(0.0); } if (Reversed) { if (ThrottlePos < BetaRangeThrottleEnd) { ThrottlePos = 0.0; // idle when in Beta-range } else { // when reversed: ThrottlePos = (ThrottlePos-BetaRangeThrottleEnd)/(1-BetaRangeThrottleEnd) * ReverseMaxPower; } } } // When trimming is finished check if user wants engine OFF or RUNNING if ((phase == tpTrim) && (in.TotalDeltaT > 0)) { if (Running && !Starved) { phase = tpRun; N2 = IdleN2; N1 = IdleN1; OilTemp_degK = 366.0; Cutoff = false; } else { phase = tpOff; Cutoff = true; Eng_ITT_degC = TAT; Eng_Temperature = TAT; OilTemp_degK = TAT+273.15; } } if (!Running && Starter) { if (phase == tpOff) { phase = tpSpinUp; if (StartTime < 0) StartTime=0; } } if (!Running && !Cutoff && (N1 > 15.0)) { phase = tpStart; StartTime = -1; } if (Cutoff && (phase != tpSpinUp)) phase = tpOff; if (in.TotalDeltaT == 0) phase = tpTrim; if (Starved) phase = tpOff; if (Condition >= 10) { phase = tpOff; StartTime=-1; } // limiter intervention wanted? if (Ielu_max_torque > 0.0) { double torque = 0.0; if (thrusterType == FGThruster::ttPropeller) { torque = ((FGPropeller*)(Thruster))->GetTorque(); } else if (thrusterType == FGThruster::ttRotor) { torque = ((FGRotor*)(Thruster))->GetTorque(); } if (Condition < 1) { if ( abs(torque) > Ielu_max_torque && ThrottlePos >= OldThrottle ) { ThrottlePos = OldThrottle - 0.1 * in.TotalDeltaT; //IELU down Ielu_intervent = true; } else if ( Ielu_intervent && ThrottlePos >= OldThrottle) { ThrottlePos = OldThrottle + 0.05 * in.TotalDeltaT; //IELU up Ielu_intervent = true; } else { Ielu_intervent = false; } } else { Ielu_intervent = false; } OldThrottle = ThrottlePos; } switch (phase) { case tpOff: HP = Off(); break; case tpRun: HP = Run(); break; case tpSpinUp: HP = SpinUp(); break; case tpStart: HP = Start(); break; default: HP = 0; } LoadThrusterInputs(); Thruster->Calculate(HP * hptoftlbssec); RunPostFunctions(); }