Skip to content

Commit 7addea4

Browse files
authored
generalize ff_controller and extended_controller to accept any system (#128)
* generalize `ff_controller` to accept any system * generalize also extended controller
2 parents 7bab236 + a2b5d53 commit 7addea4

File tree

2 files changed

+25
-10
lines changed

2 files changed

+25
-10
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "RobustAndOptimalControl"
22
uuid = "21fd56a4-db03-40ee-82ee-a87907bee541"
33
authors = ["Fredrik Bagge Carlson", "Marcus Greiff"]
4-
version = "0.4.44"
4+
version = "0.4.45"
55

66
[deps]
77
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"

src/lqg.jl

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ function extended_controller(K::AbstractStateSpace)
271271
end
272272

273273
"""
274+
extended_controller(P::StateSpace, L, K; z = nothing)
274275
extended_controller(l::LQGProblem, L = lqr(l), K = kalman(l); z = nothing)
275276
276277
Returns a statespace system representing the controller that is obtained when state-feedback `u = L(xᵣ-x̂)` is combined with a Kalman filter with gain `K` that produces state estimates x̂. The controller is an instance of `ExtendedStateSpace` where `C2 = -L, D21 = L` and `B2 = K`.
@@ -291,8 +292,7 @@ system_mapping(Ce) == -C
291292
292293
Please note, without the reference pre-filter, the DC gain from references to controlled outputs may not be identity. If a vector of output indices is provided through the keyword argument `z`, the closed-loop system from state reference `xᵣ` to outputs `z` is returned as a second return argument. The inverse of the DC-gain of this closed-loop system may be useful to compensate for the DC-gain of the controller.
293294
"""
294-
function extended_controller(l::LQGProblem, L::AbstractMatrix = lqr(l), K::AbstractMatrix = kalman(l); z::Union{Nothing, AbstractVector} = nothing)
295-
P = system_mapping(l, identity)
295+
function extended_controller(P::AbstractStateSpace, L::AbstractMatrix, K::AbstractMatrix; z::Union{Nothing, AbstractVector} = nothing)
296296
A,B,C,D = ssdata(P)
297297
Ac = A - B*L - K*C + K*D*L # 8.26b
298298
(; nx, nu, ny) = P
@@ -302,7 +302,7 @@ function extended_controller(l::LQGProblem, L::AbstractMatrix = lqr(l), K::Abstr
302302
D21 = L # L*xᵣ # should be D21?
303303
C2 = -L # - L*x̂
304304
C1 = zeros(0, nx)
305-
Ce0 = ss(Ac, B1, B2, C1, C2; D21, Ts = l.timeevol)
305+
Ce0 = ss(Ac, B1, B2, C1, C2; D21, Ts = P.timeevol)
306306
if z === nothing
307307
return Ce0
308308
end
@@ -313,6 +313,11 @@ function extended_controller(l::LQGProblem, L::AbstractMatrix = lqr(l), K::Abstr
313313
end
314314

315315

316+
function extended_controller(l::LQGProblem, L::AbstractMatrix = lqr(l), K::AbstractMatrix = kalman(l); kwargs...)
317+
P = system_mapping(l, identity)
318+
extended_controller(P, L, K; kwargs...)
319+
end
320+
316321
"""
317322
observer_controller(l::LQGProblem, L = lqr(l), K = kalman(l))
318323
@@ -349,13 +354,15 @@ function ControlSystemsBase.observer_controller(l::LQGProblem, L::AbstractMatrix
349354
ss(Ac, Bc, Cc, Dc, l.timeevol)
350355
end
351356

357+
352358
"""
359+
ff_controller(sys, L, K; comp_dc = true)
353360
ff_controller(l::LQGProblem, L = lqr(l), K = kalman(l))
354361
355362
Return the feedforward controller ``C_{ff}`` that maps references to plant inputs:
356363
``u = C_{fb}y + C_{ff}r``
357364
358-
The following should hold
365+
The following should hold for an LQGProblem `l`:
359366
```
360367
Cff = RobustAndOptimalControl.ff_controller(l)
361368
Cfb = observer_controller(l)
@@ -367,21 +374,29 @@ Note, if [`extended_controller`](@ref) is used, the DC-gain compensation above c
367374
368375
See also [`observer_controller`](@ref).
369376
"""
370-
function ff_controller(l::LQGProblem, L = lqr(l), K = kalman(l); comp_dc = true)
371-
Ae,Be,Ce,De = ssdata(system_mapping(l, identity))
377+
function ff_controller(sys::AbstractStateSpace, L, K, Lr = nothing; comp_dc = true)
378+
Ae,Be,Ce,De = ssdata(sys)
372379
Ac = Ae - Be*L - K*Ce + K*De*L # 8.26c
373380
Cc = L
374381
Dc = 0
375382
if comp_dc
376-
Lr = static_gain_compensation(l, L)
383+
if Lr === nothing
384+
Cfb = observer_controller(sys, L, K)
385+
Cff0 = ss(I(sys.nu), sys.timeevol) - ss(Ac, Be, Cc, Dc, sys.timeevol)
386+
Lr = pinv(dcgain(feedback(sys, Cfb)*Cff0))
387+
end
377388
Bc = Be*Lr
378-
return Lr - ss(Ac, Bc, Cc, Dc, l.timeevol)
389+
return Lr - ss(Ac, Bc, Cc, Dc, sys.timeevol)
379390
else
380391
Bc = Be
381-
return I(size(Cc, 1)) - ss(Ac, Bc, Cc, Dc, l.timeevol)
392+
return I(size(Cc, 1)) - ss(Ac, Bc, Cc, Dc, sys.timeevol)
382393
end
383394
end
384395

396+
function ff_controller(l::LQGProblem, L = lqr(l), K = kalman(l); kwargs...)
397+
ff_controller(system_mapping(l, identity), L, K, static_gain_compensation(l, L); kwargs...)
398+
end
399+
385400
"""
386401
closedloop(l::LQGProblem, L = lqr(l), K = kalman(l))
387402

0 commit comments

Comments
 (0)