Skip to content

Commit 6793f4b

Browse files
committed
fix(statefbk): trim refgain integral feedthrough
1 parent 146ccee commit 6793f4b

2 files changed

Lines changed: 34 additions & 1 deletion

File tree

control/statefbk.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1006,7 +1006,7 @@ def _control_output(t, states, inputs, params):
10061006
A_lqr = np.eye(C.shape[0])
10071007
B_lqr = np.hstack([-np.eye(C.shape[0], sys_ninputs), C])
10081008
C_lqr = -K[:, sys_nstates:] # integral gain (opt)
1009-
D_lqr = np.hstack([Kf, -K])
1009+
D_lqr = np.hstack([Kf, -K[:, :sys_nstates]])
10101010

10111011
ctrl = ss(
10121012
A_lqr, B_lqr, C_lqr, D_lqr, dt=sys.dt, name=name,

control/tests/statefbk_test.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,6 +1233,39 @@ def test_refgain_pattern(ninputs, Kf):
12331233
np.testing.assert_almost_equal(clsys.D[:sys.nstates, :], manual.D)
12341234

12351235

1236+
def test_refgain_pattern_integral_action():
1237+
sys = ct.ss(
1238+
[[0.0, 1.0], [-2.0, -3.0]],
1239+
[[0.0, 1.0], [1.0, 0.0]],
1240+
np.eye(2),
1241+
np.zeros((2, 2)),
1242+
)
1243+
Kp = np.array([[1.0, 2.0], [3.0, 4.0]])
1244+
Ki = np.array([[5.0], [6.0]])
1245+
K = np.hstack([Kp, Ki])
1246+
Kf = np.diag([7.0, 8.0])
1247+
C_int = np.array([[1.0, 0.0]])
1248+
1249+
ctrl, clsys = ct.create_statefbk_iosystem(
1250+
sys, K, Kf, integral_action=C_int, feedfwd_pattern='refgain')
1251+
1252+
np.testing.assert_array_equal(ctrl.A, np.zeros((1, 1)))
1253+
np.testing.assert_array_equal(ctrl.B, np.hstack([-np.eye(1, 2), C_int]))
1254+
np.testing.assert_array_equal(ctrl.C, -Ki)
1255+
np.testing.assert_array_equal(ctrl.D, np.hstack([Kf, -Kp]))
1256+
1257+
np.testing.assert_array_equal(
1258+
clsys.A, np.block([[sys.A - sys.B @ Kp, -sys.B @ Ki],
1259+
[C_int, np.zeros((1, 1))]]))
1260+
np.testing.assert_array_equal(
1261+
clsys.B, np.vstack([sys.B @ Kf, -np.eye(1, sys.ninputs)]))
1262+
np.testing.assert_array_equal(
1263+
clsys.C, np.block([[np.eye(sys.nstates), np.zeros((sys.nstates, 1))],
1264+
[-Kp, -Ki]]))
1265+
np.testing.assert_array_equal(
1266+
clsys.D, np.vstack([np.zeros((sys.nstates, sys.ninputs)), Kf]))
1267+
1268+
12361269
def test_create_statefbk_errors():
12371270
sys = ct.rss(2, 2, 1, strictly_proper=True)
12381271
sys.C = np.eye(2)

0 commit comments

Comments
 (0)