Sign in to follow this  
Guest Ron Freimuth

Speed trend vector

Recommended Posts

Hi!I try to create a speed trend vector, but without real success. I need the acceleration value for the calculation which is not given me by the flight simulator.So I compared the current airspeed with the airspeed one cycle before, this works, but it is not smooth at all.Tried it with ground_velocity, but also no success.Can someone tell me how to create a really smooth speed trend display? Do you use an interpolation routine?Kind Regards,M. Burr

Share this post


Link to post
Share on other sites
Help AVSIM continue to serve you!
Please donate today!

In my experience almost all FS variables are not really smooth, they are actually little steps, and also quite a lot slower then the frame rate or the 18Hz "tick". So any diferentiation leads to extremely spiky signals. Ways out of it: - smoothing the airspeed beforehand (low pass filtering) then differentiation, then possibly again low pass filtering. - working with a slow calculation cycle e.g. 1s and then make differences between values 1Hz apart.Arne Bartels

Share this post


Link to post
Share on other sites

>In my experience almost all FS variables are not really>smooth, they are actually little steps, and also quite a lot>slower then the frame rate or the 18Hz "tick". So any>diferentiation leads to extremely spiky signals. Ways out of>it: >- smoothing the airspeed beforehand (low pass filtering) then>differentiation, then possibly again low pass filtering. >- working with a slow calculation cycle e.g. 1s and then make>differences between values 1Hz apart.>Arne Bartels Hmm, I took successive differences of many XLM Parameters at the 18.2 per second rate, then filtered with a 0.2 to 0.5 secoond Time constant. I display 'Vdot', dTAS/dt to 0.01 ft/sec resolution in my XML Test gagues. And, pitch, roll, and Sideslip rates to 0.001 deg/sec. When the AC is flying steady even the last digit may be quite stable. When attitude, etc is changing rapidly the digital values jump around some, but are stable enough to see roll rate, etc. Even on my 467 MHz system. Some angles and accelerations are available though FSUIPC. AFSD now displays Vx, Vy, Vz and accelerations. They appear to agree with my calculated values. However, I think FSUIPC has a limit on how fast variables can be read. My XML test gauges jump around a lot less than AFSD does in some conditions. OTOH, I have to set some AIR file parameters in an AC specific XML data file to show things like drag components.Ron

Share this post


Link to post
Share on other sites

>In my experience almost all FS variables are not really>smooth, they are actually little steps, and also quite a lot>slower then the frame rate or the 18Hz "tick". So any>diferentiation leads to extremely spiky signals.Yeah, I also did trend vectors myself. IAS variale extremely spiky, so I applied low pass filtering to it.On other side vertical speed variable pretty smooth and does not requires any filtering to do trend vector

Share this post


Link to post
Share on other sites

I prefer the "exponential averaging", you need only the value of the last update cycle, the new value and a parameter.e.g.#define DAMPING 0.7//globaly or static if it is in a functionMODULE_VAR airspeed={AIRSPEED};...//check the new valuelookup_var(&airspeed);//calculate the damped valueairspeed.var_value.n=airspeed_var_value.n*(1.0-DAMPING)+airspeed.var_old.n*DAMPING;//store the present value for the next cycleairspeed.var_old.n=airspeed_var_value.n;Should give a damped airspeed, accelaration would be differ only by calculating hte input value in a different way and you can't recycle the var_old.n value so easily.In general:yn=(1.0-D)*xn + D*yn-1 (n,n-1 are indices !)yn is the present filter output, xn the present input, yn-1 the output from previous cycle.The DAMPING value can be fixed, or you can calculate it depending on sim speed. I usually don't bother with changing sim speeds and take it fixed. You can calculate DAMPING somehow, I can write it down after I recalculated it (I always forget it again sooner or later), but usually I make try and error. DAMPING is >0 and <1, the higher more damping.A bit more by the book ("numerical recipes", http://www.library.cornell.edu/nr/bookcpdf/c13-5.pdf) would be:yn=b/(1+:( * xn + b/(1+:(* xn-1 +(1-:(/(1+b)yn-1with b=tan(pi*f*dt) f transition frequency,dt time elapsed between two cycles. You need one old value more compared to the above method, so var_old.n alone doesn't do the trick.These are just two more or less convenient ways to low pass filter, there might be others also.Arne Bartels

Share this post


Link to post
Share on other sites

