1 Rotational Dynamics The goal is to characterize the rotational behavior of a bunch of point masses for use in a computer simulation. The reader is expected to be familiar with basic rotational mechanics, which is to say the meaning of angular momentum, torque, and rotational velocity, and the way these quantities transform as 3 dimensional vectors. Likewise, familiarity with linear algebra is assumed, as is a reasonable knowlege of multivariable calculus. If you got through freshman physics, you should be fine with this. Let’s start out somewhere simple and uncontroversial, with the definition of the angular momentum L ~ of a (point) object with mass m, velocity ~v and radius from the center of mass ~r: ~ = m(~r × ~v ) L Expressing ~v in terms of the angular velocity ω ~ about the center of mass: ~ = m(~r × (~ L ω × ~r)) There’s a nifty expression of a cross product as one of two matrix operations: 0 bz −by ax 0 −az ay bx ~a × ~b = −bz 0 b x ay = az 0 −ax by by −bx 0 az −ay ax 0 bz So using this trick, and introducing x, y and z as the components of the position vector ~r, we get: ~ = m(~r × (~ L ω × ~r)) x 0 z −y ωx ~ = m L y × −z 0 x ωy z y −x 0 ωz 0 −z y 0 z −y ωx ~ = m L z 0 −x −z 0 x ωy −y x 0 y −x 0 ωz or just: ~ = I~ L ω where: y2 + z 2 −xy −xy I ≡m −xy x2 + z 2 −yz −xy −yz x + y2 2 Note that this matrix I depends only on the static properties of the point mass. It does not depend on the current dynamic state of the system. This is called the inertia tensor of the object, and I’ll have more to say about it below. But first let’s generalize a little bit. A simulation of a single point mass is not terribly interesting. Consider the case where we have more than one point mass. 1 The total angular momentum will of be the sum of all the individual momenta of the n point masses: ~ = I0 ω L ~ + I1 ω ~ + ... + In ω ~ n ! ~ = X L Ii ω ~ i=0 So the L~ = I~ω equation holds not only for a single point mass, but for any finite collection of them. For any collections of masses, there is a 3 × 3 matrix I that relates the angular velocity to the angular momentum. Actually, this result generalizes just fine to the infinitesimal, where I is defined as a volume integral over the object involving the point density ρ. But since we’re talking about computer simulation of point masses here, we don’t care. The important point to grok is that all of the rotational complexity of any mass distribution can be represented by a single 3 × 3 matrix. Actually, it’s even better, since the matrix is symmetric (I = I T ) it has only six degrees of freedom. Math nerds will whine that I’m calling it a matrix, and not a second rank tensor (which would make this property “obvious”). Sue me. This inertia tensor turns out to be damn useful. For example, we can dif ferentiate with respect to time and get (remember that torque is just the time derivative of angular momentum): ~ dL d~ ω =I dt dt d~ ω = I −1~τ dt That is, we can calculate the angular acceleration as just a matrix multipli cation of the applied torque ~τ on the object. The angular acceleration is not merely a scalar multiple of the applied torque! Lots of implementations get this wrong, and those that get it right tend to jump through nasty hoops to make things work. But here there’s no muss, no fuss. Remember since I is static (or nearly so), both it and its inverse can be precomputed and stored. Even better, notice that because this matrix I is not simply a multiple of the identity matrix, the angular momentum need not point in the same direction as the angular velocity! Thus, as the object rotates around the ω̂ axis, the momentum vector will also be (instantaneously, anyway) rotating around it. But if the momentum vector is moving in a circle about the axis, then there must be a torque being applied to keep the momentum moving in a cirle. Since there is not a torque being applied, we can only conclude that a rotating object must be generating a torque on itself opposite to the one required to maintain the angular momentum in rotation about the ω̂ axis. (Phew. This is a clumsy way to make this argument. See The Feynman Lectures, chapter NN for a clearer explanation of this point.) This is a real phenomenon. An object “spun” about its center of gravity does not, in the general case, remain in a static rotation about the same axis. 2 It “wobbles” a little, trying to get to a stable state. This is the source of the wobbling motion of a precessing gyroscope, for instance, and it’s the reason that airplanes tend to remain in a “flat” spin despite their aerodynamic stability. This is another effect that most rigid body simulations (in games, anyway) tend to get wrong. So what is this torque? (Warning: I’m playing fast and loose with the math here, because I couldn’t find a more rigorous derivation that was understandable. Most readers will, I hope, forgive me. Those that cannot are probably able to provide the rigor for themselves.) Well, it must be perpendicular to the angular momentum, or else it would act to increase or decrease its magnitude instead of merely change its direction. It must likewise be perpendicular to the axis of rotation, or else it would act to change the angle between the two vectors, instead of rotating one around the other. So our torqueduetorotation vector ~τω must be some multiple of the cross product of the two vectors: ~τω = c(~ ~ ω × L) As it happens, c = 1. Why? Well, what’s “really” rotating is actually the component of L ~ that is perpendicular to the axis ( L ~ ⊥ ). By virtue of the definition of the cross product, the magnitude of this component is the same as the magnitude of the cross product of L ~ and the unit axis vector ω̂. So after ~ time t, the rotation will have pushed L⊥ “around the circle” by t~ ω  radians. In angular momentum space, this will have pushed it around t~ ~ ⊥  units ω  L (footpounds per second, or whatever unit you’re using). So: ∆L = t~ ~ ⊥ ω L = t~ ~ × ω̂ ω L = t~ ~ ×ω ω L ~ /~ ω ~ = tL × ω~ ∆L ~ ×ω = L ~ t ~ ×ω ~τω  = L ~ thus: ~τω = ω ~ ~ ×L Q.E.D., or thereabouts. It’s a wholely informal proof that completely ignores the existence of calculus. My hope is that the average software developer will find this a little more intuitive. So, putting it all together, we have an external torque ~τ0 that is to be combined with our calculated ~τω in a final rotational equation of motion: d~ ω = I −1 (~τ0 + ~τω ) dt d~ ω = I −1 (~τ0 + (~ ω × I~ ω )) dt 3 Easy to write. Easy to remember. And easy to calculate: one vector addi tion, one cross product, and two matrix multiplies (42 floating point operations) per iteration to calculate the angular acceleration. 4 2 Aerodynamic Surfaces All subsonic aerodynamic force laws have the general form: 1 2 F ∝ ρv 2 With v being the velocity of the air stream and ρ being the density. The remaining coefficients in the equation do not vary with the dynamic properties and are “intrinsic” to the body. So let us make the following assumptions: that the body has a preferred basis, a particular orientation, and within that orientation the three components of aerodynamic force are merely scalar multiples of the normalized (unit vector) wind direction along that axis. That is, if we have an orthonormal matrix R that transforms vectors in the preferred basis (call it the “wing frame”) to the frame in which the wind vector ~v is specified, then we can write the force equation as: cx 0 0 1 F~ = ρ~v 2 R 0 cy 0 RT v̂ 2 0 0 c z Note that these coefficients cx,y,z are not unitless scalars. They will de pend in very complex ways on the nature of the body they represent. But in a computer simulation, we don’t have to care. It’s sufficient that these coeffi cients produce acceptable results. We don’t have to attach meaning to them, or measure their values. The reader’s immediate question, of course, is does this work ? This scheme is pleasing from a computational perspective, but will clearly be useless if it fails to reproduce plausible behavior. As it happens, the idea is not completely without justification. In the limit of very low pressure (or very high speed), the gas molecules will not interact with each other. The body will be swimming in an ideal gas, and thus the force on it along any axis will be exactly equal to its crosssectional area across that axis multiplied by the gas mass it is encountering per unit time along that axis. That is, F~ = Aρ~v . So cx = Avx , cy = Avy and cz = Avz . Certainly the force coefficients for a body in a fluid flow will not match those for a body in an ideal gas, but the character of the solution might be expected to persist. The values of the coefficients will be different in different regimes, but cx,y,z coefficients for fluid flow might nonetheless be expected to exist. The astute will note that I’m cheating already. The c x,y,z in the previous paragraph were not intrinsic to the aerodynamic object — they depended on the velocity! The quadratic dependency on v needs to be independant of coordinate choice, and this one is not. As it happens, all aerodynamic bodies worth simulating are symmetric about some axis or another. If they are not, they can be decomposed into subparts that are. By convention, call this axis of symmetry z. We now know that 5 cx = cy , so we can redefined cz and rewrite the coefficient matrix as: 1 0 0 c0 0 1 0 0 0 cz The c0 “total drag” scalar can be pulled out to live on the far left of the force equation, and we’re left with a unitless matrix equation in the middle as we desired. We can now represent a fuselage, which has a much lower drag in the forward direction than across the body, by pointing z “forward” and using a low cz . Likewise, a flat airfoil segment, which has a much higher drag at an angle of attack of 90 ◦ than when the wind blows along the surface, has a large c z if we choose the z axis as “up”. The discussion below will use this convention, with the added assumption that we can point x “forward” for a wing segment. The y axis would then be parallel to the wing itself. Unfortunately, this scheme does fall down in a very important regime. The behavior of wings or other aerodynamic surfaces in the “normal” flight envi ronment has two properties that this mechanism does not. The “lift” (force perpendicular to the wind) is nonzero even when the wind has no z compo nent. And the stall condition (rapidly decreasing lift) is missing. But thankfully, these pathologies are treatable in a way that preserves most of the elegance of the initial solution. The first observation to make is that the basic shape of the lift curve with angle of attack α is correct. That is, the lift at small angles is linear with the angle. This follows from the fact that the z component of the wind goes as sin α and that, for small angles, sin α = α. So we simply have to modify the slope of the curve in the prestall region so that the lift peaks at the stall (α s ) and then reverts to the solution above. Modifying the slope of a line is the same thing as multiplying by a constant, so we replace the constant c z with cz fs0 (α) and introduce the “stall” function f s0 (α) as: cα if α < αs fs0 (α) = 1 elsewhere We’ve introduced cα here as the scaling factor for the lift slope. A better idea would be to express the scaling in terms of a fraction of the 45 ◦ lift peak. So introduce cs as the “stall peak coefficient”, the ratio of the heights of the initial (stall) lift peak to the poststall 45 ◦ peak. A typical value might be 1.5 or so. The derivation isn’t shown, but you can plug the value in and check for yourself that it works. Remember, this is all heuristics — we’re trying to fit a function to real life, not derive a function from life’s principles. cs 2αs if α < αs fs0 (α) = 1 elsewhere A complication here is that this function gives an infinitely sharp stall. The lift falls discontinuously from the stall to a value much lower. Real airfoils 6 have more gentle curves. Not to worry, we can fix this with a simple cubic interpolation. Introduce a stall “width” w s , across which we will interpolate, and we can compute a smoothed f s (α) in terms of fs0 from above: fs0 (α) if α < αs fs (α) = 1 if α > αs + ws fs0 (α)φ + (1 − φ) if αs < α < αs + ws 2 3 α − αs α − αs φ≡3 −2 ws ws Note that by using the “small angle” approximation, we have α = sin α and therefore α = v̂z /v̂x . (Remember the x axis is “forward” by the previously adopted convention). This is important computationally, as it reduces the prob lem of calculating an angle of attack to a simple division of two scalars we already have. The above definition for the function fs is actually incomplete. A real airfoil in fact has four stall angles — positive and negative α stalls for both forward and reverse motion. A complete implementation would thus have nine cases, parameterized by four stall angles and two stall peak coefficients. The final nit, that the lift at α = 0 should be nonzero, is solvable in the simplest way possible. Just define a constant z axis force coefficient c z0 and add it to the force vector right before we transform it back from the wing coordinates. So our complete force equation for an aerodynamic surface now looks like: 2 1 0 0 0 ρ~ v  F~ = c0 R 0 1 0 RT v̂ + 0 2 vz 0 0 cz fs ( vx ) cz0 And a complete specification of a surface, then, consists of: c0 : The “total drag” coefficient. cz : The unitless z (symmetry axis) drag coefficient. cz0 : The z coefficient offset. αs1...4 : Stall angles. ws1...4 : Stall widths. cs1...2 : Stall peak coefficients. Not too terribly complicated at all — especially since some of these values have sensible defaults. Unspecified stall definitions can be left at “sharp” and 12◦ for wings, or αs = 0 (no stall at all) for nonairfoil surfaces. Values for cz can be guessed at, but 10 (1/10 for fuselages) seems to be a good number to work with in almost all situations. Forward stall peaks work well at about 1.5, and reverse ones should be left at their default of one. (No one has ever measured the stall angle for a cessna flying backwards!) 7 3 Propellers 3.1 Groundwork A quick enumeration of some basic facts: The engine acts to produce a torque τ on the propeller, which spins with a rotational velocity (radians per second, of course) of ω. This produces a thrust force F to push the aircraft along with a forward velocity v. The power generated by the engine is P eng = τ ω, and the work done on the aircraft is P work = F v. These two powers can be related by an efficiency factor Pwork Fv η= = Peng τω where η lies in the range 0–1 (negative torques due to high speed or low engine power will be handled specially below). Note that η is not a constant, but a function that will depend on the aerodynamic situation in which the propeller finds itself. Since the propeller is a collection of airfoils, we will apply the same assump tion that we did in the discussion of aerodynamic surfaces. Namely, that the direction of the aerodynamic force depends only on the direction of the local wind, and not on its velocity. This means that for any given “angle of attack” 1 , we will have a scalar “lift to drag” 2 ratio that determines the direction of the force, and a force coefficient proportional that will be multiplied by ρv 2 /2 to get the magnitudes. 3.2 Some New Coordinates: J and λ So we should endeavor to eliminate velocity dependencies from our force equa tions. So lets make a change of coordinates and introduce the propeller’s advance ratio: v J≡ ω Roughly speaking, this value determines the direction of the incident wind 3 relative to the plane of the propeller rotation. By the assumption above, this means that J must also determine a scalar “base” magnitude for both thrust and torque, with all velocity dependence being part of the ρv 2 /2 law. We might therefore expect the efficiency factor η to be a function of J. Happily it is, and such propeller efficiency graphs can be found in books. Even more happily, all such graphs have a remarkably similar character. An example is shown in figure 1. Note that the curves for the different propeller pitches are 1 Not a true angle, of course, since the actual angle will change depending on the station along the propeller. 2 Again, a perversion of the more common term. The “lift” in this case is not perpendicular to the incident wind, but along the velocity vector. Likewise drag is parallel to the rotation of the propeller, and not to the wind. 3 Yet again, this is a slightly different definition of J than is normally found in the literature. Because the goal here is simulating a single aircraft, I have removed the diameter term as it will be constant for any given propeller. 8 1 0.8 η 0.6 0.4 0.2 0 0 0.5 1 1.5 2 2.5 J Figure 1: Propeller Efficiency Figure 2: A heuristic function for η all the same shape. Under further scrutiny, you will find that by applying the small angle approximation and representing the pitch angles as J values they are all (almost—to within a few percent of efficiency anyway) the same curve. The differ from each other only by a scalar constant along the J axis. So let us make another change of coordinates and introduce: J λ≡ J0 This value is a dimensionless scalar (always a good thing), and represents the wind relative to the propeller’s chord line. The value of J 0 is defined to be the value of J at which the curve crosses the axis—that is, the advance ratio that produces exactly zero thrust. Expressing our calculations in terms of λ has the nice advantage of allowing us to support variable pitch propellers in a seamless way. Values of J will change with propeller pitch. So now all that’s needed is to find an easily calculated function that gives us η as a function of λ. Because the physical plausibility of the model is maintained so long as we keep η between 0 and 1, we have a good deal of latitude here. All we need is a function that “looks right”. Here is one: η = ηc β(λ − λ9 ) (β ≡ (9−1/8 − 9−9/8 )−1 ≈ 1.48058) 9 Figure 3: Propeller Thrust Clearly, there is no physical basis for this function. It was chosen for the sole reason that it matches the “look” of the measured efficiency curves and is easy to calculate. A graph can be found in figure 2. Note that it crosses zero at λ = J 0 , as per the definition of J0 . The funny value for β is a scaling factor that places the peak of the function at 1. Thus, we can multiply by the “cruise” efficiency ηc to get the true efficiency number. The title presumes that an aircraft at cruise is operating at the propeller’s peak efficiency. 3.3 From Efficiency to Forces Given the definition for η in terms of power, we can now calculate a thrustto torque ratio γ: F ω η γ = =η = τ v J η = J ηc β(λ − λ9 ) = J0 λ ηc = β(1 − λ8 ) J0 We are almost there. With γ we have the ratio F/τ , but we need another scalar to fix the magnitudes for both. With a little thought, it should be clear that the thrust of the propeller should act like the “lift” of a wing. We should expect it to be linear with angle of attack, thus it should be linear in J and likewise in λ. By definition, it should be zero at J = J 0 and λ = 1. We can construct the slope by assuming, as above, that the propeller at cruise is operating at the peak of its efficiency curve. The total thrust is therefore 1 2 1−λ F = ρv F0 2 1 − λc 2Fc F0 = ρc vc2 F0 has been defined as a normalized magnitude, independent of velocity and derived from the externally specified cruise parameters. Also, note that by the definition of our η function, λc is analytically calculable 4 and has the value of 9−1/8 ≈ .759835. A final complication is that the linearity of the thrust function will hold only in the realm near λ = 1. As λ gets smaller, the local angle of attack grows until the propeller begins stalling. Real world propellers indeed show this effect, as 4 Take the derivative, set equal to zero and solve. 10 seen in figure 3. We handle this by cheating and simply clamping the thrust to a constant at a stall “angle” of J s . If we assume that the J0 angle is “small” (below 50◦ or so), then we can simply subtract a reasonable stall angle (15 ◦ , or about .25) from it to get Js ≈ r(J0 /r − .25). Note the use of a radius parameter r, to turn J into a real angle. This will be introduced in more depth below; it represents the “characteristic” radius of the propeller. The justification for this treatment is twofold. First, real world data does tend toward a constant thrust at the stall, as seen in figure XXXX. The curves wobble around a little, but the dips and swells are small relative to the value of the function. This is, of course, because the propeller stalls first at the root, and progressively stalls outwards as λ gets smaller. As the tip is stalling, a significant part of the inboard propeller has moved on into the poststall lift peak5 . The net effect is to “smooth out” the stall. The second justification for our simplistic cap is that the “stalled propeller” flight regime is very small and very transient. A stalled propeller is one that is turning much faster than a cruise propeller at that velocity. An aircraft in that configuration will either be accelerating rapidly into a normal regime or the propeller rotation will be slowing due to the extra torque. There are no steady states in this regime, which means that there aren’t any “numbers” to be violated. All we need to do is be plausible, and the cap does that. Having calculated the thrust, getting the torque is a trivial exercise. From the definition of γ, we have τ = F/γ. But some gremlins hide in that division. First, what happens when γ = 0? This equation explodes. To find out, let us expand the equation for τ with the expressions we have for γ and F , dropping all the terms that are independent of λ. F τ = γ 1−λ ∝ 1 − λ8 So indeed the function is undefined at λ = 1, but the pathology is limited to that one point. The function turns out to have a valid limit (from both sides, although we only care about the cases where λ < 1) of 1/8. 6 Should it not be zero? No. The point of zero thrust is not the same as the point of zero torque. On a moving aircraft, producing “zero” thrust still requires some power, as a propeller spinning freely in the airstream would create some drag that must be overcome. What about the number; is 1/8 the right amount of power to get zero thrust? Sadly, this is not a statistic that people measure for propellers. The best we can say is that it seems plausible. 3.4 Cleaning Up There remains one problem. The realm of discourse so far has been for a pro peller spinning with an advance ratio of between 0 (corresponding to an airspeed 5 See the aerodynamic discussion in section XXXX 6 The proof isn’t shown, but you can verify for yourself that limx→1 (1 − xn )/(1 − x) = n 11 of zero—a plane beginning its takeoff run, perhaps) and J 0 (the point of zero thrust). What about values greater than J 0 ? It is possible for a propeller to be feeling a negative torque from the engine—this happens when the pilot pulls back on the throttle and the propeller slows down, or on a diving aircraft when the high airspeed “pulls” the propeller to a faster RPM than the engine could drive by itself. Or even values less than zero? The propeller will clearly never be spinning backwards (engines just don’t do that), but the airspeed might well be negative for an aerobatic aircraft in a hammerhead stall (or merely for a taxiing plane with a tailwind). The classic folly of designing a simulation model to measured data is that it tends to give bizarre results in the unmeasured regime. We need to be sure to produce reasonable behavior. The first negative λ situation is easiest to handle. Propellers simply do not go backwards, so there is no need to handle that case. For the case of the vehicle moving backwards, we can assume that the airspeed will be very small. So include v in the determination of w, but simply clamp λ to zero. This will maintain plausibility through a hammerhead stall — pilots will not be able to put the plane into a situation where the lack of a “reverse” propeller stall is noticeable. The case where λ > 1 (the realm where the torque is negative) is a little more subtle. Recall that λ is fundamentally a slope, and that a given value identifies a particular angle of attack relative to the zerothrust (λ = 1) angle. By drawing some triangles and applying the small angle approximation, we can see that the angle between the wind and zerothrust for a λ of 2/3 is the same as that for a λ of 3/2. That is, the angle for a λ greater than one is the same as for 1/λ. If we presume that the lift goes linearly in this region as we did for the thrust computation, we can derive the forces for negative torque from the forces in the normal region by inverting the λ value. This requires one nasty trick, though. Recall that while the thrust at λ = 1 is zero, the torque is not. If we merely negate the torque function as we do for the thrust, we end up with a giant discontinuity when what we really want is for the torque to continue steadily toward its own zero point. So what we do is leave the “τ0 ” solution for λ = 1 in place, and subtract from it the value of the inverted λ solution. That is, if t(λ) is our function for torque from above: t(λ) if λ < 0 τ= 2t(1) − t(1/λ) if λ > 0 So far, we have been treating the v parameter rather loosely. In the definition of J, we assumed it meant forward velocity. When extracting the ρv 2 term from the force laws, we assumed it was the absolute wind velocity acting on the pro peller blade. These aren’t the same quantity; the spinning blades p of a stopped propeller still feel wind. So let us define a new velocity, V = v 2 + (rω)2 . This is the wind velocity across the propeller blades, and it is the value we will use to calculate force. The v used to calculate J remains the forward velocity of the aircraft. Note that this introduces a new value r, the radius of the pro peller segment feeling the force. There is no single value of r that will work 12 for the whole propeller. We solve this problem by prestidigitation. Define r as the “characteristic radius” of the propeller – the value that will give us close to correct answers. Since most of the force from a propeller is felt near the tips, this value will be near (but a little less than) the physical radius of the propeller. Again, we can justify this by an appeal to plausibility. Since our bases are covered with respect to the cruise performance of the propeller, all we need here is to avoid any strange or unphysical behavior. So long as we get r close to correct, we won’t see any. 3.5 The Algorithm So finally, we have a game plan. At initialization time, we should: 1. Collect the static parameters. These are primarily the “cruise” parameters for the propeller vc , ωc , ρc (air density, usually specified as an altitude) and Pc (engine power required). Also needed is the maximum propeller efficiency ηc (which can be left at 0.85 for almost all propellers), and a characteristic radius r. 2. Compute J0 as vc /(ωc λc ). This follows from the location of the cruise peak on our η function. Note that for variable pitch propellers, J 0 will not be a constant at runtime. It will be modified constantly as the propeller governor seeks its target RPM. Allowing it to vary by a very large factor from the “cruise” J0 should be acceptable. A “feathered” propeller will have a J0 of infinity, in theory. In practice, limiting it to the range 0–100 should be more than sufficient. Some propeller governors actually have a reverse thrust setting, and would allow J 0 to be less than zero—this will need to be treated specially. 3. Compute the cruise thrust p (via the definition of work) as F c = ηc Pc /vc , and using a value Vc = vc2 + (rωc )2 , extract the velocity scaling from the thrust to produce the thrust coefficient 2Fc 2ηc Pc F0 = 2 = ρc Vc ρc vc (vc2 + (rωc )2 ) And now calculation of the propeller thrust and torque at runtime becomes relatively straightforward. To recap from the derivations: p V = v 2 + (rω)2 v/ω if v > 0 J= 0 if v ≤ 0 λ = J/J0 ηc γ= β(1 − λ8 ) J0 13 ρV 2 1−λ F = F0 2 1 − λc F/γ if λ < 1 τ= 2τ (1) − τ ( λ1 ) if λ ≥ 1 (β ≡ (9−1/8 − 9−9/8 )−1 ≈ 1.48058) (λc ≡ 9−1/8 ≈ .759835) 14
Enter the password to open this PDF file:











