Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

state_priority ineffective when the prioritized variable's derivative is matched to a differentiated alias equation (singleton SCC forces demotion; singular Cartesian states in a planar arm)

Aperta
#101 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
5/5
Tempo stimato
Più di una settimana
Idoneità per principianti
38/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Tranquilla
Stack tecnologico
julia
Ambito
compilers

Direzione di ricerca

Inizia da src/partial_state_selection.jl, in particolare da dummy_derivative_graph!, e verifica come le variabili ordinate per priorità vengono suddivise in SCCs e associate. Riproduci il problema con TwoJointPlanarRobotPID sul branch twodof usando la configurazione ModelingToolkit indicata, quindi verifica che le coordinate articolari prioritarie rimangano selezionabili senza lo stato algebrico cartesiano singolare.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

state_priority is ineffective when the prioritized variable's derivative is matched to a differentiated alias equation: singleton SCC forces demotion, yielding singular Cartesian states in a trivial planar arm

Summary

In a planar 2-link serial arm, joint angles/velocities are marked state_priority = 10
(raising to 100 changes nothing) and body Cartesian variables state_priority = 1–2, yet
dummy-derivative selection picks the Cartesian body coordinates as differential states
and leaves one algebraic equation that solves for a joint angle:

0 ~ -(robot₊link1₊r0(t))[2] + robot₊link1₊r[1]*sin(robot₊revolute2₊frame_a₊phi(t)) + robot₊link1₊r[2]*cos(robot₊revolute2₊frame_a₊phi(t))

With r = [1, 0], the Jacobian of this equation w.r.t. its unknown is cos(phi) —
singular at phi = π/2, which is exactly the target configuration of the example's
point-to-point motion. Every solver dies with dt → eps (retcode = Unstable) as the arm
approaches the target; better-tuned controllers fail more reliably because they approach
the singular configuration more exactly. With joint coordinates as states (minimal
coordinates, what Dymola selects for this model) the system is a causal ODE with no
algebraic equation and no singularity.

What was ruled out

Traced with MTK v11.26.8 (ModelingToolkitTearing v1.13.5) / StateSelection v1.9.3:

  1. Metadata propagation is correct. On the flattened system: revolute*.phi/w
    priority 10, body.r/v priority 1, body.phi/w priority 2 (array element metadata
    resolves through getindex correctly).
  2. Alias elimination is correct. After eliminate_perfect_aliases! +
    alias_elimination!, the prioritized variables survive with correct entries in
    structure.state_priorities (pick_alias_target respects priority; the joint angle
    sits in a 3-variable relation frame_a.phi + phi ~ frame_b.phi and is not merged).
  3. The Jacobian/col_order path is not exercised. A separate latent issue was found in
    dummy_derivative_graph! (src/partial_state_selection.jl): when state_priority is
    given, vars is priority-sorted but a previously-computed integer Jacobian J is not
    column-permuted, so vars[col_order[i]] indexes mismatched orders. In this model,
    however, the kinematic-loop SCC has a trigonometric (non-integer) Jacobian, so jac
    returns nothing and the matching path runs (verified by instrumenting the jac
    closure: (neqs, nvars, integer) = (11, 13, false)). The matching path respects the
    sort within an SCC.

Root cause

dummy_derivative_graph! consults state_priority only within each SCC of
find_var_sccs(graph, var_eq_matching), and the SCC partition comes from the
priority-blind Pantelides matching. Dumping the partition (via log = Val(true) /
DummyDerivativeSummary) for this model:

  • The kinematic-loop SCC (13 candidates, 11 differentiated equations) contains only
    frame/body variables (priorities 0–2). 11 are demoted; the survivors are necessarily
    body Cartesian coordinates.

  • Each joint-coordinate derivative sits in its own singleton SCC, matched to a
    twice-differentiated alias/connection equation, e.g.

    SCC #152: D²(robot₊revolute1₊phi)  matched to  0 ~ D²(robot₊revolute1₊phi) - D²(robot₊revolute2₊frame_a₊phi)
    SCC #153: D²(robot₊revolute2₊phi)  matched to  0 ~ -D²(robot₊revolute1₊phi) - D²(robot₊revolute2₊phi) + D²(robot₊body₊phi)
    SCC #156: D(robot₊revolute2₊w)     matched to  0 ~ -D(robot₊revolute2₊w) + D²(robot₊revolute2₊phi)
    SCC #159: D(robot₊revolute1₊w)     matched to  0 ~ D²(robot₊revolute1₊phi) - D(robot₊revolute1₊w)
    

    A singleton SCC with one differentiated equation demotes its only candidate
    unconditionally — priority is never compared against anything. This is why raising the
    priority from 10 to 100 has zero effect.

The matching is not unique: matching 0 ~ D²(rev1.phi) - D²(rev2.frame_a.phi) to
D²(rev2.frame_a.phi) instead would pull rev1.phi into the loop SCC, where the priority
sort would (correctly) keep it as a state and demote the Cartesian candidates. The outcome
is thus legal w.r.t. the dummy-derivative algorithm for some matching, but the
state_priority feature is silently ineffective for the very common pattern where the
prioritized variable is connected to a kinematic loop through a rigid alias chain
(joint → flange → frame connections — i.e., essentially every multibody joint).

Reproduction

Model: TwoJointPlanarRobotPID / TwoJointPlanarArm on the twodof branch of
JuliaComputing/MultibodyComponents.jl (world → revolute1 → link1 → revolute2 → link2 →
body; Revolute.phi/w have state_priority = 10 by default, Body.r/v 1 and
Body.phi/w 2).

using ModelingToolkit, MultibodyComponents
using MultibodyComponents: multibody
@named model = MultibodyComponents.PlanarMechanics.examples.TwoJointPlanarRobotPID()
ssys = multibody(model)   # mtkcompile with multibody-suitable options
unknowns(ssys)            # body.phi, body.w, body.r[2], body.v[2] differential;
                          # revolute2.frame_a.phi algebraic (singular at phi = π/2)

Instrumentation used to localize the issue (priority traces, DummyDerivativeSummary
dump, matched-equation dump per SCC) can be provided.

Workarounds attempted

  • statePriority = 100 on the joints: no effect (mechanism above).
  • First-order filter between the subsystems whose coupling was initially suspected:
    no effect on state selection (the selection is a property of the arm kinematics alone).
  • Only effective mitigation so far: use FBDF and avoid resting exactly at the singular
    configuration — clearly not a fix.

Possible directions

  1. Make the matching/SCC condensation priority-aware: when a differentiated 2-variable
    alias equation can be matched to either end, prefer matching it to the lower-priority
    variable so high-priority variables remain selectable.
  2. Post-pass: for singleton SCCs created by differentiated alias equations, allow swapping
    the demoted variable with its alias partner when the partner has lower priority.
  3. At minimum, document/warn that state_priority cannot influence selection in this
    situation (it currently fails silently).

Related (checked, distinct): JuliaComputing/StateSelection.jl#96 (priority-aware
algebraic tearing), SciML/ModelingToolkit.jl#3093 (alias-aware priority propagation,
pre-StateSelection-split prototype), StateSelection.jl#74/#75 (merged, present in v1.9.3).
The unpermuted-Jacobian/col_order mismatch described above is a separate latent bug and
can be filed separately if useful.

Lingua principale
Julia
Stelle
7
Fork
10
Merge medio
5g 11h
PR unite (30g)
3

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di JuliaComputing/StateSelection.jl

Tutte le issue di JuliaComputing/StateSelection.jl

Issue simili

Altre issue su Julia

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.