Board index FlightGear Development Canvas

Canvas ND performance issues with route-manager

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 ND performance issues with route-manager

Postby tikibar » Wed Dec 17, 2014 9:13 pm

I've implemented the canvas ND in development versions of the 747-8 and the 757-200. It looks great, and functions beautifully. There is a problem with it, though. When I put a long route into the route manager and activate it, it kills my frame rates. It doesn't matter if the long route has 40 waypoints or just 2. The problem appears to be distance related. Here's how I tested:

-747-8F parked at KOAK with engines running, no route in RM, ~30fps
-Enter route from KOAK to EDDK with 40 waypoints, activate, ~15fps
-Clear route, back to 30fps
-Enter KOAK to EDDK with only start and end WPs, activate, ~15 fps
-Clear, back to 30fps
-Enter route KOAK to KLAX with 20 WPs, activate, stays close to 30fps
-Clear and activate KOAK to KLAX route with only start and end, ~30fps
-KOAK to KDEN (just start and finish), ~30fps
-KOAK to KJFK, start and finish only, ~25fps

Flying on the KOAK to EDDK route, the framerate dropped into single digits while dealing with other things like weather and scenery loading. The framerates don't change when I cycle the range on the display from 10-20-40-80-160-320-640, so I don't think it's a rendering issue. It seems to be more or a geoprocessing issue. Maybe there's a way to place a limit on how much of a route the ND or map structure will process? KOAK-KDEN is 832 nm, and there wasn't noticeable degradation in framerate with that route entered, so maybe an 800 nm limit would be appropriate. The display on the 747 only goes to 640 nm.

I got pretty lost looking through the ND and map structure code. Maybe someone could point me towards the right area? Thanks for reading!
Boeing 747-8 (rename folder to 747-8i)
Boeing 757-200/300 (rename folder to 757-200)
Boeing 767-300/ER (rename folder to 767-300)
User avatar
tikibar
 
Posts: 545
Joined: Mon Mar 05, 2012 7:05 am
Location: Los Angeles
Callsign: CHT0009
OS: Ubuntu 14.04

Re: Canvas ND performance issues with route-manager

Postby Hooray » Thu Dec 18, 2014 3:25 am

those are good pointers which could be useful when troubleshooting these issues, so please feel free to do more testing !
That said, the "geo-processing issue" you mentioned would manifest when the "searchCmd" method is executed - if it's route specific, adding an empty return statement (or return [];) should "fix" the issue (without showing any route obviously) - you would want to open the corresponding lcontroller file, locate the searchCmd method and then add return []; right to the top of the function.
Alternatively, there are a few debugging statements, which should automatically profile the performance of each layer/controller (including the searchCmd) method.
While the code may not necessarily be conventional Nasal-style, MapStructure files are generally pretty self-contained and also well-documented (see the wiki for details).
Unfortunately, most of the people who were originally involved in the MapStructure/ND effort seem to be kinda busy with other aspects of their lives currently, so that we may have to resort to just giving pointers and troubleshooting advice - personally, I haven't run FG in months to be honest, so I am not in a good position to test/debug anything - apart from that, I can obviously help with specific advice and pointers on how to understand where performance issues come from.
In this context, it would also be relevant to know which layers of the ND you were showing - especially the WPT/FIX layers can be kinda heavy (depending on range obviously).
And for the sake of standalone troubleshooting, it makes sense to use a test case that isn't specific to any aircraft - e.g. internally, the Canvas Map dialog (see the equipment menu) will run basically the same code - so you could try to reproduce things there, while using just the ufo - to get a more down-stripped test case that can be more easily reproduced by others.
Obviously, you'll then have to use the route manager dialog to set up a rotue manually. Back when we were working with this code, we would simply store a route on disk ($FG_HOME) and load that for debugging purposes.

If my response is too difficult to act upon, I'd suggest to post a few screen shots of the various ND settings, so that we can better tell which "layers" are enabled, which is affecting performance - because some stuff is still in Nasal space, while other things are simply invokving C++ space data structures/extension functions. However, even the underlying "navdb" is known to have a number of performance issues, and its main developer (Zakalawe) has stated repeatedly that the code wouldn't be necessarily straightforward to optimize for better performance.

Finally, even without understanding MapStructure internals, you can still use the built-in profiler to profile the ND/MapStructure code by wrapping things in between two fgcommands if you know how to rebuild FG from source: http://wiki.flightgear.org/Built-in_Profiler
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 ND performance issues with route-manager

Postby tikibar » Fri Dec 19, 2014 3:52 pm

Thank you for the detailed response, Hooray. The route layer was the only active one for my tests. It looks like RTE.lcontroller is the responsible file for this one. I tried disabling it with the return[]; at the beginning of the searchCMD function, and that did indeed remove the route lines and restore the frame rate in both the 747-8 test case and with the UFO. So I think that's a good place to implement a range limiter. I took the liberty of doing just that.

Code: Select all
var searchCmd = func {
        # FIXME: do we return the current route even if it isn't active?
        printlog(_MP_dbg_lvl, "Running query: ", name);
        var plans = []; # TODO: multiple flightplans?

        # http://wiki.flightgear.org/Nasal_Flightplan
        var fp = flightplan();
        var fpSize = fp.getPlanSize();
        var loc_curr = geo.aircraft_position();
        if (!getprop(me.layer.options.active_node)) fpSize = 0;
        var coords = [];
        var in_rangeL = 0;
        for (var i=0; i<fpSize; i += 1) {
                var leg = fp.getWP(i);
                var leg_loc = geo.Coord.new().set_latlon(leg.wp_lat, leg.wp_lon);
                var in_range = 0;
                if (loc_curr.distance_to(leg_loc)<1500000)
                    in_range = 1;
                if (in_range==1 or in_rangeL==1)
                    coords ~= leg.path();
                in_rangeL = in_range;
        }
        append(plans, coords);
        return plans;
};


This restricts drawing route lines to waypoints within 1500 km of the present aircraft position. It will draw a line to the current waypoint regardless of its distance (with a possible performance penalty if it's too far away), and the first (in the direction of travel) out-of-range WP is also included in the draw list.

Tests with both the UFO and thw 747-8 have shown this change to improve the performance of the ND with long routes activated, however long routes with only start and finish waypoints (like KOAK to EDDK) will still behave in the same way as before.
Last edited by tikibar on Tue Dec 23, 2014 11:19 am, edited 1 time in total.
Boeing 747-8 (rename folder to 747-8i)
Boeing 757-200/300 (rename folder to 757-200)
Boeing 767-300/ER (rename folder to 767-300)
User avatar
tikibar
 
Posts: 545
Joined: Mon Mar 05, 2012 7:05 am
Location: Los Angeles
Callsign: CHT0009
OS: Ubuntu 14.04

Re: Canvas ND performance issues with route-manager

Postby Hooray » Fri Dec 19, 2014 6:30 pm

good job there, glad to see that you could apply what I posted !
that being said, I would prefer to file a feature request so that the Canvas system will implicitly apply geo-based "clipping" (filtering) at the C++ level.
We did once discuss this here - and it should be straightforward to implement according to what Tom said back then.
Otherwise, the "in-range" check looks good to me, but you will find similar, but more generic logic, in the other lcontroller files - such as the TFC (=traffic) layer.
So I would suggest to look at the existing "in-range" helpers, and generalize your own code a little (maybe by exposing these things via hashes), and filing a feature request.
For testing purposes, it does help to only use the canvas-map xml dialog instead of any particular aircraft.

In the long term I would prefer to extend the underlying C++ code for doing smarter/faster geo-based filtering - the other obvious optimization here is that we don't necessarily need to redraw the whole route once the range changes, but only need to render the route once and apply different transformations (thinking zooming/offset).
Conceptually, this would be possible to implement by using a separate Canvas for the route behind the scenes and referencing it via canvas://, which is the technique we're using for the built-in SymbolCache.
So basically we could modify the code to render the route to a separate texture and then merely change the offset/zoom (=range) properties in the referenced canvasImage child, which should make these things much faster (that is, once the map is drawn once). Internally, the Canvas system should preferably still apply clipping to restrict drawing/updating to visible elements only.

But like I said, I would prefer to identify building blocks missing/useful on the C++ side, because Zakalawe and others have been wanting to replace the built-in Map dialog for ~18 months now, and performance is one of the main show-stoppers preventing us from doing that - thus, it would be better to add a handful of hooks to the C++ code, and simply adopt those in the Nasal modules, which would benefit all use-cases, MapStructure, the ND and the Map dialog.

Finally, if you don't mind working with the MapStructure files and tinkering a bit, I can provide all the details on using a separate Canvas for the RTE layer - this may take 4-5 days of spare time coding if you're relatively new to Canvas, but it will only update the route if absolutely necessary, and otherwise only "transform" the pre-rendered route layer whenever the range is changed, i.e. no redundant searchCmd() calls.

Equally, it would be possible to make searchCmd() smarter by caching the resulting vector and only applying changes instead of re-drawing the whole route from scratch.

I am sure that Philosopher and TheTom will have more/better ideas ...

PS: Please feel free to update the MapStructure/ND wiki articles accordingly - e.g. by adding to the roadmap, or by editing: http://wiki.flightgear.org/Canvas_MapStructure_Layers
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 ND performance issues with route-manager

Postby Hooray » Fri Dec 19, 2014 8:12 pm

The whole idea about using a separate Canvas for "caching" purposes is explained below:

http://wiki.flightgear.org/Howto:Using_ ... ynamically
http://wiki.flightgear.org/Howto:Using_ ... d_canvases
http://wiki.flightgear.org/Canvas_Image

Basically, you'd add a canvas image child to the canvas, which uses the other canvas as "source" for its raster image.
range/orientation updates would then merely be transformations to the canvas image, instead of having to redraw the whole route.

For this to work, the RTE layer would maintain its own private Canvas to which it renders the route - updates() would only take place if absolutely necessary (no timer hacks needed then).
While changes in orientation/range would be implemented via Canvas/Image transformations.

Even a route spanning several continents could then be rendered to a single 512x512 texture, with the current position being simply a texture map lookup on the existing canvas - for the latter, it would help if the texture map coordinates could be specified as actual lat/lon tuples obviously

PS: For development/testing purposes, it would help if you could create a complex flight plan/route and save it, so that you can share the flight plan with other contributors (e.g. by uploading it to the wiki), so that we can try to reproduce the issue, but also use this for benchmarking/performance testing. In general, having a separate canvas should be cheaper - also, because even on an airliner, both NDs are likely to show the same route (usually), and even the Map dialog is going to show the same route - thus, internally, we could be reusing the same shared Canvas, instead of drawing the same route repeatedly.
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 ND performance issues with route-manager

Postby Philosopher » Fri Dec 19, 2014 10:40 pm

Hooray, I'm not sure caching will work here because of projections issues – the same route usually won't look the same when viewed from different geo positions. It'll be close, but probably wouldn't work for large differences. (Essentially, once the geo pos or range changes, all the coordinates need to be recalculated in the C++ code to get pixel coordinates.)

P.S. Nice work tikibar!
Philosopher
 
Posts: 1593
Joined: Sun Aug 12, 2012 7:29 pm

Re: Canvas ND performance issues with route-manager

Postby Hooray » Sat Dec 20, 2014 7:05 am

right, I guess it's matter of finding a compromise that looks good enough, which will depend on the use-case - otherwise, we'll be dealing with pixelated raster image route data, too.
I guess we need to come up with some heuristics at the C++ level for selectively updating/rendering parts of the route that are visible/relevant (i.e. not necessarily visible, but part of a visible line segment)
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 ND performance issues with route-manager

Postby Hooray » Sat Dec 20, 2014 7:36 pm

Note that you could also check if performance is mainly affected by rendering or by updating - for that, you only need to replace the return statement at the end with a return statement returning an empty vector - internally, this would still run all the existing searchCmd() logic, without adding anything to the Canvas that needs rendering - so if this is still too slow, it's probably the underlying API calls (nasal positioned) that are adding up here. However, if it's just as fast, it's rendering / rasterization that is probably taking so long, which would mean that we'd need to explore selective updating/rendering of nodes that are neither visible, nor connected to anything visible (line segments). For more details, you'll want to use the built-in profiler and post the profile here.


For starters you could also add a simple print("RTE searchCmd()"); statement to the searchCmd() to see when it's getting called - to see how long it's taking, you use systime() or its wrapper: debug.benchmark() (see debug.nas). This would tell you how long searchCmd() itself is taking.
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 ND performance issues with route-manager

Postby tikibar » Tue Dec 23, 2014 11:08 am

I set up the searchCmd() function to return the empty vector, and indeed that eliminates the slowdown. So looks like rendering/rasterization is the slowdown. Using print statements, I've found that after initialization the searchCmd function is only called when the route is activated, the flight plan changes, or the display range changes. With the Boeing ND, it also updates every 30 seconds while flying and displaying map or plan view.

It appears that each leg is rendered based on a length and a direction with the waypoint being the end of the line segment. So as long as a range limiter selects all WPs in range plus the first one out of range in the direction of travel, all the needed segments should appear. I've modified the code snippet above to do just that. This will work in most use cases involving a complex flight plan with WP separation at a maximum of 800 nm or so. However, 2 point long flightplans will still have the performance degradation.

Be all that as it may... I stumbled across what is perhaps closer to the core of the issue in a flight over the North Pole. Flightplan legs are rendered as great circle segments, so long legs are drawn with a curve. Somewhere, the flightplan has to be flattened into a map view. It appears that this is easy to do over short distances in lower latitudes, but becomes increasingly difficult over long distances with a bigger component of Earth's curvature involved. The map view is not really geared for polar routes, so the leg that goes over the pole has an extreme curve drawn in it. And when that leg was in range, the frame rate dropped from 25-30 down to 8-12. Once it went out of range, frame rate was back to normal. It seems like calculating curvature may be the rate-limiting step.

Image
Boeing 747-8 (rename folder to 747-8i)
Boeing 757-200/300 (rename folder to 757-200)
Boeing 767-300/ER (rename folder to 767-300)
User avatar
tikibar
 
Posts: 545
Joined: Mon Mar 05, 2012 7:05 am
Location: Los Angeles
Callsign: CHT0009
OS: Ubuntu 14.04

Re: Canvas ND performance issues with route-manager

Postby Gijs » Tue Dec 23, 2014 11:52 am

tikibar wrote in Tue Dec 23, 2014 11:08 am:The map view is not really geared for polar routes, so the leg that goes over the pole has an extreme curve drawn in it.

We've already fixed that in the (old) map dialog, by using an azimuthal equidistant projection (see screenshot). Porting the projection to Canvas is on my todo list. Such a projection is much much better for navigational use.

Curves in routes are not calculated by Canvas, nor by the ND though. It's the route manager that splits up a route in segments in order to get smooth transitions.
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: Canvas ND performance issues with route-manager

Postby tikibar » Tue Dec 23, 2014 12:36 pm

I split the route into segments. The segment that is causing all the trouble in the above case is between W121N085 and W006N085 where the projection of what should be a straight line ground track (like in the screenshot you posted) has a massive curve in it. When that segment is in range, there's a big performance hit. When that segment is out of range, it goes back to normal. This does not occur with the old hard-coded ND. That same leg doesn't get the curve. It uses the azimuthal equidistant projection. So, maybe the problem stems from using a less-than-optimum projection. Maybe that is the fix.

This is the same route in the old ND. Note there is no curve between W121N085 and W006N085. There is also no performance degradation.
Image
Boeing 747-8 (rename folder to 747-8i)
Boeing 757-200/300 (rename folder to 757-200)
Boeing 767-300/ER (rename folder to 767-300)
User avatar
tikibar
 
Posts: 545
Joined: Mon Mar 05, 2012 7:05 am
Location: Los Angeles
Callsign: CHT0009
OS: Ubuntu 14.04

Re: Canvas ND performance issues with route-manager

Postby Gijs » Tue Dec 23, 2014 12:47 pm

I believe the old ND code only displays the waypoints and then draws a straight line between them. The new ND uses the actual route-manager paths, which allows it to draw holdings, flyby waypoints (thanks to James recent work) etc. But we'll need the azimuthal projection anyway, so I'll bump my todo list ;-)

PS: With segments I meant that a single path between two waypoints consists of multiple segments/lines/sections.
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: Canvas ND performance issues with route-manager

Postby Hooray » Wed Dec 24, 2014 5:21 am

@tikibar: that's really a tremendous amount of useful info you're posting here, awesome job !

Once it went out of range, frame rate was back to normal. It seems like calculating curvature may be the rate-limiting step.

I think the underlying Nasal code will directly add OpenVG paths - which are mapped to ShivaVG routines internally by Canvas (i.e. as vector graphics) - so I guess, that there will also be a fair amount of redundant computations going on, some of which could probably be eliminated by passing relevant information to shiva (e.g. resolution/pixel vs. nm ratio).

Otherwise, I do agree that it would make sense to sub-class the Canvas projection class and implement Gijs' changes there, like we originally discussed in the merge request: https://gitorious.org/fg/flightgear/com ... cb398323d7

https://gitorious.org/fg/flightgear/sou ... .cxx#L1573

Ideally, we would expose the projection as a property for each Map so that it can be changed dynamically.
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 ND performance issues with route-manager

Postby Hooray » Sun Jan 25, 2015 8:31 pm

(Philosopher mentioned ND performance in the other thread, so I am responding here now)

given that the full route is unlikely to be rendered most of the time, filtering by visibility (i.e. using current ref-lat/ref-lat and the current range) should help reduce the complexity of the route, while also allowing Canvas to only render relevant route elements - like I said earlier, you'll probably want to check waypoint visibility first (i.e. using a geo.Coord based in-range check) and then only draw legs that are connected to at least one visible waypoint. Unless I'm mistaken, that should reduce the complexity of most routes rather significantly, so that updating/redrawing should not take as long.

Eventually, this should ideally be configurable at the CanvasElement or CanvasMap level, i.e. so that optionally only visible elements are drawn - but in the meantime, you can accomplish the same thing in Nasal space. However, the projection issue isn't easily dealt with in Nasal space, unless you can come up with heuristics and simplify the path drawing code accordingly.
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


Return to Canvas

Who is online

Users browsing this forum: No registered users and 2 guests