# Scenario 4 — analytic Panda grasp fixture, 2026-09-21

Public reproduction note: archive aliases and `SIMCOMPARE_ROOT` are portable placeholders; use your own archive and checkout locations. Private deployment identifiers are omitted.

Eight exploratory native-engine trials: one centred cube and one 8 mm off-centre cube per
engine, seed 0, dt 1 ms, duration 3.5 s. This is not a success-rate estimate or seed study.

## Model and controller

Same pinned Panda arm mass, COM and full inertia tensors as Scenario 3. Fingers now use
their original opposed local Y prismatic axes, range 0–0.04 m. Each is independently
effort-controlled; there is no mimic/tendon constraint. Original native motors, damping
and armature are disabled. Arm collisions are disabled.

Each finger has one analytic pad: half-size (0.012, 0.004, 0.016) m, local centre
(0, 0.004, 0.0445) m. The pad boxes replace the original contact geometry. The shared
renderer displays these boxes plus illustrative source finger meshes; those meshes do
not participate in physics. Only pad–cube and cube–table contacts are intended.

Cube: 40 mm side, 100 g, diagonal inertia m a²/6. Table: 0.3 × 0.3 × 0.05 m, fixed.
Cube initially touches the tabletop, with zero canonical penetration. Initial open
finger spacing is 80 mm. Offset case translates the cube by 8 mm along hand-local X,
not along the closing axis. Nominal sliding friction is 0.5 everywhere.

External controller, held at 1 kHz:

    effort = clip(unloaded inverse-dynamics feedforward + kp*(qref-q) + kd*(qdref-qd))
    kp = [80,80,60,60,20,15,8,400,400]
    kd = [18,18,14,14,5,4,2,4,4]
    limits = [87,87,87,87,12,12,12,4,4]

Arm units are Nm/rad; finger units are N/m. Arm gains are unchanged from Scenario 3.
One frozen reference/feedforward tape is generated offline using MuJoCo 3.11, not separately
tuned to each engine. An IK solution gives an 8 cm unloaded hand lift. The additional
object load causes some tracking error; actual cube rise is about 7.3 cm.

Close: 0.3–0.8 s, finger reference 40 to 12 mm each. Lift: 1.0–1.8 s, quintic joint-space
interpolation. Hold to 2.3 s; open to 40 mm over 2.3–2.7 s; settle to 3.5 s. No policy,
grasp-success termination, object weld or object teleporting.

## Different contact implementations remain

CPU MuJoCo and Newton/MuJoCo-Warp use Euler, Newton solver, elliptic cone, 100 iterations,
tolerance 1e-10; MJCF contacts specify solref (0.01,1), solimp (0.99,0.999,0.001,0.5,2),
condim 3 and zero torsional/rolling friction. Newton uses MuJoCo contacts, float32.
CPU uses float64. Genesis uses GPU float64, elliptic cone, 100 iterations, tolerance
1e-10, constraint time constant 0.01 s, rolling/torsional friction off. PhysX uses CPU
TGS, 100 position / 1 velocity iterations, 1 mm contact offset, zero rest offset and
zero restitution. These settings are not mathematically equivalent contact laws.

Mass/COM/full-inertia readbacks pass a 1e-6 absolute SI component gate. Initial and
per-step robot FK pass a 10 µm position gate. Original arm joint limits are monitored.
Initial penetration is checked in the canonical MJCF, not claimed to be a complete
native contact-margin audit. Native collision settings and timestep sensitivity still
need a separate audit before assigning causes to submillimetre differences.

## Force measurement and visuals

CPU: native mj_contactForce rotated into world coordinates. Newton: native MuJoCo-Warp
contact_force. Genesis: force_a/force_b. PhysX: native contact normal and friction
impulses divided by dt. Forces act on the named body, with equal/opposite pad reactions.
Recorded poses precede the step whose contact forces are stored (Genesis exposes contacts
after the step). Gravity is applied at each COM. Native constraint reactions at robot
joints are not exported. Joint torques/finger actuator efforts are plotted separately.

The squeeze plot sums each pad's contact resultant on the cube, projects onto that
finger's local closing axis, takes its absolute value, then averages the two fingers.
It is not the magnitude of the net force on the cube, which would hide opposing forces.
All force arrows use 1 N = 5 cm without per-engine rescaling. Large gravity arrows may
extend outside the close-up. Viewer linear velocities are position differences; unused
angular velocity fields are explicitly zero placeholders, not measurements.

Contact plus gravity impulse over the full settled sequence is nearly zero (at most
about 2.2e-4 Ns in Newton, below 1e-6 Ns in other trials). This is a force-sign/unit
sanity check, not a full native velocity/momentum audit or a claim of energy conservation.

## Initial result and limits

All eight trials lift and release. Centred maximum cube rise: 7.35–7.37 cm; holding
normal force: 3.19–3.20 N per finger. Off-centre final horizontal displacement from
initial position: PhysX 9.0 mm, Genesis 6.9 mm, Newton 1.1 mm, CPU MuJoCo 0.3 mm.
Most displacement occurs during release/landing. No engine is treated as ground truth.
Repeats, half-step runs, geometry/contact-setting readbacks and real measurements are
needed before interpreting these differences as systematic accuracy differences.

## Reproduction and retained evidence

Project: state-of-robot-aug-2026/experiments/simcompare.
Sources: grasp_scene.py, grasp_native.py, grasp_physx.py, grasp_run.py, grasp_report.py,
setup/grasp.py. Shared tape: assets/grasp-reference.json (SHA recorded in every trace).
Raw accepted trials: output/archive-rigid/grasp-01 for PhysX/CPU/Genesis;
grasp-02 for Newton. First Newton attempt was rejected because the audit lookup did
not account for generated body-name prefixes; its log is retained. The corrected
lookup passes imported-property gates. Report: grasp-report-v2. Raw traces are retained
locally; no simulator or GPU is needed to regenerate the figures and replay bundles.
