Skip to content

ERROR: During the resolution of the non-linear system, the evaluation of the following equation(s) resulted in a non-finite number: [1, 3] #2063

Open
@dafred94

Description

@dafred94

So my student is building a model from MTK components based on the great Planarmechanics Modelica library.

simple model

One of our simpler test models is nothing but a planar pendulum which causes the error in the title.
That model consists of

  • a Fixed (fixed bearing),
  • a Revolute (revolute joint),
  • FixedTranslation (massless rod),
  • a Body (rigid body),
  • a Torque (torque source),
  • a Constant (constant input)

Here's a sketch of the system:

pendulum

code to reproduce the error

using ModelingToolkit, DifferentialEquations, LinearAlgebra
using GLMakie

@variables t
D= Differential(t)

##
# connectors

@connector function frame_a(;name, pos=[0., 0.], phi=0.0,  _f=[0., 0.], tau=0.0)
    sts = @variables ox(t)=pos[1] oy(t)=pos[2] phi(t) fx(t)=_f [connect=Flow] fy(t)=_f [connect=Flow] tau(t) [connect=Flow]  
    ODESystem(Equation[], t, sts, []; name=name)
end


@connector function flange_a(;name)
    sts = @variables phi(t)  tau(t) [connect=Flow]  
    ODESystem(Equation[], t, sts, []; name=name, defaults = Dict(phi => 0.0, tau => 0.0))
end


@connector function realInput(;name, x=0.0)  
    sts = @variables x(t) [input=true]
    ODESystem(Equation[], t, sts, []; name=name)
end


@connector function realOutput(;name, x=0.0)  
    sts = @variables x(t) [output=true]
    ODESystem(Equation[], t, sts, []; name=name)
end

##
# components

function Fixed(;name, pos=[0., 0.], phi=0.0)  
    @named fa = frame_a()
    ps = @parameters posx=pos[1] posy=pos[2] phi=phi
    
    eqs = [
        fa.ox ~ posx
        fa.oy ~ posy
        fa.phi ~ phi
    ]
    compose(ODESystem(eqs, t, [], ps; name=name), fa)
end


function Revolute(;name, phi=0.0, w=0.0, z=0.0, tau=0.0)     
    @named fa= frame_a() 
    @named fb= frame_a()
    @named fla= flange_a()
    sts= @variables phi(t)=phi w(t)=w z(t)=z tau(t)=tau  
    eqs= [  D.(phi) ~ w
            D.(w) ~ z
            fla.phi ~ phi
            fla.tau ~ tau
            fa.ox ~ fb.ox
            fa.oy ~ fb.oy 
            fa.phi + phi ~ fb.phi
            fa.fx + fb.fx ~ 0
            fa.fy + fb.fy ~ 0 
            fa.tau + fb.tau ~ 0
            fa.tau ~ tau
            ]               
    compose(ODESystem(eqs, t, sts, []; name=name), [fa,fb,fla])
end


function FixedTranslation(;name, r0 =[1. , 0.])     
    @named fa= frame_a() 
    @named fb= frame_a()
    ps= @parameters rx=r0[1] ry=r0[2]
    sts= @variables  r0x(t) r0y(t) Rx(t) Rp(t) Ry(t) Rq(t) 
    eqs= [  
        Rx ~ cos(fa.phi)
        Rp ~ -sin(fa.phi)
        Ry ~ sin(fa.phi)
        Rq ~ cos(fa.phi)
        Rx * rx + Rp * ry ~ r0x
        Ry * rx + Rq * ry ~ r0y                                                
        fa.ox + r0x ~ fb.ox
        fa.oy + r0y ~ fb.oy
        fa.phi ~ fb.phi
        fa.fx + fb.fx ~ 0
        fa.fy + fb.fy ~ 0
        fa.tau + fb.tau + r0x * fb.fy - r0y * fb.fx ~ 0
        ]
    compose(ODESystem(eqs, t, sts, ps; name=name), [fa,fb])
end


