Skip to content

controller: take stall and reached from the gripper's object status, not a velocity timeout #96

Description

@ebarnett3

controller: take stall and reached from the gripper's object status, not a velocity timeout

Problem

parallel_gripper_action_controller decides a goal from one input: the joint velocity. A goal is stalled when |velocity| stays under stall_velocity_threshold for stall_timeout, and reached when the position error is under goal_tolerance. With #92 the driver feeds a real velocity estimate, which makes this work, but the verdict comes about 1.4 s after the fingers stop: 0.5–0.7 s for the estimate to decay under the threshold, then the 1.0 s timeout. Every close-on-object pays it, and every client sees it (the MCP's first grasp verdict, MoveIt grasp checks).

The gripper already decides this itself. Its status reports object detection (Moving, DetectedWhileOpening, DetectedWhileClosing, AtRequestedPosition), the driver exports it as the object_status state interface, and the status broadcaster from #78 publishes it. The controller is the only consumer that ignores it.

Proposal

Add robotiq_controllers/GripperActionController, a copy of parallel_gripper_action_controller (the implementation is a single header) that claims object_status as an additional state interface and decides in check_for_success from it:

  • DetectedWhileOpening / DetectedWhileClosing → stalled = true, result position from the current reading; success or abort per allow_stalling as today.
  • AtRequestedPosition → reached_goal = true.
  • Moving → keep waiting; the velocity timeout stays as a safety net behind it.

When the joint exports no object_status (the topic-based Isaac Sim config, any GenericSystem), fall back to the velocity path unchanged, so the controller is a drop-in replacement in every configuration.

Gate it behind a use_object_status parameter, default false in the first release so behaviour matches PickNik's controller; flip the default once the bench confirms the verdict latency and the false-stall rate over the 20-cycle and close-on-block runs from #93.

Humble stays on the stock GripperCommand controller and keeps the velocity stall. Humble EOL: nothing to delete there; the fork is Jazzy and newer only.

Expected gain

Verdict latency drops from about 1.4 s to one exchange plus one controller cycle after the firmware's own stop decision. The firmware's decision time is not in the manual and needs one bench measurement before it goes in the README.

Consumers

Once the flags carry the firmware's decision, clients stop second-guessing them. The MCP's classify (mcp/gripper_mcp/service.py) currently reads the verdict from the achieved position against the target with a datasheet closed_tolerance_mm, because stalled was untrustworthy (#29) and goal_tolerance is wider than the datasheet's tolerance (#91). With use_object_status on, it should trust reached_goal and stalled and drop the position rule and closed_tolerance_mm. Same for any MoveIt grasp check that re-derives object detection from position.

Follow-up to

#92 (velocity estimate). Not a change to #92: the estimate stays, both as the fallback and for joint_states.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions