Board index FlightGear Development Nasal

Spoken GCA

Nasal is the scripting language of FlightGear.

Re: Spoken GCA

Postby rleibner » Wed Sep 27, 2017 4:59 pm

Well . . . how to say it? All seems to work , . . but it crashes ! ( oxymoron ? ) :oops:

Seriously speaking now, the last lines of configureGCA() reads:
Code: Select all
var buildCGA = func() {
       . . .
   gcaObject.start();
   window.clearFocus();
print("demo starts");
} # buildCGA

var toggleGCA = func() {
if (gcaRunning) {
gcaObject.stop();
gcaRunning = 0;
toggleFields(!gcaRunning); # set editable
return;
}

if (!gcaRunning and validateFields()==STATUS.SUCCESS) {
gcaRunning = 1;
toggleFields(!gcaRunning); # set readonly
buildCGA();
return;
}
} # toggleGCA()

var button = canvas.gui.widgets.Button.new(root, canvas.style, {})
   .setText("Start/Stop")
   .setFixedSize(75, 25)
   .listen("clicked", toggleGCA);

setupWidgetTooltip(widget:button, tooltip: "toggle GCA on/off");
myLayout.addItem(button);

}; # configureGCA();

When clicking the "Start/Stop" button, the toggleGCA() launches buildCGA() as expected.
Thus, PARScreen is instanced and set, PAR appears nicely and "demo starts" is printed,
. . . and FGFS crashes !

Looking my fgfs.log :
Code: Select all
nasal:5:/build/flightgear-NrffwL/flightgear-2017.2.1/src/Scripting/NasalSys.cxx:449:demo starts
general:3:/build/simgear-BoF3P8/simgear-2017.2.1/simgear/canvas/elements/CanvasElement.cxx:284:addEventListener(/canvas[0]/by-index[0]/texture[5], mousedown)
general:3:/build/simgear-BoF3P8/simgear-2017.2.1/simgear/canvas/elements/CanvasElement.cxx:284:addEventListener(/canvas[0]/by-index[0]/texture[5], wm.focus-in)
general:3:/build/simgear-BoF3P8/simgear-2017.2.1/simgear/canvas/elements/CanvasElement.cxx:284:addEventListener(/canvas[0]/by-index[0]/texture[5], wm.focus-out)
general:3:/build/simgear-BoF3P8/simgear-2017.2.1/simgear/canvas/elements/CanvasElement.cxx:284:addEventListener(/canvas[0]/by-index[0]/texture[5]/group[0]/group[0]/image[0], mouseenter)
general:3:/build/simgear-BoF3P8/simgear-2017.2.1/simgear/canvas/elements/CanvasElement.cxx:284:addEventListener(/canvas[0]/by-index[0]/texture[5]/group[0]/group[0]/image[0], mousedown)
general:3:/build/simgear-BoF3P8/simgear-2017.2.1/simgear/canvas/elements/CanvasElement.cxx:284:addEventListener(/canvas[0]/by-index[0]/texture[5]/group[0]/group[0]/image[0], mouseleave)
general:3:/build/simgear-BoF3P8/simgear-2017.2.1/simgear/canvas/elements/CanvasElement.cxx:284:addEventListener(/canvas[0]/by-index[0]/texture[5]/group[0]/group[0]/image[0], mousedown)
general:3:/build/simgear-BoF3P8/simgear-2017.2.1/simgear/canvas/elements/CanvasElement.cxx:284:addEventListener(/canvas[0]/by-index[0]/texture[5]/group[0]/group[0]/image[0], mouseup)
general:3:/build/simgear-BoF3P8/simgear-2017.2.1/simgear/canvas/elements/CanvasElement.cxx:284:addEventListener(/canvas[0]/by-index[0]/texture[5]/group[0]/group[0]/image[0], click)
general:3:/build/simgear-BoF3P8/simgear-2017.2.1/simgear/canvas/elements/CanvasElement.cxx:284:addEventListener(/canvas[0]/by-index[0]/texture[5]/group[0]/group[0]/image[0], mouseleave)
general:3:/build/simgear-BoF3P8/simgear-2017.2.1/simgear/canvas/elements/CanvasElement.cxx:284:addEventListener(/canvas[0]/by-index[0]/texture[5]/group[0]/group[0]/image[0], drag)
general:3:/build/simgear-BoF3P8/simgear-2017.2.1/simgear/canvas/elements/CanvasElement.cxx:284:addEventListener(/canvas[0]/by-index[0]/texture[5]/group[0]/group[0]/image[0], cb.clicked)
general:3:/build/simgear-BoF3P8/simgear-2017.2.1/simgear/canvas/elements/CanvasElement.cxx:284:addEventListener(/canvas[0]/by-index[0]/texture[5]/group[0]/group[0], drag)
I guess that when toggleGCA() returns, new buttons (and listeners) are added again and again ... :?:

I'm really stuck here. :roll:

P.S.: Nop, wasn't that.
I have just commented the gcaObject.start() line and there is no crashing now.
Obviously, being the timer not started, no instruction is given and PAR do not updates the fly track.
( start() func does nothing but me.timer.start() . And the timer does nothing but calling me.update() funcion.)

The mystery here is : when I enter gca.demo,update(); (via Nasal Console) ... it works ! step by step clicking the "Execute" button.
I mean I'm manually doing the timer's job ... and all works.
But when entering gca.demo.timer.start(); . . . :twisted: CRASH
:cry:
Rodolfo
*************************
Non-shared knowledge is lost knowledge
User avatar
rleibner
 
Posts: 269
Joined: Fri May 19, 2017 8:17 pm
Location: Uruguay - SUMU
Callsign: CX-BEX
Version: next
OS: Ubuntu 18.04.4

Re: Spoken GCA

Postby Hooray » Thu Sep 28, 2017 8:36 pm

that's weird, even if there is a bug, it should not trigger a crash.
You seem to have some troubleshooting already, but could you post your complete set of files ?
Otherwise it is hard to guess what may be going on...

Absent that, I would add all sorts of print() statements to see what is going on, i.e. to get a call trace.
You could also try disabling certain features - e.g. the PAR screen which is something that I haven't actually tested yet.
Doing that would only be to exclude potential sources to help us better understand what is going on.
For the same reason I would add "return" statements to methods to terminate them early, which would tell us if something is related to a certain method or not.

You could also post a gdb backtrace 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: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Spoken GCA

Postby rleibner » Thu Sep 28, 2017 11:43 pm

Wow, it took me maaany hours to find it, but I did: :D
It was a misuse of maketimer() inside the class constructor.
I have just fix it, and uploaded the whole zip.

It includes new Hz & Vt Grid entries in the UI dialog.

My TODO list:
    * improve the altitude instructions ("Climb/Descend", "Above/Below glidepath") considering terrain.
    * add a "Apply" button in the UI dialog, in order to edit the slopes looking the terrain profile prior to click "Start".
    * plot (and check) SafetySlope and DecisionHeight.

For testing/debugging I'm using a challenging situation:
Code: Select all
$ fgfs --aircraft=c172p --airport=SLLP --com1=119.5 --prop:/engines/engine[0]/running=true --offset-distance=10 --offset-azimuth=280 --altitude=14000 --vc=80 --wind=280@10

If you try it, be careful:
    At such altitudes a C172 can hardly fly.
    Pilot must manage the Mixture (for starting engines and later often when descending).
    You will be soon flying into the "mushing regime".
    If you fly a heavy aircraft, select rwy 28, cause the 28R is a grass short one.
Rodolfo
*************************
Non-shared knowledge is lost knowledge
User avatar
rleibner
 
Posts: 269
Joined: Fri May 19, 2017 8:17 pm
Location: Uruguay - SUMU
Callsign: CX-BEX
Version: next
OS: Ubuntu 18.04.4

Re: Spoken GCA

Postby Hooray » Sun Oct 01, 2017 5:35 pm

Sorry for responding to this so late, and sorry if I introduced the bug you mentioned - I don't remember the specifics, but you seemed right on track with your troubleshooting already.

Apart from that, I still have to download your code to give it a try. Regarding your question concerning conversion of variables - the only thing required to do is check if the "convert" field is not nil, and if typeof() returns "func" - if that's the case, you can directly do the equivalent of this:

(untested pseudo code);
Code: Select all
if (hash.convert != nil and typeof(hash.convert)=='func') {
var converted = hash.convert( text );
}


Thus, to actually make this work, you only change the line in the inputs vector where you want to call the num() API, specifiying:

convert: num

That way, it will assign the num callback to the convert key in the hash, and when the PAR/GCA objects are built, it can also do the conversion automatically.

And you said you are working on adding terrain profile support, right ?
If so, I would suggest to split the PARScreen class into helper functions/classes - for starters, maybe just two different modules for drawing the horizontal and the vertical profile view.

The point being that it will be much easier to add to your code if you split up things early on. As a matter of fact, once you think about it - both views share overlapping functionality (think drawing a 2D graph), so that they could both even use the same common baseclass. That would also make it possible to draw separate and independent grids for each graph if you wanted to.

Also, good work on getting additional input fields added - that should help make the whole thing even better configurable. Looking at the screenshot/diagrams you have added to the wiki, the black background color of the PAR screen could be also made configurable using the same method, to be better readable. This would also work for other settings, e.g. the size of the PAR screen window.

By the way, if you do add additional fields to the dialog you may need to change its dimensions, or things will look broken at some point, because the layout can no longer accommodate additional widgets

Then again, splitting up the PARScreen class into distinct components seems also like a good idea because you mentioned that you wanted to show a terrain preview, right ?
If that's the case, we could even created a dedicated Canvas widget (simlar to the input field or buttons), which would mean that we could optionally render the PAR screen in the same dialog as the UI - if that's what you are working towards.

Besides, preparing the groundwork for the PARScreen to become a Canvas widget in the future would also mean that its functionality could be added to the base package, e.g. as a dedicated MapStructure element, so that other developers can more easily reuse your work - it would then be treated as a conventional Canvas widget (think buttons) or a mapping layer that could be instantiated in arbitrary charting dialogs or MFDs (think navdisplay). This would also mean that people working on related functionality (think AWACS aircraft, ATC software or radar screens) could reuse some of your work.

This would also mean that the functionality of the horizontal/vertical approach profile view could be reused for things like a virtual flight instructor, flight/landing evaluation or Marius_A's missions system. Equally, the route manager could preview terminal procedures using such a profile view widget.

And again, introducing separate files for dinstinct components makes it much easier to collaborate without causing conflicts (imagine I am working on the UI, and you are only working on the PAR screen, with Alant only working on the phraseology). That way, you don't even need to use git, merging additions is much easier that way.

By the way, if you should end up updating the functional diagram you added to the wiki, I would defintitely suggest mentioning that your phraseology is configurable using XML, i.e. do mention "XML" in the description. Equally, adding "TTS/text-to-speech" for the instruction would make things more obvious.

Regarding the script and its UI, it is actually designed to be losely coupled, so that this whole thing would also work for tracking/monitoring AI/MP aircraft, and for issuing instructions to those - you can even try that locally by running two fgfs sessions on the same computer, and letting once instance run the GCA module to control the other MP plane: http://wiki.flightgear.org/Howto:Multip ... ultiplayer

Image

You should be seeing instructions computed by the first instance sent over MP to the other fgfs instance.

Once that is working well enough, I could also extend the UI such that it allows callsigns to be used instead of just /position trees in the property tree - it would be easy to do.

PS: A good test-case for the terrain profile might also be LOWI - lots of terrain surrounding the airport - from a collaboration standpoint it might be a good idea to turn this into an addon sooner or later, so that people don't have to touch $FG_ROOT to test/run and contribute to this.
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: Spoken GCA

Postby rleibner » Tue Oct 03, 2017 11:02 pm

I have just structured our prototype as Addon and uploaded to https://drive.google.com/drive/folders/0BzzojFuPdeyMdWEzaUczaFpsOFk?usp=sharing
I know that the right place would be the FGFS-Addons repository, but I'm not very sure how to create a new "SpokenGCA" directory there, in order to commit the files. :oops:
Note: the addon structure is not checked , since I've not upgraded my FG version yet. (Shame on me!)
Rodolfo
*************************
Non-shared knowledge is lost knowledge
User avatar
rleibner
 
Posts: 269
Joined: Fri May 19, 2017 8:17 pm
Location: Uruguay - SUMU
Callsign: CX-BEX
Version: next
OS: Ubuntu 18.04.4

Re: Spoken GCA

Postby Hooray » Tue Oct 03, 2017 11:04 pm

Thanks for the heads-up, by the way, I have added my comments to your questions in the wiki.
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: Spoken GCA

Postby rleibner » Wed Oct 04, 2017 12:35 am

I realized that the addon version contains an unnecessary file (init.nas) . Just ignore it.
And the scripts there, are later than the Submodule version, I'm working on same bugs.

By the way,
Hooray wrote in Tue Oct 03, 2017 11:04 pm:imagine I am working on the UI, and you are only working on the PAR screen, with Alant only working on the phraseology
I'd really like to work in such way (or similar)!

I would like the code to be easily readable for anyone, and the names of the variables may be contaminated by my own (Spanish) mnemonics.
Feel free to rename them.
Rodolfo
*************************
Non-shared knowledge is lost knowledge
User avatar
rleibner
 
Posts: 269
Joined: Fri May 19, 2017 8:17 pm
Location: Uruguay - SUMU
Callsign: CX-BEX
Version: next
OS: Ubuntu 18.04.4

Re: Spoken GCA

Postby Hooray » Sun Oct 08, 2017 11:42 am

Regarding your idea to preview the GCA/PAR screen according to the parameters entered in the config dialog, you can refer to the wiki to learn how to create a custom Canvas dialog/widget:

http://wiki.flightgear.org/Howto:Creati ... ialog_file
http://wiki.flightgear.org/Howto:Creati ... GUI_Widget
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: Spoken GCA

Postby rleibner » Mon Oct 09, 2017 3:16 am

Hooray wrote in Sun Oct 08, 2017 11:42 am:Regarding your idea to preview the GCA/PAR screen according to the parameters entered in the config dialog, ...

It's done. User can click the "Apply" button to see the PAR screen, modify some parameters in the dialog and "Apply" again, etc.

But I have a problem:
Since 'Safety Slope' depends on the terrain profile and on the 'Final Approach' value, user can lower the Safety Slope shortening the Final Approach. It works OK (e.g. at LOWI, Rwy 08, you get a Safety Slope=6.9 deg for the default Final Approach=10nm. Modifying Final to 5 nm you get an acceptable Safety Slope=3.1 deg ) Image
On the PAR screen, that Safety Slope=3.1 deg is shown fine but the config dialog remains reading 6.9.
You can see the code here, and take a look at lines 219 - 224. They are commented because I'm doing something wrong ... :roll:
I'm not pointing to the right object on which to call .LineEdit.setText()
Rodolfo
*************************
Non-shared knowledge is lost knowledge
User avatar
rleibner
 
Posts: 269
Joined: Fri May 19, 2017 8:17 pm
Location: Uruguay - SUMU
Callsign: CX-BEX
Version: next
OS: Ubuntu 18.04.4

Re: Spoken GCA

Postby Hooray » Mon Oct 09, 2017 5:53 pm

Hi, haven't yet looked at the code in question - but could you briefly describe what file/function is trying to access/set the widget value ?
The point being, that I didn't take that into account when I wrote the code - so you may need to look up the correct widget by traversing the hash/vector or by storing a handle separately.

Personally, I'd add a function to retrieve the widget dynamically - using something along the lines of the following pseudo code (untested):

Code: Select all
var getWidget = func(identifier) {
foreach(var field; inputs) {
if (field.validate == identifier) return field.widget;
} # foreach
return nil; # not found
} # getWidget


In the code above, we're "abusing" the validate field to look up the correct widget - i.e. you should be able to use something like this to get a handle to the widget:

var slopeWidget = getWidget('SafetySlope');


Obviously, if/when the identifier is changed (or a different one used), the code needs to be changed, too.

EDIT: I only just realized (looking at your code), that you are basically using the exact same approach already - so sorry about that. But I think accessing the widget just like that may be a little fragile, I would try the approach I suggested using another string as the identifer to retrieve the correct hash. Apart from that, really good job there !

PS: Regarding the terrain samping code: geodinfo() calls are commonly spread across several frames - for instance, imagine having to execute 500 queries - you could put those into batches using a vector, and invoke the callback only 50 times per frame. Apart from that, there is at least one other terrain sampling method (the terrain pre-sampler), so it may be a good idea to encapsulate the method you are using by adding a new function so that you can toggle between both options if the need arises. For the same reason, it may make sense to also expose the granularity/resolution of the terrain sampling using the UI (e.g. for the developer mode) - normally, we'd need to sample an actual "corridor" along the flight path to capture elevations in front of the aircraft (not sure what omega95/clm76 were doing in their code)
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: Spoken GCA

Postby rleibner » Tue Oct 10, 2017 5:56 pm

Regarding lines 219 - 224, I have researched a bite the origin of the error :
No problem to identify the inputs[j].widget.
But a debug.dump( inputs[j].widget ) returns "<Canvas.Widget>" and not "<Canvas.gui.widgets>" as expected.
So the object has "setFocus()", "clearFocus()", etc, but not an "LineEdit.setText()" method.
Last edited by rleibner on Tue Oct 10, 2017 6:44 pm, edited 1 time in total.
Rodolfo
*************************
Non-shared knowledge is lost knowledge
User avatar
rleibner
 
Posts: 269
Joined: Fri May 19, 2017 8:17 pm
Location: Uruguay - SUMU
Callsign: CX-BEX
Version: next
OS: Ubuntu 18.04.4

Re: Spoken GCA

Postby Hooray » Tue Oct 10, 2017 6:14 pm

You can always use the call() API to invoke an arbitrary method from a hash by passing it a handle to the object you want to modify (via me) - you were using that a few days ago for invoking methods on the GCAController object

That being said, you could add a debug.dump() to the function that adds the LineEdit widget to see what is going on.
I doubt there is a bug, probably just a misunderstanding
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: Spoken GCA

Postby rleibner » Tue Oct 10, 2017 9:27 pm

Anyway, I do not think I'm going to need it: I've been successful with the other idea I've mentioned, that is, masking unnecessary parameters.
I've added an optional argument to your configureGCA() function. I call it as follows:
Code: Select all
 var min = minSlope(me.touch, me.destination.rwy_object.heading+180, me.destination.final *NM2M);
 var defValues = {icao:me.destination.airport, rwy:me.destination.runway
         , safety_slope:min
         , channel:'/sim/sound/voices/atc', interval:1.00};
 var mask = {"Safety Slope":'',"Decision Height":'',"Position root":'' };
   configureGCA(demo, defValues, mask);
}
Note that we are not losing generality since each client can choose the default values and also which fields to mask.

I have updated the addon files.
I think that now is working as I intended.

P.S.: Regarding the Terrain profile, note that my function is a fast and cheap (in resources) one, but a bit "naif" because I'm plotting only a corridor along the final leg (is "static", computed only once when PAR screen is shown).
Rodolfo
*************************
Non-shared knowledge is lost knowledge
User avatar
rleibner
 
Posts: 269
Joined: Fri May 19, 2017 8:17 pm
Location: Uruguay - SUMU
Callsign: CX-BEX
Version: next
OS: Ubuntu 18.04.4

Re: Spoken GCA

Postby Hooray » Wed Oct 11, 2017 5:35 pm

Sounds great - is there anything else you are struggling with, or anything you'd like to have a helping hand with ?
For instance, I was thinking of adding support for using AI/MP callsigns instead of just properties, like I previously mentioned.
The point being to extend support for the multiplayer use-case, so that people can use this to tinker with doing GCAs across the multiplayer network.
Doing so, should be pretty straightforward - i.e. traversing a list of all AI/MP nodes and looking for a certain callsign and then using its position sub-tree for tracking the aicraft in question: http://wiki.flightgear.org/Howto:Workin ... properties

Another idea would be using tabs for 3 different modes for the GUI screen: pilot, controller and developer (debug/troubleshooting) - so that people could easily switch between all views, so that the corresponding fields would be masked automatically.

Apart from that, it may be time now to ask for more testing/feedback - not sure if Alant is still following the discussion or if anybody else is actually testing the script already ?
Overall, this seems like the type of feature that could have a great impact on existing features like the tutorial/missions systems we have in FlightGear.

I could also come up with a very simple scripted AI pilot class (based on tanker.nas) to instantiate arbitrary traffic at airfields and conduct virtual AI controller<->pilot interactions, which would be a super-fancy way to populate airports with traffic - imagine clicking a button to load an airplane that actually responds to the instructions of the virtual controller automatically
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: Spoken GCA

Postby rleibner » Thu Oct 12, 2017 3:26 pm

Certainly, you expose many inviting ideas.
Hooray wrote in Wed Oct 11, 2017 5:35 pm:. . . traversing a list of all AI/MP nodes and looking for a certain callsign and then using its position sub-tree for tracking the aicraft in question . . .
I have not yet explored the use of AI/MP and I have only a vague idea of how it works. I think I'll start studying that.

Hooray wrote in Wed Oct 11, 2017 5:35 pm:. . . using tabs for 3 different modes for the GUI screen: pilot, controller and developer (debug/troubleshooting) . . .
I love that. Could you make a pseudo-code scheme of how to implement it?

Hooray wrote in Wed Oct 11, 2017 5:35 pm:Apart from that, it may be time now to ask for more testing/feedback
This is really important. And not only testers but also collaborators who contribute fresh ideas and novel points of view. How to achieve it? Posting a notice in the FG-devel list ("Contributors and testers are welcome to the SpokenGCA project") ?

Hooray wrote in Wed Oct 11, 2017 5:35 pm:I could also come up with a very simple scripted AI pilot class (based on tanker.nas) to instantiate arbitrary traffic at airfields and conduct virtual AI controller<->pilot interactions, which would be a super-fancy way to populate airports with traffic - imagine clicking a button to load an airplane that actually responds to the instructions of the virtual controller automatically
Great!
I will definitely need help with all these possibilities that open up. I'm sure every one of them is worth it.
Rodolfo
*************************
Non-shared knowledge is lost knowledge
User avatar
rleibner
 
Posts: 269
Joined: Fri May 19, 2017 8:17 pm
Location: Uruguay - SUMU
Callsign: CX-BEX
Version: next
OS: Ubuntu 18.04.4

PreviousNext

Return to Nasal

Who is online

Users browsing this forum: No registered users and 4 guests