Skip to content

Commit 0937cc6

Browse files
committed
fixes in batchlin
1 parent dc8833f commit 0937cc6

File tree

4 files changed

+17
-9
lines changed

4 files changed

+17
-9
lines changed

docs/Project.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
66
ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78"
77
ModelingToolkitStandardLibrary = "16a59e39-deab-5bd0-87e4-056b12336739"
88
MonteCarloMeasurements = "0987c9cc-fe09-11e8-30f0-b96dd679fdca"
9-
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
9+
OrdinaryDiffEqNonlinearSolve = "127b3ac7-2247-4354-8eb6-78cf4e7c58e8"
10+
OrdinaryDiffEqRosenbrock = "43230ef6-c299-4910-a778-202eb28ce4ce"
1011
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
1112
RobustAndOptimalControl = "21fd56a4-db03-40ee-82ee-a87907bee541"
1213
SymbolicControlSystems = "886cb795-8fd3-4b11-92f6-8071e46f71c5"

docs/src/batch_linearization.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ If you plot the Nyquist curve using the `plotly()` backend rather than the defau
9696
Above, we tuned one controller for each operating point, wouldn't it be nice if we had some features to simulate a [gain-scheduled controller](https://en.wikipedia.org/wiki/Gain_scheduling) that interpolates between the different controllers depending on the operating pont? [`GainScheduledStateSpace`](@ref) is such a thing, we show how to use it below. For fun, we simulate some reference step responses for each individual controller in the array `Cs` and end with simulating the gain-scheduled controller.
9797

9898
```@example BATCHLIN
99-
using OrdinaryDiffEq
99+
using OrdinaryDiffEqNonlinearSolve, OrdinaryDiffEqRosenbrock
100100
using DataInterpolations # Required to interpolate between the controllers
101101
@named fb = Blocks.Add(k2=-1)
102102
@named ref = Blocks.Square(frequency=1/6, amplitude=0.5, offset=0.5, start_time=1)
@@ -134,7 +134,7 @@ eqs = [
134134
]
135135
@named closed_loop = ODESystem(eqs, t, systems=[duffing, Cgs, fb, ref, F])
136136
prob = ODEProblem(structural_simplify(closed_loop), [F.xd => 0], (0.0, 8.0))
137-
sol = solve(prob, Rodas5P(), abstol=1e-8, reltol=1e-8, initializealg=NoInit())
137+
sol = solve(prob, Rodas5P(), abstol=1e-8, reltol=1e-8, initializealg=SciMLBase.NoInit())
138138
plot!(sol, idxs=[duffing.y.u, duffing.u.u], l=(2, :red), lab="Gain scheduled")
139139
plot!(sol, idxs=F.output.u, l=(1, :black, :dash, 0.5), lab="Ref")
140140
```

src/ode_system.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,8 @@ Linearize `sys` around the trajectory `sol` at times `t`. Returns a vector of `S
523523
function trajectory_ss(sys, inputs, outputs, sol; t = _max_100(sol.t), allow_input_derivatives = false, fuzzer = nothing, verbose = true, kwargs...)
524524
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)).")
525525
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)).")
526+
527+
# NOTE: we call linearization_funciton twice :( The first call is to get x=unknowns(ssys), the second call provides the operating points.
526528
lin_fun, ssys = linearization_function(sys, inputs, outputs; kwargs...)
527529
x = unknowns(ssys)
528530
defs = ModelingToolkit.defaults(sys)
@@ -536,8 +538,10 @@ function trajectory_ss(sys, inputs, outputs, sol; t = _max_100(sol.t), allow_inp
536538
ops = reduce(vcat, opsv)
537539
t = repeat(t, inner = length(ops) ÷ length(t))
538540
end
541+
lin_fun, ssys = linearization_function(sys, inputs, outputs; op=ops[1], kwargs...)
539542
lins = map(zip(ops, t)) do (op, t)
540543
linearize(ssys, lin_fun; op, t, allow_input_derivatives)
544+
# linearize(sys, inputs, outputs; op, t, allow_input_derivatives, initialize=false)[1]
541545
end
542546
(; linsystems = [ss(l...) for l in lins], ssys, ops)
543547
end

test/test_batchlin.jl

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using ControlSystemsMTK, ModelingToolkit, RobustAndOptimalControl, MonteCarloMeasurements
22
using OrdinaryDiffEqNonlinearSolve, OrdinaryDiffEqRosenbrock
3+
using ModelingToolkitStandardLibrary.Blocks
34
using ModelingToolkit: getdefault
5+
using Test
46
unsafe_comparisons(true)
57

68
# Create a model
@@ -24,7 +26,7 @@ sample_within_bounds((l, u)) = (u - l) * rand() + l
2426
# Create a vector of operating points
2527
N = 10
2628
xs = range(getbounds(x)[1], getbounds(x)[2], length=N)
27-
ops = Dict.(x .=> xs)
29+
ops = Dict.(u.u => 0, x .=> xs)
2830

2931
inputs, outputs = [u.u], [y.u]
3032
Ps, ssys = batch_ss(duffing, inputs, outputs , ops)
@@ -55,11 +57,11 @@ import ModelingToolkitStandardLibrary.Blocks
5557

5658

5759
closed_loop_eqs = [
58-
connect(ref.output, :r, F.input)
59-
connect(F.output, fb.input1)
60-
connect(duffing.y, :y, fb.input2)
61-
connect(fb.output, C.input)
62-
connect(C.output, duffing.u)
60+
ModelingToolkit.connect(ref.output, :r, F.input)
61+
ModelingToolkit.connect(F.output, fb.input1)
62+
ModelingToolkit.connect(duffing.y, :y, fb.input2)
63+
ModelingToolkit.connect(fb.output, C.input)
64+
ModelingToolkit.connect(C.output, duffing.u)
6365
]
6466

6567
@named closed_loop = ODESystem(closed_loop_eqs, t, systems=[duffing, C, fb, ref, F])
@@ -73,6 +75,7 @@ sol = solve(prob, Rodas5P(), abstol=1e-8, reltol=1e-8)
7375

7476
time = 0:0.1:8
7577
inputs, outputs = [duffing.u.u], [duffing.y.u]
78+
op = Dict(u.u => 0)
7679
Ps2, ssys = trajectory_ss(closed_loop, closed_loop.r, closed_loop.y, sol; t=time)
7780
@test length(Ps2) == length(time)
7881
# bodeplot(Ps2)

0 commit comments

Comments
 (0)