Replies: 10 comments 8 replies
-
I don't think you can set a beta target with jsbsim/src/initialization/FGTrim.cpp Lines 839 to 846 in dd97e99 |
Beta Was this translation helpful? Give feedback.
-
Correct, custom is an option. Haven't looked into how you specifically setup custom though. But for example you could potentially set up a custom version that is the same as What exactly are your requirements in terms of |
Beta Was this translation helpful? Give feedback.
-
Okay, so you still want |
Beta Was this translation helpful? Give feedback.
-
Actually, double-checking, have you tried jsbsim/src/initialization/FGTrim.cpp Lines 805 to 815 in dd97e99 Bank angle (phi) is used to control |
Beta Was this translation helpful? Give feedback.
-
@aregis74 I tried a quick test using the full trim option and it seems to work in terms of finding trim solutions for steady heading sideslip. I used the 737 model and varied the initial beta from 0 to 5 degrees and then plotted the resulting bank angle, aileron and rudder commands from the trim solutions. import jsbsim
import matplotlib.pyplot as plt
import math
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
# Set alpha range for trim solutions
fdm['aero/alpha-max-rad'] = math.radians(12)
fdm['aero/alpha-min-rad'] = math.radians(-4.0)
betas = []
bankAngle = []
ailerons = []
rudder = []
for beta in range(0, 6, 1):
fdm['ic/h-sl-ft'] = 1000
fdm['ic/vc-kts'] = 200
fdm['ic/gamma-deg'] = 0
fdm['ic/beta-deg'] = beta
fdm.run_ic() # Initialize the aircraft with initial conditions
fdm.run()
# Trim
try:
fdm['simulation/do_simple_trim'] = 1
betas.append(fdm['aero/beta-deg'])
bankAngle.append(fdm['attitude/phi-deg'])
ailerons.append(fdm['fcs/aileron-cmd-norm'])
rudder.append(fdm['fcs/rudder-cmd-norm'])
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
fig, ax1 = plt.subplots()
ax1.set_xlabel('Beta (deg)')
ax1.set_ylabel('Bank Angle (deg)')
ax1.set_ylim(0, 9)
ax1.plot(betas, bankAngle, label='Bank Angle', color='red')
ax2 = ax1.twinx()
ax2.set_ylabel('Inceptor Position')
ax2.set_ylim(0, 1)
ax2.plot(betas, ailerons, label='Aileron')
ax2.plot(betas, rudder, label='Rudder')
ax1.legend(loc=0)
ax2.legend(loc=2)
plt.title('Steady Heading Sideslip')
plt.show() |
Beta Was this translation helpful? Give feedback.
-
Okay, although your initial request was a bit misleading then, since you specifically mentioned setting a beta target. However you could simply extend my beta loop to continue in small beta increments until the trim solution returned a solution with the rudder at maximum deflection, noting the aileron deflection and assuming that the rudder deflection reaches maximum deflection before the aileron deflection does, the beta to achieve this and the roll angle to achieve this. |
Beta Was this translation helpful? Give feedback.
-
So for the 737 example we end up with the aileron deflection hitting a maximum before the rudder deflection does. At ~13.5 deg for beta we have aileron deflection at 1 and rudder deflection at 0.92, with a bank angle of ~22.5 deg. |
Beta Was this translation helpful? Give feedback.
-
Ah, I concentrated/fixated on the comments regarding trim and setting beta. If I'd seen the diagram you just posted and/or this description of rudder kick I would've suggested something different.
So if you're trying to automate the rudder kick then I'd suggest the following. Implement a PID controller using the ailerons to keep either the heading rate = 0 or Vdot = 0. Use the full trim option to trim the aircraft for straight and level flight at the specific altitude and airspeed you want to use. The PID gains need to be optimised for this altitude and airspeed. Then use an event to perform a ramp input for the rudder to full deflection. If the PID controller is well tuned then it should keep the aircraft on a steady heading as the rudder input kicks in. Lastly setup output directives to log the relevant parameters you want a time history of. If you don't want to take on the task of tuning a PID controller I guess you could potentially try the following in terms of generating a similar ramp input for the ailerons, and see whether it does a good enough job. What I mean in terms of similar is that if you look at the slopes of the aileron and rudder inputs from my last graph, you could come up with a ramp for the aileron that ramps up slightly faster than the rudder ramp, i.e. so that it is always slightly larger than the rudder input, with a maximum value of say 1 versus a maximum value of 0.92 for the rudder input. |
Beta Was this translation helpful? Give feedback.
-
Just tried my suggestion out and these are the results I get for the 737 model. Using the following code. import jsbsim
import matplotlib.pyplot as plt
import math
import numpy as np
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
# Set alpha range for trim solutions
fdm['aero/alpha-max-rad'] = math.radians(12)
fdm['aero/alpha-min-rad'] = math.radians(-4.0)
dt = 1/120
aileronMax = 1
rudderMax = 0.92
risetime = 1
diAileron = aileronMax / (risetime/dt)
diRudder = rudderMax / (risetime/dt)
times = []
betas = []
bankAngle = []
ailerons = []
rudder = []
fdm['ic/h-sl-ft'] = 1000
fdm['ic/vc-kts'] = 200
fdm['ic/gamma-deg'] = 0
fdm['ic/beta-deg'] = 0
fdm.run_ic() # Initialize the aircraft with initial conditions
fdm.run()
# Trim
try:
fdm['simulation/do_simple_trim'] = 1
for i in range(int(10/dt)):
fdm.run()
times.append(fdm.get_sim_time())
betas.append(fdm['aero/beta-deg'])
bankAngle.append(fdm['attitude/phi-deg'])
ailerons.append(fdm['fcs/aileron-cmd-norm'])
rudder.append(fdm['fcs/rudder-cmd-norm'])
aileronCmd = fdm['fcs/aileron-cmd-norm']
rudderCmd = fdm['fcs/rudder-cmd-norm']
if aileronCmd < aileronMax:
aileronCmd += diAileron
fdm['fcs/aileron-cmd-norm'] = aileronCmd
if rudderCmd < rudderMax:
rudderCmd += diRudder
fdm['fcs/rudder-cmd-norm'] = rudderCmd
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
fig, ax1 = plt.subplots()
ax1.set_xlabel('Time (s)')
ax1.set_ylabel('Beta (deg)')
line1 = ax1.plot(times, betas, label='Beta', color='red')
ax2 = ax1.twinx()
ax2.set_ylabel('Inceptor Position')
line2 = ax2.plot(times, ailerons, label='Aileron')
line3 = ax2.plot(times, rudder, label='Rudder')
ax1.legend(handles=line1+line2+line3, loc=4)
plt.title('Rudder Kick')
plt.show() |
Beta Was this translation helpful? Give feedback.
-
Example of changing the rise time, from 1s to 3s for maximum inceptor deflections and showing the time history for 20s. |
Beta Was this translation helpful? Give feedback.
-
Hello guys! I trying to do a rudder kick maneuver, but I didn't find how to stabilize the aircraft with an sideslip angle, somebody has a clue to execute the script?
I tried to apply do.trim(5) in turn with ic/beta-deg as target, but I didn't succeed.
thank you for someone help!
Beta Was this translation helpful? Give feedback.
All reactions