@@ -267,33 +267,42 @@ end
267
267
feedback(s1::AbstractStateSpace, s2::AbstractStateSpace;
268
268
U1=1:size(s1,2), Y1=1:size(s1,1), U2=1:size(s2,2), Y2=1:size(s2,1),
269
269
W1=1:size(s1,2), Z1=1:size(s1,1), W2=Int[], Z2=Int[],
270
- w_reorder=nothing, z_reorder=nothing,
271
- neg_feeback ::Bool=true )
270
+ w_reorder=nothing, z_reorder=nothing,n
271
+ pos_feeback ::Bool=false )
272
272
273
273
274
274
`U1`, `Y1`, `U2`, `Y2` contains the indices of the signals that should be connected.
275
275
`W1`, `Z1`, `W2`, `Z2` contains the signal indices of `s1` and `s2` that should be kept.
276
276
277
- Specify `Wreorder ` and `Zreorder ` to reorder [W1; W2] and [Z1; Z2] after matrix multiplications .
277
+ Specify `Wperm ` and `Zperm ` to reorder [W1; W2] and [Z1; Z2] in the resulting statespace model .
278
278
279
- Negative feedback is the default. Specify `neg_feedback=false ` for positive feedback.
279
+ Negative feedback is the default. Specify `pos_feedback=true ` for positive feedback.
280
280
281
281
See Zhou etc. for similar (somewhat less symmetric) formulas.
282
282
"""
283
283
function feedback (s1:: AbstractStateSpace , s2:: AbstractStateSpace ;
284
284
U1= 1 : size (s1,2 ), Y1= 1 : size (s1,1 ), U2= 1 : size (s2,2 ), Y2= 1 : size (s2,1 ),
285
285
W1= 1 : size (s1,2 ), Z1= 1 : size (s1,1 ), W2= Int[], Z2= Int[],
286
- w_reorder = nothing , z_reorder = nothing ,
287
- neg_feedback :: Bool = true )
286
+ Wperm = nothing , Zperm = nothing ,
287
+ pos_feedback :: Bool = false )
288
288
289
- if ! (allunique (Y1) && allunique (Y2))
290
- warning (" Connecting a single output to multiple inputs." )
289
+
290
+
291
+ if ! allunique (Y1); @warn " Connecting single output to multiple inputs Y1=$Y1 " ; end
292
+ if ! allunique (Y2); @warn " Connecting single output to multiple inputs Y2=$Y2 " ; end
293
+ if ! allunique (U1); @warn " Connecting multiple outputs to a single input U1=$U1 " ; end
294
+ if ! allunique (U2); @warn " Connecting a single output to multiple inputs U2=$U2 " ; end
295
+
296
+ if length (U1) != length (Y2)
297
+ error (" Dimensions of input u1 ($(length (U1)) ) and output y2 ($(length (Y2)) ) must be equal" )
291
298
end
292
- if ! ( allunique (U1) && allunique (U2) )
293
- warning ( " Connecting multiple outputs to a single input. " )
299
+ if length (U2) != length (Y1 )
300
+ error ( " Dimensions of input u2 ( $( length (U2)) ) and output y1 ( $( length (Y2)) ) must be equal " )
294
301
end
295
302
296
- α = neg_feedback ? - 1 : 1 # The sign of feedback
303
+
304
+
305
+ α = pos_feedback ? 1 : - 1 # The sign of feedback
297
306
298
307
s1_B1 = s1. B[:,W1]
299
308
s1_B2 = s1. B[:,U1]
@@ -339,9 +348,9 @@ function feedback(s1::AbstractStateSpace, s2::AbstractStateSpace;
339
348
s2_D12* R2* s1_D21 s2_D11 + α* s2_D12* R2* s1_D22* s2_D21]
340
349
end
341
350
# Return while reorganizing into the desired order
342
- return StateSpace (A, isnothing (w_reorder ) ? B : B[:, w_reorder ],
343
- isnothing (z_reorder ) ? C : C[z_reorder ,:],
344
- isnothing (w_reorder ) && isnothing (z_reorder ) ? D : D[z_reorder, w_reorder ])
351
+ return StateSpace (A, isnothing (Wperm ) ? B : B[:, Wperm ],
352
+ isnothing (Zperm ) ? C : C[Zperm ,:],
353
+ isnothing (Wperm ) && isnothing (Zperm ) ? D : D[Zperm, Wperm ])
345
354
# return StateSpace(A, B_tmp, C_tmp, D_tmp)
346
355
end
347
356
@@ -373,9 +382,9 @@ function lft(G, Δ, type=:l) # QUESTION: Or lft_u, and lft_l instead?
373
382
end
374
383
375
384
if type == :l
376
- feedback (G, Δ, U1= G. nu- Δ. ny+ 1 : G. nu, Y1= G. ny- Δ. nu+ 1 : G. ny, W1= 1 : G. ny- Δ. nu, Z1= 1 : G. nu- Δ. ny, neg_feedback = false )
385
+ feedback (G, Δ, U1= G. nu- Δ. ny+ 1 : G. nu, Y1= G. ny- Δ. nu+ 1 : G. ny, W1= 1 : G. ny- Δ. nu, Z1= 1 : G. nu- Δ. ny, pos_feedback = true )
377
386
elseif type == :u
378
- feedback (G, Δ, U1= 1 : Δ. ny, Y1= 1 : Δ. nu, W1= Δ. nu+ 1 : G. ny, Z1= Δ. nu+ 1 : G. ny, neg_feedback = false )
387
+ feedback (G, Δ, U1= 1 : Δ. ny, Y1= 1 : Δ. nu, W1= Δ. nu+ 1 : G. ny, Z1= Δ. nu+ 1 : G. ny, pos_feedback = true )
379
388
else
380
389
error (" Invalid type of lft ($type ). Specify type=:l (:u) for lower (upper) lft." )
381
390
end
@@ -392,13 +401,8 @@ Compute the Redheffer star product.
392
401
For details, see Chapter 9.3 in
393
402
**Zhou, K. and JC Doyle**. Essentials of robust control, Prentice hall (NJ), 1998
394
403
"""
395
- function starprod (G1, G2, dimy:: Int , dimu:: Int )
396
- feedback (G1, G2, U1= G1. nu- dimu+ 1 : G1. nu, Y1= G1. ny- dimy+ 1 : G1. ny, W1= 1 : G1. nu- dimu, Z1= 1 : G1. ny- dimy,
397
- U2= 1 : dimy, Y2= 1 : dimu, W2= dimy+ 1 : G2. nu, Z2= dimu+ 1 : G2. ny,
398
- neg_feedback= false )
399
- end
400
- function starprod (sys1, sys2)
401
- nu = size (sys2, 2 )
402
- ny = size (sys2, 1 )
403
- starp (sys1, sys2, nu, ny)
404
- end
404
+ starprod (G1, G2, dimy:: Int , dimu:: Int ) = feedback (G1, G2,
405
+ U1= G1. nu- dimu+ 1 : G1. nu, Y1= G1. ny- dimy+ 1 : G1. ny, W1= 1 : G1. nu- dimu, Z1= 1 : G1. ny- dimy,
406
+ U2= 1 : dimy, Y2= 1 : dimu, W2= dimy+ 1 : G2. nu, Z2= dimu+ 1 : G2. ny,
407
+ pos_feedback= true )
408
+ starprod (sys1, sys2) = lft (sys1, sys2, :l )
0 commit comments