Board index FlightGear Development Canvas

How to display Airport Chart?

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.

Re: How to display Airport Chart?

Postby Gijs » Thu Nov 07, 2013 5:11 pm

Hooray wrote in Thu Nov 07, 2013 4:10 pm:Just checked (fgdata/master HEAD): seeing >= 1.5gb RAM in use at KSFO, 744

With my local 744 version, I get ca. 0.9 GB at KSFO...
Airports: EHAM, EHLE, KSFO
Aircraft: 747-400
User avatar
Gijs
Moderator
 
Posts: 9544
Joined: Tue Jul 03, 2007 3:55 pm
Location: Delft, the Netherlands
Callsign: PH-GYS
Version: Git
OS: Windows 10

Re: How to display Airport Chart?

Postby Hooray » Thu Nov 07, 2013 5:13 pm

I guess it's because of different config, settings, scenery, OS etc - because I really used "stock" git sg/fg/fgdata to check this, but the eye candy stuff is rather maxed out here, because the computer is fairly powerful. I'll try again without traffic, random buildings, vegetation, advanced weather and without quality level 5 :D

EDIT: 1gb now, on 64 bit Lunux
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: How to display Airport Chart?

Postby Philosopher » Thu Nov 07, 2013 7:39 pm

Sorry, had to run (almost late for school!)

Anyways, most of it happened during and after "loading scenery", I think it was probably the scenery (omega95's WSSS, relatively heavy on the buldings & terminals & jetways & runway stripes...). So I guess it's just more common than I thought, but I thought before (before Git, I guess) I could usually run FG & Firefox simultaneously.
Philosopher
 
Posts: 1593
Joined: Sun Aug 12, 2012 7:29 pm

Re: How to display Airport Chart?

Postby Hooray » Thu Nov 07, 2013 7:46 pm

Well it definitels is a good idea to look at memory consumption - last time I refactored the airport dialog, I also accidentally started drawing some stuff multiple times - which is easy to miss if you are not familiar with the code, and not looking into the property tree ... I already asked TheTom if we could publish update(dt) for each canvas element/group in the property tree, so that we can more easily identify problematic stuff - and knowing how much time and RAM is required would obviously be useful - Hyde also mentioned that he ran into performance issues when he adopted the canvas. But like I said previously, those are probably due to stuff happening that isn't intended, such as having more canvases/groups/elements than intended.
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: How to display Airport Chart?

Postby Philosopher » Fri Nov 08, 2013 3:48 am

Well now it's 996MB @ KSUU, so something of a scenery problem, but anyhow, it's fine (can leave Firefox open now). Getting this error (EDIT: nm, disappeared after updating FG/SG :():
Code: Select all
Nasal runtime error: No such member: new
  at /Users/philosopher/Documents/FlightGear/fgdata/Aircraft/747-400/Models/Cockpit/Instruments/EICAS/primary.nas, line 389
  called from: /Users/philosopher/Documents/FlightGear/fgdata/Nasal/globals.nas, line 105


P.S. I'm working on a Git GUI to browse your changes. Could you give a basic summary so I can see what happened? That will help me out with the structure of it; it's a foggy trail of duck-typing I think :p.
Philosopher
 
Posts: 1593
Joined: Sun Aug 12, 2012 7:29 pm

Re: How to display Airport Chart?

Postby Hooray » Fri Nov 08, 2013 11:39 am

that's weird, I didn't even touch the file mentioned in your error message and I'm not seeing it here - did that start happening after I removed hardcoded loading of those files ?
If so, I need to look at using some of your include() helpers instead...
Regarding my changes, where do I start ? :lol:
Basically, it's all discussed in this thread - actually I implemented all changes that I suggested Gijs to look into if he finds the necessary time:

  • get rid of global variables and use instance variables: http://wiki.flightgear.org/Howto:Use_SV ... nstruments
  • identified all important drawing routines and move them into *.draw files
  • changed to dynamic loading of *.draw *.model and *.layer files
  • implemented poor-man's controller hash to move use-case specific conditionals out of the draw files, and back into the instantiation, i.e. Gijs EFIS class
  • started identifying stuff that is not specific to drawing, but to what is to be drawn, i.e. Model stuff - such as positioned queries, moved those out into *.model files
  • some more work on supporting more than a single ND MFD instance per aircraft
  • renamed a handful of SVG identifiers to avoid naming conflicts and to simplify usage of SVG IDs as member fields
  • moved all of the setlistener setup out of the fdm-initialized stub right into the ctor of the Efis class (actually that's controller stuff...)
  • modified airports.xml for testing purposes, to easily test each new layer without having to add new dialogs


I think that pretty much covers it, but I didn't look at the commit messages ...
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: How to display Airport Chart?

Postby Philosopher » Fri Nov 08, 2013 1:31 pm

I think I'm getting the hang of the structure; after reformatting map.nas line-by-line I can say I did something more than glance at it ;). (Can I get access to the repo to commit that? I'll give you access to mine ;))

A couple comments:
  • The fdm-initialized happens at every reset, so it looks like it's attempting to make multiple instances? I.e. without deleting the old one?
  • I guess you're still using the removeAllChildren() logic? I personally, as I explained above, would find it cleaner to support Symbol instances that keep track of themselves and have a simple update() method (which wouldn't necessarily need to redraw all of the time). That's sort of a model->controller issue. Would you like me to try this idea?
  • Some of your member declaring in map.nas is a bit weird. When you declare members in a hash, if they're constant (i.e. non-mutable) they become "defaults", otherwise they're more of static members. If the case of your listener list, it appears that it is shared by /all/ Layers (forgot what the object was), not made individually for one.
  • Otherwise, thanks for your efforts, particularly in advocating for MVC and moving things to *.draw files (aka leading by example) :D
