Board index FlightGear Development Canvas

Canvas G1000

Canvas is FlightGear's new fully scriptable 2D drawing system that will allow you to easily create new instruments, HUDs and even GUI dialogs and custom GUI widgets, without having to write C++ code and without having to rebuild FlightGear.

Canvas G1000

Postby stuart » Mon Aug 21, 2017 9:22 am

Hi All,

I've started making some tentative steps towards a full Garmin G1000 simulation. I've started with the excellent xkv1000 as a starting point, particularly for the PFD which very closely mirrors the G1000.

For the MFD I'm planning to use the Canvas MapStructure layers (obviously).

One area I see I'm going to have to develop is tiled mapping, which the MapStructure in fgdata doesn't currently support as a layer. My current thoughts are
1) Create an OverlayLayer layer with a controller that is analogous to the SymbolLayer, but likely with a simple update method rather than SearchCmd, and no .symbol equivalent
2) Convert the tiled map example from the wiki, but also other layers such as a compass rose, airport diagram, lat/lon grid.

I'm currently undecided on how to handle the projection - whether to have the layer itself have to interpret the centerpoint of the map and scale, and then make a projection itself, or to provide it from the Map. The latter in undoubtably cleaner, but for something like a tiled map I suspect that the management will need to be quite low down the stack.

Has anyone already done any other this? I'm not familiar with the full set of aircraft using Canvas, so it's possible that someone has already done all the hard work for me :)

Any advice greatfully received. Also offers of help :).

-Stuart
G-MWLX
User avatar
stuart
Moderator
 
Posts: 1629
Joined: Wed Nov 29, 2006 10:56 am
Location: Edinburgh
Callsign: G-MWLX

my "2c" ;-)

Postby Hooray » Mon Aug 21, 2017 6:31 pm

Well, I realize that we have recently been in touch regarding your latest Canvas efforts, and that I certainly have provided more feedback than you were anticipating, so please take the following with a good grain of salt, because I am obviously biased when it comes to the MapStructure/NavDisplay frameworks and the Canvas system in general, having been involved in these efforts to some degree.

Basically, the ND/MapStructure frameworks came to be out of a certain degree of disagreement with other MFD/glass cockpit efforts using the Canvas system.

That was primarily because many of those lacked support for:
  • truly independent instances
  • reuse (other aircraft/use-cases, e.g. sharing common logic between aircraft displays and GUI dialogs)
  • customization (think styling)

Especially, we found it hugely frustrating to see awesome avionics like the Avidyne Entegra R9 being developed for aircraft like the extra500, that were impossible to reuse for other aircraft cockpits, but that also contained features/code that would have been useful elsewhere (think mapping/charting displays).

So that more often than not, copy & paste was the only option to "reuse" useful code elsewhere.

Thus, the idea was to grow a library of generic building blocks that live in $FG_ROOT and that are sufficiently generic and customizable to basically enable people to collaborate more properly by providing a strong incentive via compelling functionality that can be easily maintained/updated in the future. The thinking was that all aircraft/GUI dialogs using a single back-end would automatically benefit from significant updates to the back-end that way (think performance, features etc).

Our strategy was to adopt a MVC (model/view/controller) approach, where the model would represent what is to be rendered, the view would map the Canvas system and its primitives (elements) and underlying APIs, whereas the controller would usually be use-case specific (think cockpit vs. GUI dialog).

Looking back in time, we did accomplish these goals only partially - mainly because while we actually have many aircraft using these building blocks today (think NavDisplay and MapStructure-based avionics) - the number of actual contributors, and contributions, however flowing back into the NavDisplay/MapStructure efforts has actually been marginal in comparison. As a matter of fact, only a handful of people have made working modifications to the NavDisplay/MapStructure framework, and most of these still live outside fgdata.

In contrast however, efforts like the extra500/Avidyne Entegra R9 have actually adopted /some/ of the techniques used by the MapStructure framework, while having seen more updates over time, despite still not supporting any form of "reuse".

While providing such a degree of reusability and customizability may seem like overkill, it is actually hard to beat the flexibility provided by this approach:

http://wiki.flightgear.org/Howto:Protot ... play_Style
Image


Thus, given how much time has passed and looking back at the lessons learnt during the porting efforts of Gijs' original NavDisplay code, and how we came up with the MapStructure framework subsequently vs. the number of other glass cockpit efforts (including those that actually proved to be successful, e.g. Richard's MFD framework), the best advice I can give to people wanting to implement new avionics using Nasal and the Canvas system can be distilled to be the following:

  • absolutely do all prototyping/development of your MFD/avionics using a standalone GUI dialog - this won't just be much faster (compared to doing cockpit-centric development), but this is also crucial to actually making sure that you don't end up adding all sorts of hard-coded assumptions about the use-case or the aircraft the instrument is going to be used on. Which sooner or later will translate into more people/aircraft using your work, and contributing to it, or maintaining/updating it - possibly years after you may have moved on to other things.
  • if you find that you need custom logic to support a certain use-case/aircraft (think GUI dialog), structure your code to encapsulate such logic using delegates, i.e. function callbacks that can be passed to the underlying code to accomplish IOC (Inversion of Control).
  • for the ND/MapStructure, we ended up moving all these assumptions into a configuration hash, so that there are no hard-coded properties in the ND/MapStructure code, which is to say that -with a corresponding "driver hash", the ND/MapStructure code could just as well be driven by an AI/MP node from /ai/models instead of using /properties, /orientation etc in a hard-coded fashion
  • if it is foreseeable that you need to switch a set of APIs, encapsulate those, too - we were facing that dilemma, when people wanted to use navigraph data directly instead of the built-in navdb/navcache, by using a driver hash, we can do away with all built-in navcache queries and use a different navdb source.
  • do structure your MFD (and even a PFD) using something like Richard's MFD framework, i.e. using abstraction for pages, page items, menus and public state
  • keep the multi-pilot (dual-control) and multi-instance (multiplayer vs. FSWeekend/LinuxTag) use-cases in mind, which is to say that MFD building blocks like a map should publish element specific public state that can be shared between fgfs instances to selectively propagate/replicate relevant state to other fgfs instances running the same code, which means that even complex avionics like a G1000 could be kept in sync in a multiplayer or multi-instance use case by only replicating a fraction of crucial key state, rather than sync'ing low-level Canvas primitives at the Canvas::Element level.
  • For pretty much the same reason, I would strongly suggest to look at Richard's Emesary framework, and maybe get in touch with him in private to see if it's feasible to integrate his MFD/Emesary frameworks in a sane fashion, to actually "have our cake and eat it" - I would not underestimate the power of using this approach, it has taken us quite a bit of effort to accomplish this degree of loose coupling in the NavDisplay code, and had we had access to Richard's groundwork back then, things could have become much simpler and much more efficient.
  • do permanently profile/benchmark (stress-test) your avionics (which is another good reason for supporting N independent instances), so that you are aware of where performance is spent - and if something shows up as a bottleneck, do document/share your findings, so that we can augment/extend the underlying C++ code.
  • encapsulate all uses of timers and listeners that primarily animate MFD stuff, so that a more proper method can be easily adopted once it is made available

Apart from that, some of the more recent, and more successful Canvas related efforts involving the NavDisplay/MapStructure frameworks is certainly the Airbus related work done by artix and omega95 a while ago - however, I don't think any of that code actually made it back upstream (unfortunately).

And then, there's obviously the awesome extra500 avionics stack that is likely to contain very useful code - besides, Thorsten also mentioned on and off that he was hoping to -eventually- refactor some of his own shuttle drawing routines to grow a library of helpers for procedurally creating avionics.

Finally, regarding MapStructure specifically:

I believe that the framework is relatively well documented these days, and while it is true that most of these "docs" are indeed copied from the forum, I do believe it is still better than having no docs at all or than telling people to "just search the archives". Also, there is a fair number of working layers meanwhile, and these can usually be adapted easily to come up with new layers.
That being said, it is however true that there still is some legacy code pre-dating the MapStructure framework, originating from the days when I helped generalize Gijs' ND code, it can be identified easily by looking for *.draw files in $FG_ROOT/Nasal/canvas/map

And while I think that it's only the airports.xml dialog that you once created, that is still using the legacy back-end, it is still true that some of the more complex "layers" (=drawing routines) have not yet been ported at all (think taxiways).

