Skip to content

Discrete Time LQR Option #359

Closed
Closed

Description

@adam2392

There is no discrete-time LQR, even though it is solvable via the SLICOT function: sb02md. In lqr(*args, **keywords), there should be a way to pass in the fact that the Optimal Control problem is a discrete-time system.

I would imagine this is as simple as allowing for an additional keyword argument passed, that specifies discrete time, and converts control/statefbk.py:361 to:

    # Call the SLICOT function
    X,rcond,w,S,U,A_inv = sb02md(nstates, A_b, G, Q_b, 'D')

I can submit a PR for this.

Activity

  1. murrayrm commented on Jan 2, 2020

    @murrayrm
    Member

    Rather than overload the lqr function, it might make more sense to implement a second function dlqr for the discrete time case. This would match the approach taken by MATLAB.

    Another approach would be to create a function linear_quadratic_regulator that takes a system as its input and then solves the quadratic regulator problem based on whether the system is continuous or discrete.

    Finally, we may also want to implement dlqe and/or linear quadratic estimator at the same time, following PR #351.

  2. adam2392 commented on Jan 2, 2020

    @adam2392
    Author

    Okay, awesome I can try to implement a dlqr function, and should this just also be using https://docs.scipy.org/doc/scipy/reference/generated/scipy.linalg.solve_discrete_are.html for the solver instead of SLICOT?

    I saw that there was interest in moving away from SLICOT in #27 ?

  3. murrayrm commented on Jan 2, 2020

    @murrayrm
    Member

    I would use the scipy function, though a full implementation could use a method keyword with method=slycot (or slicot?) calling the slycot function and method=scipy (default) calling the scipy version. See issue #255 for a discussion on method.

  4. robertobucher commented on Jan 2, 2020

    @robertobucher
    Member
  5. lucasbellinaso commented on Jan 13, 2021

    @lucasbellinaso

    I have solution that I am using in my classes to calculate simple discrete-time LQR:

    def dlqr_calculate(G, H, Q, R, returnPE=False):
      '''
      Discrete-time Linear Quadratic Regulator calculation.
      State-feedback control  u[k] = -K*x[k]
    
      How to apply the function:    
          K = dlqr_calculate(G,H,Q,R)
          K, P, E = dlqr_calculate(G,H,Q,R, return_solution_eigs=True)
    
      Inputs:
        G, H, Q, R  -> all numpy arrays  (simple float number not allowed)
        returnPE: define as True to return Ricatti solution and final eigenvalues
    
      Returns:
        K: state feedback gain
        P: Ricatti equation solution
        E: eigenvalues of (G-HK)  (closed loop z-domain poles)
      '''
      from scipy.linalg import solve_discrete_are, inv, eig
      P = solve_discrete_are(G, H, Q, R)  #Solução Ricatti
      K = inv(H.T@P@H + R)@H.T@P@G    #K = (B^T P B + R)^-1 B^T P A 
    
      if returnPE == False:   return K
    
      from numpy.linalg import eigvals
      eigs = np.array([eigvals(G-H@K)]).T
      return K, P, eigs
    
  6. added this to the 0.9.x milestone on Jan 18, 2021
  7. sawyerbfuller commented on Jan 22, 2021

    @sawyerbfuller
    Contributor
  8. linked a pull request that will close this issueDLQR and DLQE #670on Nov 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions