Skip to content

Commit ca77cca

Browse files
committed
update create_statefbk_iosys/lqr/dlqr errors + unit tests
1 parent 213905c commit ca77cca

File tree

2 files changed

+62
-3
lines changed

2 files changed

+62
-3
lines changed

control/statefbk.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,7 @@ def lqr(*args, **kwargs):
698698
raise ControlArgument("Integral action must pass an array")
699699
elif integral_action.shape[1] != nstates:
700700
raise ControlArgument(
701-
"Integral gain output size must match system input size")
701+
"Integral gain size must match system state size")
702702

703703
# Process the states to be integrated
704704
nintegrators = integral_action.shape[0]
@@ -829,7 +829,7 @@ def dlqr(*args, **kwargs):
829829
raise ControlArgument("Integral action must pass an array")
830830
elif integral_action.shape[1] != nstates:
831831
raise ControlArgument(
832-
"Integral gain output size must match system input size")
832+
"Integral gain size must match system state size")
833833
else:
834834
nintegrators = integral_action.shape[0]
835835
C = integral_action
@@ -951,7 +951,7 @@ def create_statefbk_iosystem(
951951
raise ControlArgument("Integral action must pass an array")
952952
elif integral_action.shape[1] != sys.nstates:
953953
raise ControlArgument(
954-
"Integral gain output size must match system input size")
954+
"Integral gain size must match system state size")
955955
else:
956956
nintegrators = integral_action.shape[0]
957957
C = integral_action

control/tests/statefbk_test.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -826,3 +826,62 @@ def test_lqr_integral_discrete(self):
826826
np.testing.assert_array_almost_equal(ctrl.B, B_ctrl)
827827
np.testing.assert_array_almost_equal(ctrl.C, C_ctrl)
828828
np.testing.assert_array_almost_equal(ctrl.D, D_ctrl)
829+
830+
@pytest.mark.parametrize(
831+
"rss_fun, lqr_fun",
832+
[(ct.rss, lqr), (ct.drss, dlqr)])
833+
def test_lqr_errors(self, rss_fun, lqr_fun):
834+
# Generate a discrete time system for testing
835+
sys = rss_fun(4, 4, 2, strictly_proper=True)
836+
837+
with pytest.raises(ControlArgument, match="must pass an array"):
838+
K, _, _ = lqr_fun(
839+
sys, np.eye(sys.nstates), np.eye(sys.ninputs),
840+
integral_action="invalid argument")
841+
842+
with pytest.raises(ControlArgument, match="gain size must match"):
843+
C_int = np.eye(2, 3)
844+
K, _, _ = lqr_fun(
845+
sys, np.eye(sys.nstates), np.eye(sys.ninputs),
846+
integral_action=C_int)
847+
848+
with pytest.raises(TypeError, match="unrecognized keywords"):
849+
K, _, _ = lqr_fun(
850+
sys, np.eye(sys.nstates), np.eye(sys.ninputs),
851+
integrator=None)
852+
853+
def test_statefbk_errors(self):
854+
sys = ct.rss(4, 4, 2, strictly_proper=True)
855+
K, _, _ = ct.lqr(sys, np.eye(sys.nstates), np.eye(sys.ninputs))
856+
857+
with pytest.raises(ControlArgument, match="must be I/O system"):
858+
sys_tf = ct.tf([1], [1, 1])
859+
ctrl, clsys = ct.create_statefbk_iosystem(sys_tf, K)
860+
861+
with pytest.raises(ControlArgument, match="output size must match"):
862+
est = ct.rss(3, 3, 2)
863+
ctrl, clsys = ct.create_statefbk_iosystem(sys, K, estimator=est)
864+
865+
with pytest.raises(ControlArgument, match="must be the full state"):
866+
sys_nf = ct.rss(4, 3, 2, strictly_proper=True)
867+
ctrl, clsys = ct.create_statefbk_iosystem(sys_nf, K)
868+
869+
with pytest.raises(ControlArgument, match="gain must be an array"):
870+
ctrl, clsys = ct.create_statefbk_iosystem(sys, "bad argument")
871+
872+
with pytest.raises(ControlArgument, match="unknown type"):
873+
ctrl, clsys = ct.create_statefbk_iosystem(sys, K, type=1)
874+
875+
# Errors involving integral action
876+
C_int = np.eye(2, 4)
877+
K_int, _, _ = ct.lqr(
878+
sys, np.eye(sys.nstates + C_int.shape[0]), np.eye(sys.ninputs),
879+
integral_action=C_int)
880+
881+
with pytest.raises(ControlArgument, match="must pass an array"):
882+
ctrl, clsys = ct.create_statefbk_iosystem(
883+
sys, K_int, integral_action="bad argument")
884+
885+
with pytest.raises(ControlArgument, match="must be an array of size"):
886+
ctrl, clsys = ct.create_statefbk_iosystem(
887+
sys, K, integral_action=C_int)

0 commit comments

Comments
 (0)