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 Hooray » Mon Nov 11, 2013 12:17 pm

zakalawe wrote in Sat Nov 09, 2013 1:51 am:BTW a minimum-range query doesn't make the C++ code much faster, so I would rather keep the API simple for FGPositioned.
[...]
Regarding spatial queries, on the nav-cache side, delta queries would be complex to support. What the C++ NavDisplay does is keep a persistent list which is updated infrequently - only when a setting changes (range, view options config), or when the aircraft moves > 1nm. In C++, computing the delta of two arrays is fast, and that's what I would suggest to avoid the 'remove all children' logic, which is obviously unfriendly to the Canvas. What I'm not sure about, is if Nasal currently has a nice API to compute the difference (added / removed items) between two arrays, but if it's missing I am sure it can be added.


Philosopher implemented a neat little helper class for geo.nas that supports cached delta-queries for positioned objects: https://gitorious.org/fg/hoorays-fgdata ... o.nas#L326

To see for yourself, just run the .test() method.

This works great and we'll be using it for our prototyping - but switching range anywhere between 200+ <-> 640 nm is definitely having an impact here (even without any canvas ND being rendered - getting a delta for 320->640 takes ~ 30 seconds here!), so we should definitely add a C/C++ extension function that gives a delta() of two vectors - or ideally use cppbind to re-implement Philosopher's class as part of the positioned API (it's just a handful of methods). I think Tom has already ported most of NasalPositioned to use cppbind - is there any reason not to extend it accordingly and use it ?

If extending NasalPositioned for 3.0 is a no-go, then, we should really look again at supporting an optional min-range for queries, to help reduce the workload ...

Otherwise, we need to distribute the workload across several frames, which would mean that ND updates would no longer be instant.
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: 11325
Joined: Tue Mar 25, 2008 8:40 am

Re: How to display Airport Chart?

Postby Gijs » Mon Nov 11, 2013 12:22 pm

On the real thing, navaids and the like aren't shown at such large ranges. So for the instrument that's not an issue. For a map dialog that could be different, but you can wonder if it serves a purpose to show thousands of items cramped together on a relatively small map...
Airports: EHAM, EHLE, KSFO
Aircraft: 747-400
User avatar
Gijs
Moderator
 
Posts: 9363
Joined: Tue Jul 03, 2007 2:55 pm
Location: Amsterdam/Delft, the Netherlands
Callsign: PH-GYS
Version: Git
OS: Windows 10

Re: How to display Airport Chart?

Postby Hooray » Mon Nov 11, 2013 12:41 pm

right, but if we don't look at improving performance right now, we cannot realistically replace the map dialog or the navdisplay for 3.0 - I really have a very powerful computer here, and so do most contributors - but end-users may not have 8 cores, 8gb RAM, and 2048MB of VRAM - so we need to be careful here, just because we can run such unoptimized code without framerate getting below 50 fps, doesn't mean that end-users will be able to enjoy these features. It's a common problem that developers tend to have "high-end" computers and consequently develop software without ever seeing how badly their code performs on average hardware.

As I previously mentioned, it's basically still the original/unmodified code - but replacing the map dialog or the navdisplay is not an option as long the backend code is not getting faster/smarter.
And I'm not just talking about Nasal here, there's only so much we can do in Nasal space here...

Admittedly, due to the way the update() loop is structured and due to the timer running it at 0.05, we're updating the canvas basically at framerate - with dozens of setprop() calls each frame, each resulting in a complete canvas update, including all groups apparently (I added some logging to CanvasElement.cxx, and also saw non-modified groups being re-rendered, despite not having been updated)

Also, the canvas::map mode actually knows current range, ref lat/lon and heading - in other words, it could be a little faster by checking the ratio of pixels vs. position change - to have some update() threshold and not update things that have not changed significantly enough to be visible to the user - just imagine the ND at 320 nm showing airports: even when flying at >= 400 nm, it would not need to redraw everything at frame rate.

We /could/ add those optimizations at the Nasal level if we had an option to either disable internal canvas updates or simply make "atomic" updates that only result in a single update()

I haven't checked the canvas::map code, but it also seems that it is updating stuff that is in groups outside the current range, i.e. the number of totally updated elements doesn't get smaller here when rendering groups that have drawables beyond the selected range.

Given that a single canvas::update() seems to trigger a recursive update for all sub-groups, I have thought about using separate canvases for each layer, analogous to the caching mechanism discussed earlier - i.e. include each layer via canvas:// to reduce the number of update() calls, separate textures should never become "dirty" when referencing them in the ND map, so they would need to be managed separately.

Looking good, can you get this working so we can replace the map-widget for 3.0?


So from my perspective, the question is not so much if we can finish this for 3.0 - because the Nasal changes are straightforward, and Philosopher has been making tons of progress during the weekend- which is so much more sophisticated than the original hack I put together, the real question is if we can discuss the required C++ changes and optimizations as early as possible, in order not to hit the 3.0 code freeze - adding/udating Nasal code can even be safely done during the code freeze, but C++ code is a different issue obviously. But we cannot optimize things purely from Nasal space here ...
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: 11325
Joined: Tue Mar 25, 2008 8:40 am

Re: How to display Airport Chart?

Postby Gijs » Mon Nov 11, 2013 3:20 pm

I don't think my system classifies as "high end" compared to what you're mentioning (4 cores, 4GB RAM). I'm well aware that we need to optimize wherever we can. I just meant to say that we should not waste time trying to optimize things we won't be using. I never intended to update everything at frame rate, it was just the easiest to do for a quick proof of concept. ;-) We obviously need to update the various layers at different frequencies. TCAS for example requires frequent updates, while static POI only need an update after flying so many miles.

For airports we don't know what the logic behind that is. The real instrument doesn't show all airports. The easiest trick would be to only show airports with minimum runway length, but then we're still displaying different airports than the real one. Need to do some more document hunting :-D

Given that a single canvas::update() seems to trigger a recursive update for all sub-groups, I have thought about using separate canvases for each layer, analogous to the caching mechanism discussed earlier - i.e. include each layer via canvas:// to reduce the number of update() calls, separate textures should never become "dirty" when referencing them in the ND map, so they would need to be managed separately.

Hm, that's an option yeah. It doesn't sound right though. I feel that Canvas should be able to deal with this, as it's something that we'll see on lots of instruments and dialogs. Best to fix the root issue instead of creating workarounds.

To answer one of your comments:
@Gijs: the original check doesn't make sense to me ('or' vs 'and'), still I didn't want to change it for now
# for reference:
# https://gitorious.org/fg/fgdata/source/ ... D.nas#L624

The != should have been == :-)

On line 48, there's a typo; 'B7400-400'.
Airports: EHAM, EHLE, KSFO
Aircraft: 747-400
User avatar
Gijs
Moderator
 
Posts: 9363
Joined: Tue Jul 03, 2007 2:55 pm
Location: Amsterdam/Delft, the Netherlands
Callsign: PH-GYS
Version: Git
OS: Windows 10

Re: How to display Airport Chart?

Postby Hooray » Mon Nov 11, 2013 3:38 pm

We obviously need to update the various layers at different frequencies. TCAS for example requires frequent updates, while static POI only need an update after flying so many miles.


This is now supported by editing the aircraft specific configuration hash at the top of the file - however, internally, I think the canvas will still do the whole thing, or I'm misunderstanding the logging I added and the code I checked so far. Basically, "heavy" layers should at least have a flag that renders them to a separate osg::Image, to reduce unnecessary element::updates.

I feel that Canvas should be able to deal with this, as it's something that we'll see on lots of instruments and dialogs.

I am currently experimenting with having a single boolean "atomic-update" flag for each canvas::Element to directly return in the ::update() method if it's set, and recursively traverse the whole group when it's unset again - but I'm getting a segfault here, so I must be missing something still ... but that would allow Nasal code to disable all other updates, run all setprop() stuff and then update things only once.

Need to check if that's helping or not ...
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: 11325
Joined: Tue Mar 25, 2008 8:40 am

Re: How to display Airport Chart?

Postby TheTom » Tue Nov 12, 2013 9:54 am

Hooray wrote in Mon Nov 11, 2013 3:38 pm:I am currently experimenting with having a single boolean "atomic-update" flag for each canvas::Element to directly return in the ::update() method if it's set, and recursively traverse the whole group when it's unset again - but I'm getting a segfault here, so I must be missing something still


What do you want to achieve with this? Unless you manually call update() on an element, it is called exactly once per frame. Also what is the problem with update? It applies all changes made to the property tree to the elements and checks if some other updates are required. The canvas is not drawn more then once per frame (update != rendering!).

Hooray wrote in Mon Nov 11, 2013 12:41 pm:I added some logging to CanvasElement.cxx, and also saw non-modified groups being re-rendered, despite not having been updated

How can you see groups being rendered? Groups are never rendered themselves only elements really representing something renderable. Also most elements (appart from paths) are just forwarded to OSG and rendered there. You can not re-render just a single group. Either the whole canvas is drawn or nothing. Updates of single elements or groups of elements are not possible (and are also not possible to implement). If drawing is really the slow part, then it could help to render complex parts of the scene which do not change (often) to another canvas and include it as image.

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...
TheTom
 
Posts: 321
Joined: Sun Oct 09, 2011 10:20 am

Re: How to display Airport Chart?

Postby Hooray » Tue Nov 12, 2013 11:47 am

Sorry, maybe my terminology is a bit off ...

How can you see groups being rendered? Groups are never rendered themselves only elements really representing something renderable.

I added it there, because a group is a derived element, so I may have missed something there, or completely misunderstood what I saw - technically, a simple canvas ND shouldn't be slower than the built-in NavDisplay or the map dialog, as long as it doesn't need to write lots of updates/new symbols into the canvas tree, but I am seeing performance issues, will do some more profiling to understand what's going on in the C++ code and how the Nasal code should be structured to make better use of the canvas.

You can not re-render just a single group. Either the whole canvas is drawn or nothing. Updates of single elements or groups of elements are not possible (and are also not possible to implement).

Here, I was I referring to rendering individual groups to textures and merging them at the canvas level, to avoid updates of complex groups. I started looking into that when I realized how much faster a group is if it's referenced as a raster image via canvas://

If drawing is really the slow part, then it could help to render complex parts of the scene which do not change (often) to another canvas and include it as image.

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 :-)

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...

Yes, that sounds like a good idea - thanks for looking into it!
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: 11325
Joined: Tue Mar 25, 2008 8:40 am

Re: How to display Airport Chart?

Postby TheTom » Tue Nov 12, 2013 6:12 pm

Hooray wrote in Tue Nov 12, 2013 11:47 am:but I am seeing performance issues, will do some more profiling to understand what's going on in the C++ code and how the Nasal code should be structured to make better use of the canvas.

Yeah, I'm also interested in any performance issues. For example a canvas is always redrawn if any property changes within the current frame, even if the same value is just written again or changes are too small to be noticeable. Also if a property of a hidden element/group is changed, the canvas is redrawn. Maybe checking if properties have changed enough will gain some speed, but I'm not sure if this will be noticeable at all (only if always the same values are written to the tree...)

Hooray wrote in Tue Nov 12, 2013 11:47 am: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.

If time allows I will also look into the array diff problem. Which fgdata clone should I use for the current state of the ND display?
TheTom
 
Posts: 321
Joined: Sun Oct 09, 2011 10:20 am

Re: How to display Airport Chart?

Postby Hooray » Tue Nov 12, 2013 7:01 pm

Yeah, I'm also interested in any performance issues. For example a canvas is always redrawn if any property changes within the current frame, even if the same value is just written again or changes are too small to be noticeable. Also if a property of a hidden element/group is changed, the canvas is redrawn. Maybe checking if properties have changed enough will gain some speed, but I'm not sure if this will be noticeable at all (only if always the same values are written to the tree...)

right, I think now we're finally talking about the same thing :D

Yes, currently we have a fair amount of code doing fairly "dumb" things like running setprop() even though nothing is modified, I haven't yet optimized anything there - but this is straightforward to optimize at the framework level, Philosopher has come up with a clever MapStructure scheme, and once that's integrated/ported and used, things will be much better.

I don't really want to touch anything in map.nas, because it's obvious that it can go away completely due to Philosopher's work - even if that may take another 3-4 rainy weekends to fully materialize :D

Checking if a property has sufficiently changed may be useful, but it's also a form of "micro-optimization", I mentioned that when I talked about map ref-lat/ref-lon and range being possibly useful to determine if a symbol's position actually changed pixel-wise or not. Currently, the code will simply write lat/lon/range at framerate into the canvas tree, so those are not canvas issues, they are simple coding issues, because that will result in update() calls - on the other hand, we probably cannot expect Nasal programmers to be aware of "best practices" here - after all, Nasal is a garbage-collected language and people will usually not be aware of low-level internals like these, many users here first started programming due to FG and Nasal scripting.

"same value written to the tree", that's typically only happening when being stationary on the ground (or in the air) - so probably not worthwhile to optimize specifically for this case unless I'm missing something. But ignoring updates in hidden groups would make sense in my opinion. Also, does the canvas::map mode actually check the positions of symbols before they're drawn ? I am asking because in another test, I added tons of data (fixes) to a layer in range 320 - and then switched down to 80, and I was hoping that it would "filter" out invisible symbols due to current lat/lon/range settings, instead of updating everything ?

Completely automatic delegation of elements to "cache texture" will probably be not a feasible solvable problem.

I noticed that too a couple of days ago, when I played with using a 2nd texture as cache - because it's basically a placement problem, i.e. finding an area in the texture where the bounding box of the group fits in, so it's not completely trivial once there are possibly dozens of symbols in use.

If time allows I will also look into the array diff problem.

for now, we will just use the Nasal-space algo, but at some point extending NasalPositioned/NasalPositioned_cppbind would be helpful to make this faster, but obviously that's not a Canvas issue at all :D


Which fgdata clone should I use for the current state of the ND display?


We are working on the same repo/branch: https://gitorious.org/fg/hoorays-fgdata ... ration-wip
I think Gijs is waiting for us to finish before he proceeds.
From a performance standpoint, you only need to run the ND, either by starting the 744, or by using the ufo and pasting the snippet into the console I posted above, which will also work when using the ufo - but also to follow arbitrary AI traffic. When instantiated a couple of times, we'll see events/nasal and the canvas system being hotspots, I started using real profiling with the profiler-start fgcommand that you added.

Coding-wise, it's all still unoptimized and we're aware of it, there's lots of polling and setprop() calls at framerate, we will be using listeners and timers once MapStructure.nas is becoming more feature-complete, so that the map.nas stuff can be phased out, and all the draw/layer/model files replaced with Philosopher's sandbox'ed approach, which clearly is superior.
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: 11325
Joined: Tue Mar 25, 2008 8:40 am

Re: How to display Airport Chart?

Postby Gijs » Mon Nov 18, 2013 2:56 pm

Hooray wrote in Tue Nov 12, 2013 7:01 pm:I think Gijs is waiting for us to finish before he proceeds.

Right :-) I'd like to have this done in time to be included with 3.0, so please tell me if there's something I need to check or work on.
Airports: EHAM, EHLE, KSFO
Aircraft: 747-400
User avatar
Gijs
Moderator
 
Posts: 9363
Joined: Tue Jul 03, 2007 2:55 pm
Location: Amsterdam/Delft, the Netherlands
Callsign: PH-GYS
Version: Git
OS: Windows 10

Re: How to display Airport Chart?

Postby Hooray » Mon Nov 18, 2013 3:26 pm

Well, as long as you continue your work within navdisplay.mfd there's very little chance for breakage/duplicate work - just check out the branch (test it first!) and if it's working without regressions, I'd suggest to base your new work on it - I'll have to get in touch with Philosopher to see what else needs to done to make his MapStructure framework complete enough to replace map.nas entirely. I think we have about 4 weeks remaining until the feature freeze for 3.0 - on the other hand, this is not a core feature, it's an aircraft feature - but the backend code is obviously shared with the airport-select dialog.

Regarding navdisplay.mfd, you'll just want to make sure:
- use lookup keys for aircraft/cockpit specific properties (ND switches), and not use getprop() directly - or the same code won't work on other aircraft using different properties
- move drawing stuff out of the navdisplay.mfd file into some custom layer file (we can also handle that once we port things over to Philosopher's MapStructure framework tho)
- to add new elements, just edit the SVG file and then extend the config hash at the top of the file, see: https://gitorious.org/fg/hoorays-fgdata ... y.mfd#L133
- new layers can be added to the "layers" vector: https://gitorious.org/fg/hoorays-fgdata ... y.mfd#L130
- but obviously, those would need to be added as *.draw, *.model and *.layer files first - which we're hoping to revamp/replace with MapStructure.nas - but it's still straightforward to do, and technically better than adding "hard-coded" drawing stuff to the code, because it can be more easily reused.
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: 11325
Joined: Tue Mar 25, 2008 8:40 am

Re: How to display Airport Chart?

Postby Hooray » Wed Nov 27, 2013 7:37 pm

Okay, here's a little update: Hyde has started integrating the new ND framework into his 777-200ER aircraft, and it only took very little changes so far.
Image

Now, Gijs & Hyde, bothing being fgdata contributors/committers, I am hoping for them to review the code and work out how to commit the framework in its current state to fgdata, and add any missing/required airliner features until the 3.0 feature freeze. I am volunteering to handle the structural side of things, i.e. generalization and abstraction etc.
I have been in touch with Philosopher regarding his improved mapping framework (codename: MapStructure.nas) and we can look into replacing the backend code once/when it is finished, the code in navdisplay.mfd is prepared for this and should only require very few changes.

I would also appreciate it if either the 744 or the 772 could support multiple NDs, the code is already prepared/ready for it - we just need to change the cockpit buttons/mapping, and use a separate handle for the 2nd ND. I have no clue how to do that though, unless you guys can walk me through each step :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: 11325
Joined: Tue Mar 25, 2008 8:40 am

Re: How to display Airport Chart?

Postby Philosopher » Wed Nov 27, 2013 7:39 pm

Looks great!
Thanks,
Philosopher
(inactive but lurking occasionally...)
Philosopher
 
Posts: 1590
Joined: Sun Aug 12, 2012 6:29 pm
Location: Stuck in my head...
Callsign: AFTI
Version: Git
OS: Mac OS X 10.7.5

Re: How to display Airport Chart?

Postby Hooray » Wed Nov 27, 2013 7:42 pm

yeah, absolutely!
But to be fair: The aircraft/cockpit is all Hyde's work, and the ND is 100% Gijs' work - so I take no credit for anything here :lol:
Now, we just need to make sure that these great additions actually end up in 3.0 ...
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: 11325
Joined: Tue Mar 25, 2008 8:40 am

Re: How to display Airport Chart?

Postby Philosopher » Wed Nov 27, 2013 7:43 pm

... and that's our job! :D
Thanks,
Philosopher
(inactive but lurking occasionally...)
Philosopher
 
Posts: 1590
Joined: Sun Aug 12, 2012 6:29 pm
Location: Stuck in my head...
Callsign: AFTI
Version: Git
OS: Mac OS X 10.7.5

PreviousNext

Return to Canvas

Who is online

Users browsing this forum: No registered users and 9 guests