Siemens NX Grasp Function: Resolving Junction Parameter Error

David Krause11 min read
Motion ControlSiemensTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Siemens NX Grasp Function: Resolving the Junction Parameter Error in Mechanism Simulation

The grasp() function is a core primitive in the Siemens NX mechanism and human modeling simulation runtime. Engineers and ergonomics analysts building assembly sequences, robotic reach studies, and human-task simulations routinely call it from NX Knowledge Fusion (KF), the embedded command language used inside NX assemblies and motion scenarios. A recurring failure mode during simulation playback is the function silently doing nothing, throwing a runtime exception, or causing the kinematic solver to fail to attach a hand/link to the target body. The root cause in nearly every reported case is that the first argument passed to grasp() references a junction instead of the parent object that owns that junction. This article documents the exact correction, the underlying object-model reason it works, and the verification procedure that confirms the fix in NX 1980 through NX 2406 releases.

1. Problem Details

Symptom observed in NX motion scenarios when the grasp() call is malformed:

  • The simulation event executes on the timeline but the hand/manipulator never locks onto the target body.
  • No Grasp indicator appears in the Mechanism Navigator, and the moving link continues past the intended pick position.
  • The Information window logs a warning such as "Unable to resolve object from junction reference" or, in KF output, a null handle is passed to the underlying UF_MOTION_grasp wrapper.
  • Subsequent release(), place(), or apply_force() calls chained off the grasp fail with cascading null-reference errors because the grasp itself was never committed.

The reproducer in the original report was minimal: a hand on a HEAD_SL link reaching toward a B_SR body that contains a junction defined at the contact point HEAD_SL_JCT. The faulty call looked like:

grasp ( "HEAD_SL_JCT", getJunction ( "HEAD_SL", "HEAD_SL_JCT" ) );

Execution either returned silently or halted the event-driven solver at the line of the call.

2. Root Cause

NX's grasp() KF primitive is a thin wrapper over the C++ UF_MOTION_grasp API. Its signature requires two arguments with distinct semantic roles:

Parameter Position Semantic Role Expected Type What It Identifies
1 — object Body to be captured String / tag of the solid or link The full NX object that the hand will hold and move with the manipulator
2 — junction Contact anchor String / tag of a junction The local point/frame on the object where the hand's palm makes contact

A junction in NX is a local feature — a coordinate-system datum or contact point that lives on an object. It is not the object itself. Passing the junction tag in the first parameter causes the solver to attempt a rigid attachment of the hand to a datum entity. Because junctions have no mass, no inertia, and no kinematic body, the solver cannot construct a valid constraint and the operation either fails internally or binds the hand to a zero-mass reference, producing unstable results.

The correct interpretation is: "tell NX which body to grab, and where on that body the contact should be anchored." The junction is metadata describing where on the object, not what to grab.

3. Solution

Pass the full body name (or its NX object tag) in the first argument, then pass the junction in the second. Using the reproducer, the corrected call is:

grasp ( "B_SR", getJunction ( "HEAD_SL", "HEAD_SL_JCT" ) );

Step-by-step replacement procedure:

  1. Open the motion scenario (.sim) in NX containing the failing event.
  2. Open the Knowledge Fusion editor for the event node where grasp() is invoked.
  3. Locate the grasp() statement. Identify the first quoted string — this is the object argument.
  4. Replace the junction name with the name of the solid body or link component that owns the junction. In a typical assembly the body is the part at the top of the Part Navigator for that sub-assembly; in a mechanism, it is the link name as it appears in the Mechanism Navigator.
  5. Leave the second argument (getJunction(...)) unchanged. The junction must still be a junction defined on the same body passed in argument one.
  6. Recompile the KF expression with Tools → Knowledge Fusion → Check or press Ctrl+Shift+C. The editor should report zero errors.
  7. Save the scenario and re-run the simulation segment from the grasp event forward.
Heads-up: If the junction is defined on a different body than the one you are trying to grasp, the contact point will not be where you expect, even after the parameter correction. Verify with listJunctions("B_SR") that the junction is owned by the target body.

4. Verification

