You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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')
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.
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.
Hi Adam
I have a temporary solution for both dlqr and lqe functions that I'm
using in my practical systems in my Lab at SUPSI since a couple of years.
Both are implemented in the package supsictrl.ctrl_repl under
supsictrl/src/ctrl_repl.py on my github page for the pysimCoder project.
Best regards
Roberto
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
Activity
murrayrm commentedon Jan 2, 2020
Rather than overload the
lqrfunction, it might make more sense to implement a second functiondlqrfor the discrete time case. This would match the approach taken by MATLAB.Another approach would be to create a function
linear_quadratic_regulatorthat 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
dlqeand/orlinear quadratic estimatorat the same time, following PR #351.adam2392 commentedon Jan 2, 2020
Okay, awesome I can try to implement a
dlqrfunction, 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 ?
murrayrm commentedon Jan 2, 2020
I would use the
scipyfunction, though a full implementation could use amethodkeyword withmethod=slycot(orslicot?) calling theslycotfunction andmethod=scipy(default) calling thescipyversion. See issue #255 for a discussion onmethod.robertobucher commentedon Jan 2, 2020
lucasbellinaso commentedon Jan 13, 2021
I have solution that I am using in my classes to calculate simple discrete-time LQR:
sawyerbfuller commentedon Jan 22, 2021
Thank you lucas! Feel free to submit a pull request! (https://github.com/python-control/python-control/wiki/How-to-contribute-with-a-pull-request)