Skip to content

bug in create_statefbk_iosystem, option refgain #1189

Description

@miroslavfikar

D_lqr = np.hstack([Kf, -K])

Matrix D_lqr is not correctly constructed if integral action is used in 'refgain' form. The line:
D_lqr = np.hstack([Kf, -K])
should read:
D_lqr = np.hstack([Kf, -K[:, :sys_nstates]])
as K[:, sys_nstates:] is already used in C_lqr, D_lqr is too wide.

Activity

  1. murrayrm commented on Dec 20, 2025

    @murrayrm
    Member

    Thanks for the post! I'll look into this, but if you can also post some code that generates the error, that would be helpful (and we can add it to the unit tests).

  2. self-assigned this
    on Dec 20, 2025
  3. miroslavfikar commented on Dec 20, 2025

    @miroslavfikar
    ContributorAuthor

    This is my code with modified function.
    bug.py
    Replacing by the library version throws error:

    Traceback (most recent call last):
      File "<string>", line 17, in __PYTHON_EL_eval
      File "/home/fikar/miro/doc/pedagog/tar2/course_2_tar2/exercises/week_02/python/bug.py", line 54, in <module>
        ctrl, sys_cl = ct.create_statefbk_iosystem(sys_ol_full, KK, Kr, integral_action=C, feedfwd_pattern='refgain')
                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/home/fikar/miniconda3/lib/python3.13/site-packages/control/statefbk.py", line 1011, in create_statefbk_iosystem
        ctrl = ss(
            A_lqr, B_lqr, C_lqr, D_lqr, dt=sys.dt, name=name,
            inputs=inputs, outputs=outputs, states=states)
      File "/home/fikar/miniconda3/lib/python3.13/site-packages/control/statesp.py", line 1745, in ss
        sys = StateSpace(*args, **kwargs)
      File "/home/fikar/miniconda3/lib/python3.13/site-packages/control/statesp.py", line 272, in __init__
        _check_shape(D, self.noutputs, self.ninputs, name="D")
        ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/home/fikar/miniconda3/lib/python3.13/site-packages/control/mateqn.py", line 645, in _check_shape
        raise ControlDimension(
            f"Incompatible dimensions of {name} matrix; "
            f"expected ({n}, {m}) but found {M.shape}")
    control.exception.ControlDimension: Incompatible dimensions of D matrix; expected (1, 4) but found (1, 5)
    >>> 
    
  4. murrayrm commented on Dec 21, 2025

    @murrayrm
    Member

    Thanks. Extracting the code that generates the error to have everything in one place:

    import control as ct
    import numpy as np
    
    A = np.array([[0, 1, 0], [0, 0, 1], [-6, -11, -6]])
    B = np.array([[0], [0], [1]])
    C = np.array([[1, 0, 0]])
    D = np.array([[0]])
    sys_ol = ct.ss(A, B, C, D, name='OL')
    
    Cfull = np.eye(3)
    Dfull = np.array([[0], [0], [0]])
    sys_ol_full = ct.ss(A, B, Cfull, Dfull, name='OL')
    
    # Extend states by the integral part
    nx, nu = B.shape
    ny, _ = C.shape
    A1 = np.block([[A, np.zeros((nx, ny))], [-C, np.zeros((ny, 1))]])
    B1 = np.vstack((B, np.zeros((ny, nu))))
    
    # Construct the controller
    Q = 150*np.eye(nx+ny)
    R = 1*np.eye(nu)
    Q = np.diag([1, 1, 1, 1/0.01**2])
    K, _, _ = ct.lqr(A1, B1, Q, R)
    Kr = 0
    
    # Preparation for minus sign in create_statefbk_iosystem
    KK = K
    KK[0,3] = - K[0,3]
    
    ctrl, sys_cl = ct.create_statefbk_iosystem(sys_ol_full, KK, Kr, integral_action=C, feedfwd_pattern='refgain')
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions