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