-
Notifications
You must be signed in to change notification settings - Fork 272
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
is it time to improve Circling Wind calculation? #1388
Comments
In general this sounds interesting. Open a dratft PR. |
Just my thoughts on point one, to get change in turn rate from position is like third order derivative, taking derivatives increases noise level. On point 2, I think the reason the current circling wind implementation does not use airspeed is because you don't need circling wind if you have airspeed. Point 5, if you assume everyone has airspeed you might as well assume everyone has wind data already as well. As most varios who measure airspeed also calculate wind. But I think it is irrelevant for circling wind as it is a methode to get an estimate of the wind when you don't have this data. Point 6 is completly correct i think. avg(v_x) = w_x and avg(v_y) = w_y in general i think whether you fly circle or ellipse or any other closed shape. Only error there is pilot choosing to move the circle. And i don't think there really is a way of knowing whether pilot moves the circle or the wind moves the circle (with just gps data). |
Thanks for the feedback, @kobedegeest I also have doubts about what a GPS receiver can reliably deliver. As you said, it is a third order derivative and the quality of the results can vary greatly depending on operating conditions, brand and type. For this reason, I have started to analyze the replay results of different flights. Although it looks promising, there are still cases where I get unexpected results from CalcWind. I don't buy your assumption "avg(v_x) = w_x and avg(v_y) = w_y in general i think whether you fly circle or ellipse or any other closed shape". The effect is that a perfect circle in the air is an ellipse on the ground. The shape of the ellipse can be used to determine the wind. That's the underlying principle of circling wind, I guess. I remain convinced that you can distinguish between a (near) perfect circle and an arbitrary pattern (to move the center point while circling) based on the ship's rate of turn. Certain GPS receivers may not provide sufficient track data to derive a useful rate of turn. But even simple IMUs with their gyros should suffice. Fortunately, my algorithm doesn't care where the turn rate comes from. |
One more point, which might also affect the ZigZag algorithm: ground speed and TAS might have different delays in the signal processing chain. In my case it seems to be around 2 sec, which I noticed looking at the InfoBoxes when I replayed a takeoff. |
Maybe i should clarify that when i said closed shape i mean that in the reference frame of the air of course. In which case your average ground speed vector will be zero if there is no wind and will be equal to wind speed if there is wind since you keep stationary w.r.t. the air but air moves w.r.t. ground. So my reasoning is that you try to keep stationary as you try to keep flying around center of thermal and the thermal drifts so you drift with it and in that case avg(v_x) = w_x and avg(v_y) = w_y is correct. But if the pilot decides to move its center by 1m west every turn there is no way to know this is the pilots chose and not the drift of the wind. So best you can do is throw out circles where big chance in center is found and hope the rest averages out. Current implementation also weights first turns less i assume because at that point your still finding the center.
I am quit interested in knowing how you think this can be done or knowing how you do it. Gyros are useful cus they provide info on change in inclination of the plane from which you can estimate current inclination from which you can get predicated turn rate and radius and from the error you can get the wind. But once you have gyros and airspeed you get algorithms with extended kalman filters used in like hawk, larus and anemoi. And once you have gyros i totaly agree you can differentiated between pilot and wind, because you can measure change in inclination and pitch not just because you get turn rate.
It should cus if you have gyros you can do so much better than if you don't have them. I don't want to critic to much or discourage the effort as i also find the circling wind to be not too good in flight. But the answer should not be use more data (which often is not present). And also like you mention there might be delay between different data especially if you collect data from external devices and then do the calculation in XCSoar. |
I'm trying to get away with GPS (and optional airspeed) only. But I may not succeed. |
I'm submitting the code changes.
This PR is for analyzing results, not intended to include in production. |
Got stuck with github (again). The PRs build on top of each other. |
Just complete the 2nd attempt to submit the stuff. |
Use environment variable to select between the new and the old algorithm: |
You create a PullRequest to a specific branch of yours. If you need to fix stuff in the current commit: if you need edit something multiple git commit back: You can then write edit or pick or merge infront of the commit, and it will dump you to that point in the history. All of this is reflected in Important: If you edit your git history you might have to force push to the remote (replacing your current commits with the new ids) |
Thank you very much, @lordfolken ! |
I believe there is a mistake in your reasoning. You look at change in direction of track to determine quality of circle. You assume that this should be a constant. But track is Heading plus Wind. And indeed change in heading when flying nice circles is constant but that does not imply that change in track is constant just like your ground speed changes during a circle due to wind also the change in angle track changes. (Unless you do account for that somewhere and i missed it) |
I'm aware of this. The changes should be small, not 0. And it works as long as wind_speed is sufficiently low. That's why I wrote "wind_speed < TAS/3" . That's what I confirm in my replays. |
So you have
with quality_metric equal to (max_d_alpha - avg_d_alpha)/avg_d_alpha The flaw with this metric is that regardless of how good you fly this metric becomes worse with increasing wind speeds. Whereas the need for good calculation (i would say) increases with stronger winds. At wind_speed = TAS/2 this "quality_metric" becomes 1. Your 0.7 value is reached around 40%. So someone thermaling at 80km/h cant measure winds larger than 32km/h. So I think everyone can agree that this quality metric has not much to do with how good your circle is. Again feel free to correct me if i miss understand the code, i must admit i don't fully know where or how the quality is used. |
You can calculate the quality metric on paper using geometry and trigonometry, But that doesn't take into account what happens inside the GPS receiver. We discussed that earlier. The quality number which is fed into Store has 6 distinct levels: 0 - 5. I translate the "roundness" of the circle (circle_quality_metric) and the fit to the cosine curve (min_fit_metric) into these 6 level. I have to admit, there is no elaborate theory behind that. And there should be more experiments to validate or improve that. Food for thought! |
What i currently did is just straigth up calculate/ simulate what the formula would give (input heading and airspeed but not use airspeed as data). Way more time efficient than replaying flight logs, and easier than working out the equations delta_angle_track is not that nice of a formula :D . Plus can actualy check if the resulting wind is equal to the input wind. Plus you can input whatever error you want to check on the data noise on airspeed noise on gps position etc and evaluate exaclty how the calculation changes based on that. And currently i must say the formula you used for the magnitude of wind speed seems to be quite good actualy. And i think much better than the current methode (have not tested current methode). Btw did you look into just fitting everthing to the cosine now you just get angle from the cosine fit could also fit magnitude. But having a qualty metric that becomes worse just because wind gets stronger (or flight speed goes down) is not a good design. Espacily since the reverse is true for example if you have random variation on air speed the mistake on calculated wind goes down as wind increases. I understand how you calculate the 6 distinct levels. The part that i do not know is what you use the level for. Like if it just for some weighted averaging of multiple circles it might not matter as every turn will have the same bad quality if wind is high. But it also looks like you just dont do the calculation if it is in the bad qualty. And note the values given before are for perfect circle with no noise on the angle. Having some small variation like 10% noise on d heading is like adding 0.1 to that number. But yeah purely the calculation for the magnitude and direction do seem to be quite good. |
Do you have a testbench ready to use? That was one of the next things on my to-do-list and would be happy to use yours if you want to share. If nothing remains from my experiments, I think at least the method to calculate the magnitude of wind speed should go into CirclingWind.cpp . It is indeed much better. In fact, it is good enough so that an additional fitting loop will probably not improve the result (beyond the noise level). BTW: look at CirclingWind2.cpp line 223. There is the TO DO note on that subject. |
Some thoughts on realistic scenarios: |
I just have some matlab script actualy :D just cuz i was to lazy to work out the equations past d_angle_track which already had way to many sines and cosines in it. And initially that was what i wanted to check the effect on d_angle_track and whether or not this is constant. And like i said its not. So i don't have a test bench setup like you discribe. Just looking at the interesting mathematical problem, my c++ and github skils are quit limited actually. After i got d_angle_track i looked at the formula you used to calculate the wind speed. And indeed fitting a cosine to get the amplitude does not realy improve upon it. Where i think it might out perform is when the sampling rate is not constant and not uniform over the circle lets say in one half of the circle the reception is worse and you miss 50% of the gps fixes.
Yes this i can (but i assume you meant to swap TAS and wind speed?) do from what i have tested up to now i would say if that it is quit good if windspeed is larger than TAS/10 . Below that random noise on the speed or gps fix or turn rate gives really large error on wind speed. above that +-5% error on any or all parameters keeps the error within +-10% and will average out over multiple circles. But below measured wind seems to always be larger than the actual wind. This is also where fitting a cosine out performs the formula. So in using the formula their seems to be an over estimation of windspeed at low windspeeds with noisy data. When fitting cosine this is not the case and the error is more centered around the correct value so will average to correct wind speed. Don't know how hard it is to find best fit in c++ have to fit 3 parameters in the cosinefunction. So for now i mainly looked at just adding random noise to the data not really at conscious decision of pilot to move the center. That is something i still want to do, that is also the part that should be attempted to filter out. I hope this explanation already gave some extra insight. |
"you miss 50% of the gps fixes" that's very unlikely in any scenario. So the sampling rate is constant at 1 per sec. |
No i just looked at the math behind it. So i did not actualy check your implemantation. So if we both notice that i am pretty sure it is in the formula used, but also don't know yet why. But the error is quite "constant" don't know how to say. If i sweep wind speed from 0/TAS to 0.5/TAS the calculated wind at low speeds converges to a value scaling with noise on the data +-5% noise wind/TAS converges to 0.05, +-10% noise it converges to 0.1. And it looks to come from noise on the speed so either pilot not flying cst speed or noise due to gps data. Noise on the angle of heading does not influence wind at low speed so pilot not having cost turn rate.
Yeah i noticed in your code that you don't seem to look at time between "samples" as you call it and thus assume it to be the same between all of them. But is it though? In real cases? I am looking maybe more at the worst case scenarios but if you have perfect 1sec sampling rate and fly nice looking circles any algorithm will give good results.
What i meant was 50% in half of the circle so 25% in total but even if it is less than that. Jus having a non constant sampling rate over the circle will give error in the averaging if you have your cosine and you have more data points on the positive part of the cosine than on the negative side the average will be off. In my experience its not unlikely that gps reception is not equal good across the full 360° turn depending on your gps reciever position. Just pointing out potential pitfalls of the method. |
There is/was a mistake in the code. And I fixed it. I'll validate a bit more and then push, maybe later today. Line 153 checks the avg time between the samples. But you are right, I need to check if that changes too much between samples. So far I came to the conclusion the algorithm works for any step width as long as it's constant over the circle (and not to far apart). Agree? |
A related question: what if there are 2 or more GPS receivers feeding into XCSoar? Any wind algorithm will most likely produces bogus numbers! |
I do know whats going on at low wind speeds, you take the average of absolute value of noise and than multiply by 1.5708. So with zero or low wind any variation in speed will contribute a positive effect to the wind. My looking at a fitted cosine would give negative wind speed half of the time (which i now realise is not physicly meaningfull)
Yes 10 samples over the circle seems to be sufficient. But i only checked the formula for speed for now.
First device in the list that provides info will be used so if device B and C both give gps only gps of B will be used. |
Here is the essence of the fix:
The push will follow later. |
What's your opinion on w_x = mean(v_x), w_y = mean(v_y). I know you said before that you don't believe that but it is in fact true. You now take two averages one of speed to get offset and then one of abs(speed - offset) and that just gives the strength. |
Consider this: average of angle == 180° if it's a full circle. No matter what. |
average of angle does not matter. The reason w_x = mean(v_x), w_y = mean(v_y) works is because overtime you drift in the direction of the wind. w_y/w_x is tangens of the direction of the wind. I can write down a proof as well if you like? To show this to be true for full circle. Based on your answer i assume that once i convince you of the math you'd be down for this approche? |
What exactly do you call "mean()" ?? Average, or Median, or what? "w_y/w_x is tangens" is true, but only if w_y and w_x are orthogonal. Hence w_y and w_x must be vectors, not scalars. Average is a scalar, not a vector. Good luck if you want to deliver a proof. I'll be curious to see that. |
ok here it is
note1: unlike alpha, beta does not have a constant change we can thus not say avg(gx) = g as average over time is not same as average over beta, and g is also not constant. So don't be confused by that. note2: choice of angles to be wrt x-axes will not change result of proof just the expressions of the ax, ay, gx and gy etc note3: assumption of cst airspeed and turn rate are the basis of any circling wind algorithm including the current implementation and your proposal, error on these assumptions is what we have been discussing. I hope this clears up any confusion in notation as well. And that every step is clear. But happy to clarify further if needed. |
a = g + w You can multiply vec * scalar. avg(acos(alpha) + wx) = aavg(cos(alpha)) + wx Your calculation of avg(gx) and avg(gyx) are wrong. It should be a * x. Sorry, but your proof doesn't hold. |
this comes down to how one defines w i guess has no impact on proof just sub w for -w
add which point do i do this? cus i don't
clearly a typo lets not get confused by that shall we.
What the hack is x now all of a sudden? You claim a typo invalidates my proof but i should know what a undefined variable x is?
at what point please enlighten me cuz all you say is it is wrong without proving it is wrong and saying I add scalers to vectors? Please don't dismiss an idea cuz your to stubborn to admit a mistake. average of a sum is sum of the averages and average of a cst times something is that cst times the average of that something if you are gone claim that's wrong please proof so i would like to see that one. |
And unlike you i have already tryed it and it does give the wind speed so maybe give it a try before holding on to your believes I proved you wrong before about change in angle track being constant. So sorry if I have more faith in my math skills than yours. |
and its plus for all i care if my airspeed is 100km/h and their is a wind of 20 km/h in the direction i am flying my ground speed will be 120km/h and not 80
and who is violating vector operations here? not me thats for sure cuz i defined a, g, and w as bein a scalar of magnitude of the vector. So what you say not even correct anyways. |
And you say avg() is a scalar, if i want to take the average of a vector i take the average of a vector which will still be a vector. But besides the point of the proof as all variables used in the equations are scalars. |
@kobedegeest You're calling me stubborn, etc. I don't take that! |
etc? that's realy the only thing i called you. And in my defense you asked for a proof and dismissed it without disproving it. And don't stop a good idea just cuz one person challenged the idea. Anyway here are some examples compairing current implemantation your proposal and what i just asked you if you had or would consider. Just to give an idea noise is +-5%. and if you don't want any feedback fine but don't stop with something you want to do because some random guy. Was just trying to help. |
Why don't you guys plan a session together via some telefconferencing tool and start charting here on how the current or a new algorithm could be implemented. |
Thanks @lordfolken for chiming in! |
@lordfolken : how can I proceed? After extensive tests I’m now happy with the new CirclingWind algorithm. I have tested:
The bottom line: If you are interested I would like to share and discuss the results of the replays in a teleconference. Just let me know. On a related topic: running both Circling and ZigZag wind calculations simultaneously doesn’t seem to be a good idea. There is one gliding-average unit which is fed by either Circling or ZigZag depending on the flight phase. But these 2 calculations’ results are different since they measure different winds: one measures the speed at which the thermal moves the other measures the speed at which the air in between thermals is moving. The first is usually slower compared to the second. Hence, the gliding-average unit’s input switches back and forth between “different” winds. The result is a mix of “apples and oranges”. We should rethink this. For me I draw the conclusion that I will not switch on both Circling and ZigZag at the same time. |
Here is some insight related to the quality metrics discussion under #1391 . I copied some of the xcsoar.log files to a DropBox: |
How come QM can be negative? So QM can be -1 and still give Q=5. Also i would be happy to provide you with additional flight logs if that might help testing (no airspeed though). |
Good catch! |
First bring the PR up to shape. No codacy or other issues. |
Will do. Can you give me a hint how to get rid of issues like "struct/class member 'xxx' is never used" in hpp files? |
There are 6 Codacy issues which I cannot address:
@lordfolken what next? |
I am also interested in this topic, but for a different project. It is true that you don't need this algorithm when there is barometric altitude, heading and airspeed available. If you have all that, you can make the corrections for the TAS and just solve a triangle. If you lack one of those, then you still might want to fall back on circling however, and even try to enrich the algorithm with whatever data that is still available. |
@GuillermoHazebrouck thanks for the feedback! |
Take a look at my repositories for the other project... I won't mention it here or Max will censure my comments accusing me of unethical practices (yes, even when being also open source). |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
XCSoar version
7.42
What should XCSoar do differently, what functionality should be added?
The current implementation of the circling wind calculation has some room for improvement. The comments in src/Computer/Wind/CirclingWind.cpp suggest this already. For instance, it assumes “the pilot flies in perfect circles” and “with constant airspeed”. Also, the calculation of the wind bearing can be improved.
What are you trying to do, what is the use case for the suggestion?
I have a prototype running which implements the following:
it uses changes in turn rate to validate the assumption of perfect circles.
it uses true airspeed to compensate for changes.
it uses an iterative fitting to determine the bearing of the wind.
to evaluate the level of perfection of the circle, it uses the track information from the GPS. This works reasonably well as long as the wind speed is small enough compared to TAS (maybe 1/3). GPS receivers are black boxes wrt their ability to cope with changes in track and ground speed: how quickly will the values in the GPRMC sentence follow the real movements of the ship? However, future implementation may use turn rate information from gyros of simple/inexpensive IMUs. That change will make sense as soon as IMUs have a better support in XCSoar and are more widely available.
my assumption is that airspeed information is available in many installations. So it uses ground_speed – airspeed instead of just ground_speed from the GPS reciever. However, the prototype works even if TAS is not available (or derived). In that case it lacks that compensation.
in an ideal case, the speed oscillates in a sine curve. So fitting the actual speed values of a given circle to a sine curve usually provides better results for the wind direction.
I’m running the prototype in Replay mode using files from the “NMEA logger” which I usually capture during my flights. So far results look promising.
How shall I proceed? Shall I post a PR? I would like to get your feedback, even though the implementation is far from final.
The text was updated successfully, but these errors were encountered: