You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
issiso(G) ||error("root locus only supports SISO systems")
8
8
G isa TransferFunction || (G =tf(G))
9
9
P =numpoly(G)[]
@@ -69,17 +69,115 @@ function getpoles(G, K::AbstractVector{T}) where {T<:Number}
69
69
copy(poleout'), K
70
70
end
71
71
72
+
"""
73
+
getpoles(sys::StateSpace, K::AbstractMatrix; tol = 1e-2, initial_stepsize = 1e-3, output=false)
74
+
75
+
Compute the poles of the closed-loop system defined by `sys` with feedback gains `γ*K` where `γ` is a scalar that ranges from 0 to 1.
76
+
77
+
If `output = true`, `K` is assumed to be an output feedback matrix of dim `(nu, ny)`
78
+
"""
79
+
functiongetpoles(sys::StateSpace, K_matrix::AbstractMatrix; tol =1e-2, initial_stepsize =1e-3, output=false)
80
+
(; A, B, C) = sys
81
+
nx =size(A, 1) # State dimension
82
+
ny =size(C, 1) # Output dimension
83
+
tol = tol*nx # Scale tolerance with state dimension
84
+
# Check for compatibility of K_matrix dimensions with B
85
+
ifsize(K_matrix, 2) != (output ? ny : nx)
86
+
error("The number of columns in K_matrix ($(size(K_matrix, 2))) must match the state dimension ($(nx)) or output dimension ($(ny)) depending on whether output feedback is used.")
87
+
end
88
+
ifsize(K_matrix, 1) !=size(B, 2)
89
+
error("The number of rows in K_matrix ($(size(K_matrix, 1))) must match the number of inputs (columns of B, which is $(size(B, 2))).")
90
+
end
91
+
92
+
if output
93
+
# We bake C into K here to avoid repeated multiplications below
94
+
K_matrix = K_matrix * C
95
+
end
96
+
97
+
poleout_list =Vector{Vector{ComplexF64}}() # To store pole sets at each accepted step
98
+
k_scalars_collected = Float64[] # To store accepted k_scalar values
99
+
100
+
prevpoles = ComplexF64[] # Initialize prevpoles for the first iteration
101
+
102
+
stepsize = initial_stepsize
103
+
k_scalar =0.0
104
+
105
+
# Initial poles at k_scalar = 0.0
106
+
A_cl_initial = A -0.0* B * K_matrix
107
+
initial_poles =eigvals(A_cl_initial)
108
+
push!(poleout_list, initial_poles)
109
+
push!(k_scalars_collected, 0.0)
110
+
prevpoles = initial_poles # Set prevpoles for the first actual step
prevpoles = current_poles_sorted # Update prevpoles for the next iteration
150
+
k_scalar = next_k_scalar # Advance k_scalar
151
+
152
+
if cost < tol # Cost is too low, increase stepsize
153
+
stepsize *=1.1
154
+
end
155
+
# Cap stepsize to prevent overshooting 1.0 significantly in a single step
156
+
stepsize =min(stepsize, 1e-1)
157
+
end
158
+
159
+
# Break if k_scalar has reached or exceeded 1.0
160
+
if k_scalar >=1.0
161
+
break
162
+
end
163
+
end
164
+
165
+
returnhcat(poleout_list...)'|> copy, k_scalars_collected .*Ref(K_matrix) # Return transposed pole matrix and k_values
166
+
end
167
+
72
168
73
169
"""
74
170
roots, Z, K = rlocus(P::LTISystem, K = 500)
75
171
76
172
Compute the root locus of the SISO LTISystem `P` with a negative feedback loop and feedback gains between 0 and `K`. `rlocus` will use an adaptive step-size algorithm to determine the values of the feedback gains used to generate the plot.
77
173
78
174
`roots` is a complex matrix containing the poles trajectories of the closed-loop `1+k⋅G(s)` as a function of `k`, `Z` contains the zeros of the open-loop system `G(s)` and `K` the values of the feedback gain.
175
+
176
+
If `K` is a matrix and `P` a `StateSpace` system, the poles are computed as `K` ranges from `0*K` to `1*K`. In this case, `K` is assumed to be a state-feedback matrix of dimension `(nu, nx)`. To compute the poles for output feedback, use, pass `output = true` and `K` of dimension `(nu, ny)`.
0 commit comments