Here is some of what I have in my Test Base.xml file: 18.207 (>L:Iter/s,number) (* ~18.21 ticks per second *)"18.207" is a constant set just once. It could have been set as a number in the (L:Iter/s,number) in the XML code below.Next is the basic iteration formula. With the value for 'wfb'(weighting factor :( based on the "Time Constant", TC.This is one of several 'rates' I calculate and filter. In crazy "XML RPN" coding. (* limited number of calculations above *)(A:Airspeed true,feet per second) (>L:TAS_fps,number)(A:Vertical speed,feet per second) (>L:VS_fps,number)(A:Incidence Alpha,degrees) d (>L:Alpha,number) dgrd (>L:Alpha_r,number) Other FS values are also set to local variables here.(L:TAS_fps,number) s0 (L:v_n-1,number) - (>L:v_dif,number) l0 (>L:v_n-1,number)(L:v_flt,number) 0 == if{ (L:v_dif,number) (>L:v_flt,number) }(L:v_flt,number) (L:wfb1,number) * (L:v_dif,number) (L:wfa1,number) * + s0 (>L:v_flt,number) l0 (L:Iter/s,number) * (>L:vdot,number) Vdot is dV/dt, and is stable to 0.01 ft/sec if TAS is constant.(* more stuff calculated *) Arnie's message should make the algorithm clearer, but I show how to set the 'wfb1' and 'wfa1' for a specific TC. "(L:TAS_fps,number)" is just a copy of the XML TAS variable. This way, 'TAS' stays constant during each interation of the code, and is refreshed from the A:Airspeed ..." variable near the beginning of the code. So, varying times to calculate things before it's used don't make it unevenly spaced relative to the Tick. It is also used many more times after this place and is always the value assigned near the start of the cycle.. The If{ block sets v_flt to an initial value if it was 0. That could be left out since the (L:vdot,number) value soon becomes the filtered rate. This filter is like an electrical R-C network. A resistor with a capacitor to ground at the output. The Time Constant is 1/RC in that case. The TC is the time it takes for a step change in the input to get to 63% of its final value. In the second interval of one TC, it gets 63% of the remaining distance to the final value. The initial slope is simply 1.0. This is a low pass filter. The bandwidth is w=1/TC. Where w is 2*Pi*f. So, a 0.2 second TC (what I used for pitch rate, etc.) results in a bandwidth of 5 rad/sec; 0.80 Hz. It also adds a delay, which means a sampled data FB system might be less stable. The delay due to 18 samples per second is 1/36 = 0.028 seconds, which adds a phase shift of 360 * 0.028 = 10 deg/Hz. 45 degrees lag is significant and that would occur at 4.5 Hz. The LP filter adds 45 deg phase shift at 0.80 Hz, so it predominates in this case. I did a Fuel Tank Temperature which had a long, changing TC. 3600 seconds (1 hr) with full tanks, dropping to 1/5 that time with empty tanks. The float8 precision is plenty for the small change in the Temperature per cycle. However, there was no reason to calculate FTT 18.2 times a second, so I divided down the Tick by 127 and updated the FTT every eight seconds or so. Once a minute would be fast enough. That complicated things since I had to scale the TC value for the much slower iteration rate.Ron

Share this post


Link to post
Share on other sites

Hello,try the Mach Number (MN) as that token may be more stable as FS tries to add instrumental erors to IAS and poss TAS including AoA, position errors etc.If you want Specific Excess Power (Ps) use (Thrust - Drag )* TAS/Weightall but drag are easily read from internal variables. TAS = MN * 1116.45 fps * sqrt(OAT/288.2K).Ps gives the available rate of climb available and therefore the steady climb angle from that.Ian

Share this post


Link to post
Share on other sites

Arne and Ron,Ron completely lost me, even outside the fact I don't use XML but C and C++ to program the gauges. Ron has a great head for these numbers, and when I was in college I'll bet I could have actually understood what he said.Arne, what you gave looks like a simple weighting of the present and immediately previous value for airspeed, and an easier formula seems to me to be SpdLowPass = NewSpd * 0.3 + OldSpd * 0.7, doing away with the (1-Damping Value). I would assume then that you would average the number of low pass samples you decided to take over a fixed period of time, dropping off the oldest sample, then sum and divide by time interval to get the trend, but since trend is (if I remember) six seconds, you have to multiply by a factor that will give you a six second prediction, and for me that's based on the time over which I've sampled. For me, I measure speeds one second apart, compute acceleration from this, then compute speed in six seconds. It seems to work OK if I have a smooth acceleration, but if I've got windshear or FS decides to update the weather more than I like, then it gets a little spikey. But I like the idea of "damping" the new before computing. I'll give it a try.You mean there's an actual use for "Numerical Recipes in C"?! I've had that book for years, and never gotten one bit of use out of it.Thanks,Bill

Share this post


Link to post
Share on other sites

>For me, I measure speeds one second apart, compute>acceleration from this, then compute speed in six seconds. It>seems to work OK if I have a smooth acceleration, but if I've>got windshear or FS decides to update the weather more than I>like, then it gets a little spikey. But I like the idea of>"damping" the new before computing. I'll give it a try.I'm home now and just looked at my code. It's actually the speed in ten seconds that you need, so I measure the difference in speed in one second, multiply that difference times ten, then draw a line from the current speed position to the trend speed. My guess that here a low pass filter would require saving the immediately prior measurement over one second to compare to the new measurement, then damping these two to get one value before mulitplying times ten.Bill

Share this post


Link to post
Share on other sites

>Arne and Ron,>>Ron completely lost me, even outside the fact I don't use XML>but C and C++ to program the gauges. Ron has a great head for>these numbers, and when I was in college I'll bet I could have>actually understood what he said. XML is a mess. But, I think Arne's and my algorithms are the same. This is the formula for 'b', given the Time Constant one wants to use: wfb = e^-1/TC, wfa = wfb - 1.0 Note 'a' = 'b'-1. I figured out that 'b' = e^-1/TC a few months ago. So, if you want to use a Time Constant of 0.2 sec (good for filtering), then b=1/e^1/0.2 = 0.0067, so a = 0.993. However, that is based on one iteration per second. I think one has to divide 'b' by 18.2 if he is iterating at the Dos Tick rate. That makes it much smaller. Since a sample is reduced 18.2 times in one second, it has to be reduced less for each calculation to be correct after 18.2 ticks. Regardless, one should always see if his code works as hoped. I'd have to look back at the rest of my XML code to see if 'b' works out to that value above.>Arne, what you gave looks like a simple weighting of the>present and immediately previous value for airspeed, and an>easier formula seems to me to be SpdLowPass = NewSpd * 0.3 +>OldSpd * 0.7, doing away with the (1-Damping Value). If it's equivalent to mine it includes weighted factors of all samples in the Old value. It's easier to code the subtraction of 1.0 from the first value to get the second. You can change the Time Constant while the code is running and the filtering immediately changes, the new result is then values averaged with a different "TC" than the previous ones. Note that no sample ever dies out completly in the result. Its contribution just gets smaller and smaller as time increases.>I would>assume then that you would average the number of low pass>samples you decided to take over a fixed period of time,>dropping off the oldest sample, then sum and divide by time No, the older samples are automatically weighted less on each new calculation. This algorithm does 'exponential averaging' which is similar to what many physical systems do. Averaging over a window is artificial.>You mean there's an actual use for "Numerical Recipes in C"?!>I've had that book for years, and never gotten one bit of use>out of it.>Bill I'd figured out the simple TC algorithm before I had Num. Recipes. However, the stuff on Digital Filters is rather concise and obscure to me. And, there is no code for them. Ron

Share this post


Link to post
Share on other sites

I've experimented with the low pass filter, but I've decided to do something different. 1. Find the speed difference after one second using TICK18.2. Multiply that difference times ten (to determine the expected difference in speed after 10 seconds).3. Draw the trend vector line by adding the speed difference to the present speed and then "smoothing" the transition between the prior computed value and the new difference value computed above. I do this by incrementing the old value until it equals the new with an "if" statement. This eliminates the immediate jumps from one value to another and significantly reduces the "spiking" appearance. 4. Save the newly computed value as the old value to use for the next iteration of this procedure.Advantages to this method include accuracy (if you maintain this speed difference, you will arrive at your predicted speed in ten seconds) and simplicity.Bill

Share this post


Link to post
Share on other sites

I realize that this thread is somewhat old but I found another solution. Maybe it will help someone.While programming the HUD for the SAAB AJ37 Viggen as an external program using FSUIPC to extract data from MSFS, I needed the climb angle to place the horizon line. Using ground velocity and vertical velocity was not useful as the update is too slow and even with a filter it is unacceptable with the resulting lag. I then realized that there is a geometric connection between the alpha, beta, roll angle, pitch and climb angle.In the AJ37 the velocity vector is steered from the center of the HUD by the alpha and beta angles. Further more the ladder (the AJ37 has a really small ladder consisting of only the horizon line and two lines at 5 degrees and -5 degrees) are steered from the velocity vector by the climb angle and then rotated around the velocity vector based on the roll angle. But you COULD also steer the ladder from the center of the HUD based on the pitch only. However, the ladder is also moved sideways in relation to the velocity vector. Using the climb angle is faster and less error prone, which was important when the plane was constructed since computers wasn't as fast then as they are now.So the result is that the climb angle can be calculated from the following formula:CLIMB_ANGLE = PITCH - ( sin(ROLL_ANGLE) * BETA + cos(ROLL_ANGLE) * ALFA )Below is a picture of the relations between the symbols in navmod of the AJ37 HUD.http://www.viktoria.se/~yorick/project_viggen/navmod.pngIf you want to learn more about this project visit our forum: http://www.novelair.com/forum

Share this post


Link to post
Share on other sites

This thead got resurected and this was interesting reading all of it! I do the same as you do as well: it is simple, precise, and works great in eliminating spikes in sampling the trend over a period of time (for example 1 sec), and dampening the arrow drawing in an iterative way from present_pos to destination_pos over a smaller period of time (higher sampling rate). Instead of Tick18, I use a milisecond counter between readings and use the exact milisecond difference to compute the projected "in 10 sec" value.Hope this helps!

Share this post


Link to post
Share on other sites

Hi,It would be nice to see something of that proces in XML, so we could compare it with our codes.Or is it a C++ matter?Jan"Beatus Ille Procul Negotiis"

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this