Board index FlightGear Development Canvas

Garmin GPSmap196

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: Garmin GPSmap196

Postby F-JJTH » Wed May 14, 2014 6:12 pm

Well I finally got working all what I wanted :)

Image

The Philosopher's solution wasn't working but I found another solution ( https://gitorious.org/fg/fgdata/source/ ... 6.xml#L291 )

As you can see, the 3D model and the widget are now working and they share the same canvas texture.
All buttons on the widget and 3D model are triggering the correct properties.

So now it's time to draw the structure of each pages, it seems that 1 SVG file per page was the appropriate solution, let's go !

Regards,
Clément
User avatar
F-JJTH
 
Posts: 697
Joined: Fri Sep 09, 2011 11:02 am

Re: Garmin GPSmap196

Postby Hooray » Wed May 14, 2014 6:24 pm

Very good job, indeed!
I just looked at your commit, and here's some feedback, just to keep your workload low, and to keep the whole thing generic (lessons learnt from the NavDisplay port!), so this is just some advice:
  • you better initialize your properties also using a foreach loop, see navdisplay.mfd for an example
  • but it can work just by creating a new hash: var m.properties = {}, and then you can directly use the key like this m.properties[key] = m.node.initNode(name, value, type);
  • that is what we did in navdisplay.mfd, too
  • I would suggest to move your Nasal code OUT OF THE model/xml file, use a non-standard location, or a non-standard file extension, and then use io.include(); to load your instead
  • please don't use absolute property paths, better make this configurable - so that we can easily support multiple instances of your device/dialog eventually
  • your code is exceptionally clean and compact now, but some comments would be a good idea for others having a look :D
  • especially, because I'd like to see the whole effort documented through a wiki article/tutorial, or at least in the GPSMap196 wiki article
  • you should upload your screen shots to the wiki, so that we can directly reuse them in our newsletter

For your "pages", you'll probably want to introduce a handful of helper classes, see the Avidyne code (extra500) for a few good examples. Or look at Tom's MCDU code.
Hint: if your code contains more than 2-3 nested conditionals to handle "pages", "switches" and "modes", you are doing something wrong - it SHOULD NOT look like the update() method in NavDisplay (navdisplay.mfd)!! :oops: The approach taken in the MCDU code or the Avidyne is MUCH better. Please report back regularly so that we can provide feedback, and hopefully see parts of this generalized and committed to the corresponding canvas frameworks (e.g. animations)

See the stuff at: https://gitorious.org/extra500/extra500 ... neEntegra9
but ignore the map drawing, we are handling that already and can add MapStructure-functionality to your instrument within 5 minutes meanwhile (even right 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: 11430
Joined: Tue Mar 25, 2008 8:40 am

Re: Garmin GPSmap196

Postby F-JJTH » Wed May 14, 2014 9:20 pm

Hooray wrote in Wed May 14, 2014 6:24 pm:Very good job, indeed!
  • I would suggest to move your Nasal code OUT OF THE model/xml file, use a non-standard location, or a non-standard file extension, and then use io.include(); to load your instead
  • your code is exceptionally clean and compact now, but some comments would be a good idea for others having a look :D


Done ;)
User avatar
F-JJTH
 
Posts: 697
Joined: Fri Sep 09, 2011 11:02 am

Re: Garmin GPSmap196

Postby Hooray » Wed May 14, 2014 9:51 pm

See my wikimedia link for all the SVG instruments that you may need - to animate those instruments, you'll probably want to check out navdisplay.mfd, but basically it's just setRotation(), setTranslate() and setTransform(), along with getprop() obviously
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: 11430
Joined: Tue Mar 25, 2008 8:40 am

Re: Garmin GPSmap196

Postby Hooray » Thu May 15, 2014 1:51 pm

Hooray wrote:
F-JJTH wrote in Mon May 12, 2014 8:43 pm:Well as you can see we are not ready to start to draw waypoints, lines, airport or anything else in the map ;-) there is a lot of work before that.

Personally, I would probably start with the mapping page, because that's what we can support right now using MapStructure, without too much extra work ;-)
[...]we can add MapStructure-functionality to your instrument within 5 minutes meanwhile (even right now!) :D


Here, this took 60 seconds to integrate with MapStructure using 10 lines of code - it's a fully working moving map - scale is obviously off here, but it's a matter of setting another style (which can also be used to change color and most symbols)

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

And here, with some custom styling applied to change a few colors:
Image


More layers available, see: http://wiki.flightgear.org/Canvas_MapStructure#Layers

This is exactly the reason, why we've been working towards an aircraft and GUI agnostic abstraction layer using MVC design concepts - so that reusing and integrating such stuff is really straightforward



