Freesteel Blog » The Winds In Merthyr Blow Mainly Across the Grain

The Winds In Merthyr Blow Mainly Across the Grain

Monday, May 9th, 2016 at 4:49 pm Written by:

I made an interesting mistake during my flight over Merthyr which began in very rough air. My radio was charged and working, which meant I had an external source of misinformation to confuse me, that I did not have on my excellent flight from Builth Wells three days before.

One of the things I thought I overheard was that the thermals were tracking southeast in spite of the wind on the hill coming from due west. This suspect information lodged into my brain, so that when I finally got a good thermal I began tracking to the SE instead of due East with the wind, and fell out of it, and landed an embarrassing 5km away to the SE on a smooth bit of grassland feeling rather unhappy with myself.

Still, nothing important broken, except my ego. The data came out good, with the following temperature track vs altitude, where horizontal lines are degC from 0, vertical lines are 100m (topping at 1200m on the right), and green data points are during the climb, with red for the descent.

merthyralttmp

Potentially this means in such a strong thermal the temperature was one degC higher than the surrounding air, with brief drops in the readings in the moments where I fell out of the thermal. The climb rate up to 1000m was between 2 and 4m/s, but above that it became less than 1m/s — coinciding with period the temperature differential had decreased.

The thermal temperature is going to be all mixed up with rising air and surrounding air as I go in and out of the core, but it seems to have a pretty constant trend. The non-thermal air (encountered when I utterly lost the thermal) seems to be completely constant between 1000m and 1100m, which would account for the decline in thermal strength (according to theory) and at 1050m only differed by 0.3degrees.

Unfortunately, with only one thermal in the flight to derive the data from, the pattern is not definite. I think I should do something more serious with the temperature sensor, like fit a cowl over it to protect it from sunlight while directing the full flow of the wind across the device. It cannot take more than seconds to equalize. I ought to revisit my vacuum cleaner and hairdrier experiments.

The average drift direction (taken by averaging the speed over the ground within each degree heading of the compass derived from the GPS velocity record) for the whole flight was 7.4m/s in the heading 92degrees. (Compass heading zero is up, while conventional polar coordinates point the zero along the X-axis.)
merthyrwinddrift

Now, I began this day with the theory that the XCSoar estimate of wind speed and direction was self-reinforcing, so that by circling and tracking myself gradually in southeasterly direction, the software would interpret my circles as tracking the wind in that direction, and report this erroneous observation that I created right back to me. So I was going to spend the day picking apart the calculations made in the CirclingWind::CalcWind() function which attempts to detect full circles and fit a cycloid shape to it.

But then I decided to check out what this drift actually was calculated to be at each altitude zone.

The code I used looks like this:

gcont = rl.postrack.GetPath3()[0]  # (t, posXYZ)
vcont = rl.postrack.GetVelPath3(True)[0]  # (t, velocity)
kvcont = ziptvs(vcont, [(t,p.z)  for t, p in gcont  if t0<t<t1])
zmin, zmax = min(z  for t, v, z in kvcont), max(z  for t, v, z in kvcont)
s, dz = 40, 50  # 40 overlapping zsample layers each with with 100m
zs = [ Along(lam, zmin, zmax)   for lam in (i/s  for i in range(s+1)) ]
zdirs = [ ]
for zm in zs:
    lvcont = [(t,v)  for t,v,z in kvcont  if zm-dz<z<zm+dz]
    deghistrad = rl.postrack.GetDegHistRad(lvcont)
    p, sd = rl.postrack.CalcPlotAverageDrift(deghistrad, None)
    zdirs.append((zm, p, sd))
sendactivity(contours=[[(zm*gfac, sd)  for zm, p, sd in zdirs]], materialnumber=2)  # plot standard deviation
sendactivity(contours=[[(zm*gfac, 0), (zm*gfac+p[0], p[1])]  for zm, p, sd in zdirs], materialnumber=3)  # plot wind vectors

