Skip to content

Commit

Permalink
add controller function (#512)
Browse files Browse the repository at this point in the history
* add controller function

* rename controller and predictor
  • Loading branch information
baggepinnen authored May 28, 2021
1 parent c44544a commit b75faea
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 14 deletions.
3 changes: 2 additions & 1 deletion src/ControlSystems.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ export LTISystem,
similarity_transform,
prescale,
innovation_form,
predictor,
observer_predictor,
observer_controller,
# Stability Analysis
isstable,
pole,
Expand Down
34 changes: 26 additions & 8 deletions src/matrix_comps.jl
Original file line number Diff line number Diff line change
Expand Up @@ -639,24 +639,42 @@ function innovation_form(sys::ST; sysw=I, syse=I, R1=I, R2=I) where ST <: Abstra
end

"""
predictor(sys::AbstractStateSpace, R1, R2)
predictor(sys::AbstractStateSpace, K)
observer_predictor(sys::AbstractStateSpace, R1, R2)
observer_predictor(sys::AbstractStateSpace, K)
Return the predictor system
x̂' = (A - KC)x̂ + Bu + Ky
Return the observer_predictor system
x̂' = (A - KC)x̂ + (B-KD)u + Ky
ŷ = Cx + Du
with the input equation [B K] * [u; y]
If covariance matrices `R1, R2` are given, the kalman gain `K` is calculaded.
See also `innovation_form`.
"""
function predictor(sys::ST, R1, R2) where ST <: AbstractStateSpace
function observer_predictor(sys::ST, R1, R2) where ST <: AbstractStateSpace
K = kalman(sys, R1, R2)
predictor(sys, K)
observer_predictor(sys, K)
end

function ControlSystems.predictor(sys, K::AbstractMatrix)
function observer_predictor(sys, K::AbstractMatrix)
A,B,C,D = ssdata(sys)
ss(A-K*C, [B K], C, [D zeros(size(D,1), size(K, 2))], sys.timeevol)
ss(A-K*C, [B-K*D K], C, [D zeros(size(D,1), size(K, 2))], sys.timeevol)
end

"""
cont = observer_controller(sys, L::AbstractMatrix, K::AbstractMatrix)
Return the observer_controller `cont` that is given by
`ss(A - B*L - K*C + K*D*L, K, L, 0)`
Such that `feedback(sys, cont)` produces a closed-loop system with eigenvalues given by `A-KC` and `A-BL`.
# Arguments:
- `sys`: Model of system
- `L`: State-feedback gain `u = -Lx`
- `K`: Observer gain
"""
function observer_controller(sys, L::AbstractMatrix, K::AbstractMatrix)
A,B,C,D = ssdata(sys)
ss(A - B*L - K*C + K*D*L, K, L, 0, sys.timeevol)
end
31 changes: 26 additions & 5 deletions test/test_matrix_comps.jl
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,31 @@ sysi = ControlSystems.innovation_form(sys, sysw=sysw)
40.26132476965486]


# Test innovation form
sysp = ControlSystems.predictor(sys, I(2), I(1))
# Test observer_predictor
sysp = ControlSystems.observer_predictor(sys, I(2), I(1))
K = kalman(sys, I(2), I(1))
@test sysp.A == sys.A-K*sys.C
@test sysp.B == [sys.B K]

end
@test sysp.B == [sys.B-K*sys.D K]


# Test observer_controller
sys = ssrand(2,3,4)
Q1 = I(4)
Q2 = I(3)
R1 = I(4)
R2 = I(2)
L = lqr(sys, Q1, Q2)
K = kalman(sys, R1, R2)
cont = observer_controller(sys, L, K)
syscl = feedback(sys, cont)

pcl = pole(syscl)
A,B,C,D = ssdata(sys)
allpoles = [
eigvals(A-B*L)
eigvals(A-K*C)
]
@test sort(pcl, by=LinearAlgebra.eigsortby) sort(allpoles, by=LinearAlgebra.eigsortby)
@test cont.B == K

end

0 comments on commit b75faea

Please sign in to comment.