F-JJTH wrote:to be honest I'm not ready to work on this side, as I said there is a lot of work to do before drawing the map.
I have to found how to manage all the page/popup, once I have that I will be able to start to draw something (I think I will start with the compass/attitude/speed page)


This is done using 10 lines of Nasal code (svg.nas seems to have some problems with the bank indicator here, so may need some work-and colors may need to be adjusted too) - to animate each instrument, we only need to look up each element (by ID) and associate a callback with it via maketimer(). That's roughly 10 minutes of work per instrument probably:
Image
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 11430
Joined: Tue Mar 25, 2008 8:40 am

Re: Garmin GPSmap196

Postby F-JJTH » Fri May 16, 2014 7:40 pm

I've spend most of my time with Inkscape these days, here is the result:

Image

Also I've implemented a (very very very bad) switcher for pages. So it's possible to switch between pages (only Map and Panel are available for now)
Why is it a so bad swicther ? because it rely on the maketimer() which is definitely not the good solution.
I think the real solution is to add a listener on the inputs/button-page prop but I'm not sure how to do that in this OOP environment.

Another things that I don't like in my code is:
Code: Select all
me.pages.map.hide();
me.pages.panel.hide();
me.pages.route.hide();
me.pages.position.hide();

if(me.selectedPage.getValue() == 0)
  me.pages.map.show();
elsif(me.selectedPage.getValue() == 1)
  me.pages.panel.show();
elsif(me.selectedPage.getValue() == 2)
  me.pages.route.show();
elsif(me.selectedPage.getValue() == 3)
  me.pages.position.show();


because this code apply a hide() for each loop. A better solution would be to have something like:

Code: Select all
setlistener("inputs/button-page", func {
  me.pages.map.hide();
  me.pages.panel.hide();
  me.pages.route.hide();
  me.pages.position.hide();

  me.selectedPage.setIntValue( me.selectedPage.getValue() + 1 );
  if(me.selectedPage.getValue() > 3) me.selectedPage.setIntValue(0);

  if(me.selectedPage.getValue() == 0)
    me.pages.map.show();
  elsif(me.selectedPage.getValue() == 1)
    me.pages.panel.show();
  elsif(me.selectedPage.getValue() == 2)
    me.pages.route.show();
  elsif(me.selectedPage.getValue() == 3)
    me.pages.position.show();
}, 1, 0);


but I'm not sure how to integrate that, and maybe there is a better solution.
Finally all my buttons should have a listener :/

Last things: the page-panel.svg file has all the digit number, but none of them are displayed... any idea why ? is it because I have to add the "font-mapper" function ?

Regards,
Clément
User avatar
F-JJTH
 
Posts: 697
Joined: Fri Sep 09, 2011 11:02 am

Re: Garmin GPSmap196

Postby Hooray » Fri May 16, 2014 8:07 pm

this is looking really good.
Does this already include my suggested changes/patch ?

  • page switching should probably be handled by a "PageManager", which is just a container for registered pages.
  • It would really only need a handful of methods like registerPage(), getCurrentPage(), switchPage(), handleEvent() etc
  • You would then use a symbol lookup ID as a key, e.g. registerPage(name:"map", class:myMapPage), which would do the equivalent of me.pages[name]=class in in the body of the method
  • switching would then just involve calling .hide() for the non-active pages, calling .show() for the active page, and registering the I/O handler implemented by the page class, i.e. analogous to update() currently, which would just forward stuff to getCurrentPage().handleEvent();
  • listeners can still be registered via setlistener(), but you can directly pass the me.button["rocker-left"] node to the setlistener call
  • setlistener calls should always be appended to a vector - analogous to my maketimer() patch, e.g. me.listeners =[]; append(me.listener, setlistener(me.button["rocker-left"],.....));
  • timers and listeners should be managed/released in the .del() method
  • here, the callback would probably be just a dispatcher that forwards all I/O to the pageManager's getCurrentPage() callback.
  • to avoid hiding all pages separately, just keep them in a vector or hash and use the switchPage() method
  • regarding the font issue, check the console - if there are no errors, that's probably the problem


You could probably commit what you've got so that we can take a look and provide a few hints/patches to progress further.
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: 11430
Joined: Tue Mar 25, 2008 8:40 am

Re: Garmin GPSmap196

Postby F-JJTH » Fri May 16, 2014 8:22 pm

I forgot to mention that I've pushed all my changes:

https://gitorious.org/fg/fgdata/commit/ ... c3838d0de0 (only Nasal change)

http://mapserver.flightgear.org/git/?p= ... c335269d97 (no Nasal change, only 3D/SVG/PNG change)

Your source code example are always benefit, feel you free to show me an example.

I'm well aware that only data for the current page must be computed. Is it a good solution to have 4 different update() function ?
updatePanel()
updateMap()
updateRoute()
updatePosition()

only one of these function should run at a time.
User avatar
F-JJTH
 
Posts: 697
Joined: Fri Sep 09, 2011 11:02 am

Re: Garmin GPSmap196

Postby Hooray » Fri May 16, 2014 8:35 pm

yes, see my posting - it would make sense to use a helper class for your "pages", call it MFDPage, each can have its own method for hadling updates
And you would only ever run the update/event handling method whose page is active. A very simple method would be having one maketimer object per page (i.e. as part of the page) and start/stop those.in the switchPage() method
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: 11430
Joined: Tue Mar 25, 2008 8:40 am

Re: Garmin GPSmap196

Postby Hooray » Sat May 17, 2014 1:42 pm

Like I mentioned earlier, I have now prepared a small patch that addresses most of your open questions and concerns - including a handful of helper classes for setting up pages, managing them etc.
And everything is working correctly - however, I am considering to revamp button/switch handling to also do mode management. And here I don't quite understand the current setup, or rather, I do understand it now, but I don't understand why we have to use <mod-up> animations to set those properties to true/false and deal with both states separately via dedicated listener callbacks ?

To be honest, I have never used the RL device, but do you really need so much fine-grained control, or wouldn't it suffice (maybe just for now) to simply use the "click" event listener, rather than processing mousedown/mouseup etc ?

I am sure that most buttons will not require that much control ?

Either way, if the device is really that complex and supports stuff like buttons pressed for several seconds, we still need a dedicated event/mode manager helper class, which is currently difficult to support given all those low-level properties and listeners.

But otherwise, everything else is working like it should and is also extensible now, while still being just a handful of simple helper classes that can be extended over time

EDIT: Here's a patch: http://codepad.org/vVccpHDp
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: 11430
Joined: Tue Mar 25, 2008 8:40 am

Re: Garmin GPSmap196

Postby F-JJTH » Sat May 17, 2014 1:55 pm

Quick answer (sorry I don't have more time today)

Most of buttons have a "if button X is pressed 3 seconds: something happend", that's why I've chosen to use "mouseup/mousedown" instead of simple "click".
For example, switch ON/OFF the GPS require to press the power button during 2~3 seconds. In real life a simple click does nothing on this button for security: in case you accidently touch this button during manipulation the GPS would switch OFF if a simple click was enough, and you can be sure that the last thing you want is to turn OFF your GPS when manipulating it :) Hopefully Garmin has understood that and make our life easier, we can accidently click on this button without turning off the GPS :)

So now you know ;) one button can have 2 actions: 1 action if button is clicked, 1 action if button is held.

Regards,
Clément
User avatar
F-JJTH
 
Posts: 697
Joined: Fri Sep 09, 2011 11:02 am

Re: Garmin GPSmap196

Postby Hooray » Sat May 17, 2014 2:01 pm

ok, thanks for clarifying - I can think of several possibilities to simplify that, but I may need some docs to see how this works in general, and how flexible it needs to be.
for now, I have changed the "page" button to just support "click" events.
But I'll rework this once we need more flexibility
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: 11430
Joined: Tue Mar 25, 2008 8:40 am

Re: Garmin GPSmap196

Postby TheTom » Sat May 17, 2014 2:59 pm

F-JJTH wrote in Sat May 17, 2014 1:55 pm:Most of buttons have a "if button X is pressed 3 seconds: something happend", that's why I've chosen to use "mouseup/mousedown" instead of simple "click".

Maybe it would be useful to add a duration field to the click event?
TheTom
 
Posts: 321
Joined: Sun Oct 09, 2011 10:20 am

Re: Garmin GPSmap196

Postby Hooray » Sat May 17, 2014 4:13 pm

that would be great to have, I just spent 10 minutes to get that right in Nasal using a combination of listeners and timers that get started/stopped and killed until it worked using 3 different helper classes.
So some C++ code to simplify this would be great ;-)
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: 11430
Joined: Tue Mar 25, 2008 8:40 am

Re: Garmin GPSmap196

Postby TheTom » Sat May 17, 2014 4:17 pm

I will need to think about it. It's not as simple as just adding a duration field, as the action is usually triggered after a certain timeout after a mousedown event without an according mouseup event.
TheTom
 
Posts: 321
Joined: Sun Oct 09, 2011 10:20 am

PreviousNext

Return to Canvas

Who is online

Users browsing this forum: No registered users and 1 guest