80
91
if (el->FindElement("sloxiflowmax"))
81
92
SLOxiFlowMax = el->FindElementValueAsNumberConvertTo("sloxiflowmax", "LBS/SEC");
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");
103
if (variation_element->FindElement("total_isp")) {
104
TotalIspVariation = variation_element->FindElementValueAsNumber("total_isp");
106
128
double FGRocket::Calculate(void)
108
130
double dT = State->Getdt()*Propulsion->GetRate();
110
133
if (!Flameout && !Starved) ConsumeFuel();
112
135
PropellantFlowRate = (FuelExpended + OxidizerExpended)/dT;
113
136
Throttle = FCS->GetThrottlePos(EngineNumber);
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
140
// burns without regard to throttle setting.
121
142
if (ThrustTable != 0L) { // Thrust table given -> Solid fuel used
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();
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
160
BurnTime += State->Getdt(); // Increment burn time
136
167
if (Throttle < MinThrottle || Starved) { // Combustion not supported
138
PctPower = Thrust = 0.0; // desired thrust
169
PctPower = 0.0; // desired thrust
142
173
} else { // Calculate thrust
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.
145
181
Flameout = false;
146
182
VacThrust = Isp * PropellantFlowRate;
247
289
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
249
string FGRocket::GetEngineLabels(string delimeter)
251
std::ostringstream buf;
253
buf << Name << " Total Impulse (engine " << EngineNumber << " in psf)" << delimeter
254
<< Thruster->GetThrusterLabels(EngineNumber, delimeter);
259
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
261
string FGRocket::GetEngineValues(string delimeter)
263
std::ostringstream buf;
265
buf << It << delimeter << Thruster->GetThrusterValues(EngineNumber, delimeter);
270
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
271
// This funciton should tie properties to rocket engine specific properties
291
string FGRocket::GetEngineLabels(const string& delimiter)
293
std::ostringstream buf;
295
buf << Name << " Total Impulse (engine " << EngineNumber << " in psf)" << delimiter
296
<< Thruster->GetThrusterLabels(EngineNumber, delimiter);
301
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
303
string FGRocket::GetEngineValues(const string& delimiter)
305
std::ostringstream buf;
307
buf << It << delimiter << Thruster->GetThrusterValues(EngineNumber, delimiter);
312
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
313
// This function should tie properties to rocket engine specific properties
272
314
// that are not bound in the base class (FGEngine) code.
274
316
void FGRocket::bindmodel()
276
char property_name[80];
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);
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);
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);
286
339
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%