gliding simulator

Started by
5 comments, last by grisu 14 years, 10 months ago
Hello! I'm trying to build a simple gliding simulator. I do webdesign, but for my final project at school and as a glider pilot, I simply want to do this. I'm programming in Actionscript 3, with the use of Papervision3D, a 3D-Engine for Flash. I've read some books on physics and really tried a lot of things the last few weeks, but I can't make it run. I try to explain what I do: I have my speedvector, I call it v, where all forces get added up. I transform this vector into my glider's space. Then I calculate the vectors for lift and drag. Angle of attack is calculated with the dot product of lift and my glider's "up". I don't have realistic values, i play around with constants, so the values for drag and lift are simply calculated with: v*v*alpha*const I transform v into global space and add the gravity-vector. I have not yet included rotational moments, I only have a control over pitch, I want to adjust the constants to get a good angle of descent. Now this is my problem: When the speed gets very high, I fly with a low angle of attack, still a lot of lift is produced, of course. This high lift vector, which is added to the v vector, causes the v vector to point "more up". This, in the next frame, leads to a negative angle of attack, lift vector points downwards, and my values freak out. This effect starts slowly, I can see it from my alpha values, and then explodes. This problem only occurs, when the constant for lift is high, However I need a high value to get a good angle of descent. What am I missing? As I said, I read some books on this and I could not find a missing element. Thanks a lot in advance for any help! regards grisu
Advertisement
Quote:Original post by grisu
I have my speedvector, I call it v, where all forces get added up.
I transform this vector into my glider's space. Then I calculate the vectors for lift and drag. Angle of attack is calculated with the dot product of lift and my glider's "up".
I don't have realistic values, i play around with constants, so the values for drag and lift are simply calculated with:
v*v*alpha*const
I transform v into global space and add the gravity-vector.

v has units m/s, drag and lift as forces have kg m/s^2, gravity acts as simple acceleration m/s^2. I hope you do multiply the forces with Timestep/Mass, or whatever identifiers you use. Lift and drag coefficients for gliders, as well as wing area, span, etc...can be researched on the web to get initial values, Wikipedia is your friend. Use consistent units, do not optimize constants like air density away on the first try.

Quote:
Now this is my problem:
When the speed gets very high, I fly with a low angle of attack, still a lot of lift is produced, of course. This high lift vector, which is added to the v vector, causes the v vector to point "more up". This, in the next frame, leads to a negative angle of attack, lift vector points downwards, and my values freak out. This effect starts slowly, I can see it from my alpha values, and then explodes.

Welcome to numerical mathematics, sounds like your time steps are too big, resulting in numerical instabilities (if you haven't a bug in your code. We can't tell, as we haven't seen it yet). You can either:
1) (easy) decouple physics frame rate from rendering frame rate, and increase the former (calculate more frames than you render) or
2) (hard) study some numerical math and use better methods (Verlet-Integration, explicit Runge-Kutta-methods, or if the problem really does not go away, implicit methods).



One obvious question would be, "Is your system stable?" RandomBystander pointed out that your integration scheme may introduce instabilities; I'm asking if your ODE is stable to begin with. A simple test of this would be to (1) linearize your equations of motion and (2) check that the eigenvalues of your resulting system matrix all lie in the left half of the complex plane. (There are some "corner cases" this test doesn't catch, but it's nearly always good enough).

Also: To organize your thoughts and your code, and to make communicating with others easier, I always recommend writing down the state-space model for your system.

[Edited by - Emergent on June 19, 2009 7:44:12 PM]
Quote:
v has units m/s, drag and lift as forces have kg m/s^2, gravity acts as simple acceleration m/s^2. I hope you do multiply the forces with Timestep/Mass, or whatever identifiers you use. Lift and drag coefficients for gliders, as well as wing area, span, etc...can be researched on the web to get initial values, Wikipedia is your friend. Use consistent units, do not optimize constants like air density away on the first try.


I don't need realistic values, such as mass, span, etc. I just want the model to feel realistic, so i.e my gravityvector is simply (0, -20, 0).
To be honest, I did not think about timesteps. I simply added the vectors, then finally multiplied my speed vector with a deltafactor to achieve steady motion, then multiplied it back for the next frame.
I now tried multiplying every force with this factor and leave the final speedvector as it is, but now everything is going crazy from the beginning.

Quote:
Welcome to numerical mathematics, sounds like your time steps are too big, resulting in numerical instabilities (if you haven't a bug in your code. We can't tell, as we haven't seen it yet). You can either:
1) (easy) decouple physics frame rate from rendering frame rate, and increase the former (calculate more frames than you render) or
2) (hard) study some numerical math and use better methods (Verlet-Integration, explicit Runge-Kutta-methods, or if the problem really does not go away, implicit methods).


I'm reading into Runge-Kutta, improved Euler etc. now, thanks.

Quote:
One obvious question would be, "Is your system stable?" RandomBystander pointed out that your integration scheme may introduce instabilities; I'm asking if your ODE is stable to begin with. A simple test of this would be to (1) linearize your equations of motion and (2) check that the eigenvalues of your resulting system matrix all lie in the right half of the complex plane. (There are some "corner cases" this test doesn't catch, but it's nearly always good enough).

Also: To organize your thoughts and your code, and to make communicating with others easier, I always recommend writing down the state-space model for your system.


I did not understand a word :)
I started 3D-Programming some months ago, what I'm doing now is a very good practice, I'm gettig firm with vectors and matrices. But I don't have any mathematic background, I realized some days ago that I'm actually solving differential equations on the fly.

I post some code as it is now, maybe you see something obvious. And it would be great if you could explain to me the timestep thing. Am I doing it right? I am a bit confused right now.

//Delta -------------------------------------------var timeAct : Number = new Date ().getTime ();var time : Number = timeAct - _timeOld;_delta = time / TIME;			//TIME = 1000ms_timeOld = timeAct;// v in local coordinate spaceMatrix3D.multiplyVector3x3 (Matrix3D.inverse (this.transform), _v);						// drag vector_fDrag = _v.clone ();_fDrag.normalize ();_fDrag.multiplyEq ( -1);								// lift vector_fLift = Number3D.cross (Number3D.cross (_fDrag, UP), _fDrag);_fLift.normalize ();						// angle of attack - alphavar alpha : Number = Math.acos (Number3D.dot (_fLift, UP));var dotToFwd : Number = Number3D.dot (_fLift, FWD);if (dotToFwd < 0)	alpha = -alpha;			alpha *= Number3D.toDEGREES;						// Speed_speed = _v.modulo;						// value dragvar drag : Number = _speed * _speed * alpha * _delta * 0.0002;_fDrag.multiplyEq (drag);_v = Number3D.add (_v, _fDrag);						// new speed_speed = _v.modulo;						// value liftvar lift : Number = _speed * _speed * alpha * _delta * 0.002;_fLift.multiplyEq (lift);_v = Number3D.add (_v, _fLift);						// v in global spaceMatrix3D.multiplyVector3x3 (this.transform, _v);						// ...add gravityvar g : Number3D = GRAVITY.clone ();g.multiplyEq (_delta);_v = Number3D.add (_v, g);this.position = Number3D.add (this.position, _v);


Quote:Original post by grisu
I did not understand a word :)
I started 3D-Programming some months ago, what I'm doing now is a very good practice, I'm gettig firm with vectors and matrices. But I don't have any mathematic background, I realized some days ago that I'm actually solving differential equations on the fly.


Oops... I shouldn't have been quite so lazy with my last post; I guess I didn't explain much.

Let me introduce you to some ideas. They're pretty simple.

The first is the idea of state, and state space.

Your glider/airplane -- or any physical system that you want to simulate -- has what's called a state. This is a vector containing all the variables needed to fully describe the system at an instant. To visualize it, picture it as a point in some (possibly high-dimensional) space (but for visualization purposes for now 2d or 3d is fine); we'll call this space in which the state lives state space. A differential equation describes how this point, the state, moves in state space. Here, an example is worth a thousand words:

Consider a particle in 1d with mass m, acted upon by an external force u. Its state is the vector (p, v), where p is its position and v is its velocity (so, its state space is the 2d coordinate plane; if we want to be fancy we call this R2). The dynamics -- or, the way the state moves -- are,

dp/dt = v
dv/dt = (1/m) u