Philosopher
 
Posts: 1593
Joined: Sun Aug 12, 2012 7:29 pm

Re: How to display Airport Chart?

Postby Hooray » Fri Nov 08, 2013 1:49 pm

map.nas is not really doing very much here - in fact, I am considering of either rewriting it completely, or removing it once PUI got phased out, because it's primary "purpose" for now is that it can re-use those *.draw, *.model and *.layer files to use them in GUI dialogs, like the airport selection dialog, because it handles layer creation etc.

So the main concern back then was to ensure that we don't end up with lots of duplicate code - MFD instruments like the 744 ND still need to call the various ctors directly.

And yes sure, I really don't mind giving access to the repo, all feedback and input is appreciated - I think you even had access previously, but I deleted/re-cloned yesterday, because pushing would take too long otherwise, as I hadn't updated gitorious in months ...

Your points are valid, as I mentioned in the source code comments - but that's a limitation of the original code, I really didn't change anything there (yet) - but I'm completely aware of the FDM signal handler and its issue, as you can tell from the comments: https://gitorious.org/fg/hoorays-fgdata ... D.nas#L360

And yes, the removeAllChildren() stuff is basically still in place, it's just hidden deeper in various abstraction layers - at the moment, we are using .init() calls to update each layer, which will internally talk to the model and trigger a .notifyView() calls - which ends up calling removeAllChildren(). I'm aware of the issue here, but I didn't bother optimizing things there, because the original code did the exact same thing. But I do recall that you had some clever scheme in mind to update things in a more efficient fashion. In the long run, we'll want to use what TheTom and Zakalawe talked about though, i.e. C/C++ level support to optimize this.

If you have a model/controller concept in mind that handles these things, sure go ahead - we really don't have any advanced controller support at the moment, and the Layer/View and model stuff is fairly messy, too - but on the other hand, it's really just 5-10 lines of code per files, so easy to update - without having to touch tons of other places/files.

I would however prefer if I could first of all push my latest changes, so that there's no unnecessary conflict introduced by you working on certain stuff.

re: map.nas being weird, that's an understatement - its whole point was to move Stuart's useful Nasal code out of the airport selection dialog, and build layers procedurally - basically what I'm doing right now with Gijs' code, too - to be honest, I would prefer to yank it completely at some point, but as long as PUI is in use, it does serve a purpose still ... and I'm not overly eager to add tons of Nasal code to each dialog just to show a certain layer. So either we'll wait, or I'll rewrite it with our requirements in mind.

So map.nas is really just the glue code that currently allows us to easily reuse *.draw/*.model files for different purposes - once we've established this as the best practice, it can go away and be replaced with something more appropriate, and something that "deserves" being in the canvas namespace ... :D

I'll be pushing my latest changes so that you can have a look (ignore map.nas, unless it's impossible) - we really should be focusing on the MVC aspects, to ensure that things are reusable for different aircraft, instruments and GUI dialogs.

PS: Thanks for the comments!

EDIT: Is there possibly a precendece issue I'm unaware of when using a line like this:
me.efis_path ~ me.efis_switches['range'];
I'm getting this: Nasal runtime error: non-numeric string in numeric context

Trying parentheses now :D
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: How to display Airport Chart?

Postby Hooray » Fri Nov 08, 2013 2:17 pm

okay, I pushed two more commits and added you again as a contributor.

But again, I suggest to leave map.nas alone for now - it's more important to establish the MVC separation and generalize the code that it can be easily reuse in other aircraft, instruments and dialogs. Also, I really want to support multiple ND instances per aircraft, to ensure that the design is sufficiently decoupled.

Also, we'll probably want to stop loading stuff into the canvas namespace, and instead use a sub namespace - something like canvas.MFD (see the end of map.nas) - this is to avoid breakage, given the amount of *.draw files we have now, and they'll be mostly written by people who are not as familiar with the canvas as TheTom - so better to be careful here and use a separate namespace.

The listener issue can be solved by overloading setlistener() at the namespace level in the EFIS class, so that it appends() all IDs to a vector and cleans up things during reset
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: How to display Airport Chart?

Postby Hooray » Fri Nov 08, 2013 3:39 pm

I personally, as I explained above, would find it cleaner to support Symbol instances that keep track of themselves and have a simple update() method (which wouldn't necessarily need to redraw all of the time). That's sort of a model->controller issue. Would you like me to try this idea?


if/when you try this, you may find it easier to copy a certain layer (i.e. *.draw, *.model and *.layer) and customize things there - such as having "fixes-new.layer" etc - you should then be able to modify things without having to touch anything else. To use your own Layer/Model/Controller classes, just add them to the top of each file as required - that way, you don't even need to touch any of map.nas stuff. In navdisplay.mfd, you'll then want to instantiate your new layer in the newMFD ctor: https://gitorious.org/fg/hoorays-fgdata ... y.mfd#L125

Proceeding like this should allow you to reuse all useful stuff, while ignoring the ugly map.nas file completely (unless you want to test your layers in a dialog)

For testing purposes, you'll find that fixes & AI-traffic have usually tons of symbols.
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: How to display Airport Chart?

Postby Philosopher » Fri Nov 08, 2013 8:50 pm

Hey, how does zoom get handled?
Philosopher
 
Posts: 1593
Joined: Sun Aug 12, 2012 7:29 pm

Re: How to display Airport Chart?

Postby Hooray » Fri Nov 08, 2013 9:07 pm

if you're referring to zooming in on the NavDisplay, there's a range knob: https://gitorious.org/fg/hoorays-fgdata ... ay.mfd#L26

This is mapped to the property (key = value). Internally, the navdisplay code only ever uses the hash key, to abstract away property naming differences between different aircraft.
Which is what the get_switch() helper method is doing.
So you only need to look for me.get_switch('toggle_range'); - which is mapped to the right propery, as declared by the aircraft developer in ND.nas

However, Gijs' code used the rangeNm constant instead - which I have turned into an alias for the above method.

Ultimately, the canvas map range property is simply set via the getprop() call in the update() method: https://gitorious.org/fg/hoorays-fgdata ... y.mfd#L390

Zooming via the GUI deals with the same canvas/map property (see the property browser), but uses some other messy construct to hide the details, I think there's some handleZoom() method in map.nas - but I'd just ignore that for now.
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: How to display Airport Chart?

Postby Hooray » Fri Nov 08, 2013 9:51 pm

I have been playing around with some of the heavier layers (fixes, traffic) etc - and I think, we need to re-introduce an old idea: having something like a "RangeAwareLayer" which is mapped to a single canvas group for each layer, but each supported range being mapped to a sub-group - that way, we can always populate all layers with lower ranges, i.e. instead of writing all positions to a single layer when rendering 160 nm, we would be populating all lower ranges and making them visible - that way, toggling layers is just a matter of hiding the higher range layers - and updating is just a matter of using layer.findElementById(fixname).removeAllChildren();

Until we have a fast C/C++ function to get a delta of positioned queries, we can run this in Nasal space, in a worker thread:
Code: Select all
##
# http://forum.flightgear.org/viewtopic.php?f=71&t=21139&start=15#p193449

var find_in = func(what, where) {
 foreach(var e; where) {
  if (e.id == what.id) return 1; # found
 }
 return 0; # not found
}

var diff = func(old_vec,new_vec) {
 var removed = [];
 var added = [];

  foreach(var new_elem; new_vec) {
     if(find_in(new_elem, old_vec)) continue; # not new
     append(added, new_elem);
  }

  foreach(var old_elem; old_vec) {
   if(find_in(old_elem, new_vec)) continue; # not removed
   append(removed, old_elem);
  }

print("Removed: ", size(removed));
print("Added: ", size(added));

return [removed, added];
}


and then update the view (canvas groups) accordingly, by removing out-of-range symbols and adding new ones.
The worker thread would be running once per frame and populating the added/removed vectors, which would then be used to look up the canvas IDs (fix-sfo111) in the canvas tree.
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: How to display Airport Chart?

Postby Philosopher » Fri Nov 08, 2013 10:58 pm

Yeah, that's basically what I'm attempting with my Symbols, except with mine there'll be more abstraction and a Nasal-space representation for it, too (along with update() methods). I have a difference function for Nasal currently (might be a little more efficient than yours ;)), I'll see when I can finish/push my initial code, probably in a few hours if not immediately. (Shouldn't conflict any, besides my indentation changes ;))

P.S. I don't think we even need to run the thread once a frame, every ~0.3 seconds should be good if we allow a little padding.
Philosopher
 
Posts: 1593
Joined: Sun Aug 12, 2012 7:29 pm

Re: How to display Airport Chart?

Postby Hooray » Fri Nov 08, 2013 11:17 pm

don't worry, not much waiting here to be pushed anyways ... pretty satisfied with the overall state and re-usability at the moment.
Optimization is next, we'll use some hybrid approach: RangeAwareLayers that know about all valid ranges, and then only write relevant symbols to each sub group, and if symbols could be selectively told to update (show/hide) themselves that would also be useful - especially because calling removeAllChildren() is pretty slow (on avg, 200-300 symbols are added/removed when toggling the range)- so it would be better to hide all out-of-range symbols, add them to a vector of symbols that are to be removed and then do that via split-frame loops over several seconds.

We can also collect items that are likely to get out of range and update those via maketimer() background jobs, to hide them and mark them for removal.
Another possibility would be propagating items between layers, i.e. from 10nm to 20nm (this really IS touching the realms of advanced memory management, i.e. generational GC!) :lol:

Also, something else to be kept in mind (Zakalawe listening?): we could even further reduce reduce the overhead of running positioned queries by not just specifying a max range, but also a min range - because that would allow us to selectively update each range-layer individually. That way, we could even get fancy and do some background processing to update invisible layers transparently, which would mean no more noticeable delays when switching ranges, because all the positioned queries would already be done, and the the symbols would be right in the tree, the group would just need to set its visibility flag.

That sounds all pretty good and do-able, we only really need two abstractions: stuff that's static (navaids, fixes etc) and stuff that's moving (other traffic), and then use maketimer() to update things in a smart fashion.

PS: formatting changes are appreciated :D

PS: the current model is too inflexible to support such sophisticated stuff, i.e. you'll really need to add a real model and a controller, and extend navdisplay.mfd to add your own layer, sorry ... :oops:
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

PreviousNext

Return to Canvas

Who is online

Users browsing this forum: No registered users and 8 guests