Skip to content

Make the PICO grip and trigger axes available, off by default - #255

Open
ra9fuji-ui wants to merge 1 commit into
NVlabs:mainfrom
ra9fuji-ui:pico-grip-axis
Open

Make the PICO grip and trigger axes available, off by default#255
ra9fuji-ui wants to merge 1 commit into
NVlabs:mainfrom
ra9fuji-ui:pico-grip-axis

Conversation

@ra9fuji-ui

Copy link
Copy Markdown

What

generate_finger_data receives the PICO grip as an argument but never writes it
into the fingertip frames, so the axis is discarded before it reaches
G1GripperInverseKinematicsSolver. The trigger is separately collapsed to a
boolean at a 0.5 threshold, even though the solver itself interpolates
(q_open + grip * (q_closed - q_open)).

This adds three opt-in environment variables:

Variable Effect
GEAR_SONIC_GRIP_AXIS=1 Carry the grip axis on Dex3 joint 0
GEAR_SONIC_GRIP_AXIS_GAIN=1.0 Joint-0 value in rad at grip == 1.0
GEAR_SONIC_TRIGGER_CONTINUOUS=1 Pass the trigger travel through instead of thresholding

Why joint 0 is safe to use

The only gesture this producer emits is middle_close, whose amp0 is 0.0
(g1_gripper_ik_solver.py), so joint 0 is otherwise always zero. Dex3 joint 0
spans ±1.05 rad (dex3_hands.hpp MAX_LIMITS/MIN_LIMITS) and the built-in
gestures use ±0.5, so the default gain of 1.0 is inside the joint limit and
unambiguous against both. Both hands end up with the same sign on joint 0, so
one expression covers each side.

Default behaviour is unchanged

Every switch defaults to off, and the guarded paths are additive — the original
trigger branch survives as the elif.

I checked this by running the upstream and patched generate_finger_data side
by side over 2,222 input combinations (trigger × grip × hand). The returned
arrays are identical whenever no variable is set, and also when a variable is
present but set to 0.

Context

We run a G1 fitted with Inspire RH56DFX hands. Per #109 the deployment does not
support that hand natively, which is fine — we consume the Dex3 command stream
outside GEAR-SONIC and retarget it, so GEAR-SONIC itself needs no
Inspire-specific code. This PR adds none: joint 0 is a plain Dex3 axis, and
any consumer of the Dex3 command stream can use it. Without this change the grip
axis is simply unavailable to anything downstream.

Tested on a real G1 with a PICO controller on 2026-08-13.

`generate_finger_data` takes the PICO grip as an argument but never writes
it into the fingertip frames, so the axis is lost before it reaches the IK
solver. The trigger is reduced to a boolean at a 0.5 threshold even though
the solver interpolates continuously.

Add three opt-in environment variables:

  GEAR_SONIC_GRIP_AXIS=1           carry the grip axis on Dex3 joint 0
  GEAR_SONIC_GRIP_AXIS_GAIN=1.0    joint-0 value in rad at grip == 1.0
  GEAR_SONIC_TRIGGER_CONTINUOUS=1  pass the trigger travel through

Joint 0 is free: the only gesture this producer emits is `middle_close`,
whose amp0 is 0.0 (g1_gripper_ik_solver.py), so joint 0 is otherwise always
zero. Dex3 joint 0 spans +-1.05 rad (dex3_hands.hpp) and the built-in
gestures use +-0.5, so the default gain is inside the limit and unambiguous
against both.

Every switch defaults to off and the guarded paths are additive -- the old
trigger branch survives as the `elif` -- so with no environment variable set
the file behaves exactly as before.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant