Пример #1
0
void FGRocket::ConsumeFuel(void)
{
  unsigned int i;
  FGTank* Tank;
  bool haveOxTanks = false;
  double Fshortage=0, Oshortage=0, TanksWithFuel=0, TanksWithOxidizer=0;

  if (FuelFreeze) return;
  if (TrimMode) return;

  // Count how many assigned tanks have fuel for this engine at this time.
  // If there is/are fuel tanks but no oxidizer tanks, this indicates
  // a solid rocket is being modeled.

  for (i=0; i<SourceTanks.size(); i++) {
    Tank = Propulsion->GetTank(SourceTanks[i]);
    switch(Tank->GetType()) {
      case FGTank::ttFUEL:
        if (Tank->GetContents() > 0.0 && Tank->GetSelected()) ++TanksWithFuel;
        break;
      case FGTank::ttOXIDIZER:
        haveOxTanks = true;
        if (Tank->GetContents() > 0.0 && Tank->GetSelected()) ++TanksWithOxidizer;
        break;
    }
  }

  // If this engine has burned out, it is starved.

  if (TanksWithFuel==0 || (haveOxTanks && TanksWithOxidizer==0)) {
    Starved = true;
    return;
  }

  // Expend fuel from the engine's tanks if the tank is selected as a source
  // for this engine.

  double fuelNeedPerTank = CalcFuelNeed()/TanksWithFuel;
  double oxiNeedPerTank = CalcOxidizerNeed()/TanksWithOxidizer;

  for (i=0; i<SourceTanks.size(); i++) {
    Tank = Propulsion->GetTank(SourceTanks[i]);
    if ( ! Tank->GetSelected()) continue; // If this tank is not selected as a source, skip it.
    switch(Tank->GetType()) {
      case FGTank::ttFUEL:
        Fshortage += Tank->Drain(2.0*fuelNeedPerTank - previousFuelNeedPerTank);
        previousFuelNeedPerTank = fuelNeedPerTank;
        break;
      case FGTank::ttOXIDIZER:
        Oshortage += Tank->Drain(2.0*oxiNeedPerTank - previousOxiNeedPerTank);
        previousOxiNeedPerTank = oxiNeedPerTank;
        break;
    }
  }

  if (Fshortage < 0.00 || (haveOxTanks && Oshortage < 0.00)) Starved = true;
  else Starved = false;
}
Пример #2
0
string FGPropulsion::GetPropulsionTankReport()
{
  string out="";
  stringstream outstream;

  /*const FGMatrix33& mTkI =*/ CalculateTankInertias();

  for (unsigned int i=0; i<numTanks; i++)
  {
    FGTank* tank = Tanks[i];
    string tankname="";
    if (tank->GetType() == FGTank::ttFUEL && tank->GetGrainType() != FGTank::gtUNKNOWN) {
      tankname = "Solid Fuel";
    } else if (tank->GetType() == FGTank::ttFUEL) {
      tankname = "Fuel";
    } else if (tank->GetType() == FGTank::ttOXIDIZER) {
      tankname = "Oxidizer";
    } else {
      tankname = "(Unknown tank type)";
    }
    outstream << highint << left << setw(4) << i << setw(30) << tankname << normint
      << right << setw(10) << tank->GetContents() << setw(8) << tank->GetXYZ(eX)
         << setw(8) << tank->GetXYZ(eY) << setw(8) << tank->GetXYZ(eZ)
         << setw(12) << tank->GetIxx() << setw(12) << tank->GetIyy()
         << setw(12) << tank->GetIzz() << endl;
  }
  return outstream.str();
}
Пример #3
0
void FGPropulsion::ConsumeFuel(FGEngine* engine)
{
  if (FuelFreeze) return;
  if (FDMExec->GetTrimStatus()) return;

  unsigned int TanksWithFuel=0, CurrentFuelTankPriority=1;
  unsigned int TanksWithOxidizer=0, CurrentOxidizerTankPriority=1;
  vector <int> FeedListFuel, FeedListOxi;
  bool Starved = true; // Initially set Starved to true. Set to false in code below.
  bool hasOxTanks = false;

  // For this engine,
  // 1) Count how many fuel tanks with the current priority level have fuel
  // 2) If there none, then try next lower priority (higher number) - that is,
  //    increment CurrentPriority.
  // 3) Build the feed list.
  // 4) Do the same for oxidizer tanks, if needed.

  // Process fuel tanks, if any
  while ((TanksWithFuel == 0) && (CurrentFuelTankPriority <= numTanks)) {
    for (unsigned int i=0; i<engine->GetNumSourceTanks(); i++) {
      unsigned int TankId = engine->GetSourceTank(i);
      FGTank* Tank = Tanks[TankId];
      unsigned int TankPriority = Tank->GetPriority();
      if (TankPriority != 0) {
        switch(Tank->GetType()) {
        case FGTank::ttFUEL:
          if ((Tank->GetContents() > 0.0) && Tank->GetSelected() && (TankPriority == CurrentFuelTankPriority)) {
            TanksWithFuel++;
            Starved = false;
            FeedListFuel.push_back(TankId);
          } 
          break;
        case FGTank::ttOXIDIZER:
          // Skip this here (done below)
          break;
        }
      }
    }
    if (TanksWithFuel == 0) CurrentFuelTankPriority++; // No tanks at this priority, try next priority
  }

  bool FuelStarved = Starved;
  Starved = true;

  // Process Oxidizer tanks, if any
  if (engine->GetType() == FGEngine::etRocket) {
    while ((TanksWithOxidizer == 0) && (CurrentOxidizerTankPriority <= numTanks)) {
      for (unsigned int i=0; i<engine->GetNumSourceTanks(); i++) {
        unsigned int TankId = engine->GetSourceTank(i);
        FGTank* Tank = Tanks[TankId];
        unsigned int TankPriority = Tank->GetPriority();
        if (TankPriority != 0) {
          switch(Tank->GetType()) {
          case FGTank::ttFUEL:
            // Skip this here (done above)
            break;
          case FGTank::ttOXIDIZER:
            hasOxTanks = true;
            if (Tank->GetContents() > 0.0 && Tank->GetSelected() && TankPriority == CurrentOxidizerTankPriority) {
              TanksWithOxidizer++;
              if (TanksWithFuel > 0) Starved = false;
              FeedListOxi.push_back(TankId);
            }
            break;
          }
        }
      }
      if (TanksWithOxidizer == 0) CurrentOxidizerTankPriority++; // No tanks at this priority, try next priority
    }
  }

  bool OxiStarved = Starved;

  engine->SetStarved(FuelStarved || (hasOxTanks && OxiStarved)); // Tanks can be refilled, so be sure to reset engine Starved flag here.

  // No fuel or fuel/oxidizer found at any priority!
//  if (Starved) return;
  if (FuelStarved || (hasOxTanks && OxiStarved)) return;

  double FuelToBurn = engine->CalcFuelNeed();            // How much fuel does this engine need?
  double FuelNeededPerTank = FuelToBurn / TanksWithFuel; // Determine fuel needed per tank.  
  for (unsigned int i=0; i<FeedListFuel.size(); i++) {
    Tanks[FeedListFuel[i]]->Drain(FuelNeededPerTank); 
  }

  if (engine->GetType() == FGEngine::etRocket) {
    double OxidizerToBurn = engine->CalcOxidizerNeed();                // How much fuel does this engine need?
    double OxidizerNeededPerTank = 0;
    if (TanksWithOxidizer > 0) OxidizerNeededPerTank = OxidizerToBurn / TanksWithOxidizer; // Determine fuel needed per tank.  
    for (unsigned int i=0; i<FeedListOxi.size(); i++) {
      Tanks[FeedListOxi[i]]->Drain(OxidizerNeededPerTank); 
    }
  }

}