@@ -349,13 +349,15 @@ function ControlSystemsBase.observer_controller(l::LQGProblem, L::AbstractMatrix
349349 ss (Ac, Bc, Cc, Dc, l. timeevol)
350350end
351351
352+
352353"""
354+ ff_controller(sys, L, K; comp_dc = true)
353355 ff_controller(l::LQGProblem, L = lqr(l), K = kalman(l))
354356
355357Return the feedforward controller ``C_{ff}`` that maps references to plant inputs:
356358``u = C_{fb}y + C_{ff}r``
357359
358- The following should hold
360+ The following should hold for an LQGProblem `l`:
359361```
360362Cff = RobustAndOptimalControl.ff_controller(l)
361363Cfb = observer_controller(l)
@@ -367,21 +369,28 @@ Note, if [`extended_controller`](@ref) is used, the DC-gain compensation above c
367369
368370See also [`observer_controller`](@ref).
369371"""
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) )
372+ function ff_controller (sys :: AbstractStateSpace , L, K, Lr = nothing ; comp_dc = true )
373+ Ae,Be,Ce,De = ssdata (sys )
372374 Ac = Ae - Be* L - K* Ce + K* De* L # 8.26c
373375 Cc = L
374376 Dc = 0
375377 if comp_dc
376- Lr = static_gain_compensation (l, L)
378+ if Lr === nothing
379+ Cfb = observer_controller (sys, L, K)
380+ Lr = pinv (dcgain (feedback (sys* Cfb)))
381+ end
377382 Bc = Be* Lr
378- return Lr - ss (Ac, Bc, Cc, Dc, l . timeevol)
383+ return Lr - ss (Ac, Bc, Cc, Dc, sys . timeevol)
379384 else
380385 Bc = Be
381- return I (size (Cc, 1 )) - ss (Ac, Bc, Cc, Dc, l . timeevol)
386+ return I (size (Cc, 1 )) - ss (Ac, Bc, Cc, Dc, sys . timeevol)
382387 end
383388end
384389
390+ function ff_controller (l:: LQGProblem , L = lqr (l), K = kalman (l); kwargs... )
391+ ff_controller (system_mapping (l, identity), L, K, static_gain_compensation (l, L); kwargs... )
392+ end
393+
385394"""
386395 closedloop(l::LQGProblem, L = lqr(l), K = kalman(l))
387396
0 commit comments