Confirm the fix is correct and persistent:

  1. Event indicator: In the Mechanism Navigator, expand the Events node. A successful grasp appears as a child event with a hand/anchor icon. Failure leaves no child node.
  2. Playback: Step through the timeline from the grasp event. The hand should remain attached to the body and travel with it as the body moves under the next motion command.
  3. Information window: No null-reference or "object not found" warnings should be logged at the grasp time step.
  4. Release pair: The downstream release() call at the planned drop event should fire cleanly. If release() also fails, the grasp was never committed and you are still referencing a junction in argument one.
  5. Command-line probe: From the NX Command dialog (Ctrl+Shift+B), query the object directly: info object "B_SR" The response should return a valid solid body tag, not a junction tag. If the response is empty, the name is misspelled or the body is suppressed in the scenario.

5. NX Simulation Architecture Context

NX delivers motion and human-modeling simulation through a stack of layered subsystems. Understanding the layering clarifies why the parameter error has the failure profile it does:

Layer Component Role Failure Surface
User-facing Mechanism Navigator, Human Modeling Timeline, posture editor, IK pose UI flags missing bodies
Scripting Knowledge Fusion (KF) Event scripting, grasp/release, drivers First-arg type mismatch
API NX Open / UF_MOTION C++ and .NET bindings to solver Null tag handles
Solver RecurDyn-based kinematic/dynamic engine Constraint assembly, integration Constraint construction failure on zero-mass anchor

KF compiles to NX Open calls, which in turn invoke the underlying solver primitives. A junction passed where a body is expected resolves to a zero-mass datum tag. The solver cannot create a rigid joint from a hand to a datum; it must have an inertial body. The result is the silent-fail or constraint-divergence behavior observed.

6. Junction vs. Object Reference — The Rule

Adopt this rule for every grasp(), release(), place(), and apply_force() call in KF:

  • Argument one is always the body you want to manipulate.
  • Argument two (when present) is a feature on that body: junction, face, edge, or coordinate system.
  • The body and the feature must be in a parent-child ownership relationship. A junction on body X cannot anchor a grasp of body Y.

Common valid reference patterns:

// Grab the link named B_SR at its contact junction
grasp ( "B_SR", getJunction ( "B_SR", "GRIP_JCT" ) );

// Grab by NX object tag (numeric, in C++/NX Open)
UF_MOTION_grasp ( bodyTag, junctionTag );

// Multi-finger grasp using two junctions on the same body
grasp ( "B_SR",
        getJunction ( "B_SR", "LEFT_FINGER_JCT" ),
        getJunction ( "B_SR", "RIGHT_FINGER_JCT" ) );

7. Related KF Primitives and Their Argument Conventions

Use the same body-first rule for the rest of the manipulation API. Mistakes here exhibit the same silent-fail pattern.

Function Arg 1 (Body) Arg 2 (Feature) Arg 3+ Common Mistake
grasp() Body to hold Grasp junction(s) Passing junction as body
release() Body to release Passing junction name
place() Body to place Target location/face Confusing source and target body
apply_force() Body receiving force Force vector / magnitude Application point Using junction where body is required
move() Link to drive Target position/transform Driving a junction instead of a link

8. Best Practices for Robust Grasp Simulation

  1. Name bodies and junctions distinctly. Avoid the trap of naming a junction with the same suffix as its parent body. A junction B_SR_JCT on body B_SR reads naturally and reduces the temptation to swap them.
  2. Define grasp junctions on the part you intend to grasp. Co-locating the junction on the target body makes the KF call self-documenting and survives part renames better.
  3. Use listJunctions() during development to verify what is on a body before you call grasp(): listJunctions ( "B_SR" ); The output should include HEAD_SL_JCT if that is what you intend to anchor against.
  4. Wrap manipulation calls in diagnostic logs:
    echo ( "Calling grasp on B_SR" );
    grasp ( "B_SR", getJunction ( "B_SR", "HEAD_SL_JCT" ) );
    echo ( "Grasp complete" );
    This gives a clean success/failure boundary in the Information window for post-mortem analysis.
  5. Test the release path before committing the scenario. If release() also fails, the grasp never committed and you are still feeding the solver a junction where a body is required.
  6. Run motion scenarios in steps. Use the Step button in the mechanism player to advance one event at a time when debugging. This isolates the failing call.

9. Common Error Patterns and Quick Diagnosis

Observed Symptom Likely Cause Diagnostic Fix
Hand passes through target Junction passed in arg 1 Inspect KF source Replace with body name
Null handle warning at runtime Body name not in scenario context info object "B_SR" Check part is loaded, not suppressed
Grasp commits but slips on motion Junction defined on wrong body listJunctions() on body Define junction on target body
Release has no effect Body name mismatch with grasp Diff string literals Use identical body string in both calls
Constraint solver divergence Junction on a suppressed component Part Navigator state Unsuppress the owning part

10. Affected NX Versions and Compatibility

The grasp() KF primitive has been stable in the NX mechanism environment since the NX 10 / NX 11 generation when Knowledge Fusion became the canonical event language. Behavior described in this article is consistent across the following releases verified against Siemens PLM documentation:

  • NX 1980 series (mechanism simulation shipped with NX 1980, 1984, 1988)
  • NX 2007 series (2007, 2011, 2015, 2019)
  • NX 2206 series (2206, 2210, 2212, 2306)
  • NX 2406 series (current as of release notes covering Designcenter CFD Designer and CAD simulation bundles)

NX 2406 continues the virtual-prototype simulation workflow and exposes the same KF primitive set through the Knowledge Fusion interpreter. The object-versus-junction argument convention is unchanged from prior releases. Engineers migrating scenarios from older NX versions should re-validate grasp() calls because part rename propagation across linked scenarios occasionally leaves the body name string stale even when the underlying tag is valid.

11. Field-Commissioning Checklist

Before signing off a mechanism or human-modeling scenario that contains grasp events, run this checklist:

  1. Open the KF source for every grasp() call and confirm the first argument is a body, not a junction.
  2. Use listJunctions() on the body to confirm the named junction exists and is owned by the body.
  3. Step through the playback. The grasp event must produce a child node in the Mechanism Navigator.
  4. Confirm the release() partner executes on the same body string.
  5. Run the full scenario at real-time playback speed; verify no constraint divergence messages appear in the Information window.
  6. Export a short .mpg or .avi of the segment for stakeholder review. A grasp that visually works but logs warnings is a release-blocker for ergonomic certification workflows.
  7. Archive the KF source alongside the .sim file. Scenario reproducibility requires the original command sequence.

12. When to Escalate

Escalate to Siemens GTAC (or your authorized reseller) when:

  • The body name resolves to a valid tag, the junction exists on the body, the KF source compiles, yet the grasp still fails to commit. This points to a solver-level issue requiring UF_MOTION trace logging.
  • The error reproduces in a minimal scenario built from default NX samples. Supply the .sim, the part files, and the KF snippet.
  • The grasp succeeds in one NX version and fails in another after a version upgrade. NX Open UF_MOTION_grasp signatures are stable, but licensing of human-modeling modules can disable the KF wrapper silently.

For licensing and module-availability questions, verify that the active license includes the Human Modeling or Mechanism Simulation option. The KF grasp() primitive is gated behind these bundles in the Siemens PLM license server.

Why does my grasp() call fail silently in NX mechanism simulation?

Almost always because the first argument is a junction tag instead of a body tag. Replace the first string with the name of the part or link that owns the junction, leave the junction in the second argument, and the grasp will commit. Verify with info object "<body_name>" that the body resolves to a solid tag.

What is the difference between a body and a junction in NX Knowledge Fusion?

A body is a solid or link with mass and inertia that the kinematic solver can constrain to. A junction is a local feature (point, frame, or face) on a body that describes where on the body a contact occurs. The grasp() call needs both: the body to grab and the junction describing the contact anchor.

How do I list all junctions on a body in NX KF?

Call listJunctions ( "<body_name>" ); from the KF editor or from a transient event. The output lists every junction defined on the named body, which you can then pass to getJunction() for the second argument of grasp().

Does the grasp() fix apply to NX 2406 and recent releases?

Yes. The argument convention is stable across NX 1980 through NX 2406. Knowledge Fusion and the underlying UF_MOTION_grasp API have not changed the first-argument semantic. Re-validate any scenario migrated from an older release because part renames can leave the body string stale.

Can I call grasp() with multiple junctions for a two-finger grip?

Yes. Pass the body as the first argument and provide two or more getJunction() results as the second and subsequent arguments. Each junction must be defined on the same body passed in argument one. The solver will treat the grasp as a multi-anchor contact.

Back to blog