IntegratedSystems

From FlightGear wiki
Jump to navigation Jump to search
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 Configuration Center

The Aircraft Configuration 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 Configuration 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")],
};