Skip to content

Provide a non-blocking form of the SDK's blocking procedures #20

Description

@ebarnett3

activate() and recoverFromFault() block for the length of a calibration sweep, one to two seconds. Any consumer with a control loop has to run them off that loop, and the SDK gives it no help.

The ROS wrapper shows what that costs. It wraps recoverFromFault() in std::async, adds a hasFinished() helper to distinguish "outstanding" from "finished" on the future, and relies on declaration order — recovery_ declared after gripper_ — so that reverse destruction joins the future before the gripper the lambda captured is destroyed. That last one is a dangling-reference hazard avoided by a comment, and every consumer that does the same thing has to rediscover it.

This is not specific to ROS. Any polling consumer (a PLC bridge, a GUI, a robot controller) needs the same thing, and the SDK already runs a thread of its own, so a second thread per call from std::async is the wrong shape.

Proposal

A poll-based handle rather than async twins of each function: start the procedure, then poll it each cycle for InProgress / Activated / Timeout / FaultLatched. Reimplement the existing blocking activate() and recoverFromFault() on top of it so they remain the easy default and the two forms cannot diverge.

Deliberately not std::future: it commits every consumer to <future>, and it is not available freestanding, which matters if the SDK is ever built for an MCU target. A poll-based handle works everywhere and composes with any event loop.

Design questions to settle

  • Ownership and lifetime. Destroying a Gripper with an operation outstanding must be safe and defined, rather than left to the consumer's member ordering.
  • Whether the exchange thread drives the procedure or the consumer's poll() call does the work. The latter keeps the SDK single-threaded from the consumer's point of view.
  • Cancellation: whether an outstanding procedure can be abandoned, and what state the gripper is left in if it is.
  • At most one outstanding procedure per gripper, and what a second start() does.

Follow-up

In the ROS wrapper once this lands: drop std::async, hasFinished() and the declaration-order dependency from robotiq_driver's hardware interface.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions