Board index FlightGear Development Canvas

Using Canvas for visualizing orbital flights (cont'd PM)

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.

Using Canvas for visualizing orbital flights (cont'd PM)

Postby Hooray » Fri Apr 10, 2015 6:54 pm

Hooray wrote:http://wiki.flightgear.org/Flying_the_S ... eels_in_FG
Thorsten wrote:Currently there's very little support for displaying ground track or estimating the needed deceleration as function of range to target, so try aiming a track only if you're ambitious, otherwise try to survive.



I don't know what the real avionics look like - but using Nasal/Canvas it should be pretty straightforward to draw whatever you may need - in fact, there's support for procedurally-generated vector graphics - the "flight path history" shown below (blue) is generated using 5 lines of Nasal:
Image

While the Canvas system itself does have support for geographic coordinates, it can also draw using absolute screen coordinates instead - so, shouldn't be limited by any built-in assumptions about the "aircraft" always being on Earth.

Like I said, I don't know what else is required or what the real thing looks like - but a GUI dialog showing the current position in relation to an "ideal" ground track should be relatively straightforward to create - and anything that's using Canvas is just a RTT/FBO so that it can be placed/shown and updated pretty much everywhere, including HUDs, GUI dialogs, cockpit controls or even liveries etc.

Here's a conventional UI dialog using two embedded Canvas textures, #1 showing a ND, #2 doing property plotting - something like this could just as well show a ground track and/or approach gradients:
Image

Assuming that you're not overly interested in becoming familiar with Canvas, we would need to work out what is required on each side of this and how to plug together these components - for instance, we do have a wiki article containing a bunch of snippets of common Canvas purposes: http://wiki.flightgear.org/Canvas_Snippets

Note that the Canvas side of this just works via the property tree, so the corresponding computations could just as well be provided by another subsystem (think autopilot/property rules)

Like I said, I don't know much about the space shuttle or the way its avionics are supposed to look, but I can definitely provide self-contained snippets for drawing vector graphics to a Canvas RTT/FBO and display that in some UI dialog and/or HUD. But just like you are probably not interested in working out Canvas stuff, I am -quite frankly- not the slightest bit interested in working out the corresponding math - so if you'd fancy exploring this, I'd either need 2-3 APIs or just properties to provide what you need, and plot those to a corresponding texture.

So I am really just in "bootstrapping mode" here, which you should be able to relate to given your own recent bootstrapping here :)
Integration-wise, those examples are meant to be executed via the Nasal console, so are fairly self-contained (not being very interested in aircraft development myself).



Thorsten wrote:The real avionics is surprisingly (or perhaps not) spartan and not very visual. The entry management displays are velocity vs. altitude diagrams with the pre-calculated track for the mission and the envelope lines shown and the current state of the orbiter as a triangle plotted inside. Azimuthal deviation from course, AoA and target acceleration are just given as numbers.

I'm not sure at this point how much to aim for 'real' avionics (which by and large runs everything on auto and assumes mission control is just a call away and can supply all info from remote) and how much to support piloting. The Shuttle can be flown by stick control and cue cards in more or less all situations, but again the trajectories are often pre-computed.

I think what I want to have is a map of Earth displaying the future ground track projection of the orbit for a few revolutions, and at this point I'd probably need canvas.

Most of the computational tasks are currently done by JSBSim fcs_functions since they're relevant for guidance of the orbiter (they're basically something like the autopilot system, except JSBsim native - it's a pretty neat system and there's little you can't do with it). I think for track projections, I might use Nasal (since that's not guidance-critical), but at this point it's a rather vague collection of ideas. The current plan is to supply flyable systems before nice-looking systems. Also, I have to look into the description of the real avionics a little more.



Hooray wrote:may respond to your other comments later on.

Thorsten wrote:I think what I want to have is a map of Earth displaying the future ground track projection of the orbit for a few revolutions, and at this point I'd probably need canvas.

if all you need is a "flat" 2D map, that is supported out of the box - and those maps can either live in $FG_ROOT or be fetched "live" if necessary using the http protocol.
There is the notion of "layers" in Canvas using multiple Canvas groups stacked together using explicit z-indexing and transparency settings so showing a flat 2D map would be suffficient to put other layers on top.
The basic snippet to show a UI dialog (just for prototyping purposes) is this: http://wiki.flightgear.org/Canvas_Snipp ... GUI_Window
To add a raster image, you would add the 5 lines found at: http://wiki.flightgear.org/Canvas_Snipp ... ter_Images

The "filename" could just as well be a URL (just for testing), for example using: http://www.worldwidetelescope.org/docs/ ... fEarth.jpg
Image

(I am admittedly not sure if JPG is supported or not by FG/OSG by default, so this may need to be converted to png first).

Or use this URL instead: http://gallery.hd.org/_exhibits/places- ... 1-ANON.png
Image

There is a dedicated "Map" element in Canvas which will position elements (raster images, text labels etc) using lat/lon directly - i.e. implicit projection handling. So the current/intended ground track could be visualized accordingly using a few lines of Nasal, where you treat your coordinates like waypoints that are connected using some kind of line/curve (vector graphics) - which is using OpenVG, and which is also the way used for drawing the taxiways in the screen shot below: Image

think for track projections, I might use Nasal (since that's not guidance-critical), but at this point it's a rather vague collection of ideas.

like I said, projection handling in Canvas can be handled by dedicated C++ code automatically - Gijs has also begun adding support for new projections which provide better results/performance under certain circumstances (think flight plans crossing the poles).

The two "Canvas Snippets" links above are entirely self-contained for loading/displaying a raster image found either in $FG_ROOT or fetched via http.
Once that is working, we can add more layers on top of this to plot a corresponding ground track.

While using a UI dialog may seem counter-intuitive at first, it allows rapid prototyping (i.e. not reset/reload required) and it can be easily shown elsewhere later on.

Once a basic prototype is in place, I could also help generalize things to turn this into a "MapStructure" layer, with "MapStructure" being a framework for reusable gauges/charting layers (think moving map stuff), so that the display/instrument could be reused elsewhere (think vostok/spaceship2) - not unlike effects which can be reused/shared between different aircraft - e.g:
Image



Hooray wrote:@TheTom: Do you have a better idea on handling Thorsten's use-case, i.e. in terms of "Map" being used for visualizing orbital flights (shuttle, vostok, spaceship2) with a background image of the Earth being used as a geo-referenced overlay ?

Also, how would you proceed to deal with raster images used as pre-projected map backgrounds - you once said that you were designing Canvas with the "tiled map" use-case in mind - so I am wondering if we could add a pre-projected raster image and specify the used projection so that the C++ code can deal with this correctly, or do you think that's over-engineered ?
Equally, sub-textures/textures maps and clipping support may benefit from geo-support, so that coordinates can be specified as lat/lon tuples probably ?
Supporting texture maps using geo-coordinates would allow us to deal with a Map element as a CanvasImage so that caching would be supported more easily, i.e. by retrieving sub-maps from a top-level maps - which could be useful in the case of highly detailed satellite imagery.
(This is just a brainstorming/feedback, so no concrete feature requests yet - just thinking out loud to determine how to support Thorsten's use-case and spacecraft avionics in particular - and to make you aware of ongoing Canvas related efforts)



Hooray wrote:There is a dedicated "Map" element in Canvas which will position elements (raster images, text labels etc) using lat/lon directly - i.e. implicit projection handling. So the current/intended ground track could be visualized accordingly using a few lines of Nasal, where you treat your coordinates like waypoints that are connected using some kind of line/curve (vector graphics)
http://wiki.flightgear.org/Canvas_Snipp ... _on_demand
Image


Thorsten wrote:Well, pretty, but I lack a clear example how it's done. The map creating code is not precisely easy to unravel. I understand that I probably need to tell the system what coords the edge of my picture are supposed to represent, and then draw a shuttle symbol somewhere on it. The snippets are nice, but they lack a list of options of what I could change. The SVG in canvas demo doesn't work...


Hooray wrote:I don't know what SVG example you're referring to ?
I haven't tested things in a while, but last I checked, this was working: http://wiki.flightgear.org/Howto:Use_SV ... ello_World
And it should display a full SVG file including all its "layers":
Image

A few messages ago, I did offer to help with specific examples, as long as you provide the back-end snippets (computations), either in the form of a few APIs or simply properties.
The documentation may be lacking behind a bit admittedly...

But how about you ask a handful of really specific questions and I get back to you with updated docs/examples (totally self-contained of course) ?

Let's start simple please though (or _I_ may lose interest in it...) :D

Alternatively, there's a full framework for creating such maps, using "MapStructure", where all you need to do is provide two files with functions specifiying 1) a vector with lat/lon coordinates for each "waypoint/coordinate", and another function that basically iterates over the vector using foreach() and draws symbols/lines or curves between those:
http://wiki.flightgear.org/Canvas_MapStructure

Image

Image

EDIT: I have begun extending the examples based on our PMs: http://wiki.flightgear.org/Canvas_Snipp ... _on_demand
Image

Will be adding more stuff once you have laid out your requirements



Hooray wrote:@TheTom: I think Thorsten is asking for a way to automatically handle the projection/transformation of the background image by mapping image/screen coordinates via lat/lon coordinates. I don't think we have any built-in support for doing that - we can of course "hard-code" that using image dimensions for one specific image, but it would probably be better to extend the Map handling code to support doing this at some point automatically ?

Especially GeoTIFF already tend to contain the meta-data for geo-referencing the image or have associated TFW files.
So we kinda need to expose this stuff as properties for raster images added as children to Maps - i.e. projection, dimensions etc - as per: Georeferenced instrument procedures and airport diagrams

Which should also come in handy for all the EFB stuff:

Subject: A project to create a source of free geo-referenced instrume
TheTom wrote:I don't think it makes sense (and is easily possible) to include the script somehow in FlightGear. It "just" creates a matrix for a given plate containing it's scale and position, so all we have to do to display such charts within FlightGear is to load the chart image and apply the matrix created by the script. In the case of VRT files, it should be enough to just read the GeoTransform tag and set it as matrix on the Image element inside the canvas (with the parent element set up to have a coordinate system matching the current position and range).

These charts would not only be useful for FlightGear, but also for real aviation applications, like EFBs. I think I saw this or a similar script somewhere inside the sources of Avare?




Thorsten wrote:Okay, I have a nice loaded earth texture picture. I have the position of my shuttle -

  • first thing I want is to draw it in real time on the picture, see it move.
  • Next thing is - I want to display the ground track. What do I do - store past positions into an array regularly? Is it done automatically?
  • Beyond that, I want to display the groundtrack prediction based on current state. So, I can create an array of future points. Or properties. Or pass the function which, when given a time, will spit out coordinates. Don't care - whatever is best.
  • Finally, I'd like to have the ability to display the selected landing site on the map. But that's probably the same as the shuttle problem - I have a set of coords and I want a symbol drawn there.

Probably all are solved problems - but how?

Cheers and thanks for the help!

* Thorsten
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: Using Canvas for visualizing orbital flights (cont'd PM)

Postby Hooray » Fri Apr 10, 2015 8:03 pm

Thorsten wrote:first thing I want is to draw it in real time on the picture, see it move.


The easiest way to draw a symbol at the current position on a Map is using the so called "APS" (=AircraftPositionSymbol) MapStructure layer, which is responsible for drawing a SVG symbol at the current position in all MapStructure-based maps:
Image

To use this existing mapping layer, all you'd need to do is to adapt the example found at: http://wiki.flightgear.org/Canvas_Snipp ... o_a_Canvas
and change the foreach() line to only read: foreach(var type; [r('APS'), )

NOTE: this example assumes that you are appending at the bottom of the boilerplate snippet at: http://wiki.flightgear.org/Canvas_Snipp ... GUI_Window

Which would add a single layer to your map displaying the aircraft symbol on your map.

Thorsten wrote: I want to display the ground track. What do I do - store past positions into an array regularly? Is it done automatically?

both options are possible - it can be done automatically, by using the approach of the FLT (=flight path history) layer - all you need to do is create a function called searchCmd() that returns a vector of coordinates (ideally, geo.Coord() objects) - as per $FG_ROOT/Nasal/canvas/map/FLT.lcontroller (see the searchCmd() function at the bottom of the file) and a corresponding *.SYMBOL file which draws the ground track (analogous to how the flight path history is drawn using either line segments or curves).

Thorsten wrote:I want to display the groundtrack prediction based on current state. So, I can create an array of future points. Or properties. Or pass the function which, when given a time, will spit out coordinates. Don't care - whatever is best.

that would work exactly like the ground track layer, just with a different searchCmd() function (body) - i.e. the drawing routines (*.SYMBOL) files could be reused "as is".

Thorsten wrote:I want to display the groundtrack prediction based on current state. So, I can create an array of future points. Or properties. Or pass the function which, when given a time, will spit out coordinates. Don't care - whatever is best.


right, that would work like the existing "APT" (=Airports) layer, just specific to a single airport probably - i.e. you would still return a vector of airports, with the vector only having a singe element.

I do realize that the MapStructure mechanics may be a bit too fancy - so I'll make sure to post more examples and screen shots, and I am sure that others will provide more feedback/help, too.

Support for overlays using geo-referenced raster images isn't too well-developed currently, so would need to work with a few hard-coded assumptions (e.g. being specific to a certain raster image and map layout) - but maybe TheTom can provide a few more ideas on how to proceed from here - otherwise, the Map is normally not aware of any non-Map items, i.e. as long as the overlay is added "outside" the Map, it isn't even aware of the raster image - and when it is added as a map element, it would probably be rotated. So there's still some work needed here. But generally, this should work well enough even in its current form:
Image
(the screen shot is purely based on the Canvas Snippets article, i.e. it just displays a Canvas GUI dialog, adds the downloaded raster image and then adds the MapStructure APS layer - without the Map being aware of the overlay/geo-referencing that is needed currently)
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: Using Canvas for visualizing orbital flights (cont'd PM)

Postby Thorsten » Sat Apr 11, 2015 7:05 am

Okay, upon reflection and experimentation, map is almost certainly not what I need. I don't want to draw all airports in the vicinity, I want to draw just the landing site. I don't want an aircraft-centered projection, I want to place the aircraft on a global map for which there is no support.

Let's try a different way.

I want to select a symbol (say the aircraft symbol) and place it a fraction x from the left edge and a fraction y from the lower edge onto the raster image. I'd like to be able to adjust size and orientation of that symbol as well.

Then I want to draw another symbol and place it a fraction x1 and a fraction y1 from the edges elsewhere.

What do I type?

I want to update one of the positions regularly - what do I do?

(Forget coordinate projection, I can do all of this readily myself, I just want to adjust screen position - a very dumb interface, move symbols around on the canvas).
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: Using Canvas for visualizing orbital flights (cont'd PM)

Postby Thorsten » Sat Apr 11, 2015 11:08 am

Code: Select all
var sym_shuttle = {};
var sym_landing_site = {};

var create_map = func {

var window = canvas.Window.new([800,400],"dialog");
var mapCanvas = window.createCanvas().set("background", canvas.style.getColor("bg_color"));
var root = mapCanvas.createGroup();


var path = "Aircraft/SpaceShuttle/Dialogs/MapOfEarth.png";
var child=root.createChild("image")
                                   .setFile( path )
                                   .setTranslation(0,0)
                                   .setSize(800,400);
sym_shuttle = mapCanvas.createGroup();
canvas.parsesvg(sym_shuttle, "/Nasal/canvas/map/Images/boeingAirplane.svg");
sym_shuttle.setScale(0.2);

sym_landing_site = mapCanvas.createGroup();
canvas.parsesvg(sym_landing_site, "/gui/dialogs/images/ndb_symbol.svg");
sym_landing_site.setScale(0.6);


map_update();

}


var map_update = func {


var lat = getprop("/position/latitude-deg");
var lon = getprop("/position/longitude-deg");

var x = 400.0 + lon /180. * 400.0 -10.0;
var y = 200.0 - lat /90. * 200.0 -10.0;

var heading = getprop("/orientation/heading-deg");

sym_shuttle.setTranslation(x,y);
#symbol.setRotation(heading);

x = 400.0 + landing_site.lon()/180 * 400.0 -10.0;
y = 200.0 - landing_site.lat()/90. * 200.0 -10.0;

sym_landing_site.setTranslation(x,y);

settimer(map_update, 1.0);

}


Okay, this is probably rather crude, but it (sort of) works - I'm getting the current position of the shuttle as well as the selected landing site displayed.

Image

There must be an event generated upon closing the dialog that I can use to terminate the update loop again, right? Is there a way to set absolute rotations to the shuttle icon? And how to draw lines between a set of points?
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: Using Canvas for visualizing orbital flights (cont'd PM)

Postby www2 » Sat Apr 11, 2015 12:25 pm

@Thorsten
setRotation use radian try to do:
Code: Select all
newHeading = oldhHeading * D2R;
symbol.setRotation(newHeading);
www2
 
Posts: 319
Joined: Thu Apr 16, 2009 2:58 pm
OS: Ubuntu

Re: Using Canvas for visualizing orbital flights (cont'd PM)

Postby Hooray » Sat Apr 11, 2015 1:26 pm

for path drawing using OpenVG, see the API in $FG_ROOT/Nasal/canvas/api.nas

examples can be seen in $FG_ROOT/Nasal/canvas/map/airports.draw and/or taxiways.draw (more complex)

For drawing lines/curves, refer to fgplot: http://wiki.flightgear.org/Howto:Adding ... GUI_dialog (demo code to be found on the wiki)
Image

You will want to cache (reuse) the paths for groundtrack/prediction, instead of permanently deleting/adding new paths each frame (too expensive, everything going through the property tree).

PS: looking really good already - I actually started adding such snippets to the wiki earlier - but your's seems to have progress much more already :D

And the main APIs you need are: setScale(), setRotation(), setTranslation() or setTransform() (again, see api.nas for all options supported for each element) - you can add text labels using osgText nodes (see Canvas snippets for examples) - those can also be placed outside the map, i.e. next to.
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: Using Canvas for visualizing orbital flights (cont'd PM)

Postby Thorsten » Sat Apr 11, 2015 6:01 pm

Image

Yep, history groundtrack looks about right... thanks. Future groundtrack is basically the same technology, only different math.

Which just leaves - how do I terminate the position update loop when the dialog is closed? (Or prevent a second one from being started if I re-open it again? Oh, and setting a title for the dialog would be cool...

You will want to cache (reuse) the paths for groundtrack/prediction, instead of permanently deleting/adding new paths each frame (too expensive, everything going through the property tree).


Every frame??? It's enough to update the array every 30 seconds with a new position... :-)
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: Using Canvas for visualizing orbital flights (cont'd PM)

Postby Hooray » Sat Apr 11, 2015 6:12 pm

- refer to $FG_ROOT/Nasal/canvas/gui/dialogs/AircraftCenter.nas to see how the title can be modified: http://sourceforge.net/p/flightgear/fgd ... Center.nas
Code: Select all
# appended to the window/dialog constructor:
.set("title", "Trajectory Map")


- for the history/groundtrack, you can directly use the history() API (no Nasal timers/listeners needed then), as per FLT.lcontroller: http://sourceforge.net/p/flightgear/fgd ... controller

- no matter if you're updating each frame or not, it makes sense to have an array of "points" for your line/curve and reuse the underlying Canvas group/path directly

- for the position update loop, you will want to use the maketimer() API (as per my PM) and invoke the .stop() method in the dialog's del() method (IIRC)

- there's also various different types of curves supported by OpenVG (e.g. bezier curves) - refer to api.nas for supported drawing modes (or the runway/taxiway handling code mentioned earlier)


Finally, your PUI GUI dialog seems simple enough, and can be added directly to the Canvas dialog, too (labels + buttons) to have everything in a single dialog

PS: I guess it's time to send a PM to Michat and ask him for two new SVG symbols (space shuttle & landing site) ? :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: Using Canvas for visualizing orbital flights (cont'd PM)

Postby Thorsten » Mon Apr 13, 2015 10:19 am

- for the position update loop, you will want to use the maketimer() API (as per my PM) and invoke the .stop() method in the dialog's del() method (IIRC)


I guess I'm having more of a syntax than a conceptual issue. I know how to stop a Nasal loop, be it with maketimer or settimer and a flag. I gather that del() of the canvas dialog is executed when I press the close button. I could of course add code to end the loop into wherever del() is defined in the canvas Nasal files, but that's not remotely useful,

What I don't know is how to invoke any code defined in my local file when del() on the dialog runs, and I suppose it's just a question of syntax how something is added to the method or so (?)
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: Using Canvas for visualizing orbital flights (cont'd PM)

Postby TheTom » Mon Apr 13, 2015 11:13 am

Thorsten wrote in Mon Apr 13, 2015 10:19 am:What I don't know is how to invoke any code defined in my local file when del() on the dialog runs, and I suppose it's just a question of syntax how something is added to the method or so (?)


It is currently not possible to simply attach a close handler to a dialog. I will add one soon. Until then you can try to replace the dialogs del() method and then call the replaced one yourself. Something like the following (untested) code:
Code: Select all
var dlg = canvas.Window.new([300,120], "dialog")
                           .setTitle("Callback Demo");
dlg.del = func()
{
  print("Cleaning up...\n");
  call(canvas.Window.del, [], me);
};
TheTom
 
Posts: 322
Joined: Sun Oct 09, 2011 11:20 am

Re: Using Canvas for visualizing orbital flights (cont'd PM)

Postby Hooray » Mon Apr 13, 2015 1:25 pm

explanation for the call() technique at: http://wiki.flightgear.org/Object_orien ... lass_calls

@TheTom: in the mid-term, it would make sense for placements, and canvas/elements to have their own "property signals" (analogous to /sim/signals) that we can use to register event-specific callbacks (not unlike signals/slots in Qt).
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: Using Canvas for visualizing orbital flights (cont'd PM)

Postby Thorsten » Tue Apr 14, 2015 6:06 am

It is currently not possible to simply attach a close handler to a dialog. I will add one soon. Until then you can try to replace the dialogs del() method and then call the replaced one yourself. Something like the following (untested) code:


Okay, I'll try that, thanks.
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: Using Canvas for visualizing orbital flights (cont'd PM)

Postby Thorsten » Wed Apr 15, 2015 12:42 pm

Guess it works now (don't try retrograde orbits yet, it's going to be confused...)

Image


Feel free to use, wiki-post, adapt, generalize... the code

Code: Select all
var sym_shuttle = {};
var sym_landing_site = {};
var graph = {};
var samples = [];
var history = [];
var track_prediction = [];

var update_loop_flag = 0;


var lat_to_m = 110952.0; # latitude degrees to meters
var m_to_lat = 9.01290648208234e-06; # meters to latitude degrees
var lon_to_m = 0.0; # needs to be calculated dynamically
var m_to_lon = 0.0; # we do this on startup


var delete_from_vector = func(vec, index) {

var n = index+1;

var vec_end = subvec(vec, n);

setsize(vec, n-1);
return vec~vec_end;   
}

var calc_geo = func(lat) {

lon_to_m  = math.cos(lat*math.pi/180.0) * lat_to_m;
m_to_lon = 1.0/lon_to_m;
}


var lat_to_y = func (lat) {

return 200.0 - lat /90. * 200.0;

}

var lon_to_x = func (lon) {

return 400.0 + lon /180. * 400.0;

}

var create_map = func {

var window = canvas.Window.new([800,400],"dialog").set("title", "Trajectory Map");

# we need to explicitly re-define this to get a handle to stop the update loop
# upon closing the window

window.del = func()
{
  #print("Cleaning up...\n");
  update_loop_flag = 0;
  call(canvas.Window.del, [], me);
};


var mapCanvas = window.createCanvas().set("background", canvas.style.getColor("bg_color"));

var root = mapCanvas.createGroup();


var path = "Aircraft/SpaceShuttle/Dialogs/MapOfEarth.png";
var child=root.createChild("image")
                                   .setFile( path )
                                   .setTranslation(0,0)
                                   .setSize(800,400);
sym_shuttle = mapCanvas.createGroup();
canvas.parsesvg(sym_shuttle, "/Nasal/canvas/map/Images/boeingAirplane.svg");
sym_shuttle.setScale(0.2);

sym_landing_site = mapCanvas.createGroup();
canvas.parsesvg(sym_landing_site, "/gui/dialogs/images/ndb_symbol.svg");
sym_landing_site.setScale(0.6);

graph = root.createChild("group");



update_loop_flag = 1;
map_update();


}


var map_update = func {

if (update_loop_flag == 0 ) {return;}

var lat = getprop("/position/latitude-deg");
var lon = getprop("/position/longitude-deg");

var x =  lon_to_x(lon);
var y =  lat_to_y(lat);


var heading = getprop("/orientation/heading-deg") * 3.1415/180.0;

sym_shuttle.setTranslation(x,y);
sym_shuttle.setRotation(heading);

x = lon_to_x(landing_site.lon()) - 10.0;
y = lat_to_y(landing_site.lat()) - 10.0;

sym_landing_site.setTranslation(x,y);


prediction_update();
plot_tracks();

settimer(map_update, 1.0);

}


var plot_tracks = func  {


graph.removeAllChildren();
var plot = graph.createChild("path", "data")
                                   .setStrokeLineWidth(2)
                                   .setColor(0,0,1)
                                   .moveTo(history[0][0],history[0][1]);

      

      for (var i = 1; i< (size(history)-1); i=i+1)
         {
         var set = history[i+1];
         if (history[i+1][0] > history[i][0])
            {
            plot.lineTo(set[0], set[1]);
            }
         else
            {
            plot.moveTo(set[0], set[1]);
            }
         }


var pred_plot = graph.createChild("path", "data")
                                   .setStrokeLineWidth(2)
                                   .setColor(1,0,0)
                                   .moveTo(track_prediction[0][0],track_prediction[0][1]);

      

      for (var i = 1; i< (size(track_prediction)-1); i=i+1)
         {
         var set = track_prediction[i+1];
         if (track_prediction[i+1][0] > track_prediction[i][0])
            {
            pred_plot.lineTo(set[0], set[1]);
            }
         else
            {
            pred_plot.moveTo(set[0], set[1]);
            }
         }

}



var history_init = func {

var lat = getprop("/position/latitude-deg");
var lon = getprop("/position/longitude-deg");
var x =  lon_to_x(lon);
var y =  lat_to_y(lat);

for (var i = 0; i < 1000; i = i+1)
   {
   var set = [x,y];
   append(history,set);
   }
history_update();

}

var history_update = func {

history = delete_from_vector(history,0);

var lat = getprop("/position/latitude-deg");
var lon = getprop("/position/longitude-deg");
var x =  lon_to_x(lon);
var y =  lat_to_y(lat);

append(history, [x,y]);

settimer(history_update, 10.0);
}



var prediction_update = func {

setsize(track_prediction,0);

var earth_motion_degs = 0.00416666666;
var lat = getprop("/position/latitude-deg");
var lon = getprop("/position/longitude-deg");

calc_geo(lat);


var orbiter_motion_north_fps = getprop("/fdm/jsbsim/velocities/v-north-fps");



var orbital_speed_fps = getprop("/fdm/jsbsim/velocities/eci-velocity-mag-fps");
var orbital_period = getprop("/fdm/jsbsim/systems/orbital/orbital-period-s");



var rising_flag = 0.0;

if (orbiter_motion_north_fps > 0.0) {rising_flag = 1;}
else {rising_flag = -1.0};

var inclination = getprop("/fdm/jsbsim/systems/orbital/inclination-deg");
var inclination_rad = inclination * math.pi/180.0;

var sinphi = (lat/ inclination);

sinphi = math.min(sinphi, 1.0);
sinphi = math.max(sinphi,-1.0);

var phi = math.asin(sinphi);

if (rising_flag == -1) {phi = math.pi - phi;}



var lon_rising = lon - phi * 180.0/math.pi;
if (lon_rising < 0.0) {lon_rising = lon_rising + 360.0;}




var dt =  120.0;
var offset = 0.0;

var increment = 2.0 * math.pi * dt/orbital_period;

for (var i = 0; i<40; i = i+1)
   {
   var arg = phi + i * increment;

   var pred_lat = math.asin(math.sin(arg) * math.sin(inclination_rad));
   var pred_lon = math.atan2(math.cos(inclination_rad) * math.sin(arg), math.cos(arg));
   
   pred_lat = pred_lat * 180.0/math.pi;
   pred_lon = pred_lon * 180.0/math.pi;

   pred_lon = pred_lon + lon_rising - earth_motion_degs * i * dt;

   if (i==0)   
      {
      offset = lon - pred_lon;
      }
   pred_lon = pred_lon + offset;

   if (pred_lon > 180) {pred_lon = pred_lon - 360;}
   if (pred_lon < -180) {pred_lon = pred_lon + 360.0;}
   var x =  lon_to_x(pred_lon);
   var y =  lat_to_y(pred_lat);
   append(track_prediction, [x,y]);
   }

}


history_init();
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: Using Canvas for visualizing orbital flights (cont'd PM)

Postby Hooray » Wed Apr 15, 2015 4:14 pm

looking good - what is performance like, I am asking because of the removeAllChildren() approach you're using for clearing/redrawing each track (i.e. no caching/reuse of existing points), do you notice any impact on frame rate/spacing while updating ?
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: Using Canvas for visualizing orbital flights (cont'd PM)

Postby Thorsten » Thu Apr 16, 2015 6:47 am

Well, I said it works, not that it's elegant...

How do you replot just changing the points? I ended up plotting hundreds of track onto each other with whatever I tried, and I suspect that's not good either...

Btw., upon reflection - the prediction actually has to be recalculated every time, because you might be making an inclination or semi-major axis change while looking at the map (in fact, you would typically look at the map precisely to gauge the impact of these), so the prediction always needs to start computing from the current state and can't re-use points.
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Next

Return to Canvas

Who is online

Users browsing this forum: No registered users and 4 guests