Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 33 additions & 7 deletions docs/src/man/creating_systems.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Continuous-time transfer function model
```

The transfer functions created using this method will be of type `TransferFunction{SisoRational}`.
For more general expressions, it is often more convenient to define `s = tf("s")`:
For more general expressions, it is sometimes more convenient to define `s = tf("s")` (only use this approach for low-order systems).:
#### Example:
```julia
julia> s = tf("s")
Expand Down Expand Up @@ -295,10 +295,10 @@ The returned closed-loop system will have a state vector comprised of the state
---
Closed-loop system from reference to output
```
r ┌─────┐ ┌─────┐
───►│ │ u │ │ y
│ C ├────►│ P ├─┬─►
-┌►│ │ │ │ │
┌─────┐ ┌─────┐
r │ │ u │ │ y
──+►│ C ├────►│ P ├─┬─►
-│ │ │ │ │
│ └─────┘ └─────┘ │
│ │
└─────────────────────┘
Expand Down Expand Up @@ -396,6 +396,32 @@ Here, we have reversed the order of `P` and `C` to get the correct sign of the c

---

Two degree of freedom control system with feedforward ``F`` and feedback controller ``C``

```
+-------+
| |
+-----> F +----+
| | | |
| +-------+ |
| +-------+ | +-------+
r | - | | | | | y
+--+-----> C +----+----> P +---+-->
| | | | | |
| +-------+ +-------+ |
| |
+--------------------------------+
```

```math
Y = (F+C)\dfrac{P}{I + PC}R
```

Code: `feedback(P,C)*(F+C)` or `feedback2dof(P, C, F)`
- [`feedback2dof`](@ref)

---

Linear fractional transformation

```
Expand Down Expand Up @@ -445,9 +471,9 @@ I & P
w_1 \\ w_2
\end{bmatrix}
```
Code: This function requires the package [RobustAndOptimalControl.jl](https://juliacontrol.github.io/RobustAndOptimalControl.jl/dev/).
Code:
```julia
RobustAndOptimalControl.extended_gangoffour(P, C, pos=true)
extended_gangoffour(P, C, pos=true)
# For SISO P
S = G[1, 1]
PS = G[1, 2]
Expand Down
20 changes: 16 additions & 4 deletions lib/ControlSystemsBase/src/connections.jl
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,14 @@
if !(isa(Y2, Colon) || allunique(Y2)); @warn "Connecting single output to multiple inputs Y2=$Y2"; end
if !(isa(U1, Colon) || allunique(U1)); @warn "Connecting multiple outputs to a single input U1=$U1"; end
if !(isa(U2, Colon) || allunique(U2)); @warn "Connecting a single output to multiple inputs U2=$U2"; end
U1 isa Number && (U1 = [U1])
Y1 isa Number && (Y1 = [Y1])
U2 isa Number && (U2 = [U2])
Y2 isa Number && (Y2 = [Y2])
W1 isa Number && (W1 = [W1])
Z1 isa Number && (Z1 = [Z1])
W2 isa Number && (W2 = [W2])
Z2 isa Number && (Z2 = [Z2])

if (U1 isa Colon ? size(sys1, 2) : length(U1)) != (Y2 isa Colon ? size(sys2, 1) : length(Y2))
error("Lengths of U1 ($U1) and Y2 ($Y2) must be equal")
Expand Down Expand Up @@ -394,13 +402,13 @@
R1 = try
inv(α*I - s2_D22*s1_D22) # slightly faster than α*inv(I - α*s2_D22*s1_D22)
catch
error("Ill-posed feedback interconnection, I - α*s2_D22*s1_D22 or I - α*s2_D22*s1_D22 not invertible")
error("Ill-posed feedback interconnection, I - α*s2_D22*s1_D22 not invertible")

Check warning on line 405 in lib/ControlSystemsBase/src/connections.jl

View check run for this annotation

Codecov / codecov/patch

lib/ControlSystemsBase/src/connections.jl#L405

Added line #L405 was not covered by tests
end

R2 = try
inv(I - α*s1_D22*s2_D22)
catch
error("Ill-posed feedback interconnection, I - α*s2_D22*s1_D22 or I - α*s2_D22*s1_D22 not invertible")
error("Ill-posed feedback interconnection, I - α*s1_D22*s2_D22 not invertible")

Check warning on line 411 in lib/ControlSystemsBase/src/connections.jl

View check run for this annotation

Codecov / codecov/patch

lib/ControlSystemsBase/src/connections.jl#L411

Added line #L411 was not covered by tests
end

s2_B2R2 = s2_B2*R2
Expand Down Expand Up @@ -442,7 +450,7 @@
feedback2dof(B,A,R,S,T) = tf(conv(B,T),zpconv(A,R,B,S))

"""
feedback2dof(P::TransferFunction, C::TransferFunction, F::TransferFunction)
feedback2dof(P, C, F)

Return the transfer function
`P(F+C)/(1+PC)`
Expand All @@ -463,7 +471,7 @@
```
"""
function feedback2dof(P::TransferFunction{TE}, C::TransferFunction{TE}, F::TransferFunction{TE}) where TE
!issiso(P) && error("Feedback not implemented for MIMO systems")
issiso(P) || return tf(feedback2dof(ss(P), ss(C), ss(F)))
timeevol = common_timeevol(P, C, F)

Pn,Pd = numpoly(P)[], denpoly(P)[]
Expand All @@ -473,6 +481,10 @@
tf(Cd*Pn*Fn + Pn*Cn*Fd, den, timeevol)
end

function feedback2dof(P,C,F)
feedback(P,C)*(F+C)
end

"""
lft(G, Δ, type=:l)

Expand Down
5 changes: 3 additions & 2 deletions lib/ControlSystemsBase/src/pid_design.jl
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,9 @@ The `form` can be chosen as one of the following (determines how the arguments `
This controller has negative feedback built in, and the closed-loop system from `r` to `y` is thus formed as
```
Cr, Cy = C[1, 1], C[1, 2]
feedback(P, Cy, pos_feedback=true)*Cr # Alternative 1
feedback(P, -Cy)*Cr # Alternative 2
feedback(P, Cy, pos_feedback=true)*Cr # Alternative 1
feedback(P, -Cy)*Cr # Alternative 2
feedback(P, C, U2=2, W2=1, W1=[], pos_feedback=true) # Alternative 3, less pretty but more efficient, returns smaller realization
```
"""
function pid_2dof(args...; state_space = true, Ts = nothing, disc = :tustin, kwargs...)
Expand Down
2 changes: 1 addition & 1 deletion lib/ControlSystemsBase/src/sensitivity_functions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ T = G[P.ny+1:end, P.ny+1:end] # Input complimentary sensitivity function
The gang of four can be plotted like so
```julia
Gcl = extended_gangoffour(G, C) # Form closed-loop system
bodeplot(Gcl, lab=["S" "CS" "PS" "T"], plotphase=false) |> display # Plot gang of four
bodeplot(Gcl, lab=["S" "PS" "CS" "T"], plotphase=false) |> display # Plot gang of four
```
Note, the last input of Gcl is the negative of the `PS` and `T` transfer functions from `gangoffour2`. To get a transfer matrix with the same sign as [`G_PS`](@ref) and [`input_comp_sensitivity`](@ref), call `extended_gangoffour(P, C, pos=false)`.
See `glover_mcfarlane` from RobustAndOptimalControl.jl for an extended example. See also `ncfmargin` and `feedback_control` from RobustAndOptimalControl.jl.
Expand Down
2 changes: 2 additions & 0 deletions lib/ControlSystemsBase/test/test_connections.jl
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ F = tf(1.0, [1,1])
@test feedback2dof(P0, C, 0*F) == feedback(P0*C)
@test_nowarn feedback2dof(P0, C, F)

C = pid(1, 0, 1, form=:parallel)
hinfnorm(minreal(feedback2dof(ss(P0), ss(C*F), ss(F)) - feedback2dof(P0, C*F, F)))[1] < 1e-8


G1 = tf([1, 0],[1, 2, 2])
Expand Down
Loading