Skip to content

Commit e6e5e7f

Browse files
committed
add tests
1 parent 4adfecf commit e6e5e7f

File tree

3 files changed

+76
-9
lines changed

3 files changed

+76
-9
lines changed

Project.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,16 @@ DataInterpolations = "3, 4, 5, 6, 7"
2020
ModelingToolkit = "9.61"
2121
ModelingToolkitStandardLibrary = "2"
2222
MonteCarloMeasurements = "1.1"
23-
OrdinaryDiffEq = "6"
23+
OrdinaryDiffEqRosenbrock = "1.4.0"
2424
RobustAndOptimalControl = "0.4.14"
2525
Symbolics = "5, 6"
2626
UnPack = "1"
2727
julia = "1.6"
2828

2929
[extras]
3030
ControlSystems = "a6e380b2-a6ca-5380-bf3e-84a91bcd477e"
31-
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
31+
OrdinaryDiffEqRosenbrock = "43230ef6-c299-4910-a778-202eb28ce4ce"
3232
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
3333

3434
[targets]
35-
test = ["Test", "ControlSystems", "OrdinaryDiffEq"]
35+
test = ["Test", "ControlSystems", "OrdinaryDiffEqRosenbrock"]

src/ode_system.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,10 +202,9 @@ function RobustAndOptimalControl.named_ss(
202202
matrices, ssys = ModelingToolkit.linearize(sys, inputs, outputs; kwargs...)
203203
symstr(x) = Symbol(x isa AnalysisPoint ? x.name : string(x))
204204
unames = symstr.(inputs)
205-
fm(x) = convert(Matrix{Float64}, x)
206205
if nu > 0 && size(matrices.B, 2) == 2nu
207206
# This indicates that input derivatives are present
208-
duinds = findall(any(!iszero, eachcol(sys.B[:, nu+1:end]))) .+ nu
207+
duinds = findall(any(!iszero, eachcol(matrices.B[:, nu+1:end]))) .+ nu
209208
u2du = (1:nu) .=> duinds # This maps inputs to their derivatives
210209
lsys = causal_simplification(matrices, u2du)
211210
else
@@ -232,6 +231,8 @@ function causal_simplification(sys, u2duinds::Vector{Pair{Int, Int}})
232231
Iu = u_with_du_inds .== (1:nu)'
233232
E = [I(nx) -B̄; zeros(ndu, nx+ndu)]
234233

234+
fm(x) = convert(Matrix{Float64}, x)
235+
235236
Ae = cat(sys.A, -I(ndu), dims=(1,2))
236237
Be = [B; Iu]
237238
Ce = [fm(sys.C) zeros(ny, ndu)]

test/test_ODESystem.jl

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using ControlSystemsMTK,
2-
ControlSystemsBase, ModelingToolkit, OrdinaryDiffEq, RobustAndOptimalControl
2+
ControlSystemsBase, ModelingToolkit, OrdinaryDiffEqRosenbrock, RobustAndOptimalControl
33
import ModelingToolkitStandardLibrary.Blocks as Blocks
44
conn = ModelingToolkit.connect
55
connect = ModelingToolkit.connect
@@ -165,7 +165,7 @@ x0 = Pair[
165165
p = Pair[]
166166

167167
prob = ODEProblem(simplified_sys, x0, (0.0, 20.0), p, jac = true)
168-
sol = solve(prob, OrdinaryDiffEq.Rodas5(), saveat = 0:0.01:20)
168+
sol = solve(prob, Rodas5(), saveat = 0:0.01:20)
169169
if isinteractive()
170170
@show sol.retcode
171171
plot(sol, layout = length(unknowns(simplified_sys)) + 1)
@@ -177,7 +177,7 @@ if isinteractive()
177177
end
178178

179179
## Double-mass model in MTK
180-
using ModelingToolkit, OrdinaryDiffEq, LinearAlgebra
180+
using ModelingToolkit, OrdinaryDiffEqRosenbrock, LinearAlgebra
181181
using ModelingToolkitStandardLibrary.Mechanical.Rotational
182182
using ModelingToolkitStandardLibrary.Blocks: Sine
183183
using ModelingToolkit: connect
@@ -280,4 +280,70 @@ Sn = get_named_sensitivity(sys_outer, [sys_outer.inner.plant_input, sys_outer.in
280280
P = named_ss(ssrand(1,1,1), u=:jörgen, y=:solis)
281281
@named Pode = ODESystem(P)
282282
ModelingToolkit.isconnector(Pode.jörgen)
283-
ModelingToolkit.isconnector(Pode.solis)
283+
ModelingToolkit.isconnector(Pode.solis)
284+
285+
286+
287+
## Test causal simplification
288+
using LinearAlgebra
289+
using ModelingToolkit
290+
using ModelingToolkitStandardLibrary
291+
using ModelingToolkitStandardLibrary.Blocks
292+
using ModelingToolkitStandardLibrary.Mechanical.MultiBody2D
293+
using ModelingToolkitStandardLibrary.Mechanical.TranslationalPosition
294+
using Test
295+
296+
using ControlSystemsMTK
297+
using ControlSystemsMTK.ControlSystemsBase: sminreal, minreal, poles
298+
connect = ModelingToolkit.connect
299+
300+
@independent_variables t
301+
D = Differential(t)
302+
303+
@named link1 = Link(; m = 0.2, l = 10, I = 1, g = -9.807)
304+
@named cart = TranslationalPosition.Mass(; m = 1, s = 0)
305+
@named fixed = Fixed()
306+
@named force = Force(use_support = false)
307+
308+
eqs = [connect(link1.TX1, cart.flange)
309+
connect(cart.flange, force.flange)
310+
connect(link1.TY1, fixed.flange)]
311+
312+
@named model = ODESystem(eqs, t, [], []; systems = [link1, cart, force, fixed])
313+
lin_outputs = [cart.s, cart.v, link1.A, link1.dA]
314+
lin_inputs = [force.f.u]
315+
316+
# => nothing to remove extra defaults
317+
op = Dict(cart.s => 10, cart.v => 0, link1.A => -pi/2, link1.dA => 0, force.f.u => 0, link1.x1 => nothing, link1.y1 => nothing, link1.x2 => nothing, link1.x_cm => nothing)
318+
G = named_ss(model, lin_inputs, lin_outputs; allow_symbolic = true, op,
319+
allow_input_derivatives = true, zero_dummy_der = true)
320+
G = sminreal(G)
321+
@info "minreal"
322+
G = minreal(G)
323+
@info "poles"
324+
ps = poles(G)
325+
326+
@test minimum(abs, ps) < 1e-6
327+
@test minimum(abs, complex(0, 1.3777260367206716) .- ps) < 1e-10
328+
329+
lsys, syss = linearize(model, lin_inputs, lin_outputs, op = op,
330+
allow_input_derivatives = true)
331+
lsyss, sysss = ModelingToolkit.linearize_symbolic(model, lin_inputs, lin_outputs;
332+
allow_input_derivatives = true)
333+
334+
dummyder = setdiff(unknowns(sysss), unknowns(model))
335+
# op2 = merge(ModelingToolkit.guesses(model), op, Dict(x => 0.0 for x in dummyder))
336+
op2 = merge(ModelingToolkit.defaults(syss), op)
337+
op2[link1.fy1] = -op2[link1.g] * op2[link1.m]
338+
op2[cart.f] = 0
339+
340+
@test substitute(lsyss.A, op2) lsys.A
341+
# We cannot pivot symbolically, so the part where a linear solve is required
342+
# is not reliable.
343+
@test substitute(lsyss.B, op2)[1:6, 1] lsys.B[1:6, 1]
344+
@test substitute(lsyss.C, op2) lsys.C
345+
@test substitute(lsyss.D, op2) lsys.D
346+
347+
@test G.nx == 4
348+
@test G.nu == length(lin_inputs)
349+
@test G.ny == length(lin_outputs)

0 commit comments

Comments
 (0)