Skip to content

Commit 1e356b8

Browse files
committed
trying that algorithm work with 0 degrees root locus with equal number of poles and zeros
1 parent 5438746 commit 1e356b8

File tree

1 file changed

+24
-6
lines changed

1 file changed

+24
-6
lines changed

control/rlocus.py

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ def root_locus(sys, kvect=None, xlim=None, ylim=None, plotstr='-', Plot=True,
127127
ax.plot(real(zeros), imag(zeros), 'o')
128128

129129
# Now plot the loci
130+
infinity_roots=np.where(mymat.T == np.inf)
131+
print(infinity_roots)
130132
for col in mymat.T:
131133
ax.plot(real(col), imag(col), plotstr)
132134

@@ -163,12 +165,17 @@ def _default_gains(num, den, xlim, ylim):
163165
important_points = np.concatenate((singular_points, real_break), axis=0)
164166
important_points = np.concatenate((important_points, np.zeros(2)), axis=0)
165167
mymat_xl = np.append(mymat_xl, important_points)
168+
false_gain = den.coeffs[0] / num.coeffs[0]
166169

167-
if xlim is None:
170+
if xlim is None and false_gain > 0:
168171
x_tolerance = 0.05 * (np.max(np.max(np.real(mymat_xl))) - np.min(np.min(np.real(mymat_xl))))
169172
xlim = _ax_lim(mymat_xl)
173+
elif xlim is None and false_gain < 0:
174+
xlim = _ax_lim(important_points)
175+
x_tolerance = 0.05 * (np.max(np.max(np.real(mymat_xl))) - np.min(np.min(np.real(mymat_xl))))
170176
else:
171177
x_tolerance = 0.05 * (xlim[1] - xlim[0])
178+
172179
if ylim is None:
173180
y_tolerance = 0.05 * (np.max(np.max(np.imag(mymat_xl))) - np.min(np.min(np.imag(mymat_xl))))
174181
ylim = _ax_lim(mymat_xl * 1j)
@@ -178,15 +185,18 @@ def _default_gains(num, den, xlim, ylim):
178185
tolerance = np.max([x_tolerance, y_tolerance])
179186
distance_points = np.abs(np.diff(mymat, axis=0))
180187
indexes_too_far = np.where(distance_points > tolerance)
188+
181189
while (indexes_too_far[0].size > 0) & (kvect.size < 5000):
182190
for index in indexes_too_far[0]:
183191
new_gains = np.linspace(kvect[index], kvect[index+1], 5)
184192
new_points = _RLFindRoots(num, den, new_gains[1:4])
185193
kvect = np.insert(kvect, index+1, new_gains[1:4])
186194
mymat = np.insert(mymat, index+1, new_points, axis=0)
187195
mymat = _RLSortRoots(mymat)
188-
distance_points = np.abs(np.diff(mymat, axis=0))
189-
indexes_too_far = np.where(distance_points > tolerance)
196+
distance_points = np.abs(np.diff(mymat, axis=0))>tolerance
197+
points_in_figure = np.logical_and(mymat[1:]>xlim[0], mymat[1:]<xlim[1])
198+
indexes_too_far = np.where(np.logical_and(distance_points, points_in_figure))
199+
190200
new_gains = np.hstack((np.linspace(kvect[-1], kvect[-1]*200, 10)))
191201
new_points = _RLFindRoots(num, den, new_gains[1:10])
192202
kvect = np.append(kvect, new_gains[1:10])
@@ -230,15 +240,20 @@ def _k_max(num, den, real_break_points, k_break_points):
230240
asymp_number = den.order - num.order
231241
singular_points = np.concatenate((num.roots, den.roots), axis=0)
232242
important_points = np.concatenate((singular_points, real_break_points), axis=0)
243+
false_gain = den.coeffs[0] / num.coeffs[0]
233244

234245
if asymp_number > 0:
235246
asymp_center = (np.sum(den.roots) - np.sum(num.roots))/asymp_number
236247
distance_max = 2 * np.max(np.abs(important_points - asymp_center))
237248
asymp_angles = (2 * np.arange(0, asymp_number)-1) * np.pi / asymp_number
238-
farthest_points = asymp_center + distance_max * np.exp(asymp_angles * 1j) # farthest points over asymptotes
249+
if false_gain > 0:
250+
farthest_points = asymp_center + distance_max * np.exp(asymp_angles * 1j) # farthest points over asymptotes
251+
else:
252+
asymp_angles = asymp_angles + np.pi
253+
farthest_points = asymp_center + distance_max * np.exp(asymp_angles * 1j) # farthest points over asymptotes
239254
kmax_asymp = -den(farthest_points) / num(farthest_points)
240255
else:
241-
kmax_asymp = [den.coeffs[0] / num.coeffs[0] * 3]
256+
kmax_asymp = np.abs([den.coeffs[0] / num.coeffs[0] * 3])
242257

243258
kmax = np.max(np.concatenate((np.real(kmax_asymp), k_break_points), axis=0))
244259
return kmax
@@ -277,13 +292,16 @@ def _RLFindRoots(nump, denp, kvect):
277292
"""Find the roots for the root locus."""
278293

279294
# Convert numerator and denominator to polynomials if they aren't
280-
281295
roots = []
282296
for k in kvect:
283297
curpoly = denp + k * nump
284298
curroots = curpoly.r
299+
if len(curroots) < denp.order:
300+
curroots = np.insert(curroots, len(curroots), np.inf) # if i have less poles than open loop is becuase i have one in infinity
301+
285302
curroots.sort()
286303
roots.append(curroots)
304+
287305
mymat = row_stack(roots)
288306
return mymat
289307

0 commit comments

Comments
 (0)