Skip to content

Commit

Permalink
Merge branch 'master' of github.com:JuliaControl/RobustAndOptimalCont…
Browse files Browse the repository at this point in the history
…rol.jl
  • Loading branch information
baggepinnen committed Oct 12, 2023
2 parents 2187e7d + 0ec8517 commit 2968fbc
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 40 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "RobustAndOptimalControl"
uuid = "21fd56a4-db03-40ee-82ee-a87907bee541"
authors = ["Fredrik Bagge Carlson", "Marcus Greiff"]
version = "0.4.28"
version = "0.4.29"

[deps]
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
Expand Down
79 changes: 40 additions & 39 deletions src/named_systems2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -380,18 +380,45 @@ end

ControlSystemsBase.feedback(s1::NamedStateSpace{T}, s2::AbstractStateSpace{T}; kwargs...) where {T <: CS.TimeEvolution} = feedback(s1, named_ss(s2); kwargs...)

function connect(systems; u1::Vector{Symbol}, y1::Vector{Symbol}, w1, z1 = (:), verbose = true, kwargs...)
full = append(systems...)
@assert length(y1) == length(u1)
@check_unique u1 "Connected inputs not unique. If you want to connect several signals to the same input, use a summation node, e.g., named_ss(ss([1 1]), u=[:u1, :u2], y=:usum)"
@check_unique full.u "system inputs"
@check_unique full.y "system outputs"

if verbose
leftover_inputs = setdiff(full.u, [u1; w1])
isempty(leftover_inputs) || @warn("The following inputs were unconnected $leftover_inputs, ignore this warning if you rely on prefix matching")
leftover_outputs = setdiff(full.y, z1 == (:) ? y1 : [y1; z1])
isempty(leftover_outputs) || @warn("The following outputs were unconnected $leftover_outputs, ignore this warning if you rely on prefix matching")
end


z2 = []
w2 = []

# Connections
y2 = (:)
u2 = (:)

fb = named_ss(ss(I(length(y1)), full.timeevol))
G = feedback(full, fb; z1, z2, w1, w2, u1, u2, y1, y2, pos_feedback=true, kwargs...)
end


"""
connect(systems, connections; w1, z1 = (:), verbose = true, kwargs...)
Create complicated feedback interconnection.
Create block connections using named inputs and outputs.
Addition and subtraction nodes are achieved by creating a linear combination node, i.e., a system with a `D` matrix only.
# Arguments:
- `systems`: A vector of named systems to be connected
- `connections`: a vector of pairs indicating output => input mappings. Each pair in this vector maps an output to an input. Each output must appear as an output in one of `systems`, and similarly each input must appear as an input in one of `systems`. All outputs must have unique names, but an input may have the same name as an output, this is used below where several connections look like this `:uP => :uP` since `:uP` is the output of the `addP` block but also the input of `P`.
- `w1`: external signals that appear as inputs in the constructed system, `:uF` in the example below, use `(:)` to indicate all signals
- `z1`: outputs of the constructed system(can overlap with `y1`), use `(:)` to indicate all signals
- `connections`: a vector of pairs output => input, where each pair maps an output to an input. Each output must appear as an output in one of `systems`, and similarly each input must appear as an input in one of `systems`. All inputs must have unique names and so must all outputs, but an input may have the same name as an output. In the example below the connection `:uP => :uP` connects the output `:uP` of the `addP` block to `P`'s input `:uP`
- `w1`: external signals to be used as inputs in the constructed system. Use `(:)` to indicate all signals
- `z1`: outputs of the constructed system. Use `(:)` to indicate all signals
- `verbose`: Issue warnings for signals that have no connection
Note: Positive feedback is used, controllers that are intended to be connected with negative feedback must thus be negated.
Expand All @@ -401,15 +428,15 @@ The following complicated feedback interconnection
```
yF
┌────────────────────────────────┐
│ │
┌───────┐ │ ┌───────┐ yR ┌─────────┐ │ ┌───────┐
uF │ │ │ │ ├──────► │ yC │ uP│ │ yP
────► F ├─┴──► R │ C ├────+────► P ├───┬────►
│ │ │ │ ┌──► │ │ │
└───────┘ └───────┘ │ └─────────┘ └───────┘
└───────────────────────────────────┘
┌────────────────────────────────┐
│ │
┌───────┐ │ ┌───────┐ ───────┐ │ ┌───────┐
uF │ │ │ │ | yR │ yC │ uP │ │ yP
────► F ├─┴──► R │────+───► C ├────+────► P ├───┬────►
│ │ │ │ │ │ │ │
└───────┘ └───────┘ └───────┘ └───────┘ │
─────────────────────────────────┘
```
can be created by
```
Expand Down Expand Up @@ -437,32 +464,6 @@ G = connect([F, R, C, P, addP, addC], connections; w1)
If an external input is to be connected to multiple points, use a `splitter` to split up the signal into a set of unique names which are then used in the connections.
"""
function connect(systems; u1::Vector{Symbol}, y1::Vector{Symbol}, w1, z1 = (:), verbose = true, kwargs...)
full = append(systems...)
@assert length(y1) == length(u1)
@check_unique u1 "Connected inputs not unique. If you want to connect several signals to the same input, use a summation node, e.g., named_ss(ss([1 1]), u=[:u1, :u2], y=:usum)"
@check_unique full.u "system inputs"
@check_unique full.y "system outputs"

if verbose
leftover_inputs = setdiff(full.u, [u1; w1])
isempty(leftover_inputs) || @warn("The following inputs were unconnected $leftover_inputs, ignore this warning if you rely on prefix matching")
leftover_outputs = setdiff(full.y, z1 == (:) ? y1 : [y1; z1])
isempty(leftover_outputs) || @warn("The following outputs were unconnected $leftover_outputs, ignore this warning if you rely on prefix matching")
end


z2 = []
w2 = []

# Connections
y2 = (:)
u2 = (:)

fb = named_ss(ss(I(length(y1)), full.timeevol))
G = feedback(full, fb; z1, z2, w1, w2, u1, u2, y1, y2, pos_feedback=true, kwargs...)
end

function connect(systems, pairs::AbstractVector{<:Pair}; kwargs...)
connect(systems; u1 = last.(pairs), y1 = first.(pairs), kwargs...)
end
Expand Down

0 comments on commit 2968fbc

Please sign in to comment.