Who controls what
One thing we need to think about is how different "failure aware" scripts will play with each other. For example, there is the "manual failure control gui" as it exists today, but there is also an increasing interest in having aircraft specific failure/wear/damage simulations. We need to have a mechanism for these to work together, rather than fight each other.
Lets say an aircraft model is written in such a way that its FDM is able to simulate a blown tire. And lets say that the author also provided a Nasal script that tracks wear and triggers the blown tire simulation when suitable. Since the aircraft model is able to simulate blown tires, we will also want to be able to trigger that manually from the gui, and we (at least I) would prefer the gui to not be aircraft specific, but a standard menu like the one Necolatis is working on.
So how do we do this in a good way? My current line of thought is this: Supported failure modes are registered to the FailureMgr as they currently are. This makes the FailureMgr aware of what is possible to simulate. Then, instead of manipulating failure modes from anywhere in Nasal, we introduce the concept of a FailureController. FailureController's manipulate FailureModes by setting triggers, or controlling failure levels directly, and there can be more than one, however, only one FailureController can be active at a given time. FailureControllers are also subscribed to the FailureMgr and it is the FailureMgr who decides which controller owns the failure system, based on user input.
This makes it possible to do the following:
- The default GUI would be itself a FailureController and it would be available by default, making it possible for the user to control failures manually and using manually programmed triggers. - More advanced aircraft can subscribe their own FailureController. It could just be a Nasal script following a standard interface. This script can control failure modes by manually setting failure levels or by using the trigger system. - From a standard GUI provided by FlightGear, the user can choose to enable/disable aircraft provided failure/wear/damage simulation. - A remote instructor console would be another FailureController, and when selected, it would have full control of what is going on, with no interference from aircraft scripts or local GUI settings.
Partial Damage / Wear support
The way I am thinking about this is: The old implementation could fail systems on command, by clicking in the checkbox via GUI or prop tree, or by setting an MTBF/MCBF value. The system went from "perfect condition" to "failed" instantaneously when the time comes.
The new implementation (3.2+) replaces MTBF/MCBF with a trigger system that is more generic. It is be possible to fail a system at a certain altitude or at a certain location, for example. But it is still a binary condition (failed / not failed).
One way to introduce wear or partial damage, is to replace the trigger system with an even more generic "damage model", where a "damage model" is a black box that, given certain parameters, provides you with a "level of failure" at a given time. The current triggers can be seen as a damage model that jumps from not failed to failed instantly under certain conditions, but a more elaborate damage model could count usage cycles or running time internally, and provide a failure level according to a curve. The challenge is then pushed to aircraft modelers, who would be responsible for actually implementing this "progressive failure" behavior. A basic/generic library of wear models could be provided for of-the-shelf usage as we are doing with Triggers today.
Another interesting point of discussion is what would be a convenient way to make the damage/wear status persistent across flights (if that is interesting), and what should they be associated to: aircraft model? immatriculation? just dumped to a file so you can load it at will?
Things to consider:
- aircraft that depend on what is in the dialog today, and how it writes to serviceable properties and makes some properties read-only.
If we just remove all default failures, these aircraft, which might not be actively maintained, all of a sudden will lose all failure management, unless it is custom coded.
Maybe planes using the new system could set a property such as: <failure-system><version>2</version></failure-system> That would give the new system, with no predefined failures, and not specifying anything will give the old, with its predefined failures. Necolatis (talk) 22:18, 6 February 2014 (UTC)
- You've hit the nail on the head with this one. Can we please have the old way as default, with the new way as an option? along with correct behaviour of <nasal><FailureManager>false</FailureManager></nasal> in autosave.xml . ??? Thanks for nothing btw.
- No, I don't want to use your super duper mega fancy failure manager, and I set it to off and I expect to have the normal, old behaviour, so my simple failure manager works as expected, but no, if I set it to off everything's broken, because someone thought it might be fancy to have it that way...
- I4dnf (talk) 17:10, 4 August 2014 (UTC)
- @i4dnf: It should be possible to disable the module using standard mechanisms, and while enabled, the module should be fully backwards compatible. I wrote this part explicitly for handling backwards compatibility: Aircraft/Generic/Systems/compat_failure_modes.nas. I have opened a discussion in your talk page so we can work out what is missing. --Galvedro (talk) 12:13, 6 August 2014 (UTC)
- There are two big issues, besides the fundamental one of making a 'complex' piece of code mandatory for simple stuff (but that's another talk).
- 1: Failure to set sane defaults and provide for normal operation with the module disabled -> disabling the module leaves all 'serviceable' properties in the failed state, instead of the sane/failsafe default of true.
- 2: Moving properties around, changing ui items and their effect on the property tree, without proper notification/announcement (and no, i don't mean 3rd word 157th line of some obscure forum post), e.g. moving the /gear/serviceable flag to its new location. I get it that stuff is/was in disarray, but such a move should not be done overnight/pre-release and without even telling (I had to dig into the git history to see what's going on there). Given the 'age' of the original property location it is likely that aircraft might depend on it (the location of their repository is irrelevant), and such a change would break them. There are numerous examples of how this change should be handled on the devel ML.
- Thanks for considering these. Hopefully you'll also consider the possibility that not everybody wants/needs to use your code, and in many cases it's overkill.
- Also keep in mind that there are many aircraft maintained outside of fgdata, and in the future it's very likely there will be no aircraft maintained in fgdata anymore (except ufo and c172p)
- I4dnf (talk) 00:49, 7 August 2014 (UTC)
- "Also keep in mind that there are many aircraft maintained outside of fgdata, and in the future it's very likely there will be no aircraft maintained in fgdata anymore (except ufo and c172p)"
- While this might be literally true, it really isn't – I'm 100% sure there will always be a "main FG" repository of aircraft which have nowhere else to go, while certain actively-maintained aircraft could go to their respective hangars (i.e. stay there). There is a point to centrality (i.e. knowing where to find things and easy access to those) that I'm sure won't be neglected, even in the event of a potential FGData split or similar.
- —Philosopher (talk) 03:10, 7 August 2014 (UTC)
- P.S. How is 2 months "overnight/pre-release"? That's a whole third of the release cycle, plus as previously stated, it was intended to be backwards compatible – I checked the c172p and Seneca II (IIRC) myself – and it's also in the Changelog 3.2, so quit your griping.
- Ok, now I understand. There is no aircraft in fgdata that makes use of that gear property, that is why I moved it in order to get it aligned with the others. Of course I grepped the entire repository to see how the property was used before changing anything, but what I certainly didn´t anticipate was that there where aircrafts using it outside the repository. Sorry about that, I´ll learn to use the mailing list properly for this kind of changes.
- "Failure to set sane defaults ... with the module disabled" - This is certainly a bug. How are you disabling the module?
- "making a 'complex' piece of code mandatory for simple stuff" - The code underneath might be complex, but it is actually lighter in resource utilization than the original script, with still some room for improvement. Also, I didn´t add that complexity just for the sake of it, it comes with increased capabilities, capabilities that I see being demanded.
- Actually, I am not sure I understand what you mean by "making complexity mandatory". If you are talking about interfaces, interface wise, the current commit was intended to be a transparent replacement, so the engine was replaced underneath but, bugs aside, nothing should have changed for module users. Besides, the new architecture makes it quite feasable to provide a "default" script for simple aircrafts that populates the failure manager automatically with failures for the systems being modeled, i.e. an extension of what we currently do to discover and populate engine failures. Given this, and the considerations about performance made above, I fail to see where does the solution become overkill.
- --Galvedro (talk) 21:43, 7 August 2014 (UTC)
- @galvedro: Just for reference, the mechanism used by i4dnf is using ThorstenB's submodules which are using this method (see FGNasalSys::init), we're hoping to clean this up shortly via native bootstrapping: Creating_new_Nasal_scripts#Nasal_sub_modules.
- Oh! I am not on an FG computer right now, but I think I understand what the problem is. In the previous implementation, the failure manager (failures.nas) was not optional, i.e. it was a script in the base Nasal folder, even though it was arguably not an essential script. Now, it is a Nasal module that can be disabled. If you disable the module, the .../failure-manager subtree will of course not be initialized, because there is no failure manager to do that.
- @i4dnf: Do your aircraft rely on the properties hanging from .../failure-manager rather than the serviceable properties available on each subsystem?
- Second question: if you leave the failure manager on, it should be backwards compatible except (hopefully) for the gear/serviceable property. Do you experience any other issue with it (besides that you don't like it :D)?
- --Galvedro (talk) 13:28, 8 August 2014 (UTC)
- My plan for handling backwards compatibility, as can be seen in the roadmap section, is to load the compat script explicitly from every aircraft at some point. This will provide them with the same set of failure modes that they currently have. Unmaintained planes will remain that way, and those being actively maintained will be able to replace the compat script and start tailoring failure mode support to what the aircraft can actually handle. --Galvedro (talk) 12:13, 6 August 2014 (UTC)
The GUI contains instruments, such as radio, transponder, GPS, map etc.
Should these have a failure mode, or maybe an option inside the dialog to include them as failures? (not sure if any of them currently depend on any serviceable/read-only properties. Necolatis (talk) 22:18, 6 February 2014 (UTC)
I can make a prototype dialog, to show how I imagine the dialog to look, and then we can discuss it from there?
In my opinion there should only be 1 dialog, which includes failures, and setting random failures, instead of 3 dialogs, like today. That could be done with tabs. Necolatis (talk) 22:18, 6 February 2014 (UTC)
Failing ground equipment
I have just skimmed through the code to have an idea of what's involved.
The problem I see right away is that there are different animals covered under the SGSubsystem umbrella. At the very least, there are a) core sim modules, like ephemeris and sound, and b) cockpit instruments and systems. The SGSubsystem interface is in my opinion, a bit overkill for the b) category in some aspects (the initialization stuff, for example), and it falls short in others (i.e. connectivity). This is something I wanted to investigate and see if it would be beneficial (and acceptable) to separate SGSubsystem into more explicit interfaces.
Regarding failure management there is another problem in the code. The current standard IO interface for built-in instruments and systems is the property tree. Those that implement failure modes, do so via a "serviceable" property. That means that they don't care about C++ interfaces, rather, they rely on conventions. Adding an interface derived from Subsystem would not improve the the situation in this case.
Additionally, navaids and such are not accessible as Subsystem objects by themselves, but as pieces of information gathered from the navaid cache (if I followed the code correctly). If we forced a FailableSubsystem interface, the interface would apply to the entire navdb, which means that the interface will not be as simple as:
It would have to be more complex, also in order to allow non trivial subsystems to implement more than one failure mode.
Given this, as a first step, what I would do in order to support navaid failure would be to expose a simplified NavDataCache interface to Nasal and either
a) implement a "failure_actuator", as I call them in the current prototype, that sets the navaid range down to zero on failure, or b) implement a NavDataCache::fail_navaid(id) that would be exposed to Nasal, possibly together with a few other calls, now we are at it.
The easy way to do it I guess it would be to create a NavDataCache Facade class with a reduced interface suitable for Nasal, and then use cppbind to expose the class to scripting interface. Somethig like that..