~ubuntu-branches/ubuntu/precise/flightgear/precise

« back to all changes in this revision

Viewing changes to src/FDM/JSBSim/models/propulsion/FGRocket.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Ove Kaaven
  • Date: 2011-01-30 15:46:35 UTC
  • mfrom: (3.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20110130154635-rlynmg9n5hzxq5xe
Tags: 2.0.0-3
* Recommend fgfs-aircraft-base and fgfs-models-base.
  Closes. #610276.
* Added note about scenery SharedModels.tgz to README.Debian.

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 Date started: 09/12/2000
6
6
 Purpose:      This module models a rocket engine
7
7
 
8
 
 ------------- Copyright (C) 2000  Jon S. Berndt (jsb@hal-pc.org) --------------
 
8
 ------------- Copyright (C) 2000  Jon S. Berndt (jon@jsbsim.org) --------------
9
9
 
10
10
 This program is free software; you can redistribute it and/or modify it under
11
11
 the terms of the GNU Lesser General Public License as published by the Free Software
38
38
INCLUDES
39
39
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
40
40
 
 
41
#include <iostream>
41
42
#include <sstream>
42
 
 
43
43
#include "FGRocket.h"
 
44
#include "FGState.h"
 
45
#include "models/FGPropulsion.h"
 
46
#include "FGThruster.h"
 
47
#include "FGTank.h"
 
48
 
 
49
using namespace std;
44
50
 
45
51
namespace JSBSim {
46
52
 
63
69
  FuelFlowRate = 0.0;
64
70
  OxidizerFlowRate = 0.0;
65
71
  SLOxiFlowMax = 0.0;
 
72
  BuildupTime = 0.0;
66
73
  It = 0.0;
 
74
  ThrustVariation = 0.0;
 
75
  TotalIspVariation = 0.0;
67
76
 
68
77
  // Defaults
69
78
   MinThrottle = 0.0;
71
80
 
72
81
  if (el->FindElement("isp"))
73
82
    Isp = el->FindElementValueAsNumber("isp");
 
83
  if (el->FindElement("builduptime"))
 
84
    BuildupTime = el->FindElementValueAsNumber("builduptime");
74
85
  if (el->FindElement("maxthrottle"))
75
86
    MaxThrottle = el->FindElementValueAsNumber("maxthrottle");
76
87
  if (el->FindElement("minthrottle"))
80
91
  if (el->FindElement("sloxiflowmax"))
81
92
    SLOxiFlowMax = el->FindElementValueAsNumberConvertTo("sloxiflowmax", "LBS/SEC");
82
93
 
 
94
  // If there is a thrust table element, this is a solid propellant engine.
83
95
  thrust_table_element = el->FindElement("thrust_table");
84
96
  if (thrust_table_element) {
85
97
    ThrustTable = new FGTable(PropertyManager, thrust_table_element);
 
98
    Element* variation_element = el->FindElement("variation");
 
99
    if (variation_element) {
 
100
      if (variation_element->FindElement("thrust")) {
 
101
        ThrustVariation = variation_element->FindElementValueAsNumber("thrust");
 
102
      }
 
103
      if (variation_element->FindElement("total_isp")) {
 
104
        TotalIspVariation = variation_element->FindElementValueAsNumber("total_isp");
 
105
      }
 
106
    }
86
107
  }
87
108
 
88
109
  bindmodel();
98
119
 
99
120
FGRocket::~FGRocket(void)
100
121
{
 
122
  delete ThrustTable;
101
123
  Debug(1);
102
124
}
103
125
 
106
128
double FGRocket::Calculate(void)
107
129
{
108
130
  double dT = State->Getdt()*Propulsion->GetRate();
 
131
  double thrust;
109
132
 
110
133
  if (!Flameout && !Starved) ConsumeFuel();
111
134
 
112
135
  PropellantFlowRate = (FuelExpended + OxidizerExpended)/dT;
113
136
  Throttle = FCS->GetThrottlePos(EngineNumber);
114
137
 
115
 
  // If there is a thrust table, it is a function of propellant remaining. The
 
138
  // If there is a thrust table, it is a function of propellant burned. The
116
139
  // engine is started when the throttle is advanced to 1.0. After that, it
117
 
  // burns without regard to throttle setting. The table returns a value between
118
 
  // zero and one, representing the percentage of maximum vacuum thrust being
119
 
  // applied.
 
140
  // burns without regard to throttle setting.
120
141
 
121
142
  if (ThrustTable != 0L) { // Thrust table given -> Solid fuel used
122
143
 
123
144
    if ((Throttle == 1 || BurnTime > 0.0 ) && !Starved) {
124
 
      BurnTime += State->Getdt();
125
 
      double TotalEngineFuelAvailable=0.0;
126
 
      for (int i=0; i<(int)SourceTanks.size(); i++)
127
 
        TotalEngineFuelAvailable += Propulsion->GetTank(SourceTanks[i])->GetContents();
 
145
      double TotalEngineFuelBurned=0.0;
 
146
      for (int i=0; i<(int)SourceTanks.size(); i++) {
 
147
        FGTank* tank = Propulsion->GetTank(i);
 
148
        if (SourceTanks[i] == 1) {
 
149
          TotalEngineFuelBurned += tank->GetCapacity() - tank->GetContents();
 
150
        }
 
151
      }
128
152
 
129
 
      VacThrust = ThrustTable->GetValue(TotalEngineFuelAvailable);
 
153
      VacThrust = ThrustTable->GetValue(TotalEngineFuelBurned)
 
154
                * (ThrustVariation + 1)
 
155
                * (TotalIspVariation + 1);
 
156
      if (BurnTime <= BuildupTime && BuildupTime > 0.0) {
 
157
        VacThrust *= sin((BurnTime/BuildupTime)*M_PI/2.0);
 
158
        // VacThrust *= (1-cos((BurnTime/BuildupTime)*M_PI))/2.0; // 1 - cos approach
 
159
      }
 
160
      BurnTime += State->Getdt(); // Increment burn time
130
161
    } else {
131
162
      VacThrust = 0.0;
132
163
    }
135
166
 
136
167
    if (Throttle < MinThrottle || Starved) { // Combustion not supported
137
168
 
138
 
      PctPower = Thrust = 0.0; // desired thrust
 
169
      PctPower = 0.0; // desired thrust
139
170
      Flameout = true;
140
171
      VacThrust = 0.0;
141
172
 
142
173
    } else { // Calculate thrust
143
174
 
144
 
      PctPower = Throttle / MaxThrottle; // Min and MaxThrottle range from 0.0 to 1.0, normally.
 
175
      // This is nonsensical. Max throttle should be assumed to be 1.0. One might
 
176
      // conceivably have a throttle setting > 1.0 for some rocket engines. But, 1.0
 
177
      // should always be the default.
 
178
      // PctPower = Throttle / MaxThrottle; // Min and MaxThrottle range from 0.0 to 1.0, normally.
 
179
      
 
180
      PctPower = Throttle;
145
181
      Flameout = false;
146
182
      VacThrust = Isp * PropellantFlowRate;
147
183
 
149
185
 
150
186
  } // End thrust calculations
151
187
 
152
 
  Thrust = Thruster->Calculate(VacThrust);
153
 
  It += Thrust * dT;
 
188
  thrust = Thruster->Calculate(VacThrust);
 
189
  It += thrust * dT;
154
190
 
155
 
  return Thrust;
 
191
  return thrust;
156
192
}
157
193
 
158
194
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
219
255
}
220
256
 
221
257
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
258
// 
 
259
// The FuelFlowRate can be affected by the TotalIspVariation value (settable
 
260
// in a config file or via properties). The TotalIspVariation parameter affects
 
261
// thrust, but the thrust determines fuel flow rate, so it must be adjusted
 
262
// for Total Isp Variation.
222
263
 
223
264
double FGRocket::CalcFuelNeed(void)
224
265
{
226
267
 
227
268
  if (ThrustTable != 0L) {          // Thrust table given - infers solid fuel
228
269
    FuelFlowRate = VacThrust/Isp;   // This calculates wdot (weight flow rate in lbs/sec)
 
270
    FuelFlowRate /= (1 + TotalIspVariation);
229
271
  } else {
230
272
    FuelFlowRate = SLFuelFlowMax*PctPower;
231
273
  }
246
288
 
247
289
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
248
290
 
249
 
string FGRocket::GetEngineLabels(string delimeter)
250
 
{
251
 
  std::ostringstream buf;
252
 
 
253
 
  buf << Name << " Total Impulse (engine " << EngineNumber << " in psf)" << delimeter
254
 
      << Thruster->GetThrusterLabels(EngineNumber, delimeter);
255
 
 
256
 
  return buf.str();
257
 
}
258
 
 
259
 
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
260
 
 
261
 
string FGRocket::GetEngineValues(string delimeter)
262
 
{
263
 
  std::ostringstream buf;
264
 
 
265
 
  buf << It << delimeter << Thruster->GetThrusterValues(EngineNumber, delimeter);
266
 
 
267
 
  return buf.str();
268
 
}
269
 
 
270
 
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
271
 
// This funciton should tie properties to rocket engine specific properties
 
291
string FGRocket::GetEngineLabels(const string& delimiter)
 
292
{
 
293
  std::ostringstream buf;
 
294
 
 
295
  buf << Name << " Total Impulse (engine " << EngineNumber << " in psf)" << delimiter
 
296
      << Thruster->GetThrusterLabels(EngineNumber, delimiter);
 
297
 
 
298
  return buf.str();
 
299
}
 
300
 
 
301
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
302
 
 
303
string FGRocket::GetEngineValues(const string& delimiter)
 
304
{
 
305
  std::ostringstream buf;
 
306
 
 
307
  buf << It << delimiter << Thruster->GetThrusterValues(EngineNumber, delimiter);
 
308
 
 
309
  return buf.str();
 
310
}
 
311
 
 
312
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
313
// This function should tie properties to rocket engine specific properties
272
314
// that are not bound in the base class (FGEngine) code.
273
315
//
274
316
void FGRocket::bindmodel()
275
317
{
276
 
  char property_name[80];
277
 
 
278
 
  snprintf(property_name, 80, "propulsion/engine[%u]/total-impulse", EngineNumber);
279
 
  PropertyManager->Tie( property_name, this, &FGRocket::GetTotalImpulse);
280
 
  snprintf(property_name, 80, "propulsion/engine[%u]/oxi-flow-rate-pps", EngineNumber);
281
 
  PropertyManager->Tie( property_name, this, &FGRocket::GetOxiFlowRate);
282
 
  snprintf(property_name, 80, "propulsion/engine[%u]/vacuum-thrust_lbs", EngineNumber);
283
 
  PropertyManager->Tie( property_name, this, &FGRocket::GetVacThrust);
 
318
  string property_name, base_property_name;
 
319
  base_property_name = CreateIndexedPropertyName("propulsion/engine", EngineNumber);
 
320
 
 
321
  property_name = base_property_name + "/total-impulse";
 
322
  PropertyManager->Tie( property_name.c_str(), this, &FGRocket::GetTotalImpulse);
 
323
  property_name = base_property_name + "/vacuum-thrust_lbs";
 
324
  PropertyManager->Tie( property_name.c_str(), this, &FGRocket::GetVacThrust);
 
325
 
 
326
  if (ThrustTable) { // Solid rocket motor
 
327
    property_name = base_property_name + "/thrust-variation_pct";
 
328
    PropertyManager->Tie( property_name.c_str(), this, &FGRocket::GetThrustVariation,
 
329
                                                       &FGRocket::SetThrustVariation);
 
330
    property_name = base_property_name + "/total-isp-variation_pct";
 
331
    PropertyManager->Tie( property_name.c_str(), this, &FGRocket::GetTotalIspVariation,
 
332
                                                       &FGRocket::SetTotalIspVariation);
 
333
  } else { // Liquid rocket motor
 
334
    property_name = base_property_name + "/oxi-flow-rate-pps";
 
335
    PropertyManager->Tie( property_name.c_str(), this, &FGRocket::GetOxiFlowRate);
 
336
  }
284
337
}
285
338
 
286
339
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%