Regarding your OverlayLayer idea, that seems like a good idea to me (and I think it's actually mentioned somewhere inn MapStructure.nas ?) - it would also seem useful for features like these:

Image

Looking at your posting here and the questions you are posing, it is obvious that you have already looked at the MapStructure framework and actually read up on its internals, so kudos to you for that - however, it is also important to note that it isn't actually "finished" in the sense that it implements everything we were originally planning to implement.

Also, to be perfectly honest, we faced quite a few challenges over the last 5+ years using the Canvas system, and especially creating the NavDisplay/MapStructure, some of which are summarized at: http://wiki.flightgear.org/Canvas_Devel ... FlightGear

For instance, vertical layers are not implemented/supported at all (e.g. VSD drawing) - omega95 ended up implementing his own VSD code to do this, not using the MapStructure framework.

Then again, everything you said about PFD related symbology (compass rose, airport diagram, lat/lon grid) is also something that we previously discussed, and it is not just referenced in the wiki article, but also in MapStructure.nas itself.

As a matter of fact, that kind of work would be useful in and of itself, because James (and I believe you yourself) mentioned previously that the map-canvas.xml dialog was missing those features (e.g. the lat/lon grid?).

James was actually hoping to phase out the hard-coded map dialog in favor of the Canvas version sooner or later: http://wiki.flightgear.org/Canvas_MapSt ... map_dialog

Thus, I believe that these features could be easily prototyped, and tested, by extending the map-canvas.xml dialog - if a layer works there, it will also work elsewhere.

Regarding projection handling in general, I can only re-iterate my previous suggestion to look at James' hard-coded Map dialog and its commit logs - you will find that some of the most recent changes were contributed by Gijs, implementing support for a new/better projection without causing performance issues (see the referenced bug tracker ticket to read up on the details).

Besides, that would also be the right place to implement support for vertical projections, i.e. the stuff required to implement a VSD or approach profile without going through tons of Nasal code (which is something that would also be useful for the tutorial/flight instructor use-cases):

Image

I guess, looking back at my own "advice", my suggestion would be to use the map-canvas.xml dialog as a testbed to implement some of the stuff that you need for the G1000 - it can also be trivially changed to render to a native Canvas GUI dialog, e.g. see:

http://wiki.flightgear.org/Canvas_Snipp ... o_a_Canvas
Image

Equally, it is relatively straightforward to review $FG_ROOT/Nasal/canvas/widgets to come up with an actual Canvas widget wrapping the MapStructure framework, that works for both, PUI as well as the Canvas GUI:

Image

Image
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Canvas G1000

Postby www2 » Mon Aug 21, 2017 7:33 pm

I can send you documentation of G1000 and I have model the main screen and audio panel.
www2
 
Posts: 319
Joined: Thu Apr 16, 2009 2:58 pm
OS: Ubuntu

Re: Canvas G1000

Postby Hooray » Mon Aug 21, 2017 8:30 pm

Thinking a little about it, I guess that the best way to proceed with such an ambitious effort like the G1000 is to bring map-canvas.xml up to par with the hard-coded Map dialog, i.e. implement missing features like the lat/lon grid and mouse-panning (optional).
Once that is working correctly, we could look at other missing features, e.g. a tiled map - or even rendering a compass rose or airport diagram.
Even the vertical/profile view could be added that way, without anybody having to touch any cockpit panels for quite some time.
The good thing about the MapStructure framework is that these layers work regardless of the use-case - you could in fact render the whole map to a livery:

http://wiki.flightgear.org/Howto:Dynami ... via_Canvas
Image

Sooner or later, the MapStructure layers added for the G1000 will prove to come in handy for other aircraft/purposes anyway, and it is also likely that these G1000 layers will outgrow the map-canvas.xml dialog at some point, which may be the right time to explore phasing it out in favor of a native Canvas dialog, or even a corresponding widget. For instance, the route manager dialog (but even the tutorial dialog) may eventually benefit from having a MapStructure-based map/chart, including features like the ones that Stuart is now interested in developing.

Using a native canvas dialog would have the added advantage that truly independent instances can be much more easily tested than doing the same in a cockpit/panel environment where separate buttons need to be modeled/set up (bindings etc)

For instance, F-JJTH was originally prototyping the whole Garmin GPSMap 196 using a standalone dialog with a shell/skin to control the thing via just a GUI dialog (with the buttons responding properly):

http://wiki.flightgear.org/Garmin_GPSMap_196
Image

Image

If that is something, that Stuart is considering to do, I'd suggest to coordinate anything related to this with James, i.e. the creator of the original Map dialog - like I said previously, the projection handling that the hard-coded dialog widget ($FG_SRC/GUI/MapWidget.cxx) is now using would certainly come in handy "soonish":

https://sourceforge.net/p/flightgear/fl ... b398323d7/]

Fix polar rendering of map. (Bug #55)

Use an azimuth-equidistant projection, which handles high latitudes and
polar regions correctly. Written by Gijs de Rooy.
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Canvas G1000

Postby Necolatis » Tue Aug 22, 2017 3:18 am

The JA37Di has a moving map in a color MFD, if that's the kind of example you are looking for. Works in all positions as far as I know (was tricky around the longitude 180 meridian line).
It does however not use the canvas element Map, just tiled Image. It has a variable that tell texels per meter, which ofc. change based on zoom level and latitude.
However it has no grid. (yet)
Feel free to peruse the code in Nasal/display-ti.nas.
"Airplane travel is nature's way of making you look like your passport photo."
— Al Gore
User avatar
Necolatis
 
Posts: 2233
Joined: Mon Oct 29, 2012 1:40 am
Location: EKOD
Callsign: Leto
IRC name: Neco
Version: 2020.3.19
OS: Windows 10

Re: Canvas G1000

Postby stuart » Tue Aug 22, 2017 10:19 am

Hi Hooray,

Thanks for the (further) insight. In particular using map-canvas for prototyping and to provide a concrete immediate benefit without the complication of the G1000 system itself.

www2 - thanks for the offer of the G1000 model. Is this the one used by the xkv1000?

I'll see how I get on.

-Stuart
G-MWLX
User avatar
stuart
Moderator
 
Posts: 1629
Joined: Wed Nov 29, 2006 10:56 am
Location: Edinburgh
Callsign: G-MWLX

Re: Canvas G1000

Postby www2 » Tue Aug 22, 2017 11:32 am

xkv1000 have only one display out of the GDU104X family.
I can send you all the config files and source files of the screens for GDU104X family.
And the models for GDU-1500 display and GMA-1347 audio panel.

And lots of G1000 documentation include install manuals.
www2
 
Posts: 319
Joined: Thu Apr 16, 2009 2:58 pm
OS: Ubuntu

Re: Canvas G1000

Postby Hooray » Sat Aug 26, 2017 2:06 pm

hi all,

yeah, I guess, using/extending map-canvas.xml as a testbed for porting/prototyping new layers is a pretty workable approach that would also translate into useful and tangible results that would be immediately useful to the project as a whole, without any particular focus on the G1000 itself.

Concerning examples like the tiled map on the JA37 (?), I would suggest that people actually post links to their repositories, or ideally to the corresponding Nasal code, so that we can look up the implementation more easily. There are undoubtedly other aircraft that have useful features that would benefit from being generalized using the MapStructure framework.

If/when the map-canvas.xml should no suffice as a testbed, it would be fairly easy to create/use a native Canvas UI widget/dialog to come up with new mapping/charting layers.

At that point, it would also become much easier to actually develop/test independent instances of the map using separate Canvas dialogs/widgets, which will also be a good opportuntiy to stress-test the framework, and the Canvas system as a whole, to better profile/benchmark and optimize the underlying C++ code by extending/providing the corresponding C++ hooks to avoid unnecessary Nasal overhead.

For starters, it may be a good idea to port stuff like the airport/taxiway drawing routines to use the MapStructure framework.
At that point, it would also be feasible to replace airports.xml using the MapStructure back-end, which would also mean that the whole dialog could be re-implemented using native Canvas widgets, instead of the convoluted Nasal/XML workarounds we have come to use over the years, to approximate widgets that PUI does not really support (think tabs etc).

Finally, this is something that I am really interested in helping with, but my involvement is likely to be marginal at best, if it requires downloading/installing certain aircraft/cockpits and actually "flying" a plane, I would literally need stuff to be test-able using a GUI dialog and the ufo ideally, or maybe even pre-recorded flights/fgtapes - other than that, I may only be posting pointers.

However, if you do end up using dedicated UI dialogs for developing such avionics/MapStructure layers, you will quickly come to appreciate the development pace that this approach facilitates, because dialogs can be easily reloaded using the GUI - and in fact, Canvas dialogs are by default always reloaded from disk - and even PUI dialogs can io.load_nasal() or io.include() Nasal code to accomplish this - which is to say that having a typo or other mistakes in your code does not require rebooting fgfs or resetting the whole sim - equally, have pre-recoreded flights or fgtapes for testing purposes is invaluable, too.
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Canvas G1000

Postby stuart » Thu Sep 28, 2017 7:47 pm

Hi All,

I've just pushed some changes to fgdata with OpenStreetMap, OpenAIP and VFRMap layers for the Canvas Map Layer system, which can be seen on the canvas map dialog. They use a generic Slippy Map OverlayLayer Map Layer. Additional web-based mapping can be trivially added by creating a new lcontroller. See Nasal/Canvas/map/OpenAIP.lcontroller for an example.

I've also added a Web Mercator Projection to the Canvas Map support.

The wiki will be updated shortly.

-Stuart
G-MWLX
User avatar
stuart
Moderator
 
Posts: 1629
Joined: Wed Nov 29, 2006 10:56 am
Location: Edinburgh
Callsign: G-MWLX

Re: Canvas G1000

Postby wlbragg » Thu Sep 28, 2017 7:50 pm

:Applause:
Kansas and Ohio/Midwest scenery development.
KEQA, 3AU, KRCP Airport Layout
Intel i7/GeForce RTX 2070/Max-Q
User avatar
wlbragg
 
Posts: 7588
Joined: Sun Aug 26, 2012 12:31 am
Location: Kansas (Tornado Alley), USA
Callsign: WC2020
Version: next
OS: Win10/Linux/RTX 2070

Re: Canvas G1000

Postby Hooray » Thu Sep 28, 2017 8:43 pm

Last edited by Hooray on Sun Oct 01, 2017 6:51 pm, edited 1 time in total.
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Canvas G1000

Postby Hooray » Sun Oct 01, 2017 5:56 pm

Hi Stuart, regarding Thorsten's comments on caching/pre-caching and shipping pre-downloaded maps, that is something that both Tom and James originally discussed on the forum. I cannot seem to find the topic at the moment, but Tom was hoping to also support this at the fgdata level, so that a release would be "self-contained" (imagine someone downloading a release 5+ years from now, with certain APIs/domains having changed/disappeared over time). So there's that, too. I think they were contemplating using James' SQLite groundwork, if in doubt check back with them and/or search the forum.

By the way, given the concerns involved here, thanks to Torsten's Phi/mongoose groundwork it would also not be that far-fetched to actually use FlightGear itself as the map providing service (web API) - Torsten actually once touched on the whole idea:


Atlas still in use ?
Torsten wrote:Hi,
for those using bleeding edge versions from git: you may now want to try the brand new built-in moving-map-in-a-browser.
Start FlightGear with --httpd=8080 and point your favorite web browser at http://localhost:8080/gui/map/ to get your position on an openstreetmap map.

I'd really like to use the Atlas generated maps as a layer in the browser map. Is anybody out there looking for an adventure and is able to modify the Atlas map generator to generate maps on-the-fly? Input would be three parameters: z/x/y where z is the zoom level and x/y are numeric parameters describing latitude and longitude (based on image size). Output should be a generated tile of 256x256 and format png in a memory buffer.

This could be compiled as a Apache httpd module (like osm's "renderd") or linked against a standalone webserver to akt as a tileserver for any openlayers compatible map.

[...]

What I have in mind for the map is to render the map tiles (small 256x256px fragments of a map) from flightgear scenery data on the fly when the user requests them from within the map application. Thats how openstreetmaps works and I like the idea of reusing proven concepts. There is no need at all - in fact, it's not even desireable - to do that in the main loop. Running a standalone application (or call it process if you like) creating and serving the tiles will add no load to the FlightGear process, no matter how complex the map is.

[...]

Httpd runs on the main thread and the Tile renderer will run in its own process. Completely separated from FlightGear, on a remote machine if one wants to.


Torsten



Speaking in general, it would be good to also post screenshots showing your work in action, this will attract others to get involved (see Thorsten's efforts) - and we can also reuse such screenshots on the wiki (newsletter, changelog, docs etc).

Regarding the G1000 specifically, below are some quoted comments regarding Tom's and James' discussion on coming up with a semi-persistent caching scheme for the Canvas system, which is touching on two other related discussions (discussed separately in a handful of topics):

Subject: How to display Airport Chart?
TheTom wrote:I will add a new element type to render symbols from a "Cache-Texture" to improve speed of canvasses showing lots of symbols like eg. the navigation display. You will basically be able to set position (maybe rotation) and index of the symbol in the cache-texture and possibly a color for each instance...



Subject: How to display Airport Chart?
TheTom wrote:
Hooray wrote in Tue Nov 12, 2013 12:47 pm:basically the caching method we discussed earlier, just as a core part of the canvas - I just noticed that you seem to be using the same method for window decorations already, so maybe the idea was not all that novel :-)

Yes, I've got this idea already since a long time (and lots of other people probably too^^) - I just need to get ideas for good use cases and create an easy to use interface. Completely automatic delegation of elements to "cache texture" will probably be not a feasible solvable problem.



Subject: Using a canvas map in the GUI
zakalawe wrote:
TheTom wrote in Mon Sep 24, 2012 9:40 pm:I'm thinking about using a separate canvas for each symbol so that every instance of it is just a textured quad. For efficiency reasons it would be good to draw all symbols to a single canvas/texture and put all quads into a single node. So probably I'll add a new element type for putting quads into a single element which are all rendered at once. Maybe we can even use a geometry shader to just copy the positions to the GPU and generate the full quads with the shader. Ideas and suggestions are always welcome :)


Hmm - that's possible. The issue there (at least based on the NavDisplay) is that there's quite high variance in the symbols, e.g. colour changes. For the ND I keep the symbols at greyscale, and colour them based on parameter data (active vs tuned vs inactive for navaids, for example)

Definitely needs some thought, but I think it can be an upgrade - we don't need to get the design right immediately! I do like the idea of the Canvas managing the symbol cache texture, however, since generating it by hand (as the TCAS and ND currently require) is annoying.


Using a canvas map in the GUI
TheTom wrote:
zakalawe wrote in Mon Sep 24, 2012 2:13 pm:I did some experimental work on converting the map dialog last night - I need to have some discussions with Tom about symbol instancing, since the vector symbols I'm doing for waypoints, VORs and so on should ideally be shared. I'll let Tom speak about his ideas for that.


I'm thinking about using a separate canvas for each symbol so that every instance of it is just a textured quad. For efficiency reasons it would be good to draw all symbols to a single canvas/texture and put all quads into a single node. So probably I'll add a new element type for putting quads into a single element which are all rendered at once. Maybe we can even use a geometry shader to just copy the positions to the GPU and generate the full quads with the shader. Ideas and suggestions are always welcome :)
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Canvas G1000

Postby Hooray » Fri Oct 13, 2017 9:09 pm

https://sourceforge.net/p/flightgear/ma ... /36075357/
Stuart wrote:Hi All,

I've just committed some changes to update the Select Airport dialog
to use Canvas MapStructure Layers to display airport information,
rather than the now deprecated map layers.

The change should be largely transparent to end users - the only
significant change is that your can display navigation symbols.

This is all part of a long-term effort to provide the building blocks
for a Garmin G1000 - these layers could be used for the airport
display on the MFD, and could easily be combined with the APS layer to
show a moving aircraft.

-Stuart

Image




Hi Stuart,

regarding your announcement on the devel list about your the updated airports.xml dialog and the corresponding MapStructure changes, here's the usual feedback, intended to be purely constructive - so please do take the following with a grain of salt:

  • First of all, thanks for helping update the wiki regarding the latest changes !
  • By the way, in the light of the events surrounding the infamous "Honda jet", I would strongly suggest not to use "G1000" as the name for whatever instrument you end up creating ("FG1000" might be much safer ...)
  • there seem to be two minor issues at the moment: taxiways are no longer rendered/provided, right ? And also, initial checkbox state of MapStructure layers isn't honored - which means, that the controller must probably be changed to pick up initial state ?
  • Regarding any of the existing pui/xml dialogs, my suggestion would be not to add more embedded Nasal but rather use io.include() in the nasal/open block to load code from a different Nasal file - the point being, that this means the code gets reloaded automatically, without you having to re-init the UI (i.e. faster prototyping/testing).
  • I think map.nas and generic-canvas-map.xml and the corresponding *.draw and *.model files (and loading helpers) can now be safely removed, we were using those at a time when we (you, James and myself) were still debating on the forum whether a true MVC approach would be worth the hassle or not.
  • I'd suggest to check out the SymbolCache in MapStructure and the docs in the wiki - the point being that this unifies two important concepts: styling of layers/symbols, as well as caching using the equivalent of a simple texture atlas (sc::Image based texture map actually). Which means that MapStructure layers can be pretty fast, because multi-symbol layers rarely (if ever) draw directly into the Canvas layer (group), but rather instantiate Canvas::Image nodes referring to another Canvas serving as the texture cache (using lookup coordinates). As a matter of fact, it is pretty straightforward to hack the property browser to use an embedded Canvas to preview any Canvas in the tree, including the SymbolCache itself - which is where you can find a pre-styled, and scaled, version of each instanced symbol:

    Image
  • Regarding the controller changes/additions you have made, for the UI we could also register tooltips (mouseover events) to actually display symbol-specific meta information, e.g. name/frequency of a station or length of a runway. That it something that I was originally talking about with Philosopher - and for the UI dialogs, this may be a neat addition from a usability standpoint, what do you think ?
  • Depending on your priorities, we might want to consider wrapping the MapStructure logic in a dedicated Canvas widget as per $FG_ROOT/Nasal/canvas/gui/widgets - the main benefit here is that the instantiation boilerplate would be self-contained, and only reside in a single place. We are already using the framework in 2 separate dialogs meanwhile (map-canvas.xml and now airports.xml). It is foreseeable, that we may sooner or later also instantiate the same MapStructure widget in the route manager dialog (for example). Equally, if the feature is directly available as a widget, it could be just as well reused in related dialogs for previewing certain tracks (think tutorial system or the flight recorder/fgtape system). The other rationale being that updating the underlying MapStructure framework would be much easier if people only used a corresponding widget in their dialogs, instead of the raw APIs.
  • Besides, from a functionality standpoint it seems obvious that you are already outgrowing PUI rather quickly with your additions. Futhermore, any G1000-like device will inevitably need support for independent map instances - the current PUI/XML approach is rather inflexible here. As a matter of fact, not even the pui2canvas parser I once prototyped can turn such dialogs into multi-instance dialogs, because they contain numerous hard-coded assumptions. Which is to say that it may actually make sense sooner or later to introduce a dedicated Canvas GUI dialog and use that for prototyping/testing purposes - for instance, by instantiating a corresponding "MapWidget", which would also allow us to phase out the hard-coded PUI MapWidget, which is something that James mentioned being on his agenda on several ocassions (if in doubt, check back with him, obviously).
  • My suggestion would be instantiate Richard's MFD framework in a dedicated Canvas GUI dialog, and then hook that up to the MapStructure groundwork you have been doing lately. This would have the added benefit, that it would be easy to prototype the whole system using SVG files (Inkscape) and raster images for the shell/background, which can be hooked up to Canvas Event Handlers, as per F-JJTH original's Garmin 196 work: http://wiki.flightgear.org/Canvas_Event_Handling
  • For instance, there were at least 3 different efforts trying to implement a MapStructure "radar" layer by various people (simulating radio/radar signal propagation), and they could also use such a dialog to prototype/test such layers.
  • Anything involving GeoTIFF, ESRI/shapefile or PDF support would probably be best discussed on the devel list, as this is the kind of MFD/EFB-feature that cannot be implemented without additional C++ hooks


As far as I remember, the only two issues preventing us from phasing out the PUI-based MapWidget is the lack of working data labels and the projection handling code provided by Gijs not having been back-ported yet. And you said, you were hoping to implement a lat/lon grid at some point, right ?

By the way, given the increasing degree of functionality added to FlightGear for which people actually have to be online, I would suggest introducing a dedicated online/offline mode property - mainly so that such features (multiplayer, fgcom, terrasync, slippy maps etc) can fail "gracefully" and provide a self-explanatory error message, rather than failing silently.


Anyway, thanks again for doing the unglamorous work of cleaning up some of the original mess surrounding map.nas and porting some of the legacy layers to use the MapStructure framework !
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Canvas G1000

Postby stuart » Sun Nov 05, 2017 12:32 pm

Hooray - thanks for the comments above, and apologies for not having responded to them earlier. All good pointers.

(Copying from the -devel list)

I've now got the key MapStructure layers in place, though they are not styled correctly for the G1000 yet and I'd like to replace some of them (airspace in particular) with vector data, and started on the MFD architecture.

For prototyping I hacked together a PUI dialog box, which speeds up development massively as it reloads all the Nasal code each time it's opened (thanks to Hooray for pointing this out). There's a screenshot
of it here: http://wiki.flightgear.org/File:Fg1000_mfd.jpg

There's also a wiki page of the current status here: http://wiki.flightgear.org/FG1000

Next steps are to get the MFD architecture in place - this will probably require some changes to Richard's generic MFD to support buttons that don't change the MFD pages better.

I've not yet pushed this to fgdata - I'll wait until I'm happy with the overall architectures so that there is a solid base for anyone else interested in helping out.

-Stuart
G-MWLX
User avatar
stuart
Moderator
 
Posts: 1629
Joined: Wed Nov 29, 2006 10:56 am
Location: Edinburgh
Callsign: G-MWLX

Re: Canvas G1000

Postby Hooray » Sun Nov 05, 2017 2:18 pm

Hi there,

no need to respond at all, let alone to apologize for not responding - like I said previously, this kind of feedback is merely intended to provide another perspective, hoping to save you some effort/time - besides, I am myself currently finding hardly any time to follow the various FG related channels, so there's that, too.

Regarding your latest updates - that's really looking fantastic. I am happy to see that you found the dialog-based prototyping scheme to work well enough. Like I said previously, I'd even suggest to use io.include() and/or io.load_nasal() instead of adding tons of Nasal code to the PUI/XML file directly - that will make it much easier to organize your code, too - for instance, the shuttle folks are using separate Nasal files for different MFD pages. Thus, this may be a good idea to keep in mind.

Since you haven't yet shared your PUI/XML dialog, I can obviously only guess how you are hooking up the various buttons/dials to the Nasal code - but I would strongly suggest not to use Nasal there directly - we ended up facing that dilemma in various Nasal/Canvas based efforts using the NavDisplay/MapStructure code, and we found that to be rarely a good idea.

I think James and Richard were recently discussing the same dilemma in the context of the "touch animation" - in a perfect world, we'd be using some kind of IPC mechanism here (think Emesary) - but I have found another thing to work exceptionally well to encapsulate instance-specific bindings: just use James' addCommand() API - which is a Nasal API to register fgcommands that end up calling Nasal code.

That way, you can have dialog/instance specific fgcommands and use those for setting up the bindings of your G1000 MFD. The point being here that this also encapsulates event-handling in a sane fashion - for instance, even Torsten's Phi/mongoose UI is able to use the fgcommand API - thus, anything provided in the form of fgcommands can also be safely called by other front-ends, including Torsten's Phi work, but also James FGQCanvas back-end.

Like I mentioned a few weeks ago, we do already have working C++ code that hooks up Torsten's groundwork to the Canvas system, so that we can stream a Canvas texture (think MFD) via httpd - thus, if your underlying code registers its own fgcommands provide an interface, the front-end becomes irrelevant, as long as it can run fgcommand (which even the telnet/props interface can do). Besides, the mechanism itself is scaleable, too -and it can be just as well used for the cockpit/panel use-case.

Obviously, this is assuming that you are not already using a superior IPC mechanism along the lines of Richard's MFD framework.

Regarding the PUI/XML dialog itself, my suggestion would be to consider doing away with the dials and instead use buttons/checkboxes for most controls - simply because those are natively supported by the Canvas UI system, so that it would be straightforward to use a native Canvas GUI dialog, which is known to provide much better performance than a PUI-based CanvasWidget hosted in a PUI dialog.

As a matter of fact, I also took the liberty to add your updates to the newsletter, including an invitation for people to help with creating a G1000-style "skin" (or even a corresponding 3D model) so that we can use a skinnable-UI actually resembling the real thing.

Even when just using a native Canvas UI dialog it would be possible to set up buttons and set a custom background image resembling controls on the real device, and tooltips would be also straightforward to do, too.

Just like you mentioned in your announcement: Using a dialog-based prototyping setup makes sure that you don't see too many aircraft- or use-case specific assumptions added into the code (think fdm, autopilot, route manager, systems modelling) - that is why it would really be a good idea to review/generalize the idea of using "driver hashes" that contain (and encapsulate) implementation-specific details.

For the MapStructure layers that we originally created, that meant also that the same layers could be driven by AI/MP nodes, but also by instant replay/fgtape data, or inter-linked fgfs instances set up in a master/slave fashion - imagine a setup with a handful of machines and screens running several instances of the same FG1000-style display.

As you and others mentioned originally on the devel list, one key requirement here to be relevant to student pilots or actual pilots is having access to real/other navdata - this is why it is important to encapsulate any/all navcache queries and also come up with a corresponding "driver hash" - which means that people wanting to use NaviGraph data or an actual AIRAC cycle, can simply provide a corresponding driver hash.

Admittedly, I do realize that it may seem a little far-fetched to implement this degree of lose coupling at this point, but I do believe that this could motivate other aircraft/avionics developers to get involved in the creation/development and maintenance of this system, if it can really be used on any aircraft, and possibly even for non-aircraft use-cases. The extra500 folks come to mind, since they have meanwhile enormous experience creating a fairly complex Canvas based system - but one that lacks the genericity needed to be useful elsewhere (at least last I checked according to their statements).

Thus, if customization and styling/skinning become key-concepts supported by the MFD framework, this could motivate more people to get involved in this - providing support for alternate front-ends (along the lines of Phi or FGQCanvas) may just another step in that direction.

One important thing here is not to access aircraft/system-specific properties without using one layer of indirection to encapsulate such implementation details - that will also come in handy for performance reasons, i.e we were using a stacked approach to getting properties by copying their values to a hash and only doing getprop() calls once (aka memoization) - more recently, Richard seems to have come up with a better formalized method in the form of something he called "UpdateProvider" (?)

Now, regarding your recent MapStructure additions, I think it's not just your new layers that may need some work in the styling/caching department - as far as I remember, there are also still a few hard-coded assumptions where we expect the underlying Canvas to be 1024x1024, e.g. stuff where we set up clipping regions etc.

When I worked on the ND dialog, I ended up instantiating multiple NDs with different resolutions to check that most of these issues were removed.


Again, I don't expect any response - just hoping to save you some time and energy when working on this ;-)
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Next

Return to Canvas

Who is online

Users browsing this forum: No registered users and 4 guests