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



2 comments:

  1. Hi
    This looks really promising. I would also be interested in Height above TO, distance to TO and flight time.
    Thanks Paul

    ReplyDelete
  2. Thanx from the suggestion(s) Paul!

    It likely needs a ListenerBroadcaster that subscribes to groundspeed/bearing to then broadcast Flight Status (not launched, flying, circling, etc).

    Maybe a hook in the MFD in the center to show (in all cases, when flying):

    1) Glide when not climbing or circling (not in a thermal or hunting for one).
    2) Distance from launch when 1) is satisfied AND glide is relatively unchanging, and pilot is > distance X from launch (one doesn't really care about distance from launch when over it).
    3) Height ABL when circling, vario is stable and less than distance Y from launch.
    4) Vario in all other cases.

    ?

    Time of flight is simply displaying the time since the transition from not flying to flying. Where to display it (as will all of these) - is the tricky part ;)

    ReplyDelete