%% Model a Fitness Tracker
% 
% This example shows how to implement a fitness tracker by using temporal
% logic and extrinsic function calls in Stateflow(R). The fitness tracker
% consists of a Simulink(R) model and a MATLAB(R) user interface (UI)
% created by using App Designer. The model has three components. 
%
% * Human_Simulator is a subsystem that models your activity. This
% subsystem outputs signals that represent your heart rate, your speed, and
% the number of steps that you have taken.
% * Fitness Tracker is a Stateflow chart that models the core logic of the
% fitness tracker. This chart uses temporal logic to determine your
% activity status (sleep, rest, walk, or exercise) and to send
% notifications to the UI.
% * UI Controller is a Stateflow chart that updates the fitness tracker
% displays in the UI. Extrinsic function calls in this chart and callback
% functions in the UI create a bidirectional connection between the model
% and the UI.
% 
% At the start of simulation, the model opens the UI. While the example is
% running, one second of simulation represents one minute of exercise time.
% When you close the UI window, a <docid:simulink_ref#f8-894249> block
% stops the model.

% Copyright 2015-2020 The MathWorks, Inc.

%%

% Set up charts with white background
set_param(0,'ExportBackgroundColorMode','white');

mdl = 'sf_fitness';
open_system(mdl);
set_param(mdl,'SimulationCommand','Update')

rt = sfroot;

machine = rt.find('-isa','Stateflow.Machine','Name','sf_fitness');
humanSimulatorChart = machine.find('-isa','Stateflow.Chart','Name','Human Simulator');
fitnessTrackerChart = machine.find('-isa','Stateflow.Chart','Name','Fitness Tracker');
uiControllerChart = machine.find('-isa','Stateflow.Chart','Name','UI Controller');

humanSimulatorChart.Visible = 0;
fitnessTrackerChart.Visible = 0;
uiControllerChart.Visible = 0;

%
%% Determine Fitness Tracker Output by Using Temporal Logic
%
% The Fitness Tracker chart controls the output of the fitness tracker UI.
% This chart registers your activity status based on your heart rate and
% speed. The four subcharts correspond to the possible values of the
% activity status. The chart monitors the active child state and passes
% this information to the UI Controller chart through the output data
% |Activity|.
%
% The debouncing logic in the chart filters out signal noise by using the
% |<docid:stateflow_ref#duration duration>| operator. For instance, when
% you are at rest, you can make some quick and sudden movements that do not
% correspond to exercise. The chart determines that you are walking or
% exercising only if your motion lasts longer than two minutes (two seconds
% of simulation time).
%
% The subcharts in this chart use other temporal logic operators to track
% your exercise activity. These subcharts send a |Notification| message to
% the UI controller chart in these situations:
%
% * You sleep or walk for longer than five minutes. The exit actions in the
% |Sleep| and |Walk| subcharts call the
% |<docid:stateflow_ref#elapsed elapsed>| operator
% to determine how long those subcharts were active.
% * You rest or exercise for longer than the threshold you specify in the
% UI. The |Rest| and |Exercise| subcharts call the
% |<docid:stateflow_ref#after after>| operator
% to determine how long those subcharts are active.
% * Your heart rate exceeds the threshold you specify in the UI for longer
% than one minute. The |Exercise| subchart calls the |duration| operator to
% determine how long the heart rate remains above the threshold.

fitnessTrackerChart.Visible = 1;

%% Establish Connection Between Model and User Interface
%
% The UI Controller chart processes data from the Human_Simulator subsystem
% and the Fitness Tracker chart and relays this information to the UI.
%
% To communicate with the UI, the chart invokes app functions defined in
% the UI. These app functions are not supported for code generation, so the
% |Init| state first declares these app functions as
% <docid:coder_ref#brdjlmz-1>. This declaration enables the |DISPLAY| state
% to call the app functions and update the activity status, clock, step
% counter, and heart rate displays in the UI. For example, when the chart
% receives a notification message, the substate |Notification_and_Clock|
% calls the app function |updateText|. This app function replaces the clock
% display with a customized notification. After five seconds, the substate
% calls the app function |updateClock| to restore the clock display.

uiControllerChart.Visible = 1;

%% 
% During simulation, you can interact with the UI by changing the values in
% the *Settings* pane and clicking the activity buttons in the *Human
% Simulator* pane. After each interaction, the UI modifies a parameter in
% the Simulink model by calling the <docid:simulink_ref#btuf9mn-1>
% function. For example, when you click the *Rest* button on the UI, in the
% Human Simulator, the value of the |Activity| constant block changes to
% the enumerated value |Activity.Rest|. The Human Simulator responds by
% producing heart rate and speed values that model a person at rest.
%
% <<../sf_fitness_fitness_UI.png>>

bdclose all;
clear
close all force;