Skip to content

Commit a12bb3c

Browse files
committed
add named_ss method
1 parent e7c3e6c commit a12bb3c

File tree

1 file changed

+43
-2
lines changed

1 file changed

+43
-2
lines changed

src/ode_system.jl

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,47 @@ function RobustAndOptimalControl.named_ss(
139139
nsys
140140
end
141141

142+
function RobustAndOptimalControl.named_ss(
143+
sys::ModelingToolkit.AbstractSystem, linfun::ModelingToolkit.LinearizationFunction, outputs;
144+
descriptor = true,
145+
simple_infeigs = true,
146+
balance = descriptor && !simple_infeigs, # balance only if descriptor is true and simple_infeigs is false
147+
big = false,
148+
kwargs...,
149+
)
150+
ssys = sys
151+
matrices, xpt = ModelingToolkit.linearize(sys, linfun; kwargs...)
152+
inputs = linfun.inputs
153+
nu = length(inputs)
154+
unames = symstr.(inputs)
155+
if nu > 0 && size(matrices.B, 2) == 2nu
156+
# This indicates that input derivatives are present
157+
duinds = findall(any(!iszero, eachcol(matrices.B[:, nu+1:end]))) .+ nu
158+
u2du = (1:nu) .=> duinds # This maps inputs to their derivatives
159+
lsys = causal_simplification(matrices, u2du; descriptor, simple_infeigs, big, balance, verbose=false)
160+
else
161+
lsys = ss(matrices...)
162+
end
163+
pind = [ModelingToolkit.parameter_index(ssys, i) for i in ModelingToolkit.inputs(ssys)]
164+
x0 = xpt.x
165+
u0 = [xpt.p[pi] for pi in pind]
166+
xu = (; x = x0, u = u0)
167+
extra = Dict(:operating_point => xu)
168+
# If simple_infeigs=false, the system might have been reduced and the state names might not match the original system.
169+
x_names = get_x_names(lsys, ssys; descriptor, simple_infeigs, balance)
170+
nsys = named_ss(
171+
lsys;
172+
x = x_names,
173+
u = unames,
174+
y = symstr.(outputs),
175+
name = string(Base.nameof(sys)),
176+
extra,
177+
)
178+
RobustAndOptimalControl.set_extra!(nsys, :ssys, ssys)
179+
nsys
180+
181+
end
182+
142183
function get_x_names(lsys, sys; descriptor, simple_infeigs, balance)
143184
generic = if descriptor
144185
!simple_infeigs || balance
@@ -161,7 +202,7 @@ If `descriptor = true`, the function `DescriptorSystems.dss2ss` is used. In this
161202
162203
The argument `big = true` performs computations in `BigFloat` precision, useful for poorly scaled systems. This may require the user to install and load `GenericLinearAlgebra` (if you get error `no method matching svd!(::Matrix{BigFloat})`).
163204
"""
164-
function causal_simplification(sys, u2duinds::Vector{Pair{Int, Int}}; balance=false, descriptor=true, simple_infeigs = true, big = false)
205+
function causal_simplification(sys, u2duinds::Vector{Pair{Int, Int}}; balance=false, descriptor=true, simple_infeigs = true, big = false, verbose = true)
165206
T = big ? BigFloat : Float64
166207
b1 = big ? Base.big(1.0) : 1.0
167208
fm(x) = convert(Matrix{T}, x)
@@ -190,7 +231,7 @@ function causal_simplification(sys, u2duinds::Vector{Pair{Int, Int}}; balance=fa
190231
dsys, T1, T2 = RobustAndOptimalControl.DescriptorSystems.gprescale(dsys)
191232
else
192233
bq = RobustAndOptimalControl.DescriptorSystems.gbalqual(dsys)
193-
bq > 10000 && @warn("The numerical balancing of the system is poor (gbalqual = $bq), consider using `balance=true` to balance the system before conversion to StateSpace to improve accuracy of the result.")
234+
verbose && bq > 10000 && @warn("The numerical balancing of the system is poor (gbalqual = $bq), consider using `balance=true` to balance the system before conversion to StateSpace to improve accuracy of the result.")
194235
end
195236

196237
# NOTE: the conversion implemented in ss(dss) uses gss2ss due to it's initial call to gir to produce a reduced order model and then an SVD-based alg to improve numerics. Should we use this by default?

0 commit comments

Comments
 (0)