Monday 14 December 2015

It's all in the application: Recon Instruments Snow 2 vs Paragliding (Part 4)

BLE - Bluetooth Low Energy.

Its all the rage in 'wiring' up sensors to a flight data aggregator (such as the GliderHUD on the Recon Instruments Snow2).

Now that the GliderHUD app can display flight data generated by the internal GPS, its time to look at external data sources like the XCTracer vario/GPS.

Using the sample application provided by Recon (which is based on the Android BLE tutorial published by Google) - I was able to get the Snow2 and XCTracer chatting with one oddity. It appears that the BLE stack on the Snow2 struggles with multipart messages. This is not particularly surprising as the only BLE device the Snow2 could talk to originally was the remote. I imagine that the up/down state of 6 buttons could easily be packed in the 20 byte limit of a BLE message - precluding the need to address a rapid chain of messages hitting the onboard transceiver and protocol stack. Just a hunch though. It could also be the quality of the Bluetooth chip itself. Who knows.

Well, the message format I wanted to support out of the box was the native XCTracer frame with a plethora of data.

But it is not to be.

After the third (sometimes fourth) XCTracer subpart, a new message begins - meaning the remainder of the original is dropped. Trying to accommodate a rapid turn around within the characteristic notification callback, I tried posting the byte data to a Handler immediately. Still no dice. Maybe a bug on my part.

What I do know works (mostly...mostly) is the LXWP0 format - it comes across in two parts as opposed to the five or six portions with the XCTracer sentence.

So LXWP0 it is.

Sadly this costs me the groundspeed - it would be nice to be able to skip using the onboard GPS on the Snow2 altogether except as a backup.

The changes are up on GitHub - https://github.com/Levemus/GliderHUD

The vario data coming from the XCTracer via BLE (the XCTracer is reporting the altitude as a negative, which the altitude display floors at 0 m):






Continued in Part 5

Monday 7 December 2015

It's all in the application: Recon Instruments Snow 2 vs Paragliding (Part 3)

A quick recap from Part 1 and Part 2:

A killer deal on a Recon Instruments Snow2 +
A device that runs on the Android OS +
A paragliding dev with a modest amount of experience in game engine implementation on Android.
=
A Paragliding HUD work in progress.

Using the sample Compass app from Recon and some ideas on wind drift approximation from Alistair Dickie (along with a circular regression implementation from Dr. Micheal Doube) - I managed in the last pair of posts to put together a simple PG HUD that showed heading, bearing, altitude, groundspeed, and wind drift direction (along with a poor mans climb rate/vario and glide ratio).

In the 'rush' to slam together this prototype implementation, things became a bit of a hot mess (as they always do) - with the inevitable intermixing of UI and data provision (emmveecee rather than MVC, as it were).

Reorganizing


So a refactoring we will go (caveat: it is a work in progress, this is simply a snap shot at the current moment).

The result: The display elements are listeners that subscribe to broadcasters.

Broadcasters and Listeners


When the app is started, broadcasters and display elements are instantiated. The broadcasters are passed to each display (listener).

The listener attempts to register itself with the broadcaster, specifying which Flight Data elements it cares about and the minimum interval between notifications.

The broadcaster looks at the requested elements, compares them against what it can provide and replies with those it can service.

The listener stores the outstanding services it still needs until the next broadcaster is sent its way to register with.

Flight Data


Once registration is complete, the listeners wait for invocation of their onData callback. The passed param is a Flight Data object. The listener can query the Flight Data object for values it needs to update itself with. If the Flight Data object cannot provide the value (as could be the case when subscribing to multiple broadcasters providing different data) - an exception is tossed (the alternative could a TryGet like function seen in C# dictionaries, perhaps).

With data in hand, the listener (display) can update and refresh itself.

ListenerBroadcasters


Some broadcasters are aggregators of data - subscribing to get information, processing it, then providing a result to a downstream listener. The WindDrift is one such case - it subscribes to the GPS for bearing and ground speed information, processes it, and provides wind speed and direction.

Moving forward


Right now the implementation does not handle competing data broadcasters - we could get altitude information from the onboard Android GPS and we could (once implemented) get that same altitude from a BLE device such as the XCTracer. Experimentation leads me to believe that the XCTracer will provide better altitude data, but being a BLE device - it is not as reliable a source as the onboard GPS. This needs to be accounted for - some form of override and failsoft -> use the Android GPS for altitude until a better source appears, use that source until it drops off, then back to the Android GPS. Maybe an intermediary manager.

Source


Disclaimer:
Source is up on github, purely for educational purposes. Paragliding is a dangerous activity and use of this software in any way, shape, or form, can result in serious injury or death. Levemus Software Inc. assumes no responsbility and provides no guarentee related its use. Any use of the source must include the below github url from which the source originated. Any commercial use must have prior written permission from Levemus Software Inc.

https://github.com/Levemus/GliderHUD

Continued in Part 4