Which created the following plot, with the vertical bars at 100m intervals, and the rightmost at 1200m. (The red line is the standard deviation error.)
merthyrwinddriftalt
This does show a SE drift from above the 1050m mark, which is the same place that my rate of climb decreased.

But this could still be pilot error (following my mistake that things would be going to the south, and so drifting beyond the end of the thermal and losing the climb rate), but for the air temperature on the way down behaving irregularly at that altitude. So the effect may be real and due to a shear layer. I didn’t go very far, so this dataset is not effected by the propensity to fly fast and downwind on the glide out of the thermal. I could endlessly play with this data and filter out everything wasn’t circling, but I need to move on.

The deep and bad-landing valleys near Merthyr are oriented north-south, so you would expect that a high altitude wind from the NW across them would sort of get funneled along them to become a wind blowing from the north low down or within them, but this was not the pattern.

Given what it seemed to have been happening, the result of dropping out of the thermal after following it SE meant I was now to the cross-wind of it rather than downwind of it. XCSoar stores its wind estimates with altitude and time (as well as an estimate of the quality/reliability of the guestimate) and then computes a weighted average that takes account of altitude, like so:

P2 result(0,0); 
float sumquality = 0.0; 
for (int i = 0; i < measurements.size(); i++) {
    WindMeasurement& m = measurements[i];

    float altdiff = fabs(alt - m.altitude) /1000;
    int a_quality = uround(((2.0/(Square(altdiff) + 1.0)) - 1.)*100);

    float timediff = (now - m.time)/3600.0;
    int t_quality = uround(0.0025 * (1.0 - timediff)/(Square(timediff) + k)*200);
    float q_quality = m.quality*100; 

    int quality = q_quality * a_quality * t_quality;
    result += m.windvector*quality;
    sumquality += quality
}
return result/sumquality; 

A sudden replot of the snail trail at the lower altitudes would put me well outside of the circling zone, and caused me to assume that my lack of attention and incompetence was what put me so far off course (rather than a recalculated cross-wind), leading to the sort of negativity and loss of confidence that puts you on the ground in no time.

But that's all in the mind. Meanwhile, those hard-coded factors in the XCSoar source code above are obviously first guesses -- like many of the ones in my professional CNC code. There is no system in place to optimize these fixed constants by replaying real or simulated data through the algorithms to see how quickly the calculations settle down to the "right" answer.

This is a common problem in geometric computation. The algorithms you write require these magic fixed values to make them work (which you have to make up on the spot as you write the algorithm), but you never quite get round to putting in the systems to review them. You can tell these are first guesses because they are suspiciously round numbers. (Most of my numbers in the CNC code were variations of 0.02mm.) And once the code is in use and working sort of okay (but almost certainly sub-optimally) with no one complaining, you do not dare change them because the most likely thing to happen is it will break something. So you leave it as it is for the rest of time.

Still, it continues to show that local wind direction is the really, REALLY important derived information, and it's something I ought to get working on.

I tried this plot new plot drift at altitude feature on some other flights:

Mam tor, top altitude 900m:
mamwinddriftalt

Wrynose, top altitude 700m
wrynosewinddriftalt

Greifenburg, top altitude 3100m
greifenburgwinddriftalt

Llangollen, top altitude 1600m
llangollenwinddriftalt

Long Mynd, top altitude 1600m
myndwinddriftalt

Due to the power of open source development I can source some valuable information in the xcsoar forum:

Compass algorithm
For aircraft fitted with intelligent variometers and digital compasses connected to XCSoar, a wind estimation algorithm making use of magnetic heading and airspeed is being developed. This provides another method of updating the wind estimate during cruise and does not require zig-zag manoeuvres

My big question is whether it can be done using the BNO055 absolute orientation sensor. It needs that and a couple of pitot air sensors or, even better, a sonic anemometer on a long nose pole to take account of all the side slipping.

Leave a comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <blockquote cite=""> <code> <em> <strong>