Author Archives: paynterf

Hearing Aid AGC Testing

Posted 11 March 2023,

I have been wearing hearing aids for quite some time, compliments of a lifetime around airplanes, long before hearing protection became a thing. I recently got a set of Jabra ‘Enhance 200’ aids via direct order, and I like them very much, EXCEPT I have noticed that my perceived hearing acuity seems to vary quite distinctly over a period of a minute or two. I first noticed this when I would turn on a water tap while washing dishes or preparing to take a shower. I would turn on the tap, and then 20-30 sec later, the perceived sound of the water coming out of the tap would increase significantly – even though the water flow rate had not changed. Later, in a social setting (bridge club), I will experience significantly lower and higher perceived speech volumes – very frustrating! I hypothesized that the aids employ an AGC (Automatic Gain Control) of some sort that is getting triggered by an initial loud noise which reduces the gain (and my perceived noise/speech level), and then 10-50sec later the gain would go back up again.

Just recently though, another thought popped into my head – what if the perceived volume changes aren’t due to some property of the hearing aids, but instead are a physiological feature of my current hearing/understanding processes? Hmm, I know I have some issues with my Eustachian tubes blocking and unblocking, and I also know that on occasion the volume changes are correlated with a ‘blocked Eustachian tube’ feeling, so this isn’t a completely crazy hypothesis.

So, how to distinguish ‘meat space’ audio response from hearing aid responses? I decided I could set up an experiment where I could expose one or both of my hearing aids to a volume ‘step function’ and monitor the output for AGC-like responses (an initial rapid drop in output, followed by an eventual return to normal). Something like the following block diagram:

The idea is that the Teensy would produce an audio output in the human audible range that can be controlled for amplitude and duration. The audio would be presented to the hearing aid, and the amplified output of the hearing aid would then be captured with an external microphone connected back to the Teensy. A plot of captured amplitude vs time, with a ‘step function’ input should indicate if the hearing aid is employing an AGC-like response function.

After some fumbling around and searching through the posts on the Teensy forum, I ran across this post describing how to create a simple 440Hz sinewave output from the DAC pin. The original poster was having problems, but after Paul Stoffregen added the ‘magic sauce’ (adding the ‘AudioMemory(10);’) line, everything worked fine. When I copy/pasted the posters code and added the line, I got the nice 440Hz waveform shown below – yay!!

The next step is to hook the DAC output to a small speaker, so I can drive the hearing aid. When I tried hooking a speaker directly to the DAC output, it clipped badly – oops! Fortunately, I remembered that long ago I had purchased a ‘prop shield’ for the Teensy LC/3.1/3.2 controllers, and this contains a 2W audio amp whose input connects directly to the DAC output – nice! So I dug around and found the part, soldered on headers, and plugged it on top of the Teensy.

15 March 2024 Update:

So, yesterday Space X launched IFT3 (Integrated Flight Test #3), consisting of ‘Super-Heavy Booster 10’ and ‘Ship 28’. The combination was the largest, most powerful rocket ever launched, by a fair margin. The upper stage (Starship 28) flew from Boca Chica Texas to the Indian Ocean near Australia in about 49 minutes – wow! At that point, the upper stage was the largest object ever launched into space in all history – Wow Again!

OK, back to reality. I managed to get the prop shield working – after the usual number of false-starts and errors. One ‘gotcha’ was that I hadn’t realized the 2W audio amp was a Class-C type, which means it switches on and off at a very high frequency (100KHz or so) – way above human hearing range, and the audio AM modulates that signal. When it is connected to a speaker or other audio transducer, it acts like a low-pass filter and all that comes out is the audio; this is a really neat trick, but it means that the audio amp output signal is basically impossible to look at directly with a scope – oops. So, I got a pair of MEMS microphone breakout boards from Sparkfun and used the microphone to turn the speaker audio back into an electrical signal that I could view with the scope. Here’s the setup:

Teensy ‘propshield’ mounted on Teensy 3.2. Note Sparkfun MEMS microphone suspended over speaker

This worked great, and I was able to verify that the speaker audio output was a reasonable replica of what the T3.2 DAC was putting out.

The next step was to feed the MEMS mic output back into a Teensy 3.2 analog input so I could measure the signal amplitude (A4 in the above block diagram). Then I would modify the Teensy program to deliver a 1-2 sec ‘pulse’ of high amplitude audio to the hearing aid, followed by a constant low-amplitude signal. The measured amplitude of the hearing aid output (as received by the MEMS mic) would be monitored to see if the hearing aid exhibited AGC-like behavior.

However, as I started setting this up, I realized I would have to solder yet another flying lead to the top of the prop shield, as the Teensy 3.2 pins were no longer accessible directly. So I decided to fix this problem by adding female headers to the top side of the prop shield to allow access to all Teensy pins. The result is shown in the ‘before/after’ photos below:

19 March 2024 Update:

I soon discovered that my plan for routing the MEMS mic back to a Teensy analog input and just averaging the results over time wasn’t going to work, as a glance at the MEMS output to the Teensy (shown below) would make quite obvious:

MEMS output with 1000Hz sinewave input to speaker. Average value is 3.3V/2

The average value for this signal is just the DC offset, which will always be the same. The only thing that varies is the amplitude – not the average value – oops!

OK, so the obvious work-around to this problem would be to put a half-wave or full-wave rectifier circuit between the MEMS output and the Teensy so the analog input could measure the half- or full-wave amplitude instead of the average. But, I really didn’t want to add any more circuitry, and besides I have this entire 72MHz computer at my beck and call – surely I can get it to emulate a half- or full-wave rectifier?

So, after the usual number of screwups, I got this working reasonably well – at least enough for a ‘proof-of-concept. The basic idea is to take analog input readings as fast as possible, and use the resulting values to compute the average value (in A/D units – not voltage), and then take the absolute value of the difference between each measurement and the average value – this essentially implements a full wave rectifier circuit in software.

The following data and Excel plot shows the results for the waveform shown above:

The above data was collected by sampling the input at about 20KHz (50 Usec). As can be seen from the above, the average value is a constant 511.64 (out of a zero to 1023 scale), and the actual measured values varied from about 264 to about 755. Here are Excel plots of both the measured input and the calculated amplitude:

So it looks like this idea will work. For the intended application (determining if my hearing aids exhibit AGC-like behavior, I can perform a running average of the full-wave rectified signal using something like a 0.1 Sec interval (2000 samples). That should accurately capture the onset and release of the 1-sec HIGH tone, and have plenty of resolution to capture any AGC-like sensitivity increase over a longer time – say 30 Sec or so.

Here’s the code that produced the above outputs:

I made another run with the A/D resolution set to 12 bits to see if it made any appreciable difference. As can be seen in the following Excel plot – it didn’t:

Here’s another plot showing the microphone output, but this time with the DAC sinewave output amplitude reduced to the point where the microphone output isn’t large enough to clip.

Microphone Input to A/D Converter

In the reduced sinewave amplitude plot above, the ‘Meas’ plot is still centered about the halfway mark in the 12-bit range of values, while the average value of the ‘Amp’ plot has been reduced from about 1800 to about 200.

So, now that I know that the DAC-Speaker-Microphone-ADC loop works, I need to extend it to record amplitude values over an extended period – at least 30 sec, and more like a minute or more.

I modified my control program to create a 1-second ‘burst’ of a HIGH amplitude sinewave, followed by an infinitely long period of a LOW amplitude sinewave. The HIGH amplitude was chosen to fully clip the microphone output, and the LOW amplitude was chosen to be well above the noise floor, but still very small compared to the HIGH amplitude signal. Here are O’scope photos of both the HIGH & LOW signals:

Here is the output from the program (the LOW amplitude output was manually terminated after a few seconds):

31 March 2024 Update:

After getting all of the above working, I then installed one of my Jabra ‘Enhance 200’ aides in between the speaker and the microphone, as shown in the photos below:

With the aid installed, I got the following microphone output using my ‘burst + long-term low level audio’ setup.

Even though the Jabra aid did NOT exhibit anything like the AGC behavior I expected, there *was* a sort of cyclical response with the Jabra aid that wasn’t there without the aid in the middle. This cyclical behavior repeats about once every five seconds and *could* be some sort of AGC-like behavior – just not the one I was expecting.

Stay tuned,

Frank

Convert Condor Task Briefing Custom Waypoint Description Blocks to XCSoar-compatible .CUP Format ‘Additional Waypoints’ file

Posted 23 March 2024

After a multi-year hiatus, I recently started flying contests again in the Condor Soaring Simulator. As sort of a side project, I have also been working with the XCSoar glider navigation program, to see if I could use XCSoar to help navigate AAT/TAT tasks in Condor (Condor doesn’t support AAT/TAT tasks natively with the in-sim PDA).

After using XCSoar for a while, I became frustrated with XCSoar’s inability to define ‘custom’ turnpoints based on LAT/LON coordinates, which are used quite frequently in Condor contest tasks. After a long-fought and ultimately unsuccessful battle with XCSoar’s source code to see if I could modify the program to facilitate this, I admitted defeat and decided to try another way to skin this cat. XCSoar will accept an ‘Additional Waypoints’ file, so I decided to see if I could create a program to convert the ‘new TP’ blocks in the Condor ‘Task Briefing’ description to XCSoar-compatile .CUP file waypoint lines, which could then be loaded into XCSoar for selection as task waypoints.

Here is the .CUP file format defintion page from the SeeYou (naviter) program website:

The above description is NOT very easy to read. It is full of errors, so some imagination is required to make sense of it. The ‘hardpoints’ in the description are as follows:

  • Latitude strings are exactly 9 characters long. Longitude strings are exactly 10 characters long.
  • In latitude strings, the decimal point is exactly the 5th character (Char4) . In longitude strings, the decimal point is exactly the 6th character (Char5).
  • Both latitude and longitude strings apparently must be zero-padded as necessary to make the string character counts work out. For instance, in the longitude example the ‘degree’ value of ‘014’ must be exactly three characters.

Example Run:

Here’s a recent task briefing from Condor-Club:

As can be seen in the above screengrab, TP2-TP2 are all ‘custom’ turnpoints defined only by Lat/Lon coordinates. Manually adding these to a .CUP formatted file for use in XCSoar would be essentially impossible, given that the turnpoint coordinates only become visible 15 minutes before server start.

To start the process, the turnpoint blocks from the above briefing were copy/pasted one at a time into a text document (I use NotePad++), as follows (note that I manually changed the name of the last turnpoint from ‘Finish’ to TP 6, as my Python script currently only looks for ‘Start’ and ‘TP’ starting strings)

My CondorTPX_to_CupWP.py Python script opens a ‘FileOpen’ dialog where the input file (in this case ‘NewTPs_IN.txt’) can be selected by the user, and a ‘FileSave’ dialog where the output file (in this case ‘NewTPS_OUT.CUP’) can be selected, and then parses through the blocks in the input file, converting them to equivalent .CUP-formatted lines compatible with XCSoar. Here is the console printout from the ‘verbose’ (-v) version of the script:

At the very end of the above printout, the newly-written contents of the output file are read back out again as a verification that the conversion was successful. Here is the actual contents of the ‘NewTPS_OUT.CUP’ file:

This file now has to be transferred to the directory used by XCSoar for waypoints, and then selected in XCSoar (Config->System->Site Files) to load as the ‘More Waypoints’ selection. After this, all the above turnpoints will be available for task construction. Here’s a photo of my Android tablet with the above task turnpoints loaded:

XCSoar task map, using converted task briefing turnpoint blocks
Same task as above, from Condor-Club briefing

It is clear from the above images that the Condor-Club ‘custom’ task turnpoints have been converted properly from text blocks to SeeYou .CUP format waypoint strings, so now I can use XCSoar to navigate Condor tasks with ‘custom’ turnpoints – Yay!

Here’s the Python script I created to do the conversion:

Enjoy!

Frank

Bridgemate II Keypad Membrane Replacement

Posted 22 February 2024

COBA, the Central Ohio Bridge Association, owns a number of Bridgemate II table pads, and lately we have been hearing a number of complaints about having to press buttons harder than normal to get the expected response. After some research, one of our members discovered that we could purchase replacement membranes from Bridgemate for $15 each, so we decided to undertake a membrane replacement program.

Opening up a Bridgemate II

The keyboard cover/upper-half can be removed by disengaging a number of flexible plastic tabs, as shown in the following page from the Bridgemate site:

Opening the case on a Bridgemate II

While this wasn’t quite as trivial as the above description, it wasn’t really all that hard. Most of the difficulty was in trying NOT to break things during the opening process on the first unit. Once that was accomplished (thankfully without breaking anything), I’m sure the rest will go much easier. Here are some photos showing the disassembled Bridgemate II

Visual inspection of this first unit showed everything to be very clean – basically indistinguishable from a brand-new unit. In particular, the key membrane seemed to completely intact, and could be easily manipulated between the ‘pressed’ and the ‘unpressed’ states with just fingertip pressure.

Stay tuned,

Frank

Using VS Code to Debug Linux Makefile Projects

Posted 20 February 2024,

I recently got re-interesting in soaring (glider racing) after a number of years away. As part of this new journey, I became interested in contributing to the development of the XCSoar glider racing navigation software. I had contributed to this program some years ago in a very minor way, and thought maybe now that I’m retired and have plenty of time to waste (NOT!!), I could maybe contribute in a more meaningful way.

In any case, XCSoar development is done in Linux (Specifically in Debian Linux, but that’s another story), so I started thinking about creating a development environment on a Debian Linux box. I had an old Dell Precision M6700 ‘desktop replacement’ laptop that I hadn’t turned on for years, so I dug it out, installed Linux (Ubuntu first, then Debian), and with the help of Ronald Niederhagen (see this post), I was able to clone the XCSoar repo from Github and built both the Linux and Android versions.

However, I still needed to find a way to ‘break into’ the code, and to do that I was going to need a way of running the program under debug control. I have done this sort of thing for decades on the Windows world, but not so much in Linux, so I was sort of starting from scratch. After a LOT of research, I found that Microsoft had a free Linux IDE called VS Code – sort of a lightweight version of Visual Studio aimed at the Linux and IOS world.

So, I installed VS Code on my Linux box and started the ‘lets learn yet another coding IDE’ dance, again starting with a lot of Google searches, running tutorials, etc etc. After creating some basic ‘hello world’ programs using VS code, I started thinking about how to use VS Code on the XCSoar project, comprised of thousands of source files and a Makefile almost three hundred lines long. I knew just enough about Makefiles to type ‘make’ or ‘make all’, so there was a steep learning curve ahead to use VSCode for debugging.

After yet another round of Google searches and forum posts, I found a relevant tutorial on the ‘HackerNoon’ website. the HackerNoon tutorial seems to be aimed at Windows users (Linux doesn’t use extensions to denote executable files), but I was able to work my way through and translate as appropriate. I suggest you open the HackerNoon tutorial in one window, and this ‘translation’ in another.

Original:

Translation for Linux:

Download & Install VS Code: See this link. Everything else should already be available as part of any modern Linux distro (I’m using Debian 12 – ‘bookworm’).

main.cpp: (same as original – no translation required)

Makefile (Original):

Makefile (Translation for Linux):

Run the ‘main.exe’ make target, then run the executable to make sure everything works (Original):

Translation for Linux:

I placed ‘mymain.cpp’ and ‘Makefile’ in my home directory tree as shown below:

so to test the Makefile and the executable, I did the following:

This test confirms that the source code compiles correctly, that the Makefile is correct, and the output from the compiled program is as expected – yay!

Setting up VSCode debugger:

At this point the HackerNoon tutorial and my experience parted ways. I could get the ‘Run and Debug’ side panel open, and I could open ‘mymain.cpp’ in the VSCode editor window, but I couldn’t find anything that suggested it could “create a launch.json file”. I tried to send a comment to the author, but comments weren’t enabled for some reason (and yes, I did register and log in). I suspect that the disparity between the HackerNoon example and my VSCode reality is due to changes in VSCode after the HackerNoon tutorial was created. Which is why I absolutely hate posts like this that aren’t dated in any way shape or form. Because of this, it is impossible to determine if changes like I encountered are due to mistakes on the part of the author, or just changes in the underlying software being demonstrated.

So, I was left to randomly click on things until, by some miracle, the ‘launch.json’ file was created and appeared in the VSCode edit window. Later I went back and tried to re-create the miracle and I sort of figured it out; with the ‘mymain.cpp’ file open in the editor, click on the ‘gear’ icon (upper right as shown in the screenshot below):

And select ‘(gdb) Launch’ from the menu items presented. This will create a ‘launch.json’ file and open it in the editor, as shown below:

launch.json file created by VSCode

At this point we can reconnect to the ‘HackerNoon’ tutorial and copy/paste the launch.json contents from the tutorial to the newly-created launch.json file in VSCode, as shown below

launch.json after copy/pasting example code from HackerNoon site

Here’s the ‘launch.json’ file from HackerNoon:

And here’s the same file, after translating it for Linux instead of Windows:

The next step is to create a ‘tasks.json’ file using the ‘New File’ (ALT-Ctrl-N) in VSCode. This brings up a dialog forcing the user to specify the folder into which the new file will be placed, which seemed a bit strange for me, but what do I know. Put the new file in the same (hidden) .vscode folder as the companion ‘launch.json’. In my setup this was layed out as shown below:

Here’s the original ‘tasks.json’:

And here’s the same file after translation for Linux:

The above three files (mymain.cpp, launch.json and tasks.json) form a complete set (a ‘configuration?) that enables VSCode to compile and then run – under debug control – a .cpp file. Here’s a short video showing two complete compile/run cycles:

Video showing VSCode compiling/running/debugging using a Linux Makefile

At this point is is clear that the combination of VSCode, in conjunction with appropriately constructed ‘Makefile’, ‘launch.json’ and ‘tasks.json’ files is capable of debugging a Linux-base C++ program. This means that – at least in theory – I should be able to aim VSCode at the humungous Makefile associated with the equally humungous XCSoar program and step through the source code under debug control – yeeehah!

23 February 2024 Update:

Well, the theory (about being able to run XCSoar under debug control) has now been validated. I was able to run XCSoar using the following launch & tasks.json file contents

Launch.json:

Tasks.json:

And here is a short video showing the action:

So now I’m set; I can run XCSoar under debug control, and I should be able to poke around and hopefully make some changes (or at least understand some of the magic tricks). On thing I’ve already found is that (depending on where the breakpoints are) XCSoar can grab the mouse focus (not the keyboad, thankfully), so even though the mouse cursor can move around the screen outside the XCSoar window, all mouse clicks go to XCSoar. Fortunately I found that keyboard inputs still go to VSCode, so I can still (with some difficulty) get around OK.

Trying my Hand at XCSoar Program Development

Long ago and far away, back when I was doing a lot of real-life soaring, I was heavily involved in the development of the ClearNav flight computer/navigator and I’d like to think I made it better than when I first started working with it. Among other things, I helped develop the thermalling assistant in ClearNav, and also helped port that functionality to XCSoar.

Now, many years late, I am no longer doing real-life soaring, but I’m once again starting to fly in virtual soaring races using the Condor2 soaring simulator. As a part of that, I have been attempting to use the XCSoar flight computer/navigation assistant as an external adjunct to the in-sim Condor flight computer. In particular, Condor2’s flight computer has no capability to support AAT/TAT tasks, so using an external PNA (Personal Navigation Assistant) that does support AAT/TAT tasks makes sense. To facilitate this effort, Condor2 can output GPS NMEA sentences to an external device.

I have nice dual-24″ monitor setup at home, so my initial thought was to run Condor2 on one monitor, and the PC version of XC on the other. This actually works, but with a big ‘gotcha’ – when Condor is running, it captures the mouse and keyboard input, and won’t let it go unless you use ‘ALT-TAB’ to switch to another running program. This means that if you wish make an adjustment in XCSoar, you have to ALT-TAB out of Condor2 and into XCSoar, make whatever adjustments, and then ALT-TAB back to Condor2 – more than a little bit messy. In addition, while ‘away’ from Condor2, it is continuing to fly along without pilot input – maybe OK for a flatland task, but definitely bad for one’s (simulated) health in gnarly terrain.

So, my next idea was to buy a cheap Android device and run XCSoar on it, connected to Condor2 on my PC via Bluetooth. I found a really nice PRITOM M10 10 inch tablet with 2 GB RAM, 32 GB internal storage on Amazon for about $50USD, and figured out how to get NMEA data to it using Bluetooth – nice!

Then I constructed a small AAT/TAT task in Condor2’s default Slovenia scenery, loaded the same task into the M10, and flew it multiple times to see if I could figure out how to best use XCSoar to optimize navigation through both defined areas. This worked really well, but I ran into some problems with the XCSoar software. At least in the Android version, the ‘AAT Time’ and ‘AAT Delta Time’ readouts blanked out several times during the tests, rendering XCSoar pretty much useless for AAT/TAT tasks (see this post for all the gory details).

The above experience led me to think about looking through the source code to see if I could find out why these AAT-related values were going missing. Way back in the day I had done this once before when I ported the ClearNav thermalling assistant algorithm to XCSoar, but that time I didn’t know enough about Github repos and pull requests to do it the right way – I had to throw myself on the mercy of the other developers to make it happen. Since I’m now retired and not flying in real-life anymore, I have a bit more time, so I decided to give it a go.

I started by reading though the XCS Developer Manual, where I found that the primary development platform for XCSoar is Linux, and I haven’t played in Linux-land since my days as IT manager at The Ohio State University ElectroScience Lab a couple of decades ago. Nevertheless, I had an old Dell Precision M6700 15″ ‘desktop replacement’ laptop hanging around doing nothing, so I dug it out and installed Ubuntu 12.4 LTS on it. I chose Ubuntu because it was reportedly easier to use by beginners, and known to install OK on my laptop model. Installation was pretty easy, and using the information in the developer’s manual I was able to clone the Github repo, install the required packages, and actually get the default UNIX version of XCSoar compiled and running on my Ubuntu laptop – yay!

With XCSoar running on my laptop, I decided to try running the same AAT/TAT test task with Condor2 GPS NMEA sentences connected to XCSoar on my Linux laptop using VSPE on my windows box to connect Condor2 to a TCP port, and ‘socat’ on the Linux box to create a bridge between TCP and UDP ports. Then in XCSoar I set ‘Device A’ to point to the UDP port created by socat. Amazingly, this all worked! (See this post for the details). With this setup I ran the test AAT, but the ‘AAT Time’ and ‘AAT Delta Time’ values stayed rock-solid through the entire task – yikes!

This result led me to believe that maybe I could just abandon the Android M10 and just use XCSoar on my Linux box to fly AAT tasks. However, when I actually tried this on a Condor2 race, the Linux box version of XCSoar kept dropping GPS inputs – don’t know why.

So, I decided to see if I could compile XCSoar for Android on the Linux box and ‘side-load’ it onto my M10 Android tablet. If this worked, then I could instrument the code on my Linux box, run it on my M10, and maybe figure out why the AAT Time/AAT Delta Time data was getting corrupted. After all, how hard could it be – I had already cloned the source repo and gotten the UNIX target to compile properly? As it turned out – “Pretty Darned Hard!”

I was stumbling around on the XCSoar developer’s forum, trying to figure out why compiling for Android wasn’t working, when Ronald Niederhagen took pity on me and sent me a direct email with some suggestions. The foremost of those was, ‘Install Debian’ and your life will be easier’. Although I had noticed some references to Debian on some of the development steps, I hadn’t paid much attention to it – after all, all Linux installation are all the same, right? Wrong.

So, I went off into a side project for replacing Ubuntu with Debian on my Dell laptop. Once I got that part accomplished, Ronald sent me the following instructions:

The first ‘make’ command above ran successfully, and I was able to launch XCSoar on my Linux Debian laptop with no problem. However, the second ‘make’ command to compile XCSoar for Android failed miserably – ouch!

When I reported this result to Ronald, his reply was:

Ronald’s first sentence — “You are not far from success” was pretty heart-warming. I have done a LOT of programming over a half-century of engineering, and I was well aware how easily projects of this nature can spiral out of control, so ‘hearing’ such encouragement from such an obviously competent source was a life-saver.

Anyway, I ran the command to install the Java jre, confirmed success with the ‘which command, and then re-ran the ‘install-android-tools.sh’ script. This time it completed OK, so then I ran the ‘make -j4 TARGET=ANDROID command. This time it seemed to complete OK, but no corresponding *apk file was generated.

When I reported this to Ronald, he asked me to re-run the compile, but this time redirect both the normal (i.e. stdout) and the error (i.e. stderr) outputs to files and send them to him. OK, so I resurrected (with the help of Google) my 20-year old memories of how to redirect to files in Linux, got the job done, and sent them off to Ronald. In no time at all, Ronald sent back the following:

I had no idea what ‘javac’ was (other than a suspicion it was java-related). When I ran the ‘which’ command on my box it came up blank, so obviously Ronald was on the right track. After a couple more back-and-forths, Ronald said:

I ran the install, and FINALLY I was able to get the XCSoar Android version installed:

With more help from Google, I was finally able to get XCSoar ‘side-loaded’ to the M10. As it turned out, the trick was to copy the *.apk file to my Google Drive site, and then use ‘Drive’ on the M10 to ‘install’ the app. Basically the process is:

  • Copy the *.apk file from my Linux laptop to my Google Drive site
  • Uninstall XCSoar from the M10 by dragging the icon to the trashcan
  • Use ‘Files->Drive’ to access my Google Drive account from the M10
  • Double-click on the *.apk file in Google Drive
  • Select ‘install’ on the resulting dialog.

Here is a short video showing the process:

Installing a fresh Android version of XCSoar on my Android M10 tablet

So now, Thanks to Ronald Niederhagen, I’m all set for XCSoar development. In the meantime, however, the original reason I wanted to get into XCSoar development (disappearing AAT infobox data) seems to have — disappeared. Not to worry though, as I have lately gotten some other ideas for XCSoar ‘improvements’ 😉

A last thought on this subject from a septuagenarian engineer/programmer, I appreciate how much time and effort Ronald put into helping a noob along. Ronald didn’t know me from Adam, and yet he took the time to help. He didn’t know that I’m a 75-year old broke-down engineer, ex-pilot, (ex – everything, for that matter!), and I don’t know anything about him, either. Heck, Ronald could be a 12-year old kid with acne programming in his parents’ basement wearing pajamas, but in this case he was clearly the teacher and I was clearly the student. It’s pretty cool when the internet and free discourse facilitate this kind of international (and maybe intergenerational) collaboration.

Stay Tuned,

Frank

XCSoar Soaring Computer AAT Task Study, Part III

Posted 29 January 2024

This post is the third installment of my continuing attempt to learn how to use the XCSoar soaring flight computer to successfully navigate AAT/TAT tasks. Although I am using the Condor2 soaring flight simulator for this purpose, the results should be perfectly applicable to real-life AAT/TAT task navigation as well.

The experimental setup for this and previous test flights is an Android M10 tablet connected via Bluetooth to my Win10 PC running Condor2. I created a small task in the default Slovenia scenery as shown below:

And I loaded this same scenery and task into XCSoar, and started flying the task

I am using the latest version of XCSoar, compiled from source code on my Linux box and then ‘side-loaded’ to the M10 Android tablet, as shown below

Latest version of XCSoar

In response to some comments regarding an earlier test run, this time I made sure I had the proper glide polar selected for the plane (ASW-28-15) to be flown in Condor. Here’s the polar plot in Condor:

And here is the tabular information for the ASW28-15 polar in XCSoar

Another issue from the last run was that I had not selected a MC value for the flight, just accepting the default value of 1.0. There was some concern that using this value caused XCSoar to use a very low achieved speed value for task completion calculations. For this run, I selected an initial MC value of 5.0 (although I changed it a couple of times during the task in an attempt to determine the effect of the user-selected MC value on task parameters).

The next photo shows the situation just after starting the task.

Just after start

In my last run I noticed the time display was way off – like 7hrs off. So this time I added both ‘local’ and ‘UTC’ info blocks to the bottom of the cruise info set. As can be seen in the above image, the start took place at 12:03 UTC, and the local time is shown as 8:03(pm?). This is clearly wrong. I believe XCSoar is mis-interpreting the time information imbedded in the NMEA stream (or Condor2 isn’t properly converting the time in the NMEA stream from local to UTC). I looked at a representative NMEA ‘GPGGA’ string from Condor2, and it appears Condor is the culprit; I see ‘$gpgga,120235,…’, where the ‘120235’ value is supposed to be UTC, but is clearly local time – oops!

The AAT Time and AAT dt values look reasonable here, although I am suspicious that the dt value is so close to zero. What speed and distance values are being used to produce this result? If the ‘AAT Dtgt’ value (50.4) is used for the distance, and the ‘AATVtgt’ value (60.5mph) is used for speed, the result is 49.98 min, which is very close to the displayed ‘AATdt’ of 3min 48 sec. I checked this again about 3 min into the flight, and this time AATdtgt = 54.6, AATVtgt = 65.5mph ==> 50.01min ETE ==> AATdt of 5.01 min vs the displayed AAT delta of 4.75min.

After about 5 min, I figured out how to bring the Status page up, as shown below:

Status page, about 5 min after start

There are a lot of different values here, but I don’t understand most of them.

  • Assigned task time and Estimated task time – those are understandable and reasonable
  • Remaining time. I think this is strictly the ‘AAT Time’ value, counting down min by min
  • Task distance: probably the same as AATDtgt – the distance around the target points as currently placed.
  • Remaining distance: No clue
  • Speed estimated: No clue
  • Speed average: Probably just what it says – distance-made-good/time-since-start
  • MacCready: Self explanatory
  • AAT range: Shown as -19% here, so I believe that means both remaining targets are slightly in front of their respective centers.
  • Speed remaining: No clue. Maybe the distance remaining (AATdtgt?) divided by the time remaining? 49.5mi / 65mph ==>45.6min, so this is probably correct
  • Achieved MacCready, Achieved speed, Cruise efficiency: No clue

Shortly after this I launched the ‘Target Show’ utility, and stepped through the targets, as shown in the screenshots below:

Show Targets display for KURJIV area
Show Targets display for JAVORJEV

The values shown in the above pages for KURJIV & JAVROJEV seem reasonable, but I’m not sure where the ‘V rem’ value comes from.

Also, I note that the ‘Delta T’ value isn’t color-coded like it is for the ‘AAT delta time’ InfoBox. I think this is a mistake; if you color-code it in one place, you should color-code it in all places

The next two screenshots show the situation about midway through the KURJIV area

I still don’t understand much of the data shown on the ‘Status’ page, and now I note that the ‘Remaining time’ value on the Status page is not the same as the ‘AAT time’ value on the map display. The difference between these two times is (38-33’23 = 4’37) is close to the sum of the ‘AAT time’ and ‘AAT delta time’ values.

I turned in the KURJIV area shortly after passing the KURJIV center point. When I did, I somehow managed to disable all the InfoBox displays – yikes!

The case of the missing InfoBoxes!

Fortunately I managed to get them back in fairly short order by clicking on the ‘Page Show Info’ box, changing it from ‘Auto’ to ‘Hide’ (I must have inadvertently changed this feature from ‘Auto’ to ‘Hide’ earlier. Here’s a short video clip showing the mis-fingering and the re-fingering:

Note that the original ‘mis-fingering’ was me trying to bring up the ‘Status’ page with an ‘S’ gesture on the screen, and somehow got the ‘Hide the InfoBoxes’ option instead -yikes!

At some point between the KURJIV & JAVORJEV areas, I manually changed the MC value from 5 to 1 to see if that impacted the navigation and ETA calculations. AFAICT, it did absolutely nothing. Later I changed it from 1.0 to 9.2kts, and still couldn’t see any difference in the calculation.

Just as I entered the second (JAVROJEV) area, I changed to the ‘Target’ display in the JAVROJEVA area, as shown below:

Just before entering JAVROJEV area. Note that the ‘optimize’ feature is enabled

With ‘optimization’ enabled, XCSoar has adjusted the target point so as to result in a slightly overtime (4min 56 sec) arrival. Next, I manually moved the target point to the very end of the area. This also automatically disabled the ‘optimization’ feature. Within a second or two, the Delta T value changed from 4min 56sec to 12min 3sec, as expected. Then I moved the target to near the start of the area, and Delta T changed to -4min 23sec, as shown in the next two screenshots.

JAVROJEV target moved to back of area, resulting in a projected 12min 9sec over time arrival
JAVROJEV target moved to front of area, resulting in a projected -4min 23sec undertime arrival

I left the target at the front of the area, to see how XCSoar behaved in non-optimization mode. The next screenshot shows the situation just as the glider crosses through the ellipse connected to the manually placed target.

Glider just crossing early-arrival target ellipse

Note that Delta T is now -5min 5sec instead of -4min 23sec, and Vach is now 76.8mph instead of 76.5mph, consistent with the slightly earlier arrival time.

Next I flew on into the JAVROJEV area, still in non-optimized mode. As the glider went past the target ellipse, the Delta T value kept changing in a way consistent with the increased distance and (slightly) increased speed. It appears as if XCSoar is actually moving the calculation target along with the glider, even though the displayed target point isn’t moving. Sort of a ‘shadow’ optimization mode?

In the next screenshot, the glider is just at the point of turning toward home.

Glider just before turning for home

At this point the manually placed target is toward the front of the area, but now XCSoar is showing a +6min 14sec overtime arrival, which should be enough of a margin to avoid an early arrival due to a faster-than-expected final glide

The next screenshot shows the situation just after clicking on the ‘arm turn’ box.

Just after turning for home in JAVROJEV area. Note target no longer visible

The target marker and ellipse which was at the front of the area has now disappeared, and the ETA/ETD calculations now show a 3m 59sec overtime arrival down from 6min 17sec just a few seconds earlier. There is no way the glider or pilot could have caused this 3min 18sec change, so clearly there is something that isn’t quite consistent in XCSoasr’s before and after turn calculations.

At this point, the flight is essentially over. As the next screenshot shows, the flight ended with a slightly (1min 14sec) overtime arrival, as hoped for.

Flight Summary:

This test flight was much more successful than earlier ones, and I now have a reasonable expectation of being able to navigate/manage an AAT/TAT task in Condor without getting myself completely turned inside out. There are still some issues, though:

  • The ‘Time UTC’ and ‘Time loc.’ readouts are completely screwed up, but it’s not XCSoar’s fault. Condor2’s GPS NMEA sentences insert local times into the UTC field, a really bad NoNo. Since Condor knows where it is in whatever task scenery is being used, it must convert local times to UTC times internally, and put the UTC time into the NMEA stream.
  • It is still not clear to me what speed(s) XCSoar uses for arrival time calculations, I think it is using some form of ‘speed made good’ or ‘average speed to date’.
  • I don’t think the MacCready value (or it’s corresponding projected speed) is used at all. At one point I changed the MacCready value from 5.0 to 1.0, then to 9.2, and then back to 5.0 and didn’t notice any significant change in the arrival time calculations.
  • XCSoar has a few minor GUI issues. The ‘delta time readout on the status page doesn’t utilize the same (or any) color code as the ‘AAT delta time’ readout on the main navigation page.
  • When the pilot flies past the target and target ellipse, the target should start moving with the glider. AFAICT, the calculations do that already – it’s just the graphical element that isn’t tracking.
  • At one point I lost all my info boxes, and had no idea how it had happened or how to get them back again. As it turned out, the culprit was my attempt to bring up the ‘Status’ page with an ‘S’ gesture. Not only did XCSoar not recognize my feeble attempt, but it obviously did recognize it as some sort of ‘hide the infoboxes’ gesture – yikes! This seems to be a classic case of symbol interference – literally.

I have included a link to the full video of this flight below, in case someone else would like to reference it for their own research, or to buttress/rebut a claim or opinion from me.

https://drive.google.com/file/d/1CB6CgySUK0nWtdiMIg3LYffm3i57z7wQ/view?usp=sharing

Connect Condor on PC to XCSoar on Linux

Posted 17 January 2024

I recently re-started flying Condor Soaring Simulator after a long absence, and renewed an old interest in using the open-source XCSoar navigation software for external TAT/AAT planning and navigation. XCSoar runs on PC’s, Android phones/tablets, and Linux and is widely used in RL (real-life) and Condor soaring.

I started out by running XCSoar 7.42 on a cheap Android M10 tablet, connected via Bluetooth to Condor running on my Windows 10 PC. Then I created a small AAT task in the default Slovenia scenery and ran a series of test flights to see how XCSoar did. I documented my results in this post and this one.

As a result of my study, I identified some bugs and other issues on the XCSoar forum, and found out that the XCSoar software is actually written in C++ on Linux, and then cross-compiled for the various supported platforms. I’ve done a fair bit of work in C++ and in Linux, so this got me thinking that maybe I could resurrect my old Linux skills and play around with the XCSoar source code a bit. So I dug out my old moth-balled Dell Precision M6700 laptop, loaded up Ubuntu 24.0 LTS, cloned the XCSoar repo, compiled it on my Linux box, and voila! I was in business!

Well, not quite. In order to use Condor on my Windows PC as the test bed for XCSoar software mods, I had to somehow connect Condor’s NMEA output to the NMEA input to the XCSoar program running on my Linux box. This turned out to be non-trivial and involved a lot of web searching, tearing of hair (what little I have left), and gnashing of teeth, but in the words of my Nebraska cousins “We gotter done!”

This post, then is a way of capturing the surprisingly easy (once you know the magic) process of connecting the NMEA output from Condor running on my Win 10 PC to the NMEA input of XCSoar running on my Linux box.

As it turned out, I had already solved (sort of) the first half of the problem, getting NMEA data from Condor out of my Win 10 PC. When I first (re)started playing with XCSoar, I found some posts describing how to connect Condor NMEA ouput to XCSoar running on the same PC, using a nice utility called ‘Virtual Serial Ports Emulator’ (VSPE), and this actually worked very well – except for one tiny little problem; in order to make any adjustments in XCSoar, I had to ALT-TAB out of Condor over to XCSoar, and that meant ‘flying blind’ (literally) while working with XCSoar – not a good thing. I solved this problem by instead route Condor NMEA output to a Bluetooth virtual serial port connected to an Android M10 tablet.

The procedure for connecting Condor on my Win 10 PC to XCSoar running on a Linux box is:

  • Connect Condor NMEA output to a TCP port on the Win 10 Box
  • Use ‘socat’ on the Linux box to connect the Win 10 TCP port to XCSoar

Connect Condor NMEA output to a TCP port on the Win 10 Box:

This connection is composed of two legs, both using VSPE; the first one defines a virtual serial port to which Condor NMEA output can be directed. The second one creates a connection between the virtual serial port defined in the first step to a Win 10 TCP port. The screenshot below shows both these legs.

Any unused COM port number may be defined here. Once this is done, connect Condor NMEA output to this port by going to Setup->Options in Condor, checking the ‘Output NMEA’ box, and then selecting the port number defined above, as shown below:

Use ‘socat’ on the Linux box to connect the Win 10 TCP port to XCSoar:

When I first started this adventure, I found references to the Linux ‘socat’ command while Googling for things like “Connect Linux Box to Win 10 PC”. Then I started reading about ‘socat’ in particular, and although I could understand that ‘socat’ connected two ‘things’ (where a ‘thing’ could be a serial port, a TCP port a UDP port, a website, etc), it wasn’t easy to figure out how to use it for my application. Finally I ran across this tutorial, which guided me through a series of example socat applications.

After playing with the examples for a while, I realized I should be able to use the ‘STDIO’ socat example to connect the already existing TCP port on my Win 10 box to STDIO in a Linux console terminal and watch NMEA data flow through. So I fired up Condor on my PC and selected ‘Free Flight’. In the ‘NOTAM’ tab, I selected the ‘Airborne’ start option (I believe this is the default), and then selected ‘Start Flight’. Condor outputs NMEA sentences even when the glider is suspended in mid-air, waiting to start flying, so this is a convenient way to test connections. Then on my Linux box I opened a terminal window and typed in the command shown at the top of the following image:

Linux ‘socat’ command to connect Condor NMEA output to terminal window

When I executed the command, I started getting NMEA sentences from Condor – yay!!

Now that I verified that I can connect to a Linux terminal window from Condor running on my Win10 PC, the remaining piece is to change the destination from a terminal window to XCSoar’s GPS data input and then configure XCSoar to accept GPS data from that port. To do this I executed the following ‘socat’ command on a terminal window in Linux:

This establishes a connection between a randomly selected UDP port on the Linux box and a TCP port on my PC. The PC TCP port number is the one selected above connecting COM9 to a TCP port, and the UDP port on my Linux box was just a random unused port number.

Then I launched XCSoar on my Linux box and navigated to Config–>Devices, as shown in the following screenshot. Device A is defined as UDP port 4353, the port number selected above.

XCSoar ‘Devices’ page showing connection to Linux UDP port 4353

This establishes the end-to-end connection between Condor running on my Win10 PC to XCSoar running on my Linux box. With this established, XCSoar shows ‘GPS fix’ as the status for Device A, and the main screen shows the glider’s location in the selected scenery, as shown below:

Stay Tuned,

Frank

XCSoar Soaring Computer AAT Task Study, Part II

Posted 14 January 2024

This is the second installment in my study of the XCSoar cross-country race navigation software with respect to its use in AAT/TAT tasks in Condor2. In my last post, I created a small AAT task in Condor and flew it with XCSoar on a Android M10 tablet, connected to my Condor PC via bluetooth. In this installment, I fly the same task, but this time I video’d the entire task and then afterwards picked out screenshots to highlight points of interest during the task.

Before task start

This next shot illustrates a problem I had right at the start. I used my finger to swipe down (hoping to zoom in or out), but instead it froze the XCSoar app. Had to reboot the M10 tablet and go through some other gyrations to get going again. I sure would hate to have this happen just before task opening on a AAT race in Condor.

XCSoar crashed after the ‘swipe down’ gesture

After getting XCSoar back up and reconnected to Condor, I got going with the task again. Here’s a screenshot showing the situation just before exiting the start cylinder

Just before task start. All the data values look OK

Now just after the start

Just after exiting the start cylinder, with the ‘Task Start’ popup visible

Comments:

  • The ‘AAT Time’ value has decreased by 4 sec, which seems OK
  • ‘AAT delta time’ seems a bit odd, as it shows I’m going to arrive early by about 1 minute
  • The AAT Dmax/Dmin and AAT Vmax/Vmin values look consistent. IOW, to consume 45 min covering the min distance of 24.9mi, I need an average speed of 29.9mph (24.9mi / 29.9mph = 0.833hr –> 50min), and for the max dist of 92.9mi I need 111mph (92.9mi/111mph = 0.833hr — 50min). This gives me fair bit of confidence that I have the necessary data to optimize the task.
Just before entering the first turn circle

Comments:

  • All the numbers still look reasonable here. The ‘AAT Time’ has gone down by about 3.5min, and the arrival is still shown as 1:09min (according the documentation, BLUE indicates arrival will be over by at least 5 minutes).

Now, just after entering the first turn circle,

Just after entering the first turn circle

Comments:

  • It was nice to see the ‘In sector, arm advance when ready’ popup show, but I wasn’t entirely sure what it meant.
  • It was also very nice to see that the ‘target’ started following the glider symbol, meaning that I didn’t have to move it manually – yay!
  • I noted that the ‘AAT Dmin’ value changed from 24.9 to 27.4mi, so that sounds right.

Next, I brought up the Task Status page (after a LOT of fumbling), and got this:

Task Status page

Comments:

  • I was amazed by how little information on this page was useful. The only values that I found believable were the ‘Assigned Task Time’, the ‘Speed Average’, and ‘Achieved speed’ values.
  • The ‘Estimated task’ value of 2:47 and the ‘Remaining time’ value of 2:40 makes no sense. Where did they come from?

At about the halfway point something happened (or I did something stupid – AGAIN) and my ‘AAT time and ‘AAT delta time’ values – the very most critical information required for successfully completing an AAT – disappeared, only to return again when I made the the turn toward JAVORJEV. At the time I didn’t notice until well after the fact, so having the entire flight on video really paid dividends – yay! Here’s a short (~ 35 sec) video showing the point at which they disappeared.

watch as the ‘AAT Time’ and ‘AAT delta time’ values disappear, starting at about 22sec

Comments:

  • The two values that disappeared are the whole reason for using an external navigation device to fly AATs in Condor. After they disappeared, I was basically winging it from then on.
  • It is possible that the data disappearance is related in some way to the buttons I was pressing around the same time. The first screen tap happens at 13.35sec into the video clip and the ‘AAT delta time’ value starts going GAGA about 10sec later.

In the next screenshot I’m about 3/4 of the way through the first turn, and thinking about turning around. Since I lost my ‘AAT Time’ & ‘AAT delta time’ readouts I’m flying blind on timing:

About 3/4 through the first turn area

Comments:

  • The only information I have to work with are the Dmin/max and Vmin/max values, and some notion of my average speed. I think it’s around 80-90mph, and as long as it is less than 111mph I’m OK to turn at this point.

The next shot shows the ‘Show Target’ page for this turnpoint

‘Target Show’ page for this turnpoint

Comments:

  • This page shows a value for ‘V ach’ of 70.8mph, which is almost identical to the value shown for ‘AAT Vmin. Assuming I believe this number, and assuming that value will continue to increase because I’ll be ridge running the rest of the task, I should be OK turning here.
  • I have no idea what the ‘ETE’ and ‘Delta T’ values mean on this page – they don’t look consistent with the ‘AAT Vmin/max’ and ‘AAT Dmin/max numbers on the main navigation page. I don’t think there’s any way I can make it back 26 minutes and 39 seconds early, even if my glider suddenly acquire orbital velocity.

The next shot shows the same page, but for the JAVORJEV turn circle, just as I’m getting ready to turn in the KURJIV circle

Comments:

  • Apparently, moving the target position in the KURJIV circle also moves the corresponding one in the JAVORJEV circle – I didn’t expect that. I wonder what happens in a 3, 4, or 5 turn circle AAT – do ALL the targets move in unison?
  • What does the ‘Optimized’ checkbox do?

The next shot shows the situation just as I made the turn for JAVORJEV. Again I didn’t notice this at the time, but my ‘AAT Time’ and ‘AAT delta time’ datablocks returned from the dead. Here’s a short (20sec) video showing the action. Just from the video, it looks like tapping on the ‘Arm turn’ button also resurrected the AAT info boxes.

However, my joy over getting my AAT datablocks back was short-lived. A short time after making the turn, the datablock info disappeared again – for good. This time there were no button pushes to blame. The following short video shows the action

AAT datablock info disappears for the second- and final – time

The next shot shows me just before exiting the first circle on the way to JAVORJEV

Comments:

  • The AAT datablocks are still missing
  • The Target in the JAVORJEV circle is now toward the near side of the circle, so is there some optimization going on in the background?

The next shows my attempt to manually move the JAVORJEV target.

Comments:

  • The ETE & Delta T values look reasonable, and the implication is that I should be able to use up all the time by moving all the way to the back of the JAVORJEV circle
  • However, when I manually move the target to the front of the circle, there is almost NO change in the ETE/Dt values, and the small change that shows is in the wrong direction. Moving the target forward like this should make me way earlier, but the numbers show that I’ll be almost 1 minute LATER than I was before. how can this be?

As shown in the next video, I decided to try the ‘Optimized button to see what it did. This radically changed the target location, and the ETE/Dt values. After a few iterations, it looked like the Optimize function was indeed working properly.

Comments:

  • It takes a while for the optimization to converge. At first, the values for ETE & Dt are WAY off, and then they oscillate back and forth several times before stabilizing on believable numbers.

The last video covers the finish (or NOT-finish, in this case)

Comments:

  • At the start of this clip, XCSoar is in ‘Final Glide’ mode, but switches back to ‘Cruise’ just before entering the finish circle.
  • I was expecting a ‘Task Finished’ notification when I crossed into the circle, but didn’t get one. In fact, AFACT, XCSoar never finished this task at all. I’m sure this was an operator error on my part, but I don’t know what I screwed up – bummer!

XCSoar Soaring Computer AAT Task Study, Part I

Posted 14 January 2024

Among the many ‘EXs’ I claim, one of them is ‘EX-glider racing pilot’, and another is ‘EX author of “Cross-Country Soaring with Condor”, a fairly popular book in the soaring community that explains how to use the Condor Soaring Simulator to learn real-life (RL) cross-country (XC) soaring. Now that I don’t fly RL contests any more, I have decided to start flying XC races again in Condor.

Many Condor racing pilots also fly gliders in RL, and use Condor to help them with XC strategies and tactics, and how to best take advantage of the many XC navigation and racing support computer programs available, and Condor supports this by making GPS location data available to users. One of the most popular programs for this purpose is XCSoar (https://xcsoar.org/). In RL XC racing, one of the most popular task types is the Assigned Area Task (AAT) or Turn Area Task (TAT), where the pilot is free to decide where to turn to the next leg of the task, as long as he is within the bounds of an assigned area. Unfortunately, the Condor soaring simulator’s internal navigation computer doesn’t support this type of task, so the pilot must either just guess where to turn, or use some type of external navigation support.

This post is intended to describe my efforts to use XCSoar for Condor racing, and in particular how to use it for AAT/TAT optimization. To do this, I set up a small AAT task in the default Slovenia scenery, as shown in the screenshots below:

Here’s a screenshot of the task in XCSoar:

And the same task in Condor2

After starting the flight, I would pause Condor2 at progressive points along the task and take a photo of the XCSoar app running on an Android tablet, with the idea that after the task was over, I could go back and make some sense of what XCSoar was telling me throughout the flight (Note that due to the loss of GPS data when Condor2 is paused, the green track line jumps way off screen each time, so you have to ignore the impossibly straight part of the ‘breadcrumb trail’).

The following shot was taken just before exiting the start circle at KAMEN

For some reason, XCSoar thinks that almost 3 minutes have elapsed since I started the task, even though I’m still inside the start cylinder and I haven’t gotten any start notifications

OK, it may be that XCSoar started me when I crossed the circle diameter perpendicular to the task line.  I note that even though the task diagram shows a cylinder with radius of 2mi, is it possible that XCSoar is still triggering on the default start point type (Start Line, 1.8mi wide)?

The next shot (above) shows the situation just after exiting the start cylinder.  Although not shown, I did get a ‘Start’ notification at this point.  Note that the ‘AAT Time’ readout jumped backwards from 42:04 in the previous photo to 44:56 in this one.  The 44:56 number should be the correct one, as I have just exited from the start cylinder.

Note that the ‘AAT delta time’ value doesn’t make any sense to me.  It’s supposed to show ‘Difference between the estimated task time and the AAT minimum time, and if it is colored blue it is supposed to mean that I could turn right there and be assured that I would arrive home so as to be more than 5 minutes over time.  But that can’t possibly be true, as I haven’t even gotten into the first turn area yet – WTF?

The above shot shows the situation just after turning around in the first turn area.  I really wasn’t getting any good information from the data fields I had displayed – just nothing made any sense, so I guessed the turn point based on the AAT time value, which I took to be the AAT time remaining starting from 45:00 minutes and a wild-assed guess about my achieved speed (I guessed I was doing about 1.5 miles/min).  With this guess, and thinking that the remaining distance was between 41.5 and 64.2 miles (assuming I interpreted these values correctly).  The ‘AAT delta time’ readout still seems to be nonsense – or maybe it is really true at this point?

The above photo shows the situation after exiting the first turn area and proceeding towards the JAVORJEV turn area.  The ‘AAT Time’ value seems like it is behaving rationally, but look at the ‘AAT dT’ value  – if true, it should mean I’m going to arrive over 45 minutes LATE, which makes no sense at all.  The ‘AAT Dmax’ value is sort of meaningful, and I take it to mean that I have at most 64.2 miles remaining and 27:19 minutes to cover the distance, or right around 120mph.  If I believe the ‘AAT Dmin’ number, then that works out to about 90mph if I just touch the last area.  The ‘AATDtgt’ now makes sense as well, as the ‘target’ is right on the near edge of the last area, making the ‘Dmin’ and ‘Dtgt’ equal.

The above photo shows the situation about 4 minutes later, just before entering the JAVOR circle. The value of the last three datablocks haven’t changed, which makes sense, but now the ‘AAT dT’ value has changed dramatically again, this time to something a little more reasonable.  Now *I think* it is showing me arriving 4:32 early, but that would mean it should be colored RED, and it clearly isn’t – WTF again!

At this point I thought to look at the task Status page, and discovered that this page seemed to think I was going to arrive 4 minutes over time, not under, so now I’m really lost.  The help in XCSoar says that the ‘AAT delta time’ data block value will be colored BLUE if the expected arrival time for a turn at the present point will be at least 5 minutes OVER time, and RED if it is going to be UNDER time.  However, the actual color of this datablock value is BLACK, and based on the data on the Status page, it looks like BLUE means UNDER time and BLACK means over time.

Also, I saw on this page that my earlier estimate of around 90mph was pretty close to the mark. Armed with this information, and the knowledge that the rest of the task was going to be even faster, I might want to go further into the area than just the minimum.

The above shot is from (I think) the ‘Show Target’ page for the JAVORJEV turn area, after I moved the target from the near edge to well past the center of the area.  I expected this page to tell me what the effect of moving the target would have on the total task time, but AFAICT, the only real values are the 49% distance offset value and the Vach value of 93.1mph  – the ETE of 2h 52min and the Vrem of 16.4mph are clearly garbage.

The above shot shows the situation about a quarter of the way into the JAVORJEV circle.  The ‘AAT time’ value continues to be believable, but now the ‘AAT dT’ value shows me arriving (early?/late?).  After seeing the data from the Status page, I was inclined at this point to think that the BLUE coloring meant ‘early’.  The AAT Dmax value is unchanged as it should be, but now the AAT Dmin and AAT Dtgt values have both increased.  I *think* the AAT Dmin value now shows the total task distance assuming I turn immediately, and the AAT Dtgt value shows it for continuing to the target and then turning. The AAT Time value shows I have about 21 minutes remaining, so I would have to fly well above VNE to arrive just on time If I go to the target, and something like 150 if I were to turn immediately.

The above figure shows the ‘Status’ page on the way back from JAVORJEV to LESCE-BLED.  It has the ‘Assigned task time’ correct, but the ‘Estimated Task Time’ and ‘Remaining time’ are clearly not real.  The Task distance and remaining distance values look OK though.

The above shot shows the situation as I’m coming out of the JAVORJEV area heading home.  The ‘AAT Time’ looks correct, but the ‘AAT dT’ value looks crazy again.  Could it be that the value is actually correct, but now showing arrival 49.11 seconds early? Man, that’s a pretty subtle thing to have to figure out while flying close to the ground at Vne!  If this is correct, then the number should really be formatted as ‘0:49.11’ instead

The above shot shows the situation just after exiting the JAVROJEV area, and now the datablocks have changed to final glide.  Now it looks like I’m going to arrive about 4 minutes early (I’m assuming this is based on my current Vgnd of 115Kt) – bummer!

The last shot before entering the finish circle.  Not quite sure how, but I managed to lose some time on the way back, arriving at 44:03 – a little less than 1 minute early.  I deliberately left the display scale alone during the approach to the finish cylinder, as I wanted to see if the ‘AutoZoom’ feature would work.  It didn’t, but I’m not sure who’s to blame – me or XCSoar.  More investigation needs to be done.

Conclusions:

  • I set up my datablocks for cruise, climb, and FG based mostly on a video I found of a pilot flying an AAT task – I really didn’t have any idea what all the values would really show me.  In retrospect, I’m going to have to spend some more time going through the available datablocks and see if another mix makes more sense.
  • There were some seriously erroneous numbers showing up in some of the datablocks, especially the ‘AAT dTime’ one.  It occurs to me that this might have been due to the way I was pausing the flight and then taking a photo of the XCSoar screen. It might be that the values got screwed up when the GPS signal went away.  I’ll have to redo this flight without pauses (maybe video the entire flight and then just grab frames, or maybe set up my phone on a tripod so I can just press one button?)
  • The XCSoar documentation doesn’t match reality in some places, especially with respect to the ‘AAT dTime’ datablock colors.  The documentation says RED for early, BLUE for late, nothing about BLACK. 

If nothing else, this flight and the subsequent analysis gave me a lot better understanding of XCSoar’s capabilities with respect to AAT task support.  I’m a long way from being comfortable with trusting it to feed me good information in real time, but I’m a lot closer than I was before 😊

Stay tuned,

Frank

WallE3 Doesn’t Like Reflective Surfaces

Posted 08 December 2023

WallE3 went with us last month when we travelled to St. Louis for Thanksgiving with family, and I showed off his autonomous wall following skills. WallE3 actually did great for quite a while – that is until he found himself staring at the side of a floor-mounted wine cooler (wine ‘safe’?). As can be seen in the following short video, WallE3 fell in love with the cooler, and showed his love by repeatedly head-butting it – oops!

After looking at the telemetry data for the run, I saw that WallE3 was measuring much larger front distances – like several hundred centimeters – when it was only a few centimeters from the object. It appears he was backing up to a defined front distance in response to a ‘WALL_OFFSET_DISTANCE_AHEAD’ anomaly, but somehow convinced himself that instead of 20cm from the wall, he was actually more like 100cm away. Of course, since he wanted to be at 30cm (the desired wall offset distance), he drove forward to lessen the distance, thereby bonking into the wall. Then, when he hit the wall, the front LIDAR line of sight geometry changed enough to produce a true measurement of just a few centimeters, which then sent WallE3 running backwards to open up the distance. Lather, rinse, repeat. Here’s an Excel plot of a representative (but not exact – I somehow lost the actual telemetry data for this run).

Representative reflective surface ‘headbutt’ telemetry

As can be seen from the above the measured distance oscillates between the maximum measurable distance of 1000cm to nearly zero. Here’s a photo of the experimental setup that produced the above data.

WallE3 and a reflective surface

The ‘reflective surface’ is a piece of glossy black translucent plastic, oriented at an angle to reflect WallE3’s LIDAR beam upward to the ceiling and then the reflected signal from the ceiling back to WallE3.

I’ve been thinking about this issue ever since first seeing it in St. Louis, but hadn’t come up with any firm ideas about how to solve it. I tinkered with the idea of generating two running averages of the front distance when in the ‘MoveToDesiredFrontDistCm()’ function, with the two averages separated in time by some amount. When approaching a normal non-reflective surface, the two averages would closely track each other, but when approaching a reflective surface that produced the above dramatic distance shifts, then the two averages would be dramatically different around the transitions. This could then be detected, and something done to recover. Then last night while falling asleep, I wondered whether or not the STMicro VL53LXX infra-red LIDAR sensors would have the same problem – hmm, maybe not! If that were the case, then I could probably run one in parallel with the Garmin LIDAR unit, and use it instead of the Garmin for all ‘MoveToDesiredFront/RearDistCm()’ calls.

I tried this experiment using the currently installed rear distance sensors by calling ‘MoveToDesiredRearDistCm()’ with the same reflective surface setup as before, as shown in the following photo:

‘MoveToDesiredRearDistCm()’ setup with reflective surface

Here’s an excel plot of the rear distance run:

MoveToRearDistCm() with 30cm target and reflective surface

As can be seen in the above plot, the rear distance run was completely normal, so the VL53LXX infra-red LIDAR sensors don’t have the same problem – at least not with this translucent glossy plastic material.

10 December 2023 Update:

I got to thinking that maybe the reason the rear distance sensor worked so well with the shiny black material is that it could be IR transparent, meaning that while the front sensor (an LED LIDAR system) would see a ‘mirror’, the rear sensor would just see the toolbox. So, I jumped up on Amazon and got a cheap mirror square so I could answer that question. Here is a short video and Excel plot showing a ‘MoveToDesiredFrontDistCm()’ run with the new mirror square.

As can be seen from the video, WallE was perfectly happy to drive right through the mirror, but I had visions of mirror pieces all over the bench, the floor, and me, so I manually prevented that from happening. Here’s an Excel plot showing the same run:

MoveToFrontDist(cm) approaching tilted mirror

As the Excel plot shows, the robot did OK for the first 20 measurements (about 1sec) but immediately thereafter started a steady 200cm, and it stayed that way until I stopped it at about 2sec

Then I tried the same experiment, but this time utilizing the STMicro VL53LXX IR LIDAR sensor on the rear of the robot, as shown in the following short video:

As the video shows, the IR LIDAR behaved pretty much the same as the LED LIDAR (no real surprise, as they are both LIDAR technology, but still a bummer!

Here’s the Excel plot for this run:

As the Excel plot shows, the distance decreased monotonically for the first 30 points (about 1.5sec) but then shot up to 200 due to the mirror. I believe the lower distances after about point 40 (2sec) were due to me interfering with the IR beam.

So, unfortunately my theory about the rear IR sensor doing better with the shiny black plastic ‘mirror’ because it appeared transparent at that wavelength seems to be bolstered, so I now think that using the VL53LXX sensor instead of the Garmin LIDAR LED sensor for ‘MoveToFrontDistCm()’ operations is NOT going to work. Back to the drawing board :(.

23 December 2023 Update:

I’ve been thinking about this problem for a while now, and have not come up with a good answer; WallE3’s perception of the world around it depends entirely on LIDAR-type distance sensors, so if those sensors produce ‘false’ distance reports due to mirror or mirror-ish surfaces, WallE3 has no way to know the ‘true’ distance – bummer!

So, what I decided to do is to simply detect the symptoms of the ‘mirrored surface’ situation, halt the robot and yell for help. The detection algorithm uses the knowledge that when the robot is moving forward toward a ‘normal’ object, the front distance should decrease monotonically with time. Similarly when the robot is moving backwards toward a ‘normal’ object, the rear distance should decrease monotonically with time. Conversely, when approaching a ‘mirror-like’ object, the measured distance tends to be unstable, with distance increasing instead of decreasing.

The detection algorithm calculates a three-point average each time through the action loop, and compares the result to the last time through the loop. If the new average is greater than the old average, a ‘mirrored surface detection’ is declared and the robot calls ‘YellForHelp()’ which stops the motors and emits an audible Morse code ‘SOS’.

Here’s the full code for ‘DoOneMoveToFrontDistCm()’ function that actually moves the robot and checks for ‘mirrored surface’ error conditions

02 January 2024 Update:

I wasn’t really happy with my previous attempt at ‘mirrored surface’ detection as it seemed pretty to produce false positives. After thinking about the problem some more, I thought I might be able to use a distance variance calculation as a more robust detection method. The idea is that a normal monotonic increase or decrease in distance measurements would have a pretty low variance, while a distance reversal would generate a much larger value.

So, I ran some simulations in Excel using a 5-point running variance calculation, and the results were encouraging. Then, with the help of my lovely lab assistant, I set up an experiment in my office sandbox to see if I could capture a representative mirrored surface ‘screwup’, as shown below:

And here is an Excel plot showing the results (both the distance and 5-pt variance vertical scales have been truncated to show the smaller scale variations)

Front Distance and 5-pt Variance (truncated vertical scales for better visibility)

As can be see in the video and the Excel plot, the robot undergoes a number of distinct front/back oscillations, but then eventually settles down. It is clear from the plot that the 5-pt variance calculation is a good indicator of a ‘mirrored surface’ condition. Just looking at the plot, it appears that a variance threshold of 40-60 should provide for robust detection without much of a risk of false positives.

One other note about this experiment. To get multiple oscillations as shown in the video and plot, the mirrored surface had to be slanted slightly up toward the ceiling. If the surface was oriented vertically like a normal wall, the robot would often miss the first distance and hit the wall, but then would typically back off to the correct distance. I think this indicates that in the vertical configuration, there is enough backscatter from the floor and/or the robot itself to get a reasonable (if not entirely accurate) LIDAR distance measurement.

07 January 2024 Update:

After playing around some more with this issue, I think the above 5pt variance calculation for ‘mirrored surface’ detection will work, so I revised my current well-tested ‘CalcBruteFrontDistArrayVariance()’ function to take a integer argument denoting the number of elements to use, starting at the end (most recent data) and working backwards.

Then I ran another test in my lab, but this time on a non-mirrored surface, to verify that the 5pt variance calc would still work properly and to settle on a good threshold for ‘mirror’ detection. The Excel plot below shows the results of a run where the robot moved backwards (still using the front LIDAR sensor) to 90cm from the wall.

Running 5-point variance of front distances

As can be seen, the variance starts out in the 10 to 20 range during the initial ‘coarse’ distance movement, but then drops into the 0 to 5 range during the second ‘fine tuning’ movement. Comparing this to the previous ‘mirrored surface’ plot leads me to believe that a threshold of 40 would almost certainly (eventually) detect a ‘mirrored surface’ condition.

24 January 2024 Update:

I added the ‘CalcFrontNPointVar(uint16_t N)’ function to the robot code so I could obtain the front variance using just the last N front distances instead of the entire 100 point array. This turned out to work very well for detecting the ‘Mirrored Surface’ anomaly condition. Then I added ‘ANOMALY_MIRRORED_SFC’ to the list of anomaly codes, and added a ‘case’ block in ‘HandleAnomalousConditions()’ to deal with this condition. The handler function is:

At the moment, all it does is call the ‘RunToDaylightV2()’ function, which does a 360º search for the best direction in which to move next. Here’s the telemetry and a short video showing the action.

This experiment led to one of those “Well, DUH!! moments, as the robot’s preferred ‘RunToDaylight()’ heading was right back at the mirrored surface!

After recovering from my ‘face-palm’ moment, I realized I needed to modify the ‘RunToDaylight() function to take heading-start & heading-end parameters to exclude the mirrored surface sector from the ‘RunToDaylight()’ search for an appropriate recovery heading.

28 January 2024 Update:

I modified ‘RunToDaylightV2()’ to take two float parameters denoting the start and ending headings for the search. In the normal non-mirrored surface case, ‘RunToDaylightV2()’ is called with no arguments. The no-argument overload simply calls ‘RunToDaylightV2(startHdg, endHdg)’ with startHdg = endHdg. In the mirrored surface case, the two-parameter version of ‘RunToDaylightV2()’ is called from the ‘ANOMALY_MIRRORED_SFC’ case block of ‘HandleAnomalousConditions()’

Here’s a short video and the telemetry from a test run toward a mirrored surface.

Stay tuned!

Frank