function Body(;name, v=[0., 0.], a=[0., 0.],phi=0.0, w=0.0, z=0.0)  
    @named fa = frame_a()
    ps = @parameters m=1.0 I=1.0 
    sts= @variables vx(t)=v[1] vy(t)=v[2] ax(t) ay(t) phi(t)=0.0 w(t)=w z(t)=z
    
    eqs = [fa.tau ~ I * z
           D.(fa.ox) ~ vx
           D.(fa.oy) ~ vy                                                   
           D.(vx) ~ ax  
           D.(vy) ~ ay                                                  
           D.(phi) ~ w
           D.(w) ~ z
           fa.phi ~ phi
           fa.fx ~ m * ax
           fa.fy ~ m * ay ]
    compose(ODESystem(eqs, t, sts, ps; name=name), fa)
end


function Torque(;name)   
    @named in = realInput()
    @named flb = flange_a()

    eqs = [-in.x ~ flb.tau,]
    
    compose(ODESystem(eqs, t, [],[]; name=name), [flb,in])
end


function Constant(;name, k=1.0)   
    @named y = realOutput()
    ps = @parameters k=k
    eqs = [
            y.x ~ k
          ]
    compose(ODESystem(eqs, t, [],ps; name=name), y)
end

##
# the actual model

@named fixed = Fixed()
@named revolute = Revolute()
@named trans = FixedTranslation()
@named body = Body()
@named torque = Torque()
@named const_ = Constant(k=1)

eqs = [
      connect(fixed.fa, revolute.fa),
      connect(revolute.fb, trans.fa),
      connect(trans.fb, body.fa),
      connect(torque.flb, revolute.fla),
      connect(const_.y, torque.in)
]

@named model = compose(
    ODESystem(eqs, t, name=:tmp),
    [
        fixed,
        revolute,
        trans,
        body,
        torque,
        const_
    ]
)

modelTorque = model

sys = structural_simplify(model)

##

u0 = [
      # instantly crashing parametrization for trans
      trans.rx => 1.0,
      trans.ry => 0.0,

      # initially working parametrization for trans (until t ~ sqrt(2*pi), i.e. until the pendulum has rotated by pi/2)
      #trans.rx => 1/sqrt(2),
      #trans.ry => 1/sqrt(2),

      # supposedly sufficient initial conditions
      body.phi => 0.0,
      D(body.phi) => 0.0,

      # initial conditions required by MTK
      D(D(body.fa.oy)) => 1.0,
      D(D(trans.r0x)) => 0.0,
      trans.r0y => 0.0,
      D(trans.r0y) => 0.0,
]

prob = ODEProblem(sys, u0, (0, 10.0))
sol = solve(prob, Rodas4())

fig = Figure()
ax = Axis(fig[1, 1])
lines!(ax, sol.t, sol[D(D(body.fa.oy))])
display(fig)

observations

Search the code for "u0 =", where we set our initial conditions/states and parameters.

  1. if the code stays as it is, it leads to the error mentioned above
    • the equations that form the unsolvable non-linear system
      • > full_equations(sys)[1]
        • Differential(t)(trans₊r0y(t)) ~ trans₊r0yˍt(t)
      • > full_equations(sys)[3]
        • 0 ~ (trans₊rx*sin(body₊phi(t)) - trans₊r0y(t)) / trans₊ry + cos(body₊phi(t))
    • the issue seems to be that eq. 3 includes a division by parameter trans₊ry, which can be 0.
      • this can be verified by uncommenting the 2 lines below # initially working parametrization [...]
      • however, then the model crashes a bit later after ~sqrt(2*pi) seconds (i.e. after a rotation by pi)
    • Apparently, the model has been transformed in a very unfortunate manner
    • What can be done about this?
  2. the model requires a.. surprising and redundant set of initial conditions
    • it requires the lines below # initial conditions required by MTK
      • otherwise, we're greeted by a ERROR: ArgumentError: SymbolicUtils.Symbolic{Real}[body₊fa₊oyˍtt(t)] are missing from the variable map. where the list of missing symbols grows as you comment out more "required" initial conditions.
    • theoretically, the 2 lines below # supposedly sufficient initial conditions should be enough to specify the (control theoretical) system state
    • Is there any solution to this?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions