Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
ffc3041
add unsupervised calculation on gains for root locus plot.
gonmolina Mar 21, 2017
2aada8b
fix bug concatenating zero dimensional array
gonmolina Mar 21, 2017
7130434
fix bug concatenating zero dimensional when test in matlab_test.py
gonmolina Mar 21, 2017
8b829cc
fix bug with array==0! problem test in matlab_test.py
gonmolina Mar 21, 2017
d4cbc95
fix bug with axis limits with no asymptotes
gonmolina Mar 23, 2017
6d55d57
fix bug calculating kmax
gonmolina Mar 23, 2017
01e33ea
add unsupervised calculation on gains for root locus plot.
gonmolina Mar 21, 2017
95d6908
fix bug with axis limits with no asymptotes
gonmolina Mar 23, 2017
1b20bd4
add sgrid to rlocus plot, to the last version of unsupervised gains.
gonmolina Mar 31, 2017
5e47d1f
add origin to rlocus plot and x=0 line (zeta =0 grid line).
gonmolina Mar 31, 2017
ebd3904
add grid arguments in docstring.
gonmolina Mar 31, 2017
3fb2c86
Merge remote-tracking branch 'origin/unsup_rlocus_gain_selection' int…
gonmolina Mar 31, 2017
de87bb0
reorder code that calculate defaults damp coefficents constant lines …
gonmolina Apr 2, 2017
5438746
formatting code to make easier sgrid() function in future.
gonmolina Apr 2, 2017
1e356b8
trying that algorithm work with 0 degrees root locus with equal numbe…
gonmolina Jun 8, 2017
6c813ce
adding some support for 0 degrees root locus.
gonmolina Jun 13, 2017
6e4d14f
add book reference of root locus calculation.
gonmolina Jun 13, 2017
a680c6a
fix minor bug when fartest point is zero.
gonmolina Jun 14, 2017
81b73a6
fix minor bugs when that solves problems in paricular cases
gonmolina Jun 17, 2017
62ed2aa
Fixed requested issues.
gonmolina Jun 30, 2017
4eedde4
fix build problem (numerical problem)
gonmolina Jul 1, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
reorder code that calculate defaults damp coefficents constant lines …
…and wn constant lines.

grids ok in most of the examples.
  • Loading branch information
gonmolina committed Apr 2, 2017
commit de87bb0ff1b8bace2efc78efd45d19c81bd5affc
69 changes: 43 additions & 26 deletions control/rlocus.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ def root_locus(sys, kvect=None, xlim=None, ylim=None, plotstr='-', Plot=True,
ax.set_ylabel('Imaginary')
if grid:
sgrid_func(f)

return mymat, kvect


Expand All @@ -162,7 +161,7 @@ def _default_gains(num, den, xlim, ylim):
mymat_xl = mymat
singular_points = np.concatenate((num.roots, den.roots), axis=0)
important_points = np.concatenate((singular_points, real_break), axis=0)
important_points = np.concatenate((singular_points, np.zeros(2)), axis=0)
important_points = np.concatenate((important_points, np.zeros(2)), axis=0)
mymat_xl = np.append(mymat_xl, important_points)

if xlim is None:
Expand Down Expand Up @@ -267,6 +266,7 @@ def _systopoly1d(sys):
# Check to see if num, den are already polynomials; otherwise convert
if (not isinstance(nump, poly1d)):
nump = poly1d(nump)

if (not isinstance(denp, poly1d)):
denp = poly1d(denp)

Expand Down Expand Up @@ -321,55 +321,72 @@ def _RLFeedbackClicks(event, sys):
(s.real, s.imag, K.real, -1 * s.real / abs(s)))


def sgrid_func(fig):
def sgrid_func(fig, zeta=None, wn=None):
ax = fig.gca()
ylocator = ax.get_yaxis().get_major_locator()
xlocator = ax.get_yaxis().get_major_locator()
xlocator = ax.get_xaxis().get_major_locator()

angules = np.arange(-90, 80, 15)*np.pi/180
if zeta is None:
zeta = _default_zetas(xlocator(), ylocator())

angules = []
for z in zeta:
if (z >= 1e-4) & (z < 1):
angules.append(np.pi/2 + np.arcsin(z))
else:
zeta.remove(z)
y_over_x = np.tan(angules)

# zeta-constant lines
y_over_x = np.tan(angules[1::])*ylocator()[-1]/xlocator()[-1]
ylim = ax.get_ylim()
ytext_pos_lim = ylim[1]-(ylim[1]-ylim[0])*0.03
xlim = ax.get_xlim()
xtext_pos_lim = xlim[0]+(xlim[1]-xlim[0])*0.0
index = 0
zeta = np.sin(np.pi/2-angules[1::])

for yp in y_over_x:
ax.plot([0, xlocator()[0]], [0, yp*xlocator()[0]], color='gray',
linestyle='dashed', linewidth=0.5)
ax.plot([0, xlocator()[0]], [0, -yp * xlocator()[0]], color='gray',
linestyle='dashed', linewidth=0.5)
an = "%.2f" % zeta[index]
if yp > 0:
xtext_pos = -1/yp * ylim[1]
ytext_pos = -yp * xtext_pos_lim
if np.abs(xtext_pos) > np.abs(xtext_pos_lim):
xtext_pos = xtext_pos_lim
else:
ytext_pos = ytext_pos_lim
ax.annotate(an, textcoords='data', xy=[xtext_pos, ytext_pos], fontsize=8)
elif yp < 0:
xtext_pos = -1/yp * ylim[1]
if yp < 0:
xtext_pos = 1/yp * ylim[1]
ytext_pos = yp * xtext_pos_lim
if np.abs(xtext_pos) > np.abs(xtext_pos_lim):
xtext_pos = xtext_pos_lim
ytext_pos = - ytext_pos
else:
ytext_pos = ylim[0]
xtext_pos = -xtext_pos
ytext_pos = ytext_pos_lim
ax.annotate(an, textcoords='data', xy=[xtext_pos, ytext_pos], fontsize=8)
index += 1
ax.plot([0, 0], [ylim[0], ylim[1]], color='gray', linestyle='dashed', linewidth=0.5)

angules = np.linspace(-90, 90, 20)*np.pi/180
for xt in xlocator():
if xt < 0:
yp = np.sin(angules)*np.abs(xt)
xp = -np.cos(angules)*np.abs(xt)
if wn is None:
wn = _default_wn(xlocator(), ylocator())

for om in wn:
if om < 0:
yp = np.sin(angules)*np.abs(om)
xp = -np.cos(angules)*np.abs(om)
ax.plot(xp, yp, color='gray',
linestyle='dashed', linewidth=0.5)
an = "%.2f" % -xt
ax.annotate(an, textcoords='data', xy=[xt, 0], fontsize=8)
an = "%.2f" % -om
ax.annotate(an, textcoords='data', xy=[om, 0], fontsize=8)


def _default_zetas(xloc, yloc):
"""Return default list of dumps coefficients"""
# TODO: smart selection on zetas to draw in root locus plot
angules = np.arange(0, 80, 15) * np.pi / 180
zeta = np.sin(np.pi/2 - angules[1::])
return zeta.tolist()


def _default_wn(xloc, yloc):
"""Return default wn for root locus plot"""
# TODO: better selection of wn (up to maximum ylim with same separation in xloc)
wn = xloc
return wn

rlocus = root_locus