Well in that case let me explain anything and everything about flight dynamics to you in a way you won’t understand!
A dynamic configuration is the exact state the aircraft is in at that moment in time; its airspeed, pitch angle, bank angle, yaw, angle of attack, angle of sideslip, pitch rate, aoa rate etc. all these factors combined determine the aircrafts forces and moments, some of those factors are negligible, others aren’t. The most important and prominent one is the angle of attack or AoA, also denoted as α.
The angle of attack of an airfoil is the angle between its chord line and the airflow relative to it:
This is THE primary component of lift, as the angle increases, lift increases, if the angle of attack reaches a critical angle, the airflow will separate and the wing will stop producing lift.
Here’s an example graph of the F-16:
As you can see, at a little over 35 degrees AoA the lift coefficient starts going down again, this is what a stall looks like. Basically all Cl vs α curves look like this, it goes up almost linearly and then drops off. And here’s where stability derivatives lie in. If you sample 2 coefficients at 2 angles of attack, you can get a slope/
derivative, a derivative is the rate of change of a thing in regards of another thing, velocity for example is the rate of change in position. A stability derivative can be calculated like this:
change in force (or coef) / change in dynamic configuration
Here’s an example on a lift coefficient curve:
Here the resulting stability derivative is 0.13 units of lift coefficient per degree of angle of attack, if you multiply any number by this number, you will get the coefficient of lift at that angle of attack, assuming the AoA is in degrees. This linearization generally works for smaller things that actually are linear, as you can see the Clα curve is not linear, it curves downwards eventually, so the stability derivative method will work for the main lift, up until the critical angle, at which point it will just keep increasing and therefore not model stalls, you can come up with a quadratic equation that closely matches the actual numbers, or you can just use a look-up table, which is what Microsoft Flight Simulator does, they also use stability derivatives for less significant factors that
can be linearized, unlike the Clα curve.
A stability derivative also doesn’t take into account any offset that may be present at α = 0, cambered airfoils for example generate lift at 0 angle of attack, but there’s a simple solution: just add the difference after calculating the coefficient.
Look-up tables
A look-up table is exactly what is sounds like, it’s a table full of numbers which specify how much lift a given angle of attack gives.
Here’s an example of how a lookup table might look:
Here the left column is the angles of attack and the right column are the coefficients of lift. According to this table at 15 degrees of AoA the lift coefficient is 1.6.
You’re probably asking yourself now “but what if the plane is at an AoA that has no table entry? Like 4.5 for example? what if it’s some ridiculously specific number like 4.543534765474234234534534?? You can’t have infinite precision, it’s just not possible, so how do account for that?”
Simple, get the closest number below 4.5 and the closest number above 4.5 and interpolate the two coefficients at those angles. Now you can get the coefficient of lift at any angle of attack as long as the input aoa is within the minimum and maximum specified range. Here’s what the graphed out table looks like:
And this is also what the entire 360° spectrum of lift vs aoa looks like for the NACA 2412 airfoil, generally you won’t find this information anywhere as no one cares about numbers below -5 and above 15 degrees, but if you plane is tumbling or something where the aoa keeps changing rapidly and goes in all sorts of different areas, you need to get some number for your calculations to avoid errors or unwanted behavior.
So, Either make up numbers or try to find them on the internet, there’s a site called
airfoiltools.com where you can get aerodynamic data of various NACA airfoils. Apply this method for the other forces/moments, drag, side force, pitch, yaw, roll and you got your coefficients!
Now we can finally move on to getting the forces and moments, and making the plane actually move.
There’s 5 total forces acting upon an aircraft. No, not 4. 5.
Lift, Drag, Weight, Thrust and the Side force. The side force is basically lateral lift created by the fuselage and the tail of the plane if it flies with a yaw angle, which is not negligible. We won’t talk about weight and thrust because I don’t know how to model engines and weight is already done by Roblox. Just add a forward force * a throttle setting or something.
Drag acts in the direction opposite the airflow:
dir_drag = -aircraft.Velocity.Unit
That’s it.
Lift and side forces act perpendicular to the direction of the airflow.
A common misconception is that lift acts upward of the actual airfoil/aircraft, THIS IS NOT TRUE, THAT IS THE NORMAL FORCE! You can use either lift & drag, or normal & axial forces, you don’t need both. if you know one pair of forces, you can figure out the other.
So now we need the angle of attack (again), to get the direction of lift:
Assuming -Z is the forward direction, you can calculate the angle of attack as such:
AoA = atan2(-v.Y, -v.Z)
and while we’re at it, sideslip:
AoS = asin(v.X / v.Magnitude)
Note the v is the velocity in the local body frame of reference, which can be calculated as:
aircraft.CFrame:VectorToObjectSpace(aircraft.Velocity)
(i think you may have to normalize it so put a .Unit at the end just in case, idk tho)
Now you can rotate the body frame into what’s called the wind axis:
windex = aircraft.CFrame * CFrame.Angles(-AoA, 0, 0) * CFrame.Angles(0, -AoS, 0)
(idk why theres so many minus signs, im just copy pasting my code which works)
Using this CFrame you can— no. no you don’t use that CFrame to set the plane’s position no. This CFrame will act as the wind frame of reference, if you remove the sideslip term you’ll get the stability frame (which is stupidest reference frame seriously who uses this)
Now you can get the lift and side direction:
dir_lift = windex.UpVector
dir_side = windex.RightVector
dir_drag = -windex.LookVector
- or just the negative velocity unit, both works
Ok now let’s start with calculating the lift force.
We will use a very simple model with only one parameter for lift:
Cl_α
- Cl vs angle of attack
First you get the lift coefficient from the angle of attack, whether it be from a lookup table, quadratic function or a stability derivative.
Then you get the density of the air at the aircrafts position, which varies with altitude, you can use either the international standard atmosphere table or just google the equation for air density vs altitude it’s a really simple equation.
The air density unit will be in slugs/ft^3 and the velocity in feet/sec and with it you calculate the dynamic pressure:
Q = air_density * .5 * aircraft_velocity.Magnitude^2
The reference area S
can be any number you want, in square feet
And here’s your final lift force:
F_lift = Cl_a(AoA) * Q * S
(forces are in pounds)
Now on to drag:
Drag is both created by the air pushing against the plane, called parasitic drag and the compressibility of the air as the plane approaches the sound barrier, called wave drag. But is also induced via lift, that’s why we calculated the lift first, we don’t need the lift force, just the coefficient. And the parasite drag… can be neglected for some reason?? Because Microsoft Flight Simulator actually neglects parasitic drag vs angle of attack, and only uses lift-induced drag + parasitic drag at AoA = 0, so if this is good enough I guess we can simplify this and just use 1 constant for drag at 0° AoA.
We can ignore wave drag.
Hence, the drag coefficient is calculated as:
Cd0 =
any number you want, generally between .01 - .025
– drag at 0-aoa
Cdi = (Cl_a(AoA)^2) / (pi * AR * oswald)
- lift induced drag
Where
pi
is 3
AR
is the aspect ratio of the wings, calculated as: (wing_span^2) / wing_area
oswald
is the oswald efficiency factor, generally less than 1
(MSFS calculates induced drag slightly differently and I can give you their equation if you want, but this is good enough)
And the total drag force is:
F_drag = (Cd0 + Cdi) * Q * S
Side force:
ughhh let’s move on
Moments
The general moment equation is similar to the lift & drag equation but with 1 extra parameter: wing span (b) for yaw and roll, or mean geometric chord (c_) for pitch
Let’s start with the pitch moment
As the angle of attack increases, the plane will either want to pitch down if it’s stable, not do anything if it’s neutral, or pitch up even more if it’s unstable. You can use a simple stability derivative for the pitching moment even though a lookup table would be better as the pitching behavior changes post-stall.
So the pitching moment is calculated quite easily:
M_pth = (CM_a * AoA) * Q * S * c_
except, you can’t ignore dynamic effects and you need to include at least one extra factor:
The pitching moment due to pitch rate (CM_q
), there’s also the pitching moment due to AoA rate (CM_adot
), so we might as well just include that as well.
These are generally linearized so 1 single number for both will be enough, no need for tables. You want CM_q
to be negative and this derivative can get quite large.
These are also called damping coefficients, these are required so that your plane doesn’t pitch up and down like crazy, like a spring without a damper.
Since these are dynamic coefficients you can’t just add them onto the main pitching moment coefficient, you need to add them onto the total pitching moment like this:
M_pth = M_pth + (((CM_q * q) + (CM_adot * adot)) * ((c_)/(2*airspeed)) * Q * S * c_)
Where q
and adot
are the pitch rate and aoa rate respectively
Do the same thing with the yawing moment:
M_yaw = (CN_b * AoS) * Q * S * b
M_yaw += (((CN_r * r)) * ((b)/(2*airspeed)) * Q * S * b)
Once again, CN_b
is the yawing moment vs sideslip, AoS
is sideslip, CN_r
is the yawing moment due to yaw rate and r
is the yaw rate itself
And of course roll just damping:
M_roll += (((CL_p * p)) * ((b)/(2*airspeed)) * Q * S * b)
Of course, if you want to add controls, all you need to do is add another extra coefficient and multiply it by the deflection of the flight stick.
for example:
M_roll += (CL_da * ail) * Q * S
where CL_da
is the roll moment due to aileron deflection and ail
is the aileron deflection. Do the same for pitch and yaw and you got working controls.
Now to make the aircraft move:
Since you asked, :ApplyImpulse() and :ApplyAngularImpulse() just simply apply a force and a moment (or torque) to a part, that’s it. Imagine pushing something, yeah that’s it.
So you add up all forces:
F_lift3d = dir_lift * F_lift
F_drag3d = dir_drag * F_drag
F_thrust3d = aircraft.CFrame.LookVector * F_thrust
And you apply the forces:
aircraft:ApplyImpulse(F_lift3d + F_drag3d + F_thrust3d)
And the moments are in the local object space, so it’s slightly different:
aircraft:ApplyAngularImpulse(
(-aircraft.CFrame.LookVector * M_roll) +
(aircraft.CFrame.RightVector * M_pth) +
(aircraft.CFrame.UpVector * M_yaw)
)
There you go, do that every frame and you got a very basic simple plane