Replies: 35 comments 59 replies
-
So if you just need a first order calculation and you ignore the CG and lift due to the tailplane elevator combination then all you need is the Cl vs alpha data for the aircraft, e.g. from the JSBSim 737 model. Lines 658 to 676 in d8f9496 With that simply set the lift formula equal to the weight and iterate over the range of alpha and for each alpha solve for the speed. Use the alpha, speed points to plot your graph. So nothing specific in terms of JSBSim. If you do want to take into account varying CG and the varying tailplane elevator combination to the overall lift then one option is to use JSBSim's trim functionality. So for example choose a weight and CG combination and then use JSBSim to iterate over a bunch of trim solutions covering the speed range. For each trim solution record the alpha and now you have a set of speed, alpha points for the weight and CG combination. |
Beta Was this translation helpful? Give feedback.
-
My point was this doesn't require JSBSim. The idea being you do it by hand on a piece of paper or in Excel, or as a basic python script, whatever you're comfortable with. You can repeat it for multiple weights. It just doesn't capture CG changes and the lift from the tail plane and elevator combination. Would be interesting to see how much of a difference there is when you take the CG and the tail plane elevator lift combination into account. In terms of my suggestion of using JSBSim's trim function you can take a look at some of these test cases as a starting point. https://github.com/JSBSim-Team/jsbsim/blob/master/tests/CheckTrim.py |
Beta Was this translation helpful? Give feedback.
-
Yes you can vary the weight and CG via the aircraft's xml file. In terms of different configurations for take-off, climb, cruise, descent, landing etc. that's really just a matter of setting the flap and gear configuration which you can do via your script or in python to set the gear position and flap position for the different configurations you want to test/analyse. |
Beta Was this translation helpful? Give feedback.
-
How do I set Lift equals to weight?
And the landing gear?
|
Beta Was this translation helpful? Give feedback.
-
@gasilva I knocked up a basic python script, see below to generate an AoA vs Speed curve using JSBSim. Note the fairly high minimum airspeed, that's because this was for the clean configuration, i.e. no flaps. Also for the default weight and cg as per the standard 737 model in JSBSim. You could obviously vary those independently and compare the graph you get. import jsbsim
import matplotlib.pyplot as plt
fdm = jsbsim.FGFDMExec('.') # The path supplied to FGFDMExec is the location of the folders "aircraft", "engines" and "systems"
fdm.load_model('737') # Load the aircraft 737
# Set engines running
fdm['propulsion/engine[0]/set-running'] = 1
fdm['propulsion/engine[1]/set-running'] = 1
results = []
for speed in range(120, 460, 10):
fdm['ic/h-sl-ft'] = 250
fdm['ic/vc-kts'] = speed
fdm['ic/gamma-deg'] = 0
fdm.run_ic() # Initialize the aircraft with initial conditions
fdm.run()
# Trim
try:
fdm['simulation/do_simple_trim'] = 1
results.append((fdm['velocities/vc-kts'], fdm['aero/alpha-deg']))
except RuntimeError as e:
# The trim cannot succeed. Just make sure that the raised exception
# is due to the trim failure otherwise rethrow.
if e.args[0] != 'Trim Failed':
raise
for result in results:
print(result[0], result[1])
speed, alpha = zip(*results)
plt.plot(speed, alpha)
plt.xlabel('IAS (kt)')
plt.ylabel('AoA (deg)')
plt.title('AoA vs IAS')
plt.show() |
Beta Was this translation helpful? Give feedback.
-
@bcoconni you should recognize some of the python code I grabbed from some of your python tests 😉 Although I wasn't surprised by the fairly high speeds given the clean no flaps config I was a bit surprised that there were no trim solutions below 200KIAS at ~7.5 degrees alpha. I was expecting a trim solution up until alpha-cl-max which is a lot higher than 7.5 degrees. Turns out that the trim code looks up an alpha range to use during it's trim calculations. If not set in the aircraft config then there are some default values. case tAlpha:
control_min=fdmex->GetAerodynamics()->GetAlphaCLMin();
control_max=fdmex->GetAerodynamics()->GetAlphaCLMax(); So I set min and max values in my python code. # Set alpha range for trim solutions
fdm['aero/alpha-max-rad'] = math.radians(12)
fdm['aero/alpha-min-rad'] = math.radians(-4.0) Which now shows trim solutions down to 160KIAS 11.5 degrees alpha. |
Beta Was this translation helpful? Give feedback.
-
@gasilva there was mention of trim drag early on in this thread. So I've plotted the trim drag simply by recording results.append((fdm['velocities/vc-kts'], fdm['aero/alpha-deg'], fdm['aero/coefficient/CDde'])) Don't be confused by the term <function name="aero/coefficient/CDde">
<description>Drag_due_to_Elevator_Deflection</description>
<product>
<property>aero/qbar-psf</property>
<property>metrics/Sw-sqft</property>
<property>fcs/mag-elevator-pos-rad</property>
<value>0.059</value>
</product>
</function> |
Beta Was this translation helpful? Give feedback.
-
In terms of generating the complete envelope you showed. I'm trying to understand some of the logic behind the limits in order to write a script that could generate one. So I've marked up your example envelope with guesses for some of the limits. Can you confirm whether my guesses are correct? There are a couple with '?' that I'm less sure about. Can you explain those limits as well? |
Beta Was this translation helpful? Give feedback.
-
Hi,
Yes, changing the xml is not the way to do. It can cause problems of
aircraft configuration. I was thinking to copy the file in the
beginning and copy again at the end to preserve it.
Your solution is much better and elegant. That is the way to do it.
Another question: what is the property to change in order to change CG?
Where can I find a list of properties? I tried to search for it but I
couldn't find it.
Regards,
Guilherme A. Lima da Silva
|
Beta Was this translation helpful? Give feedback.
-
Hi,
I implemented the python script to get AoA vs. KCAS by varying weight, CG
and altitude.
See in the post above the result. It is exactly what I am looking for.
If you would like to receive a PR, I will do it. Just let me know where to
place it.
Thank you very much.
Regards,
Guilherme A. Lima da Silva, Dr.
|
Beta Was this translation helpful? Give feedback.
-
How can I find the CG in terms of MAC? Is there any place where it defined the x coordinate of wing root? Or conversion of inches into MAC? |
Beta Was this translation helpful? Give feedback.
-
@gasilva @bcoconni for fun I took my original code and expanded the AoA envelope to encompass negative AoA and inverted flight. Also to double-check if the JSBSim trim routines would handle the inverted case. |
Beta Was this translation helpful? Give feedback.
-
@seanmcleod yes the code below confirms that the optimum consumption is related to Mach number as you said before. Thank you for you note about the subject. The L/D max angle is 5.08 degrees according to calculations of FAA TC 18/7. But the 11.5 degrees result is close to alpha minimum power required, which is 14.8 degrees. By the way the 11.5 degrees is the highest possible angle since it is a leveled flight with no flaps at maximum weight and 30 kft. # Originally developed by JSBSim Team
# Modified by Guilherme A. L. da Silva - aerothermalsolutions.co
# Calculation required by aircraft icing enginering - fuel consumption
import jsbsim
import matplotlib.pyplot as plt
import matplotlib.style as style
style.use('fivethirtyeight')
results=[]
i=0
tank=[]
for j in range(10):
fdm = jsbsim.FGFDMExec('../../')
fdm.load_model('global5000')
# Set engines running
fdm['propulsion/engine[0]/set-running'] = 1
fdm['propulsion/engine[1]/set-running'] = 1
fdm['ic/h-sl-ft'] = 30000
fdm['ic/gamma-deg'] = 0
fdm['ap/alpha_hold']= 0
fdm['ap/altitude_hold']= 0
fdm['ic/vc-kts']=155+6*float(j)
tank0i=fdm["propulsion/tank[0]/contents-lbs"]
tank1i=fdm["propulsion/tank[1]/contents-lbs"]
tank2i=fdm["propulsion/tank[2]/contents-lbs"]
fdm.run_ic() # Initialize the aircraft with initial conditions
fdm.run()
# Trim
try:
fdm['simulation/do_simple_trim'] = 1
except RuntimeError as e:
if e.args[0] != 'Trim Failed':
raise
while fdm.run() and fdm.get_sim_time() <= 1000:
if fdm.get_sim_time()<1:
fdm['ap/alpha_hold']= 0
fdm['ap/altitude_setpoint']= 30000
fdm['ap/altitude_hold']= 1
fdm.run()
results.append((fdm['simulation/sim-time-sec'],fdm['velocities/vc-kts'], fdm['aero/alpha-deg'],fdm["propulsion/tank[0]/contents-lbs"],fdm["propulsion/tank[1]/contents-lbs"],fdm["propulsion/tank[2]/contents-lbs"]))
tank0f=fdm["propulsion/tank[0]/contents-lbs"]
tank1f=fdm["propulsion/tank[1]/contents-lbs"]
tank2f=fdm["propulsion/tank[2]/contents-lbs"]
deltaTank0=tank0i-tank0f
deltaTank1=tank1i-tank1f
deltaTank2=tank2i-tank2f
deltaTotal=deltaTank0+deltaTank2+deltaTank1
print("--------------------------------------")
print("Fuel Consumed = {}".format(deltaTotal))
print("Average Rate Fuel Consumed per hour = {}".format(deltaTotal/(1600/3600)))
print("--------------------------------------")
tank.append((fdm['velocities/mach'],fdm['aero/alpha-deg'],fdm['ic/h-sl-ft'],deltaTotal))
time, speed, alpha, tank0, tank1, tank2 = zip(*results)
machPlot,alpha,altitude,deltaPlot = zip(*tank)
#prepare subplots to overlay plots
fig, ax = plt.subplots(figsize=(9,7))
plt.plot(machPlot[:], deltaPlot[:],'-',label="Fuel")
plt.legend(frameon=False)
plt.xlabel('Mach')
plt.ylabel('Delta Fuel [lb]')
plt.title('Fuel Consumption per Mach')
plt.tight_layout()
plt.show()
#prepare subplots to overlay plots
fig, ax = plt.subplots(figsize=(9,7))
plt.plot(machPlot[:], alpha[:],'-',label="AoA")
plt.ylabel('aplha [degrees]')
plt.title('Alpha per Mach')
plt.tight_layout()
plt.show()
#prepare subplots to overlay plots
fig, ax = plt.subplots(figsize=(9,7))
plt.plot(machPlot[:], altitude[:],'-',label="altitude")
plt.ylabel('Altitude [ft]')
plt.title('Altitude per Mach')
plt.tight_layout()
plt.show()
print(tank) |
Beta Was this translation helpful? Give feedback.
-
@gasilva how about plotting fuel consumption per nm on the y-axis with Mach on the x-axis to confirm there is a minimum for some particular Mach number. And then do that for different altitudes to see if you get an optimal Mach climb schedule similar to the graph I found earlier. |
Beta Was this translation helpful? Give feedback.
-
PropertyManager->Tie("position/distance-from-start-mag-mt", this, &FGAuxiliary::GetDistanceRelativePosition); |
Beta Was this translation helpful? Give feedback.
-
I'm still suspicious of the high throttle values for the 737, but here is the resulting fuel burn per nm. With a clear minimum round Mach 0.79. This is for the default weight and at 30,000ft. mach = fdm['velocities/mach']
fuelflow = fdm['propulsion/engine[0]/fuel-flow-rate-pps'] * 2
time = 589.1641 / 3600 # time in s to cover 1nm at Mach 1 at 30,000ft
fuelburn = (time / mach) * fuelflow |
Beta Was this translation helpful? Give feedback.
-
And for the 737 at 20,000ft. |
Beta Was this translation helpful? Give feedback.
-
Your results are one order higher and the minimum is located at high speed
like a Carson Cruise.
See my new results after a correction.
Now it is similar than yours bur the consumption is still high.
what is the conversion factor that you are using to nm?
|
Beta Was this translation helpful? Give feedback.
-
Yep, messed up the conversion from lb/s fuel flow to lb/nm. Corrected graphs, same shape and minimum, but different values for lb/nm. At 30,000ft. At 20,000ft |
Beta Was this translation helpful? Give feedback.
-
So, came across this snippet for the A320 in terms of engine performance, max cruise thrust limits. And plotting n1 % for the JSBSim 737 model I get for 30,000ft. Guess there could be an issue with the engine model being used by the 737, or maybe the 737 model has excessive drag? |
Beta Was this translation helpful? Give feedback.
-
Can you post your before and after changes to the drag entries? |
Beta Was this translation helpful? Give feedback.
-
In terms of the kink at Mach 0.79 for most of the 737 graphs, it looks like it's triggered by the increase in drag due to mach that only starts kicking in from Mach 0.79. Bit suspicious that the value for 0.79 is 0. <function name="aero/coefficient/CDmach">
<description>Drag_due_to_mach</description>
<product>
<property>aero/qbar-psf</property>
<property>metrics/Sw-sqft</property>
<table>
<independentVar>velocities/mach</independentVar>
<tableData>
0.00 0.0000
0.79 0.0000
1.10 0.0230
1.80 0.0150
</tableData>
</table>
</product>
</function> |
Beta Was this translation helpful? Give feedback.
-
Yep, I guess I was expecting it to be more of a gradual increase from a lower Mach number, as opposed to 0 and then a sudden kink at 0.79. However looking up some examples the shape doesn't seem to be that far off. |
Beta Was this translation helpful? Give feedback.
-
I am trying to implement a autopilot to keep mach number during a long flight. However, it is not working. To keep alpha is OK. @seanmcleod told me that the correct to save fuel is to keep mach instead of alpha.
|
Beta Was this translation helpful? Give feedback.
-
You've got a logic error in your clipto for calculating the mach error, it needs to go from -0.5 5o +0.5. |
Beta Was this translation helpful? Give feedback.
-
Log |
Beta Was this translation helpful? Give feedback.
-
So the set point is smaller than the current Mach but pos-norm has been increased relative to cmd-norm, another sign issue? |
Beta Was this translation helpful? Give feedback.
-
But why do you think\expect <summer name="fcs/throttle-cmd-norm[0]">
<input> fcs/throttle-cmd-norm[0] </input>
<input> -ap/throttle-cmd </input>
<clipto>
<min> 0.5 </min>
<max> 1.0 </max>
</clipto>
</summer> |
Beta Was this translation helpful? Give feedback.
-
What does the response look like after you apply a step input to the Mach setpoint, e.g. if you increase the Mach setpoint to say Mach 0.5 at time 2500s? |
Beta Was this translation helpful? Give feedback.
-
Does imply that the PID gains ideally need to be tuned. Can you zoom in by graphing say just 5s before the step input until say 5s after it stabilizes at Mach 0.5 to getter idea of the oscillations in-between? |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
How can I generate a curve KCAS versus angle of attack by considering weight and CG position?
Does JSBSim solve it?
The curve for one weight and one CG should be:
https://www.boeing.com/commercial/aeromagazine/aero_12/images/attack_aoaanderrors.jpg
Beta Was this translation helpful? Give feedback.
All reactions