@@ -195,3 +195,113 @@ lsys, ssys = linearize(sat, [u], [y]; op = Dict(u => 2))
195
195
@test isempty (lsys. B)
196
196
@test isempty (lsys. C)
197
197
@test lsys. D[] == 0
198
+
199
+ # Test case when unknowns in system do not have equations in initialization system
200
+ using ModelingToolkit, OrdinaryDiffEq, LinearAlgebra
201
+ using ModelingToolkitStandardLibrary. Mechanical. Rotational
202
+ using ModelingToolkitStandardLibrary. Blocks: Add, Sine, PID, SecondOrder, Step, RealOutput
203
+ using ModelingToolkit: connect
204
+
205
+ # Parameters
206
+ m1 = 1
207
+ m2 = 1
208
+ k = 1000 # Spring stiffness
209
+ c = 10 # Damping coefficient
210
+ @named inertia1 = Inertia (; J = m1)
211
+ @named inertia2 = Inertia (; J = m2)
212
+ @named spring = Spring (; c = k)
213
+ @named damper = Damper (; d = c)
214
+ @named torque = Torque ()
215
+
216
+ function SystemModel (u = nothing ; name = :model )
217
+ eqs = [connect (torque. flange, inertia1. flange_a)
218
+ connect (inertia1. flange_b, spring. flange_a, damper. flange_a)
219
+ connect (inertia2. flange_a, spring. flange_b, damper. flange_b)]
220
+ if u != = nothing
221
+ push! (eqs, connect (torque. tau, u. output))
222
+ return ODESystem (eqs, t;
223
+ systems = [
224
+ torque,
225
+ inertia1,
226
+ inertia2,
227
+ spring,
228
+ damper,
229
+ u
230
+ ],
231
+ name)
232
+ end
233
+ ODESystem (eqs, t; systems = [torque, inertia1, inertia2, spring, damper], name)
234
+ end
235
+
236
+ @named r = Step (start_time = 0 )
237
+ model = SystemModel ()
238
+ @named pid = PID (k = 100 , Ti = 0.5 , Td = 1 )
239
+ @named filt = SecondOrder (d = 0.9 , w = 10 )
240
+ @named sensor = AngleSensor ()
241
+ @named er = Add (k2 = - 1 )
242
+
243
+ connections = [connect (r. output, :r , filt. input)
244
+ connect (filt. output, er. input1)
245
+ connect (pid. ctr_output, :u , model. torque. tau)
246
+ connect (model. inertia2. flange_b, sensor. flange)
247
+ connect (sensor. phi, :y , er. input2)
248
+ connect (er. output, :e , pid. err_input)]
249
+
250
+ closed_loop = ODESystem (connections, t, systems = [model, pid, filt, sensor, r, er],
251
+ name = :closed_loop , defaults = [
252
+ model. inertia1. phi => 0.0 ,
253
+ model. inertia2. phi => 0.0 ,
254
+ model. inertia1. w => 0.0 ,
255
+ model. inertia2. w => 0.0 ,
256
+ filt. x => 0.0 ,
257
+ filt. xd => 0.0
258
+ ])
259
+
260
+ @test_nowarn linearize (closed_loop, :r , :y )
261
+
262
+ # https://discourse.julialang.org/t/mtk-change-in-linearize/115760/3
263
+ @mtkmodel Tank_noi begin
264
+ # Model parameters
265
+ @parameters begin
266
+ ρ = 1 , [description = " Liquid density" ]
267
+ A = 5 , [description = " Cross sectional tank area" ]
268
+ K = 5 , [description = " Effluent valve constant" ]
269
+ h_ς = 3 , [description = " Scaling level in valve model" ]
270
+ end
271
+ # Model variables, with initial values needed
272
+ @variables begin
273
+ m (t) = 1.5 * ρ * A, [description = " Liquid mass" ]
274
+ md_i (t), [description = " Influent mass flow rate" ]
275
+ md_e (t), [description = " Effluent mass flow rate" ]
276
+ V (t), [description = " Liquid volume" ]
277
+ h (t), [description = " level" ]
278
+ end
279
+ # Providing model equations
280
+ @equations begin
281
+ D (m) ~ md_i - md_e
282
+ m ~ ρ * V
283
+ V ~ A * h
284
+ md_e ~ K * sqrt (h / h_ς)
285
+ end
286
+ end
287
+
288
+ @named tank_noi = Tank_noi ()
289
+ @unpack md_i, h, m = tank_noi
290
+ m_ss = 2.4000000003229878
291
+ @test_nowarn linearize (tank_noi, [md_i], [h]; op = Dict (m => m_ss, md_i => 2 ))
292
+
293
+ # Test initialization
294
+ @variables x (t) y (t) u (t)= 1.0
295
+ @parameters p = 1.0
296
+ eqs = [D (x) ~ p * u, x ~ y]
297
+ @named sys = ODESystem (eqs, t)
298
+
299
+ matrices1, _ = linearize (sys, [u], []; op = Dict (x => 2.0 ))
300
+ matrices2, _ = linearize (sys, [u], []; op = Dict (y => 2.0 ))
301
+ @test matrices1 == matrices2
302
+
303
+ # Ensure parameter values passed as `Dict` are respected
304
+ linfun, _ = linearization_function (sys, [u], []; op = Dict (x => 2.0 ))
305
+ matrices = linfun ([1.0 ], Dict (p => 3.0 ), 1.0 )
306
+ # this would be 1 if the parameter value isn't respected
307
+ @test matrices. f_u[] == 3.0
0 commit comments