IntegratedSystems
Started in | 2019 |
---|---|
Contributor(s) | Octal450 |
IntegratedSystems (IS) is a design framework for developing aircraft systems in a clean and integrated way. It also facilitates easy maintenance of various different aircraft.
IntegratedSystems only works with JSBSim FDMs due to the extensive use of JSBSim Systems to create aircraft systems. However, some components of IntegratedSystems could be adapted to other FDMs if desired.
Examples of a complete IS setup can be seen in the MD-11 and MD-80.
THIS ARTICLE IS A WORK IN PROGRESS
Documentation of IntegratedSystems is a work in progress.
Common Aircraft Interfaces
All IS compliant aircraft implement the following interfaces:
- Autopilot disconnect:
cockpit.ApPanel.apDisc()
- Autothrottle disconnect:
cockpit.ApPanel.atDisc()
- Takeoff/Go Around button:
cockpit.ApPanel.toga()
In addition, custom overrides are provided for the following default binding options:
- All Reverser Toggle
- All flight control bindings as required
- Autopilot disconnect
IS Components
- Aircraft Config Center
- IS Base (required)
- IS Modules
- IT Autoflight (or compatible)
- Note: ITAF does not use a standard IS Module and is self-contained.
- JSBSim FDM (required)
- Property Tree Setup (required)
Aircraft Config Center
The Aircraft Config Center (ACConfig) is the suggested front-end GUI of an IS aircraft. Many features of IS have been designed with ACConfig in mind. Version 2 integrates completely with IS and can control aircraft equipment and options, as well as leveraging IS to implement a robust panel state and failure system. Further information will be provided soon.
Failure System
Info coming soon.
Panel States
Info coming soon.
IS Base
Info coming soon.
DU Controller (Optional)
Info coming soon.
Failure Bridge (Optional)
Info coming soon.
Hack Canvas
Info coming soon.
Libraries
Info coming soon.
View Controller
Info coming soon.
IS Modules
IS Modules are the heart of IS. Each system should have one module which interfaces it with other IS components.
Module Guidelines
- Each module must be configured so that the sim starts in the "Cold and Dark" state.
- Each module must be designed to integrate with Panel States.
- Each module should handle its own failures if applicable.
- Modules should not initialize their own properties unless absolutely needed, they should be initialized in the -set file and then imported into nodes by the module.
- Use the
Controls
node for any switches/knobs/buttons of a system (/controls/my-system/my-switch
) - Use the
Lights
node for any lights or indicators of a system (/systems/my-system/lights/my-light
) - Use the
Failures
node for any failure triggers (/systems/failures/my-system/my-failure
) - Keep other system nodes organized in a clean way, using vectors as needed
- Use properties in nodes unless you are sure you will only need to interact with other Nasal code, or have some other way of exporting
- Prefer to keep the actual code in a JSBSim System file, unless specifically needed.
- If you NEED to use a loop, use the Loop Guidlines below.
Standard Functions
Standard Modules
init()
(Required)
- Used by Panel States to quickly reset the entire system.
- This function must completely reset a system to the state it was in when the sim launches (usually cold and dark).
- This requires that any JSBSim System Files are designed in a way that allows the init function to reset the state.
Object Orientated Modules
setup()
(Required)
- This is the run-once method which sets up the objects in the system.
- Call the constructors
new()
from this function.
reset()
(Required):
- Used by Panel States to quickly reset the entire system.
- This function must completely reset a system to the state it was in when the sim launches (usually cold and dark).
- This requires that any JSBSim System Files are designed in a way that allows the init function to reset the state.
Standard & Object Orientated Modules
resetFailures
(Optional)
- Used by the Aircraft Config Center Failure System to reset the failures.
- This function resets any failures in the system and also resets any consequences of a failure being activated.
- This function must be called before anything else in the
init()
function.
Loop Guidlines
Info coming soon.
Example Module
The following example is for a very basic electrical system implemented in a JSBSim System.
<PropertyList>
<!-- Other -set nodes -->
<!-- Controls section -->
<controls n="0">
<electrical n="0"> <!-- Initialize switch properties -->
<battery type="bool">0</battery>
<gen type="bool">0</gen>
</electrical>
</controls>
<!-- Systems section -->
<systems n="0">
<electrical n="0">
<lights n="0"> <!-- Initialize light/indicator properties -->
<battery type="bool">0</battery>
</lights>
</electrical>
<failures n="0">
<electrical n="0"> <!-- Initialize failure properties -->
<battery type="bool">0</battery>
<gen type="bool">0</gen>
</electrical>
</failures>
</systems>
<!-- Nasal section -->
<nasal n="0">
<pts> <!-- Don't forget PTS! -->
<file>Aircraft/MyPlane/Nasal/property-tree-setup.nas</file>
</pts>
<libraries> <!-- IS Libraries -->
<file>Aircraft/MyPlane/Nasal/libraries.nas</file>
</libraries>
<systems> <!-- Include the system itself -->
<file>Aircraft/MyPlane/Nasal/Systems/electrical.nas</file>
</systems>
<!-- Other nasal files -->
</nasal>
</PropertyList>
electrical.nas
var ELECTRICAL = { # Define the module class
Bus: { # Just a node used in this system
ac: props.globals.getNode("/systems/electrical/bus/ac"),
dc: props.globals.getNode("/systems/electrical/bus/dc"),
emerAc: props.globals.getNode("/systems/electrical/bus/emer-ac"),
emerDc: props.globals.getNode("/systems/electrical/bus/emer-dc"),
},
Controls: { # The switches
battery: props.globals.getNode("/controls/electrical/switches/battery"),
gen: props.globals.getNode("/controls/electrical/switches/gen"),
},
Failures: { # Failure properties
battery: props.globals.getNode("/systems/failures/electrical/battery"),
gen: props.globals.getNode("/systems/failures/electrical/gen"),
},
Lights: { # The lights/indicators
battery: props.globals.getNode("/systems/electrical/lights/battery"),
},
init: func() {
me.resetFailures();
me.Controls.battery.setBoolValue(0);
me.Controls.gen.setBoolValue(0);
},
resetFailures: func() {
me.Failures.battery.setBoolValue(0);
me.Failures.gen.setBoolValue(0);
},
};
Property Tree Setup
The property tree is used to communicate between 3D XML files, JSBSim files, and Nasal files. However the default getprop()
and setprop
are messy and very inefficient on resources.
The Property Tree Setup (PTS) solves this by creating an efficient connection from IS to the properties that are NOT part of other modules, such as sim properties, or when not enough properties exist to warrant making a whole module with them. It organizes the nodes following the structure of the property tree itself, except with lots of identical properties (example: Gear wow), where vectors are used to make it easier. PTS must live in a node called pts
and must be declared before any other nasal files. It is strongly recommended to alphabetize the PTS file.
Each system you create should handle its own nodes via an IS Module. PTS should only be used to tie the REST of the property tree in, or in situations when creating a whole module is not justified - such as when there are only a few nodes.
In the below example, a basic PTS implementation to set up the node pts.Consumables.Fuel.totalFuelLbs
to the property /consumables/fuel/total-fuel-lbs
is shown. You can then use getValue()
and setValue()
or any other props.nas operations.
The Gear.wow
node is also shown as an example of how vectors can be used with multiple identical properties. Note that the vector is on the property itself, not its parent. The nodes then become pts.Gear.wow[x]
where x is 0, 1, or 2.
<PropertyList>
<!-- Other -set nodes -->
<!-- Nasal section -->
<nasal>
<pts>
<file>Aircraft/MyPlane/Nasal/property-tree-setup.nas</file>
</pts>
<!-- Other nasal files -->
</nasal>
</PropertyList>
- property-tree-setup.nas
var Consumables = {
Fuel: {
totalFuelLbs: props.globals.getNode("/consumables/fuel/total-fuel-lbs"),
},
};
var Gear = {
wow: [props.globals.getNode("/gear/gear[0]/wow"), props.globals.getNode("/gear/gear[1]/wow"), props.globals.getNode("/gear/gear[2]/wow")],
};