You can see that this is equivalent to good old "F = m a" (or in this case, "u = m (d2p/dt2) ).

More generally, the state space form for a differential equation is just,

dx/dt = f(x, u, t)

where x is your state vector, u is called the control input and is a vector of "controls" -- for instance, the angle of a steering wheel, or the current value for the throttle of a vehicle -- and t is of course the time. The function f simply returns the direction in which the state moves, given the current state, the time, and a control input.

Another example: Consider a car driving around in a plane. It has a position (p1, p2) in the 2d plane, and a heading angle theta. Let's say that you can control how fast it goes (we'll call the speed u1) and the steering angle (we'll call this u2) -- so the control input is u=(u1,u2). The state is then x=(p1,p2,theta), and the dynamics are,

d p1/dt = u1 cos(theta)
d p2/dt = u1 sin(theta)
d theta/dt = u2

This describes a car -- or, more accurately, a unicycle -- driving around on a plane.

You can describe your glider with a state-space model as well. In fact, this must be what you're doing in your code already, if you stop and think about it. I just think it'd be helpful to be clear about what this model actually is. So I ask:
1. What is the state, x, of your glider?
2. What are the control inputs, u, of your glider?
3. What is the system function, f, for your glider?
These questions should help to organize your thoughts.

This will give you a differential equation

dx/dt = f(x,u,t)

describing your glider. In fact, I'll assume that your glider is not time-varying (meaning, it behaves the same no matter what the time is), in which case your differential equation will just look like,

dx/dt = f(x,u) .

These are pretty simple concepts, right? Sorry to belabor them.

Anyway, I need to go now, so I'll post later with some info about stability.
Ok... now about stability... Imagine a pendulum hanging down on a rigid rod. If it is jostled a little, it will eventually return to this hanging-down position. By contrast, if you try to balance it "upside down," it will, like a pencil balanced on its tip, fall down at the slightest disturbance. The "down" position is stable; the up position is unstable.

I'll talk here about how to determine when a system is stable (at a particular operating point) and when it is not.

Fix some nominal state x0 that you're interested in flying your glider at. What value will you have to fix your control input at when you're at this state to keep it there? To find out, solve the equation

f(x0, u) = 0

for the control input u. It may have multiple solutions; I'll assume that one of them is the solution of interest; let's call it u0.

Now, the question: If you are at state x0 and issuing control input u0, and your airplane is "bumped" a little... will it go back to the state x0, or will it oscillate and go unstable? To find out, linearize your differential equation. To do this, compute the Jacobian (check Wikipedia) of f at x0; I'll denote this by (df/dx)(x0, u0). Then, the linearized dynamics are

dx/dt ~= [(df/dx)(x0, u0)](x - x0)

or, defining z = x - x0, just

dz/dt ~= [(df/dx)(x0, u0)] z .

When is such a linear system stable? A sufficient condition is that all the eigenvalues (check Wikipedia) of the matrix [(df/dx)(x0, u0)] have negative real part. When they do, we say that they "lie in the left half of the complex plane," since that's how we normally draw the complex plane.

If any of the eigenvalues has positive real part ("is in the right half plane") the system is definitely unstable.

Eigenvalues that lie on the imaginary axis (have zero real part) are a little trickier. Normally, they signify that the system will oscillate indefinitely but not blow up, but that's not always true. Anyway, don't concern yourself with that case.

Now you have a way to determine whether the differential equations describing your aircraft are stable or not. If they are stable but your simulation is exploding anyway, then ether you need a better numerical integration scheme (as RandomBystander suspects) or there's a bug in your code. If they are not stable then perhaps you do not have a correct mathematical model for a glider.
Thanks a lot for that explanation. But this is still very high for me... I'm trying to understand it :)
I would need more time, also to get some basics, and I have to get my plane flying until thursday - I'm getting a bit nervous.
I thought this would be a simple task, simply adding some vectors. A vector is something i can visualize easily, I made a small class to actually show the vectors, to see how they behave.

I have some more concrete questions.
What about this timestep? I now summed up my forces in a vector, then multiplied this vector with the timestep-factor, before adding it to speed. Is this ok?
But then, to achieve steady motion, independent of my framerate, do I have to multiply my speedvector with this factor again, after the translation multiplying it back? This seems a bit weird to me.
Or was I right with my original version, simply multiplying the speedvector with the factor?
I think this is a very important point.

Second question is:
Where do the rotation moments in an airplane come from?
I tried something simple: pitchmoment depends on angle of attack. Positive angle causes the plane to pitch down, negative up.
What about bank? When I bank the plane, it should turn by itself. Is this a roll, yaw, or pitch moment? On which component does it depend?
In my sim, already a very small bank causes the speedvector to turn rapidly. With a bank angle of 10 degress speed already points to the left, 90 degrees.

Already thanks for your answers. Fly Baby!! ;)

Chris

This topic is closed to new replies.

Advertisement