Context
As discussed in Broadcast inside of `@mtkmodel` macro causes precompilation failures when put into a package - #11 by BambOoxX, I’m trying to define mtkmodel
s to model a moving rigid body submitted to some actions.
Although I could do everything by hand the purpose is to test the @mtkmodel
syntax and see where the trouble comes.
In Mechanical Components · ModelingToolkitStandardLibrary.jl there are nice simple components that show how to do most things, but I’ve reached a point where I understand the problems, but not the solutions.
Given that I’m using the latest syntax, it seems previous answers on related topics offer limited help.
Actual problem
What I am trying to do first is to setup a simulation of a ball submitted to its weight, ballistics 101, in a 3D space.
For that I’ve re-implemented 3D versions of serveral components from ModelingToolkitStandardLibrary
. In need in particular, 3D versions of MechanicalPort
, Force
, Mass
and Free
. These are implemented below
# Example to demonstrate the trajectory of a moving mass in 3D using ModelingToolkit and modified ModelingToolkitStandardLibrary components
using ModelingToolkit, LinearAlgebra, DifferentialEquations
using ModelingToolkitStandardLibrary.Blocks: RealInput
using GeometryBasics, GLMakie
@variables t
D = Differential(t)
@connector MechanicalPort3 begin
v(t)[1:3] = zeros(3), [description = "Translational velocity of the node in [m/s]"]
f(t)[1:3] = zeros(3), [description = "Force entering the node in [N]", connect = Flow]
end
@mtkmodel Force3 begin
@parameters begin
f_0[1:3] = zeros(3)
end
@components begin
node = MechanicalPort3()
f = RealInput(; nin=3, u_start=f_0)
end
@equations begin
collect(node.f .~ -f.u)...
end
end
@mtkmodel Mass3 begin
# Definition of the model icon
#@icon "..."
# Definition of the model parameters
@parameters begin
m, [description = "Mass of the moving rigid body in [kg]"]
v_0[1:3] = zeros(3), [description = "Initial velocities in [m/s] along X, Y and Z axes of the rigid body"]
s_0[1:3] = zeros(3), [description = "Initial positions in [m] along X, Y and Z axes of the rigid body"]
f_0[1:3] = zeros(3), [description = "Initial forces in [N] along X, Y and Z axes entering the rigid body"]
end
@components begin
node = MechanicalPort3(v=v)
end
@variables begin
(s(t))[1:3] = s_0, [description = "Positions in [m] along X, Y and Z axes of the rigid body"]
(v(t))[1:3] = v_0, [description = "Velocities in [m/s] along X, Y and Z axes of the rigid body"]
(f(t))[1:3] = f_0, [description = "Forces in [N] along X, Y and Z axes entering the rigid body"]
end
@equations begin
collect(node.v .~ v)...
collect(node.f .~ f)...
collect(D.(s) .~ v)...
collect(D.(v) .~ f ./ m)...
end
end
@mtkmodel Free3 begin
@components begin
node = MechanicalPort3()
end
@variables begin
f(t)[1:3] = zeros(3)
end
@equations begin
collect(node.f .~ f)...
end
end
Now I can actually instantiate my components with
@named mass = Mass3(m=1, v_0=[0.0, 0.0, 0.0])
@named g = Force3(f_0=[0.0, 0.0, -9.81])
@named free = Free3()
My problem comes when I try to make the connections to assemble my model.
I figured that the g
and mass
nodes should be connected together to obtain the proper results with
eqs = Equation[
ModelingToolkit.connect(g.node, mass.node)
]
@named model = ODESystem(eqs, t, [mass.s; mass.v; mass.f],[];systems = [mass,g])
sys = structural_simplify(model)
However that leaves me with an ExtraVariablesException
, so there is something I’m missing there, though I can’t figure what.
Nevertheless, if I add manually a relation between mass.f
and g.f_0
with
eqs = Equation[
collect(mass.f .~ g.f_0)...
ModelingToolkit.connect(g.node, mass.node)
]
I get a seemingly correct behavior, while I would have though initially that connect
would take care of this relation.
Could someone explain if I missed something in the components or in the way connections works ?