Nasal HLA standalone

From FlightGear wiki
Jump to navigation Jump to search

  • Last updated: 06/2013
  • Contributors: Dbelcham, Callahanp, Hooray


One of the things that is most frustrating and time consuming when working with Nasal scripts is the brute force and manual nature of testing the scripts. A simple misspelling in a custom script can take 5-10, or more, minutes to fix from the point of finding it (shut down FG, change script, startup FG and get back to a point in the sim where the code will execute). Obviously Nasal is tightly coupled to FG at this point and most scripts won't run without access to the property tree. That doesn't mean that it can't be done though.

This article will serve as the guinea pig for writing Developing with HLA, using FlightGear HLA support (High Level Architecture).

Cquote1.png I do like the idea of a stand-alone script interpreter communicating via HLA or some similar IPC, but we still have to consider fragments of script code embedded in models to create or enhance fancy animations. Not all script fragments make sense to run externally.
Cquote1.png Regarding Nasal as a scripting language and AW, I'm hopeful that the work I'm doing on HLA will allow us to run Nasal in a separate thread from the FDM and display, so Nasal GC no-longer can impact frame-rates. It would also allow for writing a weather simulation completely external to the FlightGear instance, which could be quite neat.
— stuart (Nov 24th, 2015). Re: the real cost of the Nasal Garbage Collector.
(powered by Instant-Cquotes)
Cquote1.png I suspect that Nasal might give problems as there are a fair amount of assumptions related to code that will run at the rendering frame rate - but this will be aircraft dependent and it's worth considering during the design phase. Whilst it would be ideal to be completely compatible with all existing models I suspect there may have to be some model changes. The move to HLA has great potential to really open up the possibilities.
— Richard Harrison (Nov 28th, 2015). Re: [Flightgear-devel] HLA developments.
(powered by Instant-Cquotes)
Cquote1.png Another thing that would work well is to proxy all nasal script invocations to a Nasal helper thread - again this assumes scripts

basically interact with the sim via properties (which they already do) and that any system functions they call are thread safe - not very

hard to do. As more and more functions get moved to nasal, this might become a very easy way to balance the CPU usage.[1]
— James Turner
Cquote1.png you're all hoping for a better FG. A large redesign, so we can make use of multi-core systems, can even distribute parts across multiple machines. Can separate the GUI. Get Nasal outside the main simulation loop.[2]
— ThorstenB
Cquote1.png I've always wondered what would be involved in adopting HLA. Could we start using it today, i.e. for a very small proof of concept? Do we need an implementation? Who would be able to do it? What does the code already in SimGear do? A little message passing doesn't sound like a bad idea to me, if I understand it right.
— Philosopher (Jul 8th, 2014). Re: .
(powered by Instant-Cquotes)
Cquote1.png Actually, I have an idea for subsystems: unless there's some restrictions with using the network (like if we have to run a request in another thread), we could still use the subsystem manager and insert proxy systems. So geodinfo() would call the proxy system which would run an HLA request to access the real system in the master thread (or the scenery thread, or whatever). Would that work? It might be a bit of work to implement it for each subsystem that we need to do it for, but it might work really well
— Philosopher (Jul 10th, 2014). Re: .
(powered by Instant-Cquotes)

Status 06/2013


A standalone interpreter

Providing a standalone Nasal binary that has its own property tree instance would not be very difficult, it would be mostly copy/paste from SimGear/FlightGear ($SG_SRC/nasal and $FG_SRC/Scripting).

You could definitely add the FG/SG property tree code to the standalone interpreter - it would not even be very difficult, if you know C++, it should only take a couple of hours to make it work, but that will just ensure that your scripts have their own property tree, it doesn't provide any of the other FG/Nasal APIs or subsystems, such as the autopilot etc.

Philosopher is for example using a heavily customized standalone Nasal interpreter for development purposes that has many features which FG doesn't have (yet). But that doesn't make it any easier to develop scripts FOR FlightGear. Most scripts in FlightGear use a plethora of APIs and FG-specific Nasal modules ($FG_ROOT/Nasal), so FG has become a runtime dependency (APIs, data structures like the property tree, and "live" state),

Now, testing scripts is so time-consuming because of various issues: 1) Nasal being a dynamically typed language, where errors often only show up at runtime, 2) the lexer/parser is not particularly robust - so that error messages are not very informative, and may only show up fairly late. Philosopher has been working on improving things a little. 3) The main issue is FlightGear's way of loading Nasal scripts just once during startup, i.e. there's no design/mechanism in place to do Nasal housekeeping, so that the interpreter cannot be re-initialized at runtime, which is why most scripts are not safe to reload currently.

To reload Nasal scripts, the whole process must be terminated and restarted currently. You can only reload scripts manually if you explicitly design them to support this use-case, which includes releasing resources like running callbacks (loops, listeners, timers) or files and threads. Even if the FG design were to be fixed, I'd expect that most scripts would need to be changed.

Thus, a standalone Nasal interpreter in and of itself would not be particularly useful for developing/testing Nasal code for use in FlightGear, that would require some way of IPC (think CORBA or HLA)- so that the interpreter can run in its own thread/process and still hook into the fgfs process to access other subsystems, like the property tree.

High Level Architecture

We were recently talking about using HLA to support a standaloe Nasal interpreter it in another thread, and because Nasal has some performance issues (garbage collection) that are having an impact on framerate/latency under certain circumstances.

Thus, providing an option to run /some/ scripts separately, outside the main loop and connect things through HLA woul seem like a straightforward first step - especially because the SimGear machinery for exposing the full property tree through HLA is already in place (so not much coding needed, just understanding/applying) and there are some more low-level wrappers available in simgear/hla to expose C++ classes, objects etc - so basically it works a lot like CORBA/RPC through a central "broker" (openRTI).

At some point, the ongoing HLA work should facilitate a scripting API exposed via HLA, so that scripting languages like Nasal (or Python or any other language) would be able to call FG APIs (like extension functions) via HLA

Also, there's a standalone interpreter for unit testing: gitorious/fg/hoorays-simgear/HEAD

So we already do have a standalone Nasal interpreter that cannot currently talk to the fgfs process - making it talk to fgfs through HLA would be a first step, and the setprop/getprop APIs (or whole props module eventually) would be an obvious candidate, because the property tree infrastructure is already in place im simgear/hla (see HLAPropertyDataElement).

One of the goals could be to support multiple standalone Nasal processes which run setprop()/getprop(), which in turn is marshalled through HLA/OpenRTI to fgfs. That would not seem overly complicated, but like a pretty simple and useful first use-case to allow people to run certain stuff outside the main process

Obviously, one would need to expose other FG/Nasal APIs eventually, but we should probably learn to walk before we run

At the time of writing, The SimGear repository already contains all required HLA primitives to map the property tree and other C++ classes to HLA. For example, see:

Demo code at:

HLA support through cppbind

In the long run, one would need to implement the full interface of the HLAObjectClass, for example as part of the cppbind framework in simgear/nasal/cppbind- that way, cppbind APIs would become accessible through HLA, so that all cppbind APIs could also be used from a standalone interpreter that would not need to run inside the fgfs main loop anymore.

To add HLA support to cppbind, we'd need to provide corresponding from_nasal_helper() and to_nasal_helper() templates to convert various HLA types to their corresponding Nasal equivalents and vice versa.

All the SimGear machinery to help with marshalling should be in place in $SG_SRC/simgear/hla

Tom can probably help clarify what else may be missing currently ?

  1. James Turner (Fri, 03 Oct 2008 06:52:12 -0700). [Flightgear-devel] multi-threading / CPU usage.
  2. ThorstenB (Wed, 15 Jun 2011 16:06:00 -0700). Re: [Flightgear-devel] Heads up: scenery download / built-in.