Blog | Robotiq

Robotiq Releases an Open-Source C++ SDK for Adaptive Grippers

Written by Robotiq Team | Aug 12, 2026 11:14 AM



As physical AI moves from research into real applications, developers need a solid primitive that meets them where they work: control loops that decide, hundreds of times per second, when to close, how fast, and with how much force.

Today we're publishing an open-source C++ SDK, a standalone library for controlling adaptive grippers (2F-85, 2F-140, and Hand-E) over their Modbus RTU serial link. It is open source under the BSD-3-Clause license and runs on Linux, Windows, and macOS, or directly in embedded firmware on MCUs.

The SDK exposes the gripper's complete documented register set. On the command side: position, speed, force, activation, and automatic release. On the status side, everything the gripper reports: object detection (your grip check, whether an object was gripped while closing or opening, is still moving, or arrived empty), actual position, motor current, activation and motion status, and fault status for both the gripper and its controller.

Why a standalone C++ SDK?

Not every system that needs a gripper runs the Robot Operating System (ROS). Physical AI stacks in particular tend to be custom C++ runtimes, and until now, connecting one to a Robotiq Adaptive Gripper meant writing your own Modbus RTU layer from the instruction manual or using third-party implementations: framing, checksums, register packing, and the retry logic around them.

The SDK replaces that work with a layered library that carries no ROS dependency, and no imposed dependencies at all beyond libserialport. It vendors its Modbus implementation (nanoMODBUS), and it will not pick your logging framework: diagnostics flow through a minimal injectable Logger seam, 1 virtual method, so they land in whatever backend you already use.

What you can build

  • Policy-driven grasping loops. The exchange cycle runs at up to roughly 200 Hz, and status reads are instant and thread-safe, leaving headroom for a learned policy or vision model adjusting grip in closed loop.
  • Data collection. The command and status blocks mirror the instruction manual byte for byte, and data() exposes the raw bytes, ready to append to a sensor stream or demonstration log.
  • Setup and diagnostic tooling. A synchronous, one-transaction-per-call Modbus client serves test benches and tooling that need deterministic wire behavior.
  • Threadless embedded integrations. The same synchronous client suits microcontroller superloops that drive the exchange themselves.
  • Hardware-free continuous integration (CI). makeFakeGripper() provides a fake device with the real device's semantics, so your integration code exercises the exact hardware API on every commit.

Example

Example as of August 12th 2026. Please refer directly to the repository for the latest version.

Here is the core of move_gripper.cpp, the SDK's shipped example. Construction opens the serial link, reads the gripper (failing fast if nothing answers), and starts the exchange cycle. A constructed Gripper is always live, with no connecting limbo to poll.

cpp
#include <Robotiq/gripper.hpp>
#include <Robotiq/gripper/stderr_logger.hpp>

Robotiq::ConnectionConfig config;
config.serial.port = "/dev/ttyUSB0";  // COM3 on Windows

// The name tags the SDK's log lines, so they read apart from your own.
auto logger  = std::make_shared<Robotiq::StderrLogger>("robotiq");
auto gripper = std::make_unique<Robotiq::Gripper>(config, logger);

Connecting never disturbs a running gripper: before anything is written, the command image seeds itself from the gripper's own state echoes, so a process restarting mid-shift while the gripper holds a part changes nothing.

Activation is stateful, not blind. Already active and fault-free means skip, in progress means wait, and a latched fault runs the documented recovery sequence:

cpp
Robotiq::activate(*gripper);  // calibration sweep, or a no-op if already active

Commands are whole blocks composed by your application. A default-constructed command is inert; motion is opt-in:

cpp
auto command = Robotiq::GripperCommand::defaults();
command.positionRequest = 255;  // close
command.action.set(Robotiq::ActionRequestBit::GoTo, true);
gripper->setCommand(command);

setCommand() and getStatus() read and write the process image instantly; no call ever blocks on serial traffic. Reads return whole snapshots, so position and object-detection status always come from the same exchange cycle, and the wait helpers make settle-detection a one-liner:

cpp
Robotiq::waitFor([&] {
    return gripper->getStatus().gripperStatus.objectDetection()
           != Robotiq::ObjectDetection::Moving;
}, 5s);

The full example, with argument handling, fault recovery, and log-sink injection, is 148 lines.

What's next

The official Robotiq ROS 2 driver will move onto the SDK, so both approaches run the same tested core (coming soon). On the SDK side, the next additions are already scoped: an exchange-cycle sync primitive, so control loops can run in step with the bus, and a human-readable dump of the command and status blocks for debugging. Both are additive: from v1.0.0 the SDK follows semantic versioning, and the documented API breaks only on a major release.

Beyond that, the roadmap is shaped by what you build with it. Design feedback and feature requests filed on GitHub directly inform what comes next.

Getting started

You can use the SDK now:

bash
git clone https://github.com/robotiq/grippers.git
cmake -S grippers/sdk_cpp -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j
ctest --test-dir build                        # unit tests, no hardware needed
./build/examples/move_gripper /dev/ttyUSB0    # activates, opens, closes. Keep the jaws clear

Issues, pull requests, and feedback are welcome on GitHub.

Learn more about Robotiq's physical AI at robotiq.com/physical-ai.