Board index FlightGear Development Nasal

Spoken GCA

Nasal is the scripting language of FlightGear.

Re: Spoken GCA

Postby Thorsten » Sun Sep 10, 2017 5:39 pm

Would it be possible to create these modules outside of main FGFS and act through properties over e.g. http?


Actually, when you thread stuff out, you create overhead in synchronizing things so that you can do a safe property write. If you keep threading out low performance stuff, you'll cause much more framerate drain due to this overhead than you gain by the threading out.

Most of the time Nasal isn't the cause of poor performance, poorly designed code is.

Seriously: Unless you have analyzed a bottleneck, understand it and can give the numbers to back up your assessment - don't give code design advice. There's been much harm done in the past by well-meant but poorly working suggestions.

In any case, you ought to be able to configure FG such that you get stable 60 fps on a modern gaming computer for everything but the most high-end planes (I certainly can). Maxing out all the graphics goodies (at times using settings that can't be accessed in the GUI) brings me to around 30 fps min.

Only super systems and avionics heavy planes demand more.
Thorsten
 
Posts: 11087
Joined: Mon Nov 02, 2009 8:33 am

Re: Spoken GCA

Postby rleibner » Mon Sep 11, 2017 6:56 pm

Alant wrote in Sat Sep 09, 2017 10:37 pm:I will need to fly some approaches to test it. The first impression is that the heading changes are not sufficinet to get the aircraft back on track.
This may be because I am coming in with my TSR2 at 180kts. Perhaps I should use the Cesna or similar for this exercise.
Alan

I've made some modifications as follows:
    Once into the area, the controller directs a perpendicular path to the app course.
    At 1.5 nm from app course, "Make half standard rate turns. Turn <left/right> heading <toRwyHdg>".
    A few seconds latter "Approaching glidepath. Begin descent. "
A bit of math to substantiate that:
A 90 deg half standard turn takes 60 secs = 0.017 h
At some 110 kts IAS results an arc of 110 x 0.017 = 1.87 nm
Such arc is rxPI/ 2 thus r = 2 x 1.87 / PI = 1.2 nm.
Adding some secs to configure attitude, we have 1.5 nm.

Blindly following the instructions of the controller, I've got: Image

I have updated the zip file so that you can test it.
Rodolfo
*************************
Non-shared knowledge is lost knowledge
User avatar
rleibner
 
Posts: 246
Joined: Fri May 19, 2017 7:17 pm
Location: Uruguay - SUMU
Callsign: CX-BEX
Version: 2180.4.0
OS: Ubuntu 18.04

Re: Spoken GCA

Postby Alant » Mon Sep 11, 2017 7:09 pm

Rodolfo

Thanks. I have installed it in place of the old version and will test at the first oportunity.

Alan
Alant
 
Posts: 913
Joined: Wed Jun 23, 2010 5:58 am
Location: Portugal
Callsign: Tarnish99
Version: from Git
OS: Windows 10

Re: Spoken GCA

Postby Hooray » Wed Sep 13, 2017 7:53 pm

Thanks for the heads-up and thanks for your PM - I do absolutely agree, this looks fantastic.
Regarding your code/design questions, I think you have already extended the class beyond what I was envisioning originally.
And it seems you even completed the visualization routine already, which is something that didn't even start yet.
From a code management point, I was hoping to come up with a decoupled design using 3 distinct classes - one for handling the GCA itself, and to helper classes whose constructor would take a handle to the GCA class to retrieve any instance specific state from it directly, e.g. for visualizing the running GCA, but also for setting up the whole thing using the UI that I created.

I haven't yet looked at any of your code, so I don't know if you were already tinkering with integrating the UI, too ?
That is actually something that started doing 1-2 weeks ago, when I began moving everything to an addon/submodule structure - but in the meantime you have made so much progress, that it would be kinda moot to share that code now.

Finally, regarding the threading related questions: I am entirely with Thorsten on that one, the runtime footprint caused by this script should be marginal even under the worst of conditions - thus, there's hardly any point in porting it to some other language/framework or moving it to a separate thread at this point. As a matter of fact, people who don't buy that, can easily benchmark the script using debug.benchmark() - moving the computations to a Nasal worker thread would be easy enough, but would buy us nothing. Thus, I would suggest not to over-engineer things by prematurely optimizing this feature so early.

Even if we should be able to identify a few bottlenecks in the time to come, it should only take a few experienced Nasal coders to optimize the script and make it work well enough for most people - it's not like this is some kind of heavy eye-candy feature after all.


Like Thorsten said already, I wouldn't underestimate the overhead cause by porting/rewriting the script using a different framework and by sync'ing the relevant state using whatever IPC you have in mind.

My guess is that the Canvas based visualization dialog is much heavier in terms of added footprint than the script itself, and it's not like people are suggesting to move Canvas/Nasal to a different thread (yet).

That being said, and totally unrelated to spokenATC and the GCA module, if/when threading should ever become an option, it would make more sense to thread-out individual Nasal scripts, or even associate individual interpreter instances to a single Canvas instance (texture), so that each texture could have its own associated scripting interpreter updating it, using a private property tree.

I once tinkered with such a scheme when I was working on disabling Nasal entirely and making it initialize incrementally afterwards - the point being that such a Nasal interpreter would only have/require a subset of the usual FG/Nasal APIs, so that it would be much more lightweight - which also means you cannot just getprop() or setprop() arbitrary properties, but really need a sane form of IPC - for starters that could be Torsten's mongoose/Phi work.

http://wiki.flightgear.org/Howto:Disable_Nasal_entirely
http://wiki.flightgear.org/Initializing_Nasal_early

In other words, there is no clean way to run Nasal/Canvas based code in a worker thread unless you are willing to provide each Canvas texture with its own scripting interpreter that runs outside the main loop. And that's a potentially interesting scheme, because such textures -while still GC bound- could be updated at much higher rates. i.e. higher than 60 hz, which would also be of interest to certain aggrressive threading optimizations that OSG can make

For that to work, each Canvas would have to use its own private property tree instance (SGPropertyNode) and only replicate relevant state/events in the global property tree at framerate, whereas things would be internally updated much faster
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: 11340
Joined: Tue Mar 25, 2008 8:40 am

Re: Spoken GCA

Postby rleibner » Thu Sep 14, 2017 5:32 pm

Thanks Hooray for your feedback.

I have updated the zip file with some improvements:
    A new "Slightly <right/left> of course" zone, in the neighborhoods of "Oncourse" zone.
    A descending control, "<Above/On/below> glidepath".
    Bigger use of class members, instead of setprop()/getprop().
TODO:
    Move Join() functoin and phraseology out of GCA module, in order to make it accessible to other callers.
    Integrate the UI params editor and all the stuff that Hooray proposes wisely.
Since I am a newcomer in the field of OOP, I would welcome the participation of collaborators/co-authors for those tasks.
Rodolfo
*************************
Non-shared knowledge is lost knowledge
User avatar
rleibner
 
Posts: 246
Joined: Fri May 19, 2017 7:17 pm
Location: Uruguay - SUMU
Callsign: CX-BEX
Version: 2180.4.0
OS: Ubuntu 18.04

Re: Spoken GCA

Postby Hooray » Thu Sep 14, 2017 5:46 pm

I would welcome the participation of collaborators/co-authors for those tasks.

I think I may be able to help with this, but we may want to use a repository at some point.

If on the other hand, you could simply extend/modify your own code to provide setters for the corresponding fields shown in the UI, I could probably hook those up to the UI without much work at all.

Basically, you would need to add methods (functions referencing variables in the me namespace) to set the corresponding values.
Once you have provided those setters, I can handle the UI part and post the modified UI here so that you can test the whole thing without having to know much about OOP

http://wiki.flightgear.org/Howto:Implem ... GCA_system
Image

Looking at the code I wrote a few weeks ago, I already used the following names for the corresponding callbacks (see the callback: field in the hash specificying the method's name as a string):

Code: Select all
var inputs = [
{text: 'Position root', default_value:'/position', focus:1, callback:'setPosition', tooltip:'property path to position node', validate: 'AircraftRoot', convert:nil, unit: 'property path'},
{text: 'Airport', default_value:'KSFO', focus:0, callback:'setAirport', tooltip:'ICAO ID, e.g. KSFO', validate: 'Airport', convert:nil, unit:'ICAO'},
{text: 'Runway', default_value:'28R', focus:0, callback:'setRunway', tooltip:'runway identifier, e.g. 28L', validate: 'Runway', convert:nil, unit:'rwy'},
{text: 'Final Approach', default_value:'10.00', focus:0, callback:'setFinalApproach', tooltip:'length of final approach leg', validate: 'FinalApproach', convert:nil, unit:'nm'},

{text: 'Glidepath', default_value:'3.00', focus:0, callback:'setGlidepath', tooltip:'glidepath in degrees, e.g. 3', validate: 'Glidepath', convert:nil, unit:'degrees'},
{text: 'Safety Slope', default_value:'2.00', focus:0, callback:'setSafetySlope', tooltip:'safety slope in degrees', validate: 'SafetySlope', convert:nil, unit:'degrees'},

{text: 'Decision Height', default_value:'200.00', focus:0, callback:'setDecisionHeight', tooltip:'decision height (vertical offset)', validate: 'DecisionHeight', convert:nil, unit:'ft'},
{text: 'Touchdown Offset', default_value:'0.00', focus:0, callback:'setTouchdownOffset', tooltip:'touchdown offset', validate: 'TouchdownOffset', convert:nil, unit:'m'},
{text: 'Transmission interval', default_value:'5.00', focus:0, callback:'setTransmissionInterval', tooltip:'Controller/timer resolution', validate: 'TransmissionInterval', convert:nil, unit:'secs'},
{text: 'Transmission channel', default_value:'/sim/messages/approach', focus:0, callback:'setTransmissionChannel', tooltip:'property to use for transmissions. For example: /sim/multiplay/chat or /sim/sound/voices/approach', validate: 'TransmissionProperty', convert:nil, unit:'property'},
]; # input fields


PS: Using methods and class members (instance variables) instead of properties is generally a good thing, especially if/when we need to run multiple instances of the script "concurrently".
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: 11340
Joined: Tue Mar 25, 2008 8:40 am

Re: Spoken GCA

Postby rleibner » Fri Sep 15, 2017 12:58 am

Hooray wrote in Thu Sep 14, 2017 5:46 pm:I think I may be able to help with this, but we may want to use a repository at some point.
Glad to hear that.
I think I must fork SF repository and upload an addon version. If I have not done it before, it's because I'm afraid to screw the 2013.3.1 release.

For now, I'm instancing the class:
Code: Select all
demo = gca.GCAController.new( timer_interval_secs: 1 );
then setting:
Code: Select all
demo.setAircraft( root: "/position", callsign:"foo");
. . .
demo.setDestination( airport:icao, runway:best, glidepath:3.00, gate_distance:6 );
. . .
demo.registerReceiver( receiver );
demo.start();

When receiving his instrucion, I check:
Code: Select all
demo.phrase
demo.maxsecs
demo.rwyDist
demo.destination.gate_distance

For your reference, I've added these coms to the class file:
Code: Select all
# members:
#   .aircraft_state.altitude_ft
#   .aircraft_state.latitude_deg
#   .aircraft_state.longitude_deg
#   .aircraft_state.heading_magnetic_deg
#   .destination.airport
#   .destination.runways
#   .destination.runway
#   .destination.rwy_obj
#   .destination.elevation
#   .destination.glidepath
#   .destination.gate_distance
#   .timer
#   .phrase
#   .maxsecs
#   .callsign
#   .gateAlt
#   .rwyDist
#
# methods:
#   .start()
#   .stop()
#   .del()
#   .restart()
#   .restart(seconds)
#   .setAircraft(root)
#   .setDestination()
#   .computeRequiredHeading()
#   .computeRequiredAltitude()

Note:
    1. My gate_distance is your Final approach (*)
    2. The script chooses the airport according comm1 freq., and the best rwy (like SpokenATC does).
    3. I'm supposing the Touchdown Offset = .destination.rwy_object.theshold
    4. I keep Transmission interval constant (1 sec) and the caller's AI decides when to paste the voice property.
(*) in general, your (English) terminology is better than mine. I will adopt yours.
P.S., It may be time to start documenting how the script works, its AI criteria, the instructions logic ...
Thinking not only for coders reference, but especially for pilots.
Rodolfo
*************************
Non-shared knowledge is lost knowledge
User avatar
rleibner
 
Posts: 246
Joined: Fri May 19, 2017 7:17 pm
Location: Uruguay - SUMU
Callsign: CX-BEX
Version: 2180.4.0
OS: Ubuntu 18.04

Re: Spoken GCA

Postby Hooray » Fri Sep 15, 2017 3:00 am

Ok, I see - thanks for taking the time to explain these details.
The script that I modified a few weeks ago, would use a much simpler constructor and use a handful of methods to separately set up things that I originally initialized using the constructor.
That is why I added/asked for a number of "setter" functions (=methods), so that if/when a field in the UI dialog is modified, I can directly invoke the corresponding setter in the class, instead of having to re-create the whole object.

Basically, I added the following after the del() method to the class:

Code: Select all
'setTransmissionInterval': func(secs) {
me.timer = maketimer(num(secs), func me.update);
},
'setPosition': func(node) {
me.setAircraft(node);
},
'setAirport': func(airport) {
},
'setRunway': func(rwy) {
},
'setFinalApproach': func(final) {
},
'setGlidepath': func(slope) {
},
'setSafetySlope': func(slope) {
},
'setDecisionHeight': func(height) {
},
'setTouchdownOffset': func(offset) {
},
'setTransmissionChannel': func(node) {
},



As you can see these are just empty placeholders for now - but we can now use these to modify the corresponding internal variables and update the gca object.

PS: Like Alant was hinting at a few days ago, I also read that the usual transmission interval would be about 5 seconds, which is why I used that in the UI
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: 11340
Joined: Tue Mar 25, 2008 8:40 am

Re: Spoken GCA

Postby rleibner » Fri Sep 15, 2017 8:04 pm

Hooray wrote in Fri Sep 15, 2017 3:00 am:Basically, I added the following after the del() method to the class:

I see. I appended the destination hash with runway, elevation, ... keys.
But I agree, separate setters are clearer. I will fix that.
Hooray wrote in Fri Sep 15, 2017 3:00 am:Like Alant was hinting at a few days ago, I also read that the usual transmission interval would be about 5 seconds, which is why I used that in the UI

In fact, I've found that 5 seconds interval is almost the minimum one that TTS can speak without step on the tail. It is necessary on short final, when pilot must make immediate corrections, but when instruction is a vector towards base ... such loquacity is really annoying!
And, at that time:
Alant wrote in Sat Sep 09, 2017 12:33 pm:. . . The messages are a little more frequent than I remember, but it was a long time ago. . .

So I adopted a dynamic criteria.
Please see the details here.
Rodolfo
*************************
Non-shared knowledge is lost knowledge
User avatar
rleibner
 
Posts: 246
Joined: Fri May 19, 2017 7:17 pm
Location: Uruguay - SUMU
Callsign: CX-BEX
Version: 2180.4.0
OS: Ubuntu 18.04

Re: Spoken GCA

Postby rleibner » Fri Sep 15, 2017 11:11 pm

rleibner wrote in Fri Sep 15, 2017 8:04 pm:But I agree, separate setters are clearer. I will fix that.

Done !

Do you think it's a good time to fork SF? it would be easier in order to work as a team.
Rodolfo
*************************
Non-shared knowledge is lost knowledge
User avatar
rleibner
 
Posts: 246
Joined: Fri May 19, 2017 7:17 pm
Location: Uruguay - SUMU
Callsign: CX-BEX
Version: 2180.4.0
OS: Ubuntu 18.04

Re: Spoken GCA

Postby Hooray » Tue Sep 19, 2017 6:32 pm

Not so sure about "forking", assuming you mean fgdata ?
As far as I can see, you mentioned plans about integrating this with the spoken ATC addon you have been developing.
Thus, one way or another, this is likely to become available as an "addon" - no matter if that means as part of your spoken ATC work, or some other/separate module.
Speaking in general, it would not even be that farfetched to also review Marius_A's missions system and/or Stuart's tutorial system to see if/how those could be extended to provide the corresponding building blocks that would facilitate implementing such functionality as part of those systems

Equally, the assumption about the IAS of the aircraft is not a safe one to be made - it may be better to also make that configurable via the UI (dedicated setter), possibly in the form of a gradient (groundspeed/distance over terrain) - so that the whole thing would also work for jet/fighter aircraft (think concorde). The whole addon may actually be easiliy adapted to also work for carrier approaches, thus I would not make too many hard-coded assumptions but better introduce variables for those and separate setters so that we can expose those via the UI. In the case of the main aircraft, the corresponding defaults could even be retrieved from the checklists system automatically.

Anyway, sorry for getting back to this so late - it may still take me a few days to look at any of your code, but integrating the UI pieces I have with your changes should be straightforward now.

I would still suggest to modularize the code a little more, e.g. use separate files for separate functions (think the visualization dialog being currently parts of tools.nas) - the reason being that it will be much easier to collaborate with others by stating clearly that you are only touching a single file.

For instance, the visualization tool you have created could also benefit from beiing turned into MapStructure layer, you are already replicating functionality that others have come up with, such as a VERTICAL SITUATION DISPLAY (=VSD)



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

Thus, I guess it would not be a bad idea to identify overlapping/similar functionality and come up with generic modules for these purposes.
Equally, your approach profile may benefit from optoinally displaying a terrain profile, too.

But again, this is just to say that it may not be such a bad idea to use separate files for distinct components, so that we can more easily work independently on different modules.

Porting your tool.nas work to use the MapStructure MVC framework would also mean that it could trivially display all sorts of related info/symbols (think other airports, navaids, the flight plan, flight path history etc):

Image


(To be fair, there is currently not support for vertical layers, but that would be easy to add if we want 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: 11340
Joined: Tue Mar 25, 2008 8:40 am

Re: Spoken GCA

Postby rleibner » Wed Sep 20, 2017 3:00 am

Hooray wrote in Tue Sep 19, 2017 6:32 pm:Not so sure about "forking", assuming you mean fgdata ?
No, sorry: I meant "branching" SourceForge addons folder.

For the rest, I understand you and I will see how to implement it.
To begin, I updated yet the zip file (and its link in the wiki).
When I have your UI, I can take the idea to do something similar with the parameters of the new PARScreen_class.

Hooray wrote in Tue Sep 19, 2017 6:32 pm:For instance, the visualization tool you have created could also benefit from beiing turned into MapStructure layer, you are already replicating functionality that others have come up with, such as a VERTICAL SITUATION DISPLAY (=VSD)

Yes, I thought about that. Although I live in a rather flat country, I foresee that it would be disastrous to use a simple 3 deg glideslope in SLLP (La Paz, Bolivia). not to mention the demon-possessed VHHH (Hong Kong) !
Rodolfo
*************************
Non-shared knowledge is lost knowledge
User avatar
rleibner
 
Posts: 246
Joined: Fri May 19, 2017 7:17 pm
Location: Uruguay - SUMU
Callsign: CX-BEX
Version: 2180.4.0
OS: Ubuntu 18.04

Re: Spoken GCA

Postby Hooray » Thu Sep 21, 2017 7:29 pm

Actually, my original idea was to simply use the GCA class as a "container" for all GCA related state, and then pass that to/from the UI, as well as the visualization front-end.
That way, stuff like the other parameters (think IAS, slopes etc) would be part of the GCA class itself, and could be filled in by the same UI dialog.
I would only change the constructor of the PARScreen_class to accept a handle to the gca object, maybe in conjunction with re/setting that handle if necessary.
Equally, the UI dialog I created a few weeks ago is simply storing a handle to the gca class and then uses that to directly invoke its methods.
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: 11340
Joined: Tue Mar 25, 2008 8:40 am

Re: Spoken GCA

Postby rleibner » Fri Sep 22, 2017 8:50 pm

Hooray wrote in Thu Sep 21, 2017 7:29 pm:Actually, my original idea was to simply use the GCA class as a "container" for all GCA related state, and then...
We agree, that is my idea too ... at long term (I must learn a lot to achieve such "architecture").
By the moment I'm focused on the heuristic and the associated math. I think I'm close.

On the other hand, I took a look at www : saw references to map the "xy" plane but non of "xz".
As I did no found the omega95's VSD code, I've made my (elementary) one.
And found weird behavior using geo.elevation(). See it by yourself:
Image
The first snapshot is when on "short final" and the terrain profile is the real one.
But some secs earlier I got this (autozoom was enabeled): Image
Note the hole some 2 nm from the rwy. It is NOT REAL ! The geo.elevation() there returned nil.
I guess that the tile was unloaded.

So the big question: Can I "force" the loading of a far tile?

P.S.: I know you see the "whole picture" in FG, and I don't yet. So excuse me if I keep walking (as Johnny Walker says :) ) on the field that I feel more comfortable. There will be time to arrange all this in a proper way.
Last edited by rleibner on Fri Sep 22, 2017 9:13 pm, edited 2 times in total.
Rodolfo
*************************
Non-shared knowledge is lost knowledge
User avatar
rleibner
 
Posts: 246
Joined: Fri May 19, 2017 7:17 pm
Location: Uruguay - SUMU
Callsign: CX-BEX
Version: 2180.4.0
OS: Ubuntu 18.04

Re: Spoken GCA

Postby Hooray » Fri Sep 22, 2017 9:02 pm

yeah, spot-on regarding the tile manager .... note that there is also a dedicated terrain presampler implemented in C++, I think so far only Thorsten's advanced weather system is using it - you may find some info about it by looking through local_weather for "geodinfo" calls and surrounding alternatives.

Omega95's VSD is part of some aircraft as far as I remember, there should be a topic on the forum detailing where the code is to be found.
Like you say, this is about projection handling, i.e. creating an altitude/terrain profile and plotting the position 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: 11340
Joined: Tue Mar 25, 2008 8:40 am

PreviousNext

Return to Nasal

Who is online

Users browsing this forum: No registered users and 1 guest