So what you basically suggest as one option is to strip down FlightGear (by compile time config and/or #ifdef code exclusion) to just be able to interpret Nasal code (and other infrastructure) to sufficient render an instrument panel (with one instrument only) locally on a low-power IG machine (e.g. Raspberry Pi). Basically degrade FlightGear into an instrument simulator.
right, that's basically correct: that is how "fgpanel" came to be, too (just specific to legacy/steam instrumentation only and pre-dating the canvas era). With FGQCanvas being a re-implementation of the fgpanel idea, with a focus on replicating Canvas avionics remotely using a separate/standalone binary. However, FGQCanvas comes with its own pros & cons (it being a re-implementation of the canvas system itself, and it using Qt5 under the hood). As you have pointed out already, there are some compatibility issues when it comes to FGQCanvas and more sophisticated avionics (like the FG1000).
We already have support to interlink multiple fgfs instances to create a single simulator environment - for that purpose, fgfs can be told to disable a number of built-in subsystems and use a so called "master/slave" setup, where multiple "slaves" receive state from a master node (think flight dynamics).
In other words, you would only need those bits of FlightGear required to render instruments and sync/replicate state between multiple instances (which exists already!)
Some subsystems can already be toggled on/off during startup (or even dynamically), others not yet - and it's those that you'd need to explicitly disable using either feature toggles and/or #ifdef blocks in conjunction with dedicated cmake build options. That's the trivial part actually, and it's well documented in the wiki.
The less trivial part is figuring out conflicts due to implicit/hard-coded assumptions in existing subsystems - because some subsystems may assume that stuff like "ai traffic", "autopilot" or "route manager" is always available - which basically means a null pointer access at run-time, if you don't grep through the sources to identify such hard-coded assumptions.
Other than that, when it comes to the Canvas, you don't even need Nasal necessarily - because under the hood the setup is relatively basic:
1) Nasal scripting is used to assemble/compile a property tree structure under /canvas
2) there's a dedicated Canvas subsystem that processes write accesses to /canvas
3) internally, this will set up a scene graph structure using a handful of rendering primitives
4) finally, there's an offscreen rendering context created/updated (animated)
Thus, to replicate a Canvas TEXTURE, all you need is to replicate the local property tree structure of a certain /canvas/by-index/texture[0] - and forward the corresponding updates to the other slave/child instance to a matching node underneath the remote /canvas tree.
At that point, the remote fgfs instance will happily replicate the texture remotely, without requiring Nasal - Nasal would only be running on the master/parent instance in that scenario to set up/assemble and update the canvas texture(s)
You would then use an IPC mechanism (a number of which are built-in/supported "as is") to forward local updates to the remote fgfs instance.
And that remote fgfs instance would then be running a lightweight version of FlightGear, or a stripped-down "runtime mode" (let's call it "canvas display server" for now).
Over the years, we have seen the recurring idea to introduce dedicated support for different "startup modes":
https://wiki.flightgear.org/Startup_Modesthe rest of this project would then need to ensure a fast enough data binding between the two machines to keep everything in sync.
If I understand correctly, parts of this synchronisation (maybe even all of it?) seems to be already available through property tree distribution
The most relevant/up to date work in that area is Erik's DDS work actually (previously linked to above):
https://wiki.flightgear.org/Data_Distri ... es_supportHowever, we have also previously succeeded replicating/synchronizing canvas trees (textures) by using the existing props/telnet and http protocols - but those are not binary, so unnecessarily verbose and not very performance friendly.
To learn more about the number/name of FlightGear subsystems, use the built-in performance monitor:
https://wiki.flightgear.org/Howto:Use_t ... em_monitorTo learn more about FlightGear's subsystem architecture, see:
https://wiki.flightgear.org/Howto:Create_new_subsystemsHow to optionally disable FlightGear subsystems is illustrated here:
https://wiki.flightgear.org/Howto:Disab ... l_entirelyEdward (bugman on the forum) has been doing a bunch of work related to this:
https://wiki.flightgear.org/Howto:Make_ ... s_optionalMore recently, Scott (xDraconian on the forum) has been working on commenting out legacy code in order to work towards OpenGL Core Profile migration, and he mentioned separately that he's considering introducing support for dedicated "feature toggles" (basically so that SGSubsystems can be individually disabled via properties and/or startup flags):
https://wiki.flightgear.org/OpenGL#StatusSome of us have previously suceeded at using this approach to manually disable stuff for more constrained systems (and some folks even toyed with the idea of implementing "run levels" for FlightGear to make its initialization less monolithic).
The following screen shot shows a heavily patched/stripped down version of FlightGear where numerous subsystems are removed/disabled, and others are added to a dedicated subsystem group:
https://wiki.flightgear.org/Reset_%26_re-initAgain, depending on what you have in mind, you might also want to consider posting to the FlightGear developers mailing list.
Also, if latency/throughput is an issue (think in a multiplayer environment), it would actually be preferable not to replicate the Canvas PFD/MFD at the primitives level (canvas tree/elements), or the texture level (streaming texture updates). Instead, you could also use a customized fgfs binary to run a slaved/child fgfs instance that merely processes the same inputs (brezel) - that way, you would be running the MFD/PFD code on each slaved/child instance - and while these would be independent instances running the whole thing, these would be using a common input layer. That, too, can be accomplished by using Nasal/Emesary - and it would not require much C++ work (if any). However, the setup would obviously be a bit heavier performance-wise, because you're -unnecessarily- running the same code on multiple machines, even though you really only need the visuals (texture). But for an MP environment, that would still be a pretty good setup, since the amount of traffic/bandwidth required, would be marginal at best - whereas the tree-level replication of a MFD/PFD via canvas primitives, is going to cause hundreds of "updates" in the form of property GET/SET instructions. But again, a binary protocol (or DDS based), should make this still pretty appealing.
In the meantime, it would be great if you could reach out to the OP in the other topic, and maybe discuss if/how the two of you might collaborate here - especially since you seem to have overlapping requirements, and apparently you're bringing useful skills to the table, too
PS: As long as you're willing to document/share your journey with the community by using the wiki/forum and a public git repo, I would also be willing to answer related questions directly (via PM), since I have previously done something very similar (as you can see by looking at those screen shots). But again, if Qt5 works for you, then you don't have to do any work at all - and in fact, another option might be fixing up/extending the Qt5 port of the Canvas. If in doubt, please talk to the other user interested in working on this, and then we can take it from there.