%% Modeling a Redundant Sensor Pair Using Atomic Subcharts
% 
% This model shows how to model a simple redundant sensor pair using
% a new Stateflow(R) feature called Atomic Subcharts. This feature allows
% you to compose a large chart from other charts which reside in a
% different library file.

%%
% 

%   Copyright 2007-2013 The MathWorks, Inc.

mdl = 'sf_atomic_sensor_pair';
open_system(mdl);
r = sfroot;
m = r.find('-isa', 'Stateflow.Machine', 'Name', mdl);
c = m.find('-isa', 'Stateflow.Chart', 'Name', 'RedundantSensors');
c.Visible = 0;

%% Main Chart
% The main Stateflow chart |RedundantSensors| consists of two "linked
% atomic subcharts" called |Sensor1| and |Sensor2|.

c.Visible = 1;
ed = c.Editor;
ed.WindowPosition(3) = ed.WindowPosition(3)/1.5;
ed.WindowPosition(4) = ed.WindowPosition(4)/1.5;
ed.ZoomFactor = ed.ZoomFactor*1.5;

%% 
% By default, |Sensor1| is active. It reads input |u1| and sets the output
% |y|. When it fails, we switch to |Sensor2| which reads input |u2| and
% sets the output |y|. When both of them fail, we fall into the |Alarm|
% state and produce a nominal zero output.
% 
% |Sensor1| and |Sensor2| are "linked atomic subcharts". These look and
% behave just like normal Stateflow states except that the contents of the
% linked atomic subchart reside in a chart in another library model. In
% this case, both of the linked atomic subcharts correspond to the library
% chart |sf_atomic_sensor_lib/SingleSensor|.
% 
%% Library Chart
% 
% The |SingleSensor| chart models a single sensor which accepts a sensor
% input |u| and provides a filtered sensor output |y|. It has logic
% built-in to detect out-of-range errors. By default the sensor is assumed
% to be in the state "OK". If the sensor reading goes out of range (which
% is modeled by the transition from "OK" to "FailOnce") and stays faulty
% for 0.5 seconds, then we transition to "Fail". In this case, the sensor
% outputs a constant 0. This allows the sensor to model faults but ignore
% very transient spikes in the sensor reading.
% 
% Notice the following:
% 
% * The transition from "OK" to "FailOnce" relies on two Stateflow chart
% parameters "LOW" and "HIGH". 
% * There is a top-level function called "inFailed" which is used to convey
% to the container chart whether the sensor is in a failed state.
% 

open_system('sf_atomic_sensor_lib');
open_system('sf_atomic_sensor_lib/SingleSensor');
set_param('sf_atomic_sensor_lib', 'Lock', 'off');

cid = sfprivate('block2chart', 'sf_atomic_sensor_lib/SingleSensor');
c = idToHandle(sfroot, cid);
ed = c.Editor;
ed.WindowPosition(3) = ed.WindowPosition(3)/1.5;
ed.WindowPosition(4) = ed.WindowPosition(4)/1.5;
ed.ZoomFactor = ed.ZoomFactor*1.5;


%% Mapping Inputs, Outputs and Parameters
% Notice that the main chart |RedundantSensors| has two inputs |u1| and
% |u2|, while the library chart corresponding to the linked atomic
% subcharts has only a single input |u|. In this case, we want the linked
% subchart |Sensor1| to access the chart input |u1| and the linked subchart
% |Sensor2| to access the chart input |u2|. In order to accomplish this, we
% need to specify "Mappings" for each instance of the linked atomic
% subchart. For example, if you right-click on |Sensor1| and select the
% context menu item |Subchart Mappings|, you will see the following
% dialog:
% 
% <<sf_atomic_sensor_pair_binding_sensor1.png>>
% 
% This dialog allows you to map symbols (inputs, outputs and parameters)
% from the main chart to symbols in the library chart. Notice how the input
% "u" is mapped to the main chart input "u1". Similarly, parameters defined
% in the library chart can be given different values amongst the various
% instances of the subchart.
% 
% In this case, the mappings for |Sensor1| and |Sensor2| are as follows:
% 
% <<sf_atomic_sensor_pair_mapping.png>>
% 
%% Simulation Behavior
% If you simulate the model, you will notice the following behavior:
% 
% * Initially, both inputs to the main chart are zero. Hence the output
% produced is zero.
% * When you vary the first input between, u1, between (-75, 75), the
% output will track u1.
% * As soon as u1 is outside these bounds, y begins to track u2.
% * When u2 falls outside the range (-100, 100), then y begins to produce a
% nominal zero output.
% 
% You can <matlab:open_system('sf_atomic_sensor_pair') open>
% this model now and start the simulation to see this behavior. To change
% the inputs to the chart, double click on the gain blocks and drag the
% sliders.

bdclose all;