Board index FlightGear Development Nasal

Run Nasal Function at consistent rate regardless of frames

Nasal is the scripting language of FlightGear.

Run Nasal Function at consistent rate regardless of frames

Postby it0uchpods » Sun Apr 09, 2017 3:15 pm

Hi,
I'm working on a FBW system, and found that my settimer refreshes differently on my Main PC, 40FPS, and my laptop 15FPS.

I have:
Code: Select all
settimer(pitch_input, 0.1);


How can I make this refresh at a consistent rate? (using real clock?)

If this is not consistent, then the Airbus will respond differently on every system.

I tried this, as I saw in the wiki (http://wiki.flightgear.org/Nasal_library#settimer.28.29), you can use realtime in a settimer:
Code: Select all
settimer(pitch_input, [0.1, 1]);


But that causes FGFS to freeze on loading on my laptop (on vacation, no access to Main PC), so either the syntax is wrong for what I want, or it is refreshing to quickly for my laptop's AMD Athlon II CPU.

Any ideas? I have 2 functions to refresh, roll_input(); and pitch_input();

Thanks,
Josh
it0uchpods/WTF411

FGFS Aircraft Developer
Lead Programmer at it0uchpods Design Group
Download High Quality Aircraft from it0uchpods Hangar
User avatar
it0uchpods
 
Posts: 3567
Joined: Tue Oct 06, 2015 12:51 pm
Version: 2018.2.1
OS: Windows 10 x64

Re: Run Nasal Function at consistent rate regardless of fram

Postby Hooray » Sun Apr 09, 2017 3:36 pm

Disclaimer: You generally don't want to do this kind of thing - primarily because the main loop needs to be fast and "fixed" - vs. Nasal is a dynamic programming language with a so called garbage collector that may be triggered rather "randomly", which in turn makes the main loop less deterministic - this is important to keep in mind in general, but especially when dealing with systems (Nasal code) that is intended to be "FDM coupled" (run at FDM rate).

For starters, the square brackets in your settimer() call are almost certainly not doing what you expect them to do - that is because the call you are using will pass a Nasal vector (an array) to the API, and I don't think it accepts one at all - as a matter of fact, if the docs are using this syntax, it is primarily to denote optional arguments, which is in line with EBNF (see wikipedia) to specify optional arguments and how/where to use those.

Besides, you probably want to stop using settimer() in favor of maketimer() - in general, it is not a good idea to keep on using APIs like settimer() or setlistener() - instead, they should be wrapped by higher level helpers that may automatically help with resource management (cleaning timers/listeners) - not using those APIs properly is the the single most problematic reason for Nasal code running unnecessarily in the FlightGear main loop without people (aircraft developers and end users) being aware of that - in fact, there is no good way to actually tell what is going on here, unless you are intimately familiar with SG/FG and Nasal internals.

For the gory details, refer to:

viewtopic.php?f=46&t=17069

For details on timers and listeners and how/why they can be "leaking", see James and Torsten's comments quoted below:

Subject: Listener objects
zakalawe wrote:Dumb question of the day. Someone recently pointed out that the setlistener() / removelistener() API makes it easy to leak resources. So I wondered about making an alternate API where the return value from setlistener must be kept, or the listener is removed. I can imagine this with a helper object

var myL = setlistener2("some/prop", func { ... }} )
myL.addprop("some/other/prop");
myL.addprop("yet/another/prop");

Now you need to retain a ref to myL or the listeners on all the props are removed. I don't think we can retro-fit this to the existing API, because I suspect many places just ignore the return value and would break with this change.

(Or even pass a vec of property names to setlistener2, to avoid all the discrete calls to 'addprop', that's a seperate detail really)

It seems like this would work, and be easy enough to implement - question is if it gives enough benefit to be worth the confusion.



To learn more about tracking Nasal callbacks invoked via timers and listeners, refer to:

Subject: Nasal Callback tracking (timers & listeners)

Hooray wrote:http://sourceforge.net/p/flightgear/mailman/message/34810857/
Thorsten wrote:it's relatively easy to do bad things
unintentionally. Like tie a bit of code to an FDM property and run updates
of a display 120 times per second rather than the 30 times you actually
need. Like start a loop multiple times so that you update the same
property 30 times per frame rather than the one time you actually need.

It's actually pretty hard to catch these things, because the code is
formally okay, does the right thing and just eats more performance than
necessary, and there's no simple output telling you that you're running 30
loops rather than the one you expect. The only way I've found is to clock
down loops and print to console inside them - when you clock them per
second and see 30 messages printed each second, you know that something is
afoot...

So it's really not impossible to come up with aircraft Nasal that ends up
using a hundred times more performance than it has to. Unfortunately,
better CPU utilization is not really the way to attack these problems
though....


given that this obviously a recurring problem, I was wondering what we could do abot this - so I started prototyping a Nasal/Canvas-based UI to for displaying active Nasal callbacks (i.e. timers & listeners).

And I think it would be a good idea to gather some feedback to determine what kind of data would be useful and how it should be ideally represented - obviously, the screenshot below is not much more than a mockup (well, it is working Nasal code, just the data that is shown is arbitrary) - but otherwise, exposing the SGEventMgr logic at the Nasal level to provide a list of active events, including their callbacks (and location in Nasal code, i.e. filename and line number) is relatively straightforward.

So what else do we need to come up with an intuitive "task monitor" that shows Nasal callbacks registered in the form of timers and callbacks ?

Should we differentiate between aircraft and scenery code, between different sub-modules ? Technically, that would be possible to do, because we will need to patch some C++ code anyway - i.e. roughly 50-100 lines of code in both SG and FG will need to be touched to expose the SGEventMgr queues to scripting space (or even just in the form of live properties that are updated each frame)


http://wiki.flightgear.org/Howto:Troubl ... _Callbacks
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: 11192
Joined: Tue Mar 25, 2008 8:40 am

Re: Run Nasal Function at consistent rate regardless of fram

Postby sanhozay » Sun Apr 09, 2017 3:44 pm

You can't rely on these timers giving you real time events. The usual approach is to accept that and look at the system clock to work out the time difference between your last invocation and current invocation for use in calculations. So if you set a timer at 1s and it fires at 0.5s or 2s it doesn't matter, because you are doing your calculations on 0.5s or 2s rather than assuming the delta (time difference between events) is exactly 1s.

ps. As it says in that link, you should be using maketimer, rather than settimer.
sanhozay
 
Posts: 1207
Joined: Thu Dec 26, 2013 11:57 am
Location: EGNM
Callsign: G-SHOZ
Version: Git
OS: Ubuntu 16.04

Re: Run Nasal Function at consistent rate regardless of fram

Postby Necolatis » Sun Apr 09, 2017 4:01 pm

I recommend doing FBW in autopilot code for Yasim and in JSBSim functions for JSBSim. Then you get 120 Hz updates fairly stable.
"Airplane travel is nature's way of making you look like your passport photo."
— Al Gore


Hangar: https://sites.google.com/site/fghangar/
User avatar
Necolatis
 
Posts: 1872
Joined: Mon Oct 29, 2012 12:40 am
Location: EKOD
Callsign: Leto
IRC name: Neco
Version: 2018.2.2
OS: Windows 10 Pro

Re: Run Nasal Function at consistent rate regardless of fram

Postby it0uchpods » Sun Apr 09, 2017 4:06 pm

@Hooray
Alright, I can switch to maketimer.

So I am slightly confused, are you telling me I CANNOT run a nasal loop a consistent rate?

If so, do you have any ideas on how I can adjust a prop target-pitch with the input from elevator, the more elevator input, the move the prop moves? It must be a consistent way of doing it?

@sanhozay
Is there a wiki article, or anything that would help me figure out how to do that?

@Neocolatis
I use PID controllers for the actual FBW "flying", I have that working well, so I don't really want to change it ATM.

The aircraft is JSBsim,
Are you proposing my logic to adjust target-pitch and target-roll is moved to a JSB function?

Thanks,
Josh
it0uchpods/WTF411

FGFS Aircraft Developer
Lead Programmer at it0uchpods Design Group
Download High Quality Aircraft from it0uchpods Hangar
User avatar
it0uchpods
 
Posts: 3567
Joined: Tue Oct 06, 2015 12:51 pm
Version: 2018.2.1
OS: Windows 10 x64

Re: Run Nasal Function at consistent rate regardless of fram

Postby Necolatis » Sun Apr 09, 2017 4:58 pm

it0uchpods wrote in Sun Apr 09, 2017 4:06 pm:The aircraft is JSBsim,
Are you proposing my logic to adjust target-pitch and target-roll is moved to a JSB function?


yes.
"Airplane travel is nature's way of making you look like your passport photo."
— Al Gore


Hangar: https://sites.google.com/site/fghangar/
User avatar
Necolatis
 
Posts: 1872
Joined: Mon Oct 29, 2012 12:40 am
Location: EKOD
Callsign: Leto
IRC name: Neco
Version: 2018.2.2
OS: Windows 10 Pro

Re: Run Nasal Function at consistent rate regardless of fram

Postby Thorsten » Sun Apr 09, 2017 5:00 pm

So I am slightly confused, are you telling me I CANNOT run a nasal loop a consistent rate?


You theoretically can by using a listener to an FDM property, but not with any timers. But doing so is highly hackish and not recommended.

If so, do you have any ideas on how I can adjust a prop target-pitch with the input from elevator, the more elevator input, the move the prop moves? It must be a consistent way of doing it?


This seems an AP task, so you should use an autopilot function (either JSBSim or FG-native) to solve it. Nasal is absolutely not intended to solve these kinds of low-level issues.
Thorsten
 
Posts: 9997
Joined: Mon Nov 02, 2009 8:33 am

Re: Run Nasal Function at consistent rate regardless of fram

Postby Hooray » Sun Apr 09, 2017 5:21 pm

The FDM coupled listener callback is also discussed in the thread linked to above - however, that still doesn't prevent the Nasal memory management routines ("garbage collector") to kick in "at will" - which means things will be much less determinisic than you want them to be.
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: 11192
Joined: Tue Mar 25, 2008 8:40 am

Re: Run Nasal Function at consistent rate regardless of fram

Postby it0uchpods » Sun Apr 09, 2017 7:54 pm

No you misunderstand me.

I have a nasal function which adjusts a property based on elevator and aileron input. This what I need to have. The autopilot (PID) part works fine, and I don't need to change it.

What is the suggestion? Can I use a JSB function to adjust my property by elevator input? Or what?

Basically for each 0.1 of deflection, I adjust the property at a faster rate. Can I do this in JSB? If so, where can I find resources for such things?

Thanks guys,
Josh
it0uchpods/WTF411

FGFS Aircraft Developer
Lead Programmer at it0uchpods Design Group
Download High Quality Aircraft from it0uchpods Hangar
User avatar
it0uchpods
 
Posts: 3567
Joined: Tue Oct 06, 2015 12:51 pm
Version: 2018.2.1
OS: Windows 10 x64

Re: Run Nasal Function at consistent rate regardless of fram

Postby Necolatis » Sun Apr 09, 2017 9:10 pm

Yes, you can.

See here: http://jsbsim.sourceforge.net/JSBSim/cl ... ction.html

And there more components than function that might help, depending on what you specifically are trying to do.
"Airplane travel is nature's way of making you look like your passport photo."
— Al Gore


Hangar: https://sites.google.com/site/fghangar/
User avatar
Necolatis
 
Posts: 1872
Joined: Mon Oct 29, 2012 12:40 am
Location: EKOD
Callsign: Leto
IRC name: Neco
Version: 2018.2.2
OS: Windows 10 Pro

Re: Run Nasal Function at consistent rate regardless of fram

Postby it0uchpods » Sun Apr 09, 2017 11:57 pm

Thank you very much guys! Awesome.

I'll get to work with this when I have some time (still on vacation). I may have a few questions during the process.

Kind Regards,
Josh
it0uchpods/WTF411

FGFS Aircraft Developer
Lead Programmer at it0uchpods Design Group
Download High Quality Aircraft from it0uchpods Hangar
User avatar
it0uchpods
 
Posts: 3567
Joined: Tue Oct 06, 2015 12:51 pm
Version: 2018.2.1
OS: Windows 10 x64

Re: Run Nasal Function at consistent rate regardless of fram

Postby it0uchpods » Fri May 05, 2017 3:10 am

And it's done and working. Thanks @Richard for his help!

Here is the finished product: https://github.com/it0uchpods/A320Famil ... it-fbw.xml

@Hooray
I changed the Nasal part to a maketimer in most systems on this plane.
it0uchpods/WTF411

FGFS Aircraft Developer
Lead Programmer at it0uchpods Design Group
Download High Quality Aircraft from it0uchpods Hangar
User avatar
it0uchpods
 
Posts: 3567
Joined: Tue Oct 06, 2015 12:51 pm
Version: 2018.2.1
OS: Windows 10 x64


Return to Nasal

Who is online

Users browsing this forum: No registered users and 2 guests