11using ControlSystemsMTK,
2- ControlSystemsBase, ModelingToolkit, OrdinaryDiffEq, RobustAndOptimalControl
2+ ControlSystemsBase, ModelingToolkit, RobustAndOptimalControl
33import ModelingToolkitStandardLibrary. Blocks as Blocks
4+ using OrdinaryDiffEqNonlinearSolve, OrdinaryDiffEqRosenbrock
45conn = ModelingToolkit. connect
56connect = ModelingToolkit. connect
67# # Test SISO (single input, single output) system
@@ -165,7 +166,7 @@ x0 = Pair[
165166p = Pair[]
166167
167168prob = ODEProblem (simplified_sys, x0, (0.0 , 20.0 ), p, jac = true )
168- sol = solve (prob, OrdinaryDiffEq . Rodas5 (), saveat = 0 : 0.01 : 20 )
169+ sol = solve (prob, Rodas5 (), saveat = 0 : 0.01 : 20 )
169170if isinteractive ()
170171 @show sol. retcode
171172 plot (sol, layout = length (unknowns (simplified_sys)) + 1 )
@@ -177,7 +178,7 @@ if isinteractive()
177178end
178179
179180# # Double-mass model in MTK
180- using ModelingToolkit, OrdinaryDiffEq , LinearAlgebra
181+ using ModelingToolkit, OrdinaryDiffEqRosenbrock , LinearAlgebra
181182using ModelingToolkitStandardLibrary. Mechanical. Rotational
182183using ModelingToolkitStandardLibrary. Blocks: Sine
183184using ModelingToolkit: connect
@@ -280,4 +281,70 @@ Sn = get_named_sensitivity(sys_outer, [sys_outer.inner.plant_input, sys_outer.in
280281P = named_ss (ssrand (1 ,1 ,1 ), u= :jörgen , y= :solis )
281282@named Pode = ODESystem (P)
282283ModelingToolkit. isconnector (Pode. jörgen)
283- ModelingToolkit. isconnector (Pode. solis)
284+ ModelingToolkit. isconnector (Pode. solis)
285+
286+
287+
288+ # # Test causal simplification
289+ using LinearAlgebra
290+ using ModelingToolkit
291+ using ModelingToolkitStandardLibrary
292+ using ModelingToolkitStandardLibrary. Blocks
293+ using ModelingToolkitStandardLibrary. Mechanical. MultiBody2D
294+ using ModelingToolkitStandardLibrary. Mechanical. TranslationalPosition
295+ using Test
296+
297+ using ControlSystemsMTK
298+ using ControlSystemsMTK. ControlSystemsBase: sminreal, minreal, poles
299+ connect = ModelingToolkit. connect
300+
301+ @independent_variables t
302+ D = Differential (t)
303+
304+ @named link1 = Link (; m = 0.2 , l = 10 , I = 1 , g = - 9.807 )
305+ @named cart = TranslationalPosition. Mass (; m = 1 , s = 0 )
306+ @named fixed = TranslationalPosition. Fixed ()
307+ @named force = Force (use_support = false )
308+
309+ eqs = [connect (link1. TX1, cart. flange)
310+ connect (cart. flange, force. flange)
311+ connect (link1. TY1, fixed. flange)]
312+
313+ @named model = ODESystem (eqs, t, [], []; systems = [link1, cart, force, fixed])
314+ lin_outputs = [cart. s, cart. v, link1. A, link1. dA]
315+ lin_inputs = [force. f. u]
316+
317+ # => nothing to remove extra defaults
318+ 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 )
319+ G = named_ss (model, lin_inputs, lin_outputs; allow_symbolic = true , op,
320+ allow_input_derivatives = true , zero_dummy_der = true )
321+ G = sminreal (G)
322+ @info " minreal"
323+ G = minreal (G)
324+ @info " poles"
325+ ps = poles (G)
326+
327+ @test minimum (abs, ps) < 1e-6
328+ @test minimum (abs, complex (0 , 1.3777260367206716 ) .- ps) < 1e-10
329+
330+ lsys, syss = linearize (model, lin_inputs, lin_outputs, op = op,
331+ allow_input_derivatives = true )
332+ lsyss, sysss = ModelingToolkit. linearize_symbolic (model, lin_inputs, lin_outputs;
333+ allow_input_derivatives = true )
334+
335+ dummyder = setdiff (unknowns (sysss), unknowns (model))
336+ # op2 = merge(ModelingToolkit.guesses(model), op, Dict(x => 0.0 for x in dummyder))
337+ op2 = merge (ModelingToolkit. defaults (syss), op)
338+ op2[link1. fy1] = - op2[link1. g] * op2[link1. m]
339+ op2[cart. f] = 0
340+
341+ @test substitute (lsyss. A, op2) ≈ lsys. A
342+ # We cannot pivot symbolically, so the part where a linear solve is required
343+ # is not reliable.
344+ @test substitute (lsyss. B, op2)[1 : 6 , 1 ] ≈ lsys. B[1 : 6 , 1 ]
345+ @test substitute (lsyss. C, op2) ≈ lsys. C
346+ @test substitute (lsyss. D, op2) ≈ lsys. D
347+
348+ @test G. nx == 4
349+ @test G. nu == length (lin_inputs)
350+ @test G. ny == length (lin_outputs)
0 commit comments