NTRT Simulator  Version: Master
 All Classes Namespaces Files Functions Variables Typedefs Friends Pages
scaling_counterexample.m
1 % Scaling counterexample
2 % Drew Sabelhaus
3 % 7-13-14
4 
5 % This basic simulation is designed to show, by counterexample,
6 % why use of nondimensional numbers is necessary for NTRT.
7 % Equivalently, this would show why the commutative property of
8 % multiplication does not apply to scaling of units.
9 
10 clear all; clc; close all;
11 
12 % This disproves the following posulate:
13 % 10 * (length / time ^2) == (10 * length) / time^2
14 
15 % A spring-mass-damper oriented vertically.
16 m = 2; % kg;
17 y0 = 1; % meters;
18 %y_rest = 0.50; % meters;
19 y_rest = 1;
20 g = 9.81; % m/s^2
21 k = 150; % N/m
22 c = 10; % N*s/m, or kg/sec
23 
24 % Newton's third law for this 1-DOF system is
25 % m * y_ddot + c * y_dot + k * (y - y_rest) = -mg
26 
27 % So, in state space, we're looking at a linear system (technically an
28 % affine system) which is the following, where x = [y; y_dot]
29 % x_dot = A * x + C;
30 
31 A = [ 0, 1; ...
32  -k/m, -c/m];
33 
34 C = [ 0; -g + k * y_rest/m];
35 
36 % Forward-integrate (Euler style) for a handful of seconds
37 dt = 0.01; % sec
38 t_final = 4; % sec
39 t = [0:dt:t_final];
40 num_timesteps = size(t,2);
41 y = zeros(2, num_timesteps); % because we have 2 state variables plus the affine offset. Want column vectors for each timestep.
42 
43 % initialize. Particle starts at y0, with zero velocity.
44 y(:,1) = [ y0; 0];
45 
46 for i=2:num_timesteps
47  % simulate. note that only the Ax terms get euler integrated, we need
48  % the affine term to stay == 1.
49  y(:, i) = ( A * y(:, i-1) + C) * dt + y(:,i-1);
50 end
51 
52 hold on;
53 plot(t, y(1,:));
54 plot(t, y(2,:), 'r');
55 title('Original, unscaled simulation');
56 xlabel('time, sec');
57 ylabel('Vertical height of particle, meters');
58 
59 % Now, for comparison, scale gravity. This should be different!
60 g_scaled = 10 * g;
61 % A does not change, but C does:
62 C = [ 0; -g_scaled + k * y_rest/m];
63 % We can use the same timestepping, but need to collect new data points:
64 y_new = zeros(2, num_timesteps);
65 y_new(:,1) = [ y0; 0];
66 
67 for i=2:num_timesteps
68  % simulate. note that only the Ax terms get euler integrated, we need
69  % the affine term to stay == 1.
70  y_new(:, i) = ( A * y_new(:, i-1) + C) * dt + y_new(:,i-1);
71 end
72 
73 figure;
74 hold on;
75 plot(t, y_new(1,:));
76 plot(t, y_new(2,:), 'r');
77 title('With only gravity scaled');
78 xlabel('time, sec');
79 ylabel('Vertical height of particle, meters');
80 
81 % Here's the fun part: do a third simulation, and scale length,
82 % as we'd normally do in NTRT. Our length constants are y0 and y_rest.
83 length_scaling_factor = g_scaled/g;
84 y0_new = length_scaling_factor * y0;
85 y_rest_new = length_scaling_factor * y_rest;
86 
87 % Recalculate C, again, and initialize.
88 C = [ 0; -g_scaled + k * y_rest_new/m];
89 y_new_length_scaled = zeros(2, num_timesteps);
90 y_new_length_scaled(:,1) = [y0_new; 0];
91 
92 for i=2:num_timesteps
93  % simulate. note that only the Ax terms get euler integrated, we need
94  % the affine term to stay == 1.
95  y_new_length_scaled(:, i) = ( A * y_new_length_scaled(:, i-1) + C) * dt + y_new_length_scaled(:,i-1);
96 end
97 
98 % Now, re-adjust the length scale as we'd do in NTRT.
99 y_new_length_scaled = y_new_length_scaled ./ length_scaling_factor;
100 
101 figure;
102 hold on;
103 plot(t, y_new_length_scaled(1,:));
104 plot(t, y_new_length_scaled(2,:), 'r');
105 title('With both gravity and initial length constants scaled');
106 xlabel('time, sec');
107 ylabel('Vertical height of particle, meters');
108 
109 % These plots are the same, and that makes sense by laws of superposition.
110 % Since scaling g is equivalent to scaling a step input in the system, this
111 % can be thought of as an increase in the magnitude of the input, and we
112 % expect a proportional increase in the magnitude of the output via linear
113 % systems laws.
114 
115 % Now, let's do something explicitly nonlinear.
116 
117 
118 
void simulate(tgSimulation *simulation)