@@ -104,7 +104,7 @@ function RobustAndOptimalControl.named_ss(
104104 out
105105 end
106106 end
107- matrices, ssys = ModelingToolkit. linearize (sys, inputs, outputs; kwargs... )
107+ matrices, ssys, xpt = ModelingToolkit. linearize (sys, inputs, outputs; kwargs... )
108108 symstr (x) = Symbol (x isa AnalysisPoint ? x. name : string (x))
109109 unames = symstr .(inputs)
110110 if nu > 0 && size (matrices. B, 2 ) == 2 nu
@@ -115,12 +115,19 @@ function RobustAndOptimalControl.named_ss(
115115 else
116116 lsys = ss (matrices... )
117117 end
118+ pind = [ModelingToolkit. parameter_index (ssys, i) for i in ModelingToolkit. inputs (ssys)]
119+ x0 = xpt. x
120+ u0 = [xpt. p[pi ] for pi in pind]
121+ xu = (; x = x0, u = u0)
122+ extra = Dict (:operating_point => xu)
123+
118124 named_ss (
119125 lsys;
120126 x = symstr .(unknowns (ssys)),
121127 u = unames,
122128 y = symstr .(outputs),
123129 name = string (Base. nameof (sys)),
130+ extra,
124131 )
125132end
126133
@@ -300,7 +307,7 @@ The second problem above, the ordering of the states, can be worked around using
300307- `costs`: A vector of pairs.
301308"""
302309function build_quadratic_cost_matrix (sys:: System , inputs:: AbstractVector , costs:: AbstractVector{<:Pair} ; kwargs... )
303- matrices, ssys = ModelingToolkit. linearize (sys, inputs, first .(costs); kwargs... )
310+ matrices, ssys, extras = ModelingToolkit. linearize (sys, inputs, first .(costs); kwargs... )
304311 x = ModelingToolkit. unknowns (ssys)
305312 y = ModelingToolkit. outputs (ssys)
306313 nx = length (x)
@@ -323,10 +330,12 @@ function batch_linearize(sys, inputs, outputs, ops::AbstractVector{<:AbstractDic
323330 allow_input_derivatives = false ,
324331 kwargs... )
325332 lin_fun, ssys = linearization_function (sys, inputs, outputs; op= ops[1 ], kwargs... )
326- lins = map (ops) do op
333+ lins_ops = map (ops) do op
327334 linearize (ssys, lin_fun; op, t, allow_input_derivatives)
328335 end
329- lins, ssys
336+ lins = first .(lins_ops)
337+ resolved_ops = last .(lins_ops)
338+ lins, ssys, resolved_ops
330339end
331340
332341"""
@@ -404,8 +413,8 @@ nyquistcircles!(w, centers, radii, ylims = (-4, 1), xlims = (-3, 4))
404413See also [`trajectory_ss`](@ref) and [`fuzz`](@ref).
405414"""
406415function batch_ss (args... ; kwargs... )
407- lins, ssys = batch_linearize (args... ; kwargs... )
408- [ss (l... ) for l in lins], ssys
416+ lins, ssys, resolved_ops = batch_linearize (args... ; kwargs... )
417+ [ss (l... ) for l in lins], ssys, resolved_ops
409418end
410419
411420"""
@@ -422,18 +431,22 @@ Linearize `sys` around the trajectory `sol` at times `t`. Returns a vector of `S
422431- `verbose`: If `true`, print warnings for variables that are not found in `sol`.
423432- `kwargs`: Are sent to the linearization functions.
424433"""
425- function trajectory_ss (sys, inputs, outputs, sol; t = _max_100 (sol. t), allow_input_derivatives = false , fuzzer = nothing , verbose = true , kwargs... )
434+ function trajectory_ss (sys, inputs, outputs, sol; t = _max_100 (sol. t), allow_input_derivatives = false , fuzzer = nothing , verbose = true ,kwargs... )
426435 maximum (t) > maximum (sol. t) && @warn (" The maximum time in `t`: $(maximum (t)) , is larger than the maximum time in `sol.t`: $(maximum (sol. t)) ." )
427436 minimum (t) < minimum (sol. t) && @warn (" The minimum time in `t`: $(minimum (t)) , is smaller than the minimum time in `sol.t`: $(minimum (sol. t)) ." )
428437 # NOTE: we call linearization_funciton twice :( The first call is to get x=unknowns(ssys), the second call provides the operating points.
429438 # lin_fun, ssys = linearization_function(sys, inputs, outputs; warn_initialize_determined = false, kwargs...)
430439 lin_fun, ssys = linearization_function (sys, inputs, outputs; warn_empty_op = false , warn_initialize_determined = false , kwargs... )
431-
432440 x = unknowns (ssys)
441+
442+ # TODO : The value of the output (or input) of the input analysis points should be mapped to the perturbation vars
443+ @show perturbation_vars = ModelingToolkit. inputs (ssys)
444+ # original_inputs = [ap.input.u for ap in vcat(inputs)] # assuming all inputs are analysis points for now
433445 op_nothing = Dict (unknowns (sys) .=> nothing ) # Remove all defaults present in the original system
434446 defs = ModelingToolkit. defaults (sys)
435447 ops = map (t) do ti
436448 opsol = Dict (x => robust_sol_getindex (sol, ti, x, defs; verbose) for x in x)
449+ # opsolu = Dict(new_u => robust_sol_getindex(sol, ti, u, defs; verbose) for (new_u, u) in zip(perturbation_vars, original_inputs))
437450 merge (op_nothing, opsol)
438451 end
439452 # @show ops[1]
@@ -445,11 +458,13 @@ function trajectory_ss(sys, inputs, outputs, sol; t = _max_100(sol.t), allow_inp
445458 t = repeat (t, inner = length (ops) ÷ length (t))
446459 end
447460 lin_fun, ssys = linearization_function (sys, inputs, outputs; op= ops[1 ], kwargs... ) # initializealg=ModelingToolkit.SciMLBase.NoInit()
448- lins = map (zip (ops, t)) do (op, t)
461+ lins_ops = map (zip (ops, t)) do (op, t)
449462 linearize (ssys, lin_fun; op, t, allow_input_derivatives)
450463 # linearize(sys, inputs, outputs; op, t, allow_input_derivatives, initialize=false)[1]
451464 end
452- (; linsystems = [ss (l... ) for l in lins], ssys, ops)
465+ lins = first .(lins_ops)
466+ resolved_ops = last .(lins_ops)
467+ (; linsystems = [ss (l... ) for l in lins], ssys, ops, resolved_ops)
453468end
454469
455470" _max_100(t) = length(t) > 100 ? range(extrema(t)..., 100) : t"
0 commit comments