Skip to content

Commit 427f7b4

Browse files
authored
Merge pull request #73 from JuliaControl/cont_outputint
add and test continuous-time output integrator augmentation
2 parents f91bd3b + 58d57d9 commit 427f7b4

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

src/model_augmentation.jl

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ Augment `sys` with a resonant disturbance model.
8484
- `Ai`: The affected state
8585
- `measurement`: If true, the disturbace is acting on the output, this will cause the controller to have zeros at ω (roots of poly s² + 2ζωs + ω²). If false, the disturbance is acting on the input, this will cause the controller to have poles at ω (roots of poly s² + 2ζωs + ω²).
8686
"""
87-
function add_resonant_disturbance(sys::AbstractStateSpace{Continuous}, ω, ζ, Ai::Integer; measurement=false)
87+
function add_resonant_disturbance(sys::AbstractStateSpace, ω, ζ, Ai::Integer; measurement=false)
8888
nx,nu,ny = sys.nx,sys.nu,sys.ny
8989
if measurement
9090
1 Ai sys.ny || throw(ArgumentError("Ai must be a valid output index"))
@@ -96,6 +96,9 @@ function add_resonant_disturbance(sys::AbstractStateSpace{Continuous}, ω, ζ, A
9696
Cd[Ai, 1] = 1
9797
end
9898
Ad = [-ζ -ω; ω -ζ]
99+
if isdiscrete(sys)
100+
Ad = exp(Ad * sys.Ts)
101+
end
99102
measurement ? add_measurement_disturbance(sys, Ad, Cd) : add_disturbance(sys, Ad, Cd)
100103
end
101104

@@ -160,6 +163,15 @@ function add_output_integrator(sys::AbstractStateSpace{<: Discrete}, ind=1; ϵ=0
160163
tf(M)*sys
161164
end
162165

166+
function add_output_integrator(sys::AbstractStateSpace{Continuous}, ind=1; ϵ=0)
167+
int = tf(1.0, [1, ϵ])
168+
𝟏 = tf(1.0)
169+
𝟎 = tf(0.0)
170+
M = [i==j ? 𝟏 : 𝟎 for i = 1:sys.ny, j = 1:sys.ny]
171+
M = [M; permutedims([i==ind ? int : 𝟎 for i = 1:sys.ny])]
172+
tf(M)*sys
173+
end
174+
163175
"""
164176
add_input_integrator(sys::StateSpace, ui = 1, ϵ = 0)
165177

test/test_augmentation.jl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ Gd = add_resonant_disturbance(G, 1, 0, [1.0])
3636
allapproxin(a, b) = all(any(a .≈ b', dims=2))
3737
@test allapproxin(poles(Gd), [eigvals(exp([0 -1; 1 0]*0.1)); exp(-1*0.1)])
3838

39+
# Discrete time and input index
40+
G = c2d(ss(tf(1.0, [1, 1])), 0.1)
41+
Gd = add_resonant_disturbance(G, 1, 0, 1)
42+
@test sminreal(Gd) == G
43+
@test Gd.nx == 3
44+
allapproxin(a, b) = all(any(a .≈ b', dims=2))
45+
@test allapproxin(poles(Gd), [eigvals(exp([0 -1; 1 0]*0.1)); exp(-1*0.1)])
46+
3947

4048
##
4149

@@ -56,6 +64,14 @@ Gd2 = [tf(1,1); tf(1, [1, -1], 1)]*G
5664
@test sminreal(Gd[1,1]) == G # Exact equivalence should hold here
5765
@test Gd.nx == 4 # To guard agains changes in realization of tf as ss
5866

67+
68+
Gc = ssrand(1,1,3, proper=true)
69+
Gdc = add_output_integrator(Gc)
70+
Gd2c = [tf(1); tf(1, [1, 0])]*Gc
71+
@test Gdc Gd2c
72+
@test sminreal(Gdc[1,1]) == Gc # Exact equivalence should hold here
73+
@test Gdc.nx == 4 # To guard agains changes in realization of tf as ss
74+
5975
Gd = add_input_integrator(G)
6076
@test sminreal(Gd[1,1]) == G # Exact equivalence should hold here
6177
@test Gd.nx == 4 # To guard agains changes in realization of tf as ss

0 commit comments

Comments
 (0)