Skip to content

Commit 58c2aea

Browse files
committed
add operating point to named ss
1 parent 24651b5 commit 58c2aea

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

src/named_systems2.jl

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,11 @@ struct NamedStateSpace{T,S} <: AbstractStateSpace{T} where S <: AbstractStateSpa
6161
u::Vector{Symbol}
6262
y::Vector{Symbol}
6363
name::String
64+
extra::Dict{Symbol, Any}
6465
end
6566

66-
NamedStateSpace(A,B,C,D,x::AbstractVector,u,y,name::String="") = NamedStateSpace{Continuous, StateSpace{Continuous, eltype(A)}}(ss(A,B,C,D), x, u, y, name)
67-
NamedStateSpace(A,B,C,D,Ts::Number,x,u,y,name::String="") = NamedStateSpace{Discrete{typeof(Ts)}, StateSpace{Discrete{typeof(Ts)}, eltype(A)}}(ss(A,B,C,D,Ts), x, u, y,name)
67+
NamedStateSpace(A,B,C,D,x::AbstractVector,u,y,name::String="",extra=Dict{Symbol,Any}()) = NamedStateSpace{Continuous, StateSpace{Continuous, eltype(A)}}(ss(A,B,C,D), x, u, y, name, extra)
68+
NamedStateSpace(A,B,C,D,Ts::Number,x,u,y,name::String="",extra=Dict{Symbol,Any}()) = NamedStateSpace{Discrete{typeof(Ts)}, StateSpace{Discrete{typeof(Ts)}, eltype(A)}}(ss(A,B,C,D,Ts), x, u, y,name,extra)
6869

6970
# This method is used by the basetype(ST)(A, B, C, D, timeevol) construct
7071
NamedStateSpace(A,B,C,D,te::ControlSystemsBase.TimeEvolution, args...; kwargs...) = named_ss(ss(A,B,C,D,te), args...; kwargs...)
@@ -135,6 +136,22 @@ ControlSystemsBase.system_name(P::NamedStateSpace, i=(:)) = P.name
135136
ControlSystemsBase.input_names(P::NamedStateSpace, i=(:)) = string.(getindex(P.u, i))
136137
ControlSystemsBase.output_names(P::NamedStateSpace, i=(:)) = string.(getindex(P.y, i))
137138
ControlSystemsBase.state_names(P::NamedStateSpace, i=(:)) = string.(getindex(P.x, i))
139+
function get_extra(P::NamedStateSpace, key::Symbol, default)
140+
get(P.extra, key, default)
141+
end
142+
function set_extra!(P::NamedStateSpace, key::Symbol, value)
143+
P.extra[key] = value
144+
return P
145+
end
146+
147+
148+
"""
149+
operating_point(P::NamedStateSpace)
150+
151+
Return a named tuple `(; x, u)` containing the operating point of the system `P`. If no operating point is set, a zero operating point of correct dimension is returned.
152+
"""
153+
operating_point(P::NamedStateSpace) = get_extra(P, :operating_point, (x=zeros(P.nx), u=zeros(P.nu)))
154+
set_operating_point!(P::NamedStateSpace, xu::NamedTuple{(:x,:u)}) = set_extra!(P, :operating_point, xu)
138155

139156
const NamedIndex = Union{Symbol, Vector{Symbol}, Colon}
140157

@@ -193,6 +210,7 @@ function named_ss(sys::AbstractStateSpace{T};
193210
y = :y,
194211
name::String = "",
195212
unique = true,
213+
extra = Dict{Symbol, Any}(),
196214
) where T
197215
if sys isa NamedStateSpace
198216
error("Cannot wrap a named statespace in a named statespace")
@@ -213,7 +231,7 @@ function named_ss(sys::AbstractStateSpace{T};
213231
check_unique(u, "u", "To allow connecting a single input signal to several inputs with the same name, pass `unique = false`.")
214232
end
215233

216-
NamedStateSpace{T, typeof(sys)}(sys, x, u, y, name)
234+
NamedStateSpace{T, typeof(sys)}(sys, x, u, y, name, extra)
217235
end
218236

219237
"""
@@ -226,8 +244,9 @@ function named_ss(sys::AbstractStateSpace, name;
226244
x = Symbol(string(name)*"x"),
227245
y = Symbol(string(name)*"y"),
228246
u = Symbol(string(name)*"u"),
247+
extra = Dict{Symbol, Any}(),
229248
)
230-
named_ss(sys; x, y, u, name=string(name))
249+
named_ss(sys; x, y, u, name=string(name), extra)
231250
end
232251

233252
named_ss(G::LTISystem, args...; kwargs...) = named_ss(ss(G), args...; kwargs...)

test/test_named_systems2.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,16 @@ s12 = [s1; s2; s3]
212212
@test occursin("x1", string(s12.x[5]))
213213
@test occursin("x2", string(s12.x[6]))
214214

215+
216+
op = RobustAndOptimalControl.operating_point(s1)
217+
@test op.x == zeros(s1.nx)
218+
@test op.u == zeros(s1.nu)
219+
220+
opx = randn(s1.nx)
221+
opu = randn(s1.nu)
222+
RobustAndOptimalControl.set_operating_point!(s1, (x = opx, u = opu))
223+
@test RobustAndOptimalControl.operating_point(s1) == (x = opx, u = opu)
224+
215225
## Promotion and conversion
216226
@testset "Promotion and conversion" begin
217227
@info "Testing Promotion and conversion"

0 commit comments

Comments
 (0)