%% Modeling Newton's Cradle
% This example shows how to model a popular toy called "Newton's cradle"
% which consists of a row of seven identical balls which are hung from a
% common height. At rest they are arranged such that they just touch each
% other. One or more balls from one end are then raised from their rest
% position and released. 
%
% An interesting consequence of elastic collisions between the balls is
% that the balls which are released seem to come to a stop and an equal
% number of balls from the other end get released (with almost the same
% energy as the incoming balls). The balls in the middle do not seem to
% move, although they are responsible for transferring momentum from one end
% to another.

% Copyright 2007-2014 The MathWorks, Inc.

clear
close all
bdclose all

mdl = 'sf_newtons_cradle';
open_system(mdl);

r = sfroot;
m = r.find('-isa', 'Stateflow.Machine');
c = m.find('-isa', 'Stateflow.Chart', 'Name', 'newtons_cradle');

c.Visible = 0;

%% 
% This model uses a simple elastic collision model to describe the
% interactions between the balls. The Stateflow(R) chart uses local
% variables to depict the continuous states of the system, namely the
% position |p| and the velocity |v|. Note that both these local variables
% are defined to have "Update method" as "continuous". This allows you to
% refer to their derivatives as |p_dot| and |v_dot| respectively. Since the
% nominal dynamics of all the balls are identical, vector assignments
% describe them en-masse as:
% 
%  p_dot = v;
% v_dot = -g/l*sin(p);
% 
% Note that |p_dot| and |v_dot| are not chart local variables. They are
% automatically created because |p| and |v| are defined to be "continuous".

c.Visible = 1;

%%
% The model uses a simple for-loop to detect collisions between balls. In a
% one-dimensional setting, the chart only models collisions between
% successive balls with a single for loop.

f = c.find('-isa', 'Stateflow.Function', 'Name', 'isCollisionPossible');
f.view;

%% 
% The response to a collision is also expressed simply. Each collision is
% treated as a perfectly elastic instantaneous collision. The position and
% velocity are exchanged for each of the balls involved in the collision.

f = c.find('-isa', 'Stateflow.Function', 'Name', 'resetPositionsAndVelocities');
f.view;

%% 
% Simulating this model brings up a very simple GUI which shows the motion
% of the balls.

c.Visible = 0;
set_param(mdl, 'StopTime', '1');
evalc('sim(mdl)');
