def test_root_locus_zoom(self): """Check the zooming functionality of the Root locus plot""" system = TransferFunction([1000], [1, 25, 100, 0]) plt.figure() root_locus(system) fig = plt.gcf() ax_rlocus = fig.axes[0] event = type( 'test', (object, ), { 'xdata': 14.7607954359, 'ydata': -35.6171379864, 'inaxes': ax_rlocus.axes })() ax_rlocus.set_xlim((-10.813628105112421, 14.760795435937652)) ax_rlocus.set_ylim((-35.61713798641108, 33.879716621220311)) plt.get_current_fig_manager().toolbar.mode = 'zoom rect' _RLClickDispatcher(event, system, fig, ax_rlocus, '-') zoom_x = ax_rlocus.lines[-2].get_data()[0][0:5] zoom_y = ax_rlocus.lines[-2].get_data()[1][0:5] zoom_y = [abs(y) for y in zoom_y] zoom_x_valid = [ -5., -4.61281263, -4.16689986, -4.04122642, -3.90736502 ] zoom_y_valid = [0., 0., 0., 0., 0.] assert_array_almost_equal(zoom_x, zoom_x_valid) assert_array_almost_equal(zoom_y, zoom_y_valid)
def rlocus(sys, klist = None, **keywords): """Root locus plot The root-locus plot has a callback function that prints pole location, gain and damping to the Python consol on mouseclicks on the root-locus graph. Parameters ---------- sys: StateSpace or TransferFunction Linear system klist: optional list of gains Returns ------- rlist: list of roots for each gain klist: list of gains used to compute roots """ from control.rlocus import root_locus #! TODO: update with a smart calculation of the gains using sys poles/zeros if klist == None: klist = logspace(-3, 3) rlist = root_locus(sys, klist, **keywords) return rlist, klist
def testRootLocus(self): """Basic root locus plot""" klist = [-1, 0, 1] for sys in self.systems: roots, k_out = root_locus(sys, klist, Plot=False) np.testing.assert_equal(len(roots), len(klist)) np.testing.assert_array_equal(klist, k_out) self.check_cl_poles(sys, roots, klist)
def testRootLocus(self, sys): """Basic root locus (no plot)""" klist = [-1, 0, 1] roots, k_out = root_locus(sys, klist, plot=False) np.testing.assert_equal(len(roots), len(klist)) np.testing.assert_allclose(klist, k_out) self.check_cl_poles(sys, roots, klist)
def testRootLocus(self): """Basic root locus plot""" klist = [-1, 0, 1] rlist = root_locus(self.sys1, [-1, 0, 1], Plot=False) for k in klist: np.testing.assert_array_almost_equal( np.sort(rlist[k]), np.sort(feedback(self.sys1, klist[k]).pole()))
def test_root_locus_plot_grid(self, sys, grid): rlist, klist = root_locus(sys, grid=grid) ax = plt.gca() n_gridlines = sum([ int(line.get_linestyle() in [':', 'dotted', '--', 'dashed']) for line in ax.lines ]) if grid is False: assert n_gridlines == 2 else: assert n_gridlines > 2
def test_root_locus_zoom(self): """Check the zooming functionality of the Root locus plot""" system = TransferFunction([1000], [1, 25, 100, 0]) root_locus(system) fig = plt.gcf() ax_rlocus = fig.axes[0] event = type('test', (object,), {'xdata': 14.7607954359, 'ydata': -35.6171379864, 'inaxes': ax_rlocus.axes})() ax_rlocus.set_xlim((-10.813628105112421, 14.760795435937652)) ax_rlocus.set_ylim((-35.61713798641108, 33.879716621220311)) plt.get_current_fig_manager().toolbar.mode = 'zoom rect' _RLClickDispatcher(event, system, fig, ax_rlocus, '-') zoom_x = ax_rlocus.lines[-2].get_data()[0][0:5] zoom_y = ax_rlocus.lines[-2].get_data()[1][0:5] zoom_y = [abs(y) for y in zoom_y] zoom_x_valid = [-5. ,- 4.61281263, - 4.16689986, - 4.04122642, - 3.90736502] zoom_y_valid = [0. ,0., 0., 0., 0.] assert_array_almost_equal(zoom_x,zoom_x_valid) assert_array_almost_equal(zoom_y,zoom_y_valid)
def rlocus(sys, klist = None, **keywords): """Root locus plot Parameters ---------- sys: StateSpace or TransferFunction Linear system klist: optional list of gains Returns ------- rlist: list of roots for each gain klist: list of gains used to compute roots """ from control.rlocus import root_locus #! TODO: update with a smart calculation of the gains using sys poles/zeros if klist == None: klist = logspace(-3, 3) rlist = root_locus(sys, klist, **keywords) return rlist, klist
def test_without_gains(self): for sys in self.systems: roots, kvect = root_locus(sys, Plot=False) self.check_cl_poles(sys, roots, kvect)
def test_without_gains(self, sys): roots, kvect = root_locus(sys, plot=False) self.check_cl_poles(sys, roots, kvect)
def test_root_locus_neg_false_gain_nonproper(self): """ Non proper TranferFunction with negative gain: Not implemented""" with pytest.raises(ValueError, match="with equal order"): root_locus(TransferFunction([-1, 2], [1, 2]))
def test_root_locus_warnings(self): sys = TransferFunction([1000], [1, 25, 100, 0]) with pytest.warns(FutureWarning, match="Plot.*deprecated"): rlist, klist = root_locus(sys, Plot=True) with pytest.warns(FutureWarning, match="PrintGain.*deprecated"): rlist, klist = root_locus(sys, PrintGain=True)