1
0
Fork 0
fgdata/Nasal/FailureMgr/public.nas

230 lines
6.4 KiB
Text
Raw Normal View History

# Failure Manager public interface
#
# Copyright (C) 2014 Anton Gomez Alvedro
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
var proproot = "sim/failure-manager/";
##
# Subscribe a new failure mode to the system.
#
# id: Unique identifier for this failure mode.
# eg: "engine/carburetor-ice"
#
# description: Short text description, suitable for printing to the user.
# eg: "Ice in the carburetor"
#
# actuator: Object implementing the FailureActuator interface.
# Used by the failure manager to apply a certain level of
# failure to the failure mode.
var add_failure_mode = func(id, description, actuator) {
_failmgr.add_failure_mode(
FailureMode.new(id, description, actuator));
}
##
# Remove a failure mode from the system.
# id: FailureMode id string, e.g. "systems/pitot"
var remove_failure_mode = func(id) {
_failmgr.remove_failure_mode(id);
}
##
# Removes all failure modes from the failure manager.
var remove_all = func {
_failmgr.remove_all();
}
##
# Attaches a trigger to the given failure mode. Discards the current trigger
# if any.
#
# mode_id: FailureMode id string, e.g. "systems/pitot"
# trigger: Trigger object or nil. Nil will just detach the current trigger
var set_trigger = func(mode_id, trigger) {
_failmgr.set_trigger(mode_id, trigger);
}
##
# Returns the trigger object attached to the given failure mode.
# mode_id: FailureMode id string, e.g. "systems/pitot"
var get_trigger = func(mode_id) {
_failmgr.get_trigger(mode_id);
}
##
# Applies a certain level of failure to this failure mode.
#
# mode_id: Failure mode id string.
# level: Floating point number in the range [0, 1]
# Zero represents no failure and one means total failure.
var set_failure_level = func (mode_id, level) {
setprop(proproot ~ mode_id ~ "/failure-level", level);
}
##
# Allows applications to disable the failure manager and restore it later on.
# While disabled, no failure modes will be activated from the failure manager.
var enable = func setprop(proproot ~ "enabled", 1);
var disable = func setprop(proproot ~ "enabled", 0);
##
# Encapsulates a condition that when met, will make the failure manager to
# apply a certain level of failure to the failure mode it is bound to.
#
# Two types of triggers are supported: pollable and asynchronous.
#
# Pollable triggers require periodic check for trigger conditions. For example,
# an altitude trigger will need to poll current altitude until the fire
# condition is reached.
#
# Asynchronous trigger do not require periodic updates. They can detect
# the firing condition by themselves by using timers or listeners.
# Async triggers must call the inherited method on_fire() to let the Failure
# Manager know about the fired condition.
#
# See Aircraft/Generic/Systems/failures.nas for concrete examples of triggers.
var Trigger = {
# 1 for pollable triggers, 0 for async triggers.
requires_polling: 0,
new: func {
return {
parents: [Trigger],
params: {},
fired: 0,
##
# Async triggers shall call the on_fire() callback when their fire
# conditions are met to notify the failure manager.
on_fire: func 0,
_path: nil
};
},
##
# Enables/disables the trigger. While a trigger is disabled, any timer
# or listener that could potentially own shall be disabled.
enable: func,
disable: func,
##
# Forces a check of the firing conditions. Returns 1 if the trigger fired,
# 0 otherwise.
update: func 0,
##
# Returns a printable string describing the trigger condition.
to_str: func "undefined trigger",
##
# Modify a trigger parameter. Parameters will take effect after the next
# call to reset()
set_param: func(param, value) {
contains(me.params, param) or
die("Trigger.set_param: undefined param: " ~ param);
me._path != nil or
die("Trigger.set_param: Unbound trigger");
setprop(sprintf("%s/%s",me._path, param), value);
},
##
# Reload trigger parameters and reset internal state, i.e. start from
# scratch. If the trigger was fired, the trigger is set to not fired.
reset: func {
me._path or die("Trigger.reset: unbound trigger");
foreach (var p; keys(me.params))
me.params[p] = getprop(sprintf("%s/%s", me._path, p));
me.fired = 0;
me._path != nil and setprop(me._path ~ "/reset", 0);
},
##
# Creates an interface for the trigger in the property tree.
# Every parameter in the params hash will be exposed, in addition to
# a path/reset property for resetting the trigger from the prop tree.
bind: func(path) {
me._path == nil or
die("Trigger.bind(): attempt to bind an already bound trigger");
me._path = path;
props.globals.getNode(path) != nil or props.globals.initNode(path);
props.globals.getNode(path).setValues(me.params);
var reset_prop = path ~ "/reset";
props.globals.initNode(reset_prop, 0, "BOOL");
setlistener(reset_prop, func me.reset(), 0, 0);
},
##
# Removes this trigger's interface from the property tree.
unbind: func {
props.globals.getNode(me._path ~ "/reset").remove();
foreach (var p; keys(me.params))
props.globals.getNode(me._path ~ "/" ~ p).remove();
me._path = nil;
}
};
##
# FailureActuators encapsulate the actions required for activating the actual
# failure simulation.
#
# Traditionally this action was just manipulating a "serviceable" property
# somewhere, but the FailureActuator gives you more flexibility, allowing you
# to touch several properties at once or call other Nasal scripts, for example.
#
# See Aircraft/Generic/Systems/failure.nas and
# Aircraft/Generic/Systems/compat_failures.nas for some examples of actuators.
var FailureActuator = {
##
# Called from the failure manager to activate a certain level of failure.
# level: Target level of failure [0 to 1].
set_failure_level: func(level) 0,
##
# Returns the level of failure that is currently being simulated.
get_failure_level: func 0,
};