1+ function Struct = dmc_nonlinear(Struct , x_now , ts )
2+ if ~isfield(Struct , ' upast' ) || isempty(Struct .upast)
3+ N = numel(Struct .sr);
4+ n = N - Struct .p;
5+ Struct.upast = zeros(n , 1 );
6+
7+ % Ypast matrix
8+ step_response = Struct .sr(1 : n );
9+
10+ % Toeplitz Matrix
11+ Struct.G = toeplitz(Struct .sr(1 : Struct .p), Struct .sr(1 )*eye(1 ,Struct .m)); % Toeplitz
12+
13+ % DMC gain
14+ Q = diag(Struct .Q);
15+ R = diag(Struct .R);
16+ K = (Struct .G' *Q * Struct .G + R ) \ (Struct .G' *Q );
17+ Struct.k = K(1 , : );
18+
19+ % Control variables
20+ Struct.u = - 0.897 ;
21+ Struct.u_prev = - 0.897 ;
22+ Struct.d = 0 ;
23+ Struct.control = zeros(Struct .m, 1 );
24+ Struct.block_counter = 0 ;
25+
26+ if isfield(Struct , ' x0' )
27+ Struct.y_prev = Struct .x0(1 );
28+ Struct.y = Struct .x0(1 );
29+ else
30+ Struct.y_prev = 0 ;
31+ Struct.y = 0 ;
32+ end
33+ end
34+
35+ % Disturbance
36+ if isfield(Struct , ' is_open_loop' ) && Struct .is_open_loop
37+ Struct.d = 0 ;
38+ else
39+ Struct.d = Struct .y - Struct .y_prev;
40+ end
41+
42+ D = ones(Struct .p,1 ) * Struct .d;
43+
44+ Ypast = zeros(Struct .p, 1 );
45+ u_current = Struct .u_prev;
46+ x = x_now ;
47+ for k = 1 : Struct .p
48+ x = update_nonlinear_state(x , u_current , ts );
49+ Ypast(k ) = x(1 );
50+ end
51+
52+ if Struct .is_programmed
53+ number_reference = numel(Struct .r);
54+ if number_reference >= Struct .p
55+ ref = Struct .r(1 : Struct .p);
56+ else
57+ ref = [Struct .r(: ); Struct .r(end ) * ones(Struct .p - number_reference , 1 )];
58+ end
59+ else
60+ ref = Struct .r(1 ) * ones(Struct .p, 1 ); % Unprogrammed: assume reference stays constant
61+ end
62+
63+ Struct.w = filter([0 (1 - Struct .a)], [1 - Struct .a], ref , Struct .y); % Filtered Reference
64+
65+ Q = diag(Struct .Q);
66+ R = diag(Struct .R);
67+ K = (Struct .G' *Q * Struct .G + R ) \ (Struct .G' *Q );
68+ Struct.Ebar = Struct .w - Ypast - D ;
69+ Struct.control = K * Struct .Ebar;
70+
71+ % Apply control input
72+ Struct.du = Struct .control(1 );
73+ Struct.upast = [Struct .du; Struct .upast(1 : end - 1 )];
74+ Struct.u = Struct .u_prev + Struct .du;
75+
76+ % Predict next output
77+ Struct.y_prev = Ypast(1 ) + Struct .G(1 , 1 ) * Struct .du;
78+
79+ % Shift and update
80+ Struct.control = [Struct .control(2 : end ); 0 ];
81+ Struct.u_prev = Struct .u;
82+ end
0 commit comments