RevoHuman Glove#

A Linux-only plugin for BrainCo RevoHuman exoskeleton gloves. It reads each glove’s 21 encoder angles and its tactile forces through the RevoHuman C SDK, maps the SDK’s hand points to the 26 OpenXR hand joints and injects them into the OpenXR hand-tracking layer. It also pushes the encoder angles as joint states and the forces with the common tactile contract, laid out with the SDK’s taxel layout.

Data flow#

RevoHuman glove (USB) ──► RevoHuman C SDK ─┐
                                           ├─► revohuman plugin ──► CloudXR OpenXR runtime
Optical hand / controller ─────────────────┘   (hand points,        (hand joints, joint states,
                                                wrist-pose fusion)   tactile forces)

The plugin computes no kinematics of its own: the SDK turns the angles into hand points for the glove’s mechanical model, and the plugin maps those points to OpenXR order with corrections reviewed for that model. No URDF is loaded.

Outputs#

Per hand, with the default collection prefix revohuman (--collection-prefix=NAME changes it):

Output

Contents

OpenXR hand /hand/left, /hand/right

26 joints relative to the wrist, placed at the wrist pose described below

revohuman_<side>_joint_state / tensor joint_state

JointStateOutput with the 21 encoder angles in radians, in SDK order; see Generic Joint-Space Device

revohuman_<side>_tactile / tensor tactile

TactileDataArray taxel forces: the SDK’s calibrated reading, unchanged, along each taxel’s outward normal; see Tactile devices

revohuman_<side>_tactile/metadata

The TactileMetadata layout the forces belong to

Started by hand, the plugin publishes <id>/device_status only with --plugin-root-id=<id>.

Prerequisites#

  • Linux — x86_64 or aarch64.

  • Source-build prerequisites — the toolchain and system packages in Build from Source, for install.sh and the manual CMake build alike.

  • RevoHuman C SDK 0.1.3 — the c-sdk-v0.1.3 release of brainco-revohuman-sdk, which extracts to include/revohuman.h, lib/librevohuman.so with its versioned names, and LICENSE. The install script downloads it automatically. A Python SDK wheel cannot replace it.

  • RevoHuman gloves connected over USB, with access to their serial ports.

  • CloudXR runtime running on the plugin host.

Installation#

install.sh downloads the pinned C SDK release, verifies it against a per-architecture SHA-256, extracts it next to the script (re-runs reuse the extracted copy), and configures, builds, and installs the plugin with the SDK library and its licence next to it:

./src/plugins/revohuman/install.sh

Pass --build-dir <path> to reuse a non-default top-level CMake build directory and --install-prefix <dir> to choose where the plugin goes. --sdk-root <dir> (or REVOHUMAN_SDK_ROOT) uses an SDK package you already extracted.

To drive CMake directly:

cmake -B build -DBUILD_PLUGINS=ON -DBUILD_PLUGIN_REVOHUMAN=ON \
    -DREVOHUMAN_SDK_ROOT=/path/to/revohuman-c-sdk
cmake --build build --target revohuman_plugin
cmake --install build --component revohuman

The installed plugin finds the SDK library next to itself, so it needs neither the download nor the build directory afterwards. Keep the library’s symlinks.

Running the Plugin#

The plugin reaches the Teleop session through the CloudXR / OpenXR runtime, so start the runtime first and source its environment in the shell that launches the plugin:

python -m isaaccapture.cloudxr.service start   # runs in the background
source ~/.cloudxr/run/cloudxr.env
./install/plugins/revohuman/revohuman_plugin

See CloudXR Service and Load CloudXR environment variables for the full service setup. Applications can also launch it through its plugin.yaml using TeleopSession. The gloves are its only source, so it takes no source argument; an unknown argument such as --live or --replay is ignored with a warning.

The plugin neither records nor plays back: record its collections with McapRecordingConfig and play them back with McapReplayConfig, as for any other tracker (see MCAP Recording & Replay).

The plugin finds the gloves through the SDK, at most one left and one right, with nothing to declare. When both are plugged in, it opens them in one two-hand SDK kit with time sync on, so the two hands’ samples come from the same USB frame. A glove plugged in alone opens on its own; when the other one arrives, both are reopened together. Gloves that cannot be opened together keep streaming on their own. Until a glove is found, the plugin looks for it every 2 s and reports the SDK’s reason in its status, without holding up the other hand. The SDK reconnects a glove after a short dropout; when the stream ends anyway, the plugin closes the glove, together with its partner when the two share a kit, and looks for them again.

Each glove’s mechanical model follows the product the SDK identifies: a PTV1 glove uses the DV1 model and a P1 glove the P model. A P1 glove has no tactile sensors, so it streams the hand and joint states without tactile outputs. A glove of the wrong product or with incompatible firmware is reported as failed.

Wrist pose#

The glove stream contains wrist-relative joints but no absolute 6DoF wrist pose. Before injection, the plugin places the hand at a wrist pose from optical hand tracking or from a controller aim pose combined with a rigid per-hand offset.

Set REVOHUMAN_WRIST_SOURCE (or pass --wrist-source) to auto (the default), hand_tracking, or controller. In auto mode, optical tracking is preferred; the controller is used when optical tracking provides no valid pose. The plugin refuses a --wrist-source that disagrees with the variable.

A controller reports its aim pose, not the wrist. No controller mount is calibrated for these gloves yet, so the aim-to-wrist offsets default to identity and the plugin warns for each hand without one unless the source is hand_tracking. Set them with:

./install/plugins/revohuman/revohuman_plugin \
    --aim-to-wrist-left=px,py,pz,qx,qy,qz,qw \
    --aim-to-wrist-right=px,py,pz,qx,qy,qz,qw

Position values are in meters and quaternion values use (x, y, z, w).

Without a tracked wrist the hand is still injected, without tracking flags, at the last valid wrist pose (or the stage origin), and its status is degraded.

The glove’s wrist is a reference point of its mechanical model: the origin of its palm_link, on the back of the hand near the end of the forearm, moved about 12.6 mm towards the palm to the depth of the palm centre. It is not the anatomical wrist centre that the OpenXR wrist joint stands for. Nominally the wrist centre is about 4 cm further towards the fingers and about 0.2 to 0.7 cm further towards the palm; these figures come from typical adult hand dimensions, not from measurements on the glove, and vary with the wearer. With optical hand tracking, the injected hand therefore sits that much further towards the fingers and the palm than the tracked hand. With a controller, set the aim-to-wrist offsets to end at the glove’s wrist point. Verify the alignment for the wearer.

Tactile layout#

At start-up the plugin builds each hand’s TactileMetadata from the C SDK’s taxel layout for the DV1 model (rh_hand_model_taxel_layout); there is no layout file or option. Each taxel is bound rigidly to the OpenXR joint its SDK link moves with, with its +Z along the outward normal. That joint is rigid on the link, so the skinned taxels stay on the SDK’s taxels as the fingers bend. The log names the layout source, taxel count and SHA-256 of each hand’s metadata. When the SDK has no layout, the plugin logs why and pushes no tactile data; the other outputs are unaffected.

A force sample is pushed only while it is calibrated, recent and newer than the last one, and its status names the reason when it is not. Consumers must check that status as well as the presence of data.

Troubleshooting#

Symptom

Fix

install.sh fails with a SHA-256 mismatch

The downloaded package does not match the pinned release. Re-run to rule out a corrupted download; if it persists, do not bypass the check — verify the release assets upstream.

No revohuman_plugin is built, install.sh refuses the install, or the plugin stops before the OpenXR session naming an SDK function

The SDK found during configuration is incomplete: its library is missing or lacks a function the plugin calls. Point REVOHUMAN_SDK_ROOT at a complete C SDK release and reconfigure.

A glove is never opened and its status names a busy port

Another process, such as the SDK viewer, holds the glove’s serial port. Close it; the plugin opens the glove on its next attempt.

A glove is reported as failed

The status carries the SDK’s reason: a product or variant the plugin does not support, or incompatible firmware. These are not retried.

Hands appear but a downstream client sees no tactile data

A P1 glove has no tactile sensors. Otherwise check the start-up log for why there is no TactileMetadata (an SDK without the taxel layout), and the tactile status for the reason a sample was not pushed.