GitHub - XR-Robotics/XRoboToolkit-PC-Service (original) (raw)

Project Overview

XRoboToolkit-PC-Service is built upon an enterprise-level assistant application that includes multiple submodules and SDKs, developed using C++/Qt. The project aims to provide one-stop management and control services for VR teleoperated robots, including device management, data recording, demonstration, and control functionalities.

Main Modules

Server

SDK and Demo

Third-party Dependencies

Build Process

Build Scripts

The project provides build scripts for different platforms to simplify the build process:

Note: QT 6.6.3 is required for for this project. Please modify the QT path variables in the build scripts to your own QT installation location.

Windows Platform Build

Linux x86_64 Platform Build

Linux ARM64 Platform Build

QT_GCC_ARM64=/home/orin_pico/Qt/6.7.3/gcc_arm64  
export QT6_TOOLS=/home/orin_pico/Qt/Tools  
export PATH=/home/orin_pico/Qt/6.7.3/gcc_arm64/bin:$PATH  
export PATH=/home/orin_pico/Qt/6.7.3/gcc_arm64/include:$PATH  
export PATH=/home/orin_pico/Qt/Tools/QtCreator/bin:$PATH  
export PATH=/home/orin_pico/Qt/Tools/CMake/bin:$PATH  

Packaging Process

The project provides packaging scripts for different platforms to generate distributable installation packages:

Windows Platform Packaging

Linux x86_64 Platform Packaging

Linux ARM64 Platform Packaging

SDK Interface Description

Connect to Service

/**

Disconnect from Service

/**

Send JSON Message to VR Device

/**

VR Data Reception

Mainly obtained through callback functions

The callback function is specified when connecting to the service (see PXREAInit function)

Format as follows

/**

Callback type description

enum PXREAClientCallbackType { /// @brief Server connected PXREAServerConnect = 1<<2, /// @brief Server disconnected PXREAServerDisconnect = 1<<3, /// @brief Device online PXREADeviceFind = 1<<4, /// @brief Device offline PXREADeviceMissing = 1<<5, /// @brief Device connected PXREADeviceConnect = 1<<9, /// @brief Device state JSON description PXREADeviceStateJson = 1<<25, /// @brief Mask, used to enable all callbacks PXREAFullMask = 0xffffffff };

The device data obtained by the user is mainly through the PXREADeviceStateJson callback, and the corresponding callback function parameters are as follows

Callback Type context type userData status
JSON format device state description User-defined PXREADeviceStateJson 0

PICO Device JSON Data Description

Currently, there are five types of tracking data: head, controller, hand gesture, full-body motion capture, and independent tracking. All data will be sent as a JSON string with the following basic structure.

{"functionName":"Tracking","value":"{"Head":"Head","Controller":"Controller","Hand":"Hand","Body":"Body Motion Capture","Motion":"Tracker Independent Tracking","timeStampNs":"Timestamp","Input":"Input method 0 head 1 controller 2 gesture"}"}

Field description

Key value type Description
function string Tracking indicates the data is tracking data
value Json Contains specific data
Head Json Headset tracking data
Controller Json Controller tracking data
Hand Json Hand gesture data
Body Json Full-body motion capture data
Motion Json Tracker independent tracking data
timeStampNs int64 Timestamp when the data was obtained, Unix (nanoseconds)
Input int Current input method, 0 head input, 1 controller input, 2 gesture input

JsonData data = JsonMapper.ToObject(HeadJson); string valueStr = data["value"].ToString().Replace("\", ""); JsonData valueJson = JsonMapper.ToObject(valueStr);

Pose: A string representing seven float data for pose, separated by commas. The first three floats represent position (x, y, z), and the last four floats represent rotation (quaternion: x, y, z, w);

Coordinate System: Right-handed coordinate system (X right, Y up, Z in), the origin is set as the head position when the application starts. The following figure marks the position and orientation of the Head point.

head_pose

1. Headset Pose:

{"pose":"0.0,0.0,0.0,0.0,-0.0,0.0,0.0","status":3,"timeStampNs":1732613222842776064,"handMode":0}"

key type description
pose seven float Pose (right-handed, X right, Y up, Z in)
status int Indicates confidence (0 not reliable, 1 reliable)
handMode Current hand gesture type 0 not enabled, 1 controller enabled, 2 hand gesture tracking enabled
timeStampNs int64 Unix timestamp (nanoseconds)

2. Controller

{"axisX":0.0,"axisY":0.0,"grip":0.0,"trigger":0.0,"primaryButton":false,"secondaryButton":false,"menuButton":false,"pose":"0.0,0.0,0.0,0.0,0.0,0.0"},"right":{"axisX":0.0,"axisY":0.0,"grip":0.0,"trigger":0.0,"primaryButton":false,"secondaryButton":false,"menuButton":false,"pose":"0.0,0.0,0.0,0.0,0.0,0.0,0.0"},"timeStampNs":1732613438765715200}"

Key Type Left Controller Right Controller
menuButton bool Menu button Screenshot/Record button
trigger float Trigger button Trigger button
grip float Grip button Grip button
axisX, axisY float Joystick Joystick
axisClick bool Joystick click or press Joystick click or press
primaryButton bool X A
secondaryButton bool Y B
timeStampNs int64 Unix timestamp (nanoseconds)

3. Hand Gesture

"leftHand":{"isActive":0,"count":26,"scale":1.0,"timeStampNs":1732613438765715200,"HandJointLocations":[{"p":"0,0,0,0,0,0,0","s":0.0,"r":0.0}, ...]},"rightHand":{"isActive":0,"count":26,"scale":1.0,"HandJointLocations":[{"p":"0,0,0,0,0,0,0","s":0.0,"r":0.0}, ...]}

key Type Description
isActive int Hand tracking quality (0 low, 1 high)
count int Number of finger joints (fixed = 26)
scale float Hand scale
HandJointLocations Array Array of joint pose data, length = count (see joint description below)
timeStampNs int64 Unix timestamp (nanoseconds)

Finger Joint Data

key Type Description
p seven float Pose (left-handed, X right, Y up, Z in)
s ulong Hand joint tracking status, currently only four values: OrientationValid = 0x00000001, PositionValid = 0x00000002, OrientationTracked = 0x00000004, PositionTracked = 0x00000008
r float Joint radius

Hand Joint Description

Below is the description of the 26 finger joints in the HandJointLocations array.

The figure below shows finger joint locations in Unity coordinate system (x right, y up, z out). In the actual data, z-axis follows the z-in direction, same as controller pose and head pose.finger_joints

0 Palm Palm center
1 Wrist Wrist joint
2 Thumb_metacarpal Thumb metacarpal joint
3 Thumb_proximal Thumb proximal joint
4 Thumb_distal Thumb distal joint
5 Thumb_tip Thumb tip joint
6 Index_metacarpal Index metacarpal joint
7 Index_proximal Index proximal joint
8 Index_intermediate Index intermediate joint
9 Index_distal Index distal joint
10 Index_tip Index tip joint
11 Middle_metacarpal Middle metacarpal joint
12 Middle_proximal Middle proximal joint
13 Middle_intermediate Middle intermediate joint
14 Middle_distal Middle distal joint
15 Middle_tip Middle tip joint
16 Ring_metacarpal Ring metacarpal joint
17 Ring_proximal Ring proximal joint
18 Ring_intermediate Ring intermediate joint
19 Ring_distal Ring distal joint
20 Ring_tip Ring tip joint
21 Little_metacarpal Little metacarpal joint
22 Little_proximal Little proximal joint
23 Little_intermediate Little intermediate joint
24 Little_distal Little distal joint
25 Little_tip Little tip joint

4. Full-body Motion Capture Tracking

Full-body motion capture requires additional Pico Swift devices (at least two) and proper adaptation and calibration in the Pico headset.

Note: Each time the headset is activated, calibration is required.

Human Joint Reference

The full-body motion capture function of the PICO SDK supports tracking the 24 human joints shown in the figure below.

body_joints

The following are related concept descriptions:

Concept Description
Coordinate System Same world coordinate system as the headset data.
Root Joint Node 0 (Pelvis)
Parent/Child Joint Node Nodes 1 to 23, the one closer to the root joint is the parent, the one closer to the limb end is the child.
Bone A rigid body between two nodes, its pose is stored in the parent node structure closer to the root joint. For example: the pose angle of the lower leg bone is stored in the Knee joint structure. More examples:

The following is the BodyTrackerRole enumeration, corresponding one-to-one with the joints in the reference diagram.

public enum BodyTrackerRole { Pelvis = 0, // Pelvis LEFT_HIP = 1, // Left hip RIGHT_HIP = 2, // Right hip SPINE1 = 3, // Spine LEFT_KNEE = 4, // Left knee RIGHT_KNEE = 5, // Right knee SPINE2 = 6, // Spine LEFT_ANKLE = 7, // Left ankle RIGHT_ANKLE = 8, // Right ankle SPINE3 = 9, // Spine LEFT_FOOT = 10, // Left foot RIGHT_FOOT = 11, // Right foot NECK = 12, // Neck LEFT_COLLAR = 13, // Left collarbone RIGHT_COLLAR = 14, // Right collarbone HEAD = 15, // Head LEFT_SHOULDER = 16, // Left shoulder RIGHT_SHOULDER = 17, // Right shoulder LEFT_ELBOW = 18, // Left elbow RIGHT_ELBOW = 19, // Right elbow LEFT_WRIST = 20, // Left wrist RIGHT_WRIST = 21, // Right wrist LEFT_HAND = 22, // Left hand RIGHT_HAND = 23 // Right hand }

JSON data description

{"dt":0,"flags":0,"timeStampNs":1732613438765715200, "joints":[{ "p":"0.0,0.0,0.0,0.0,0.0,0.0,0.0", "t":0, "va":"0,0,0,0,0,0", "wva":"0,0,0,0,0,0"},.....}]}

key Type Description
joints Json Array, represents 24 bones
timeStampNs int64 Unix timestamp (nanoseconds)
p string Current bone's Pose (position and rotation, seven values)
t long IMU timestamp.
va string Position velocity (x,y,z) angular velocity (x,y,z)
wva string Position acceleration (x,y,z) angular acceleration (x,y,z)

5. Tracker Independent Tracking

Original data of tracking Tracker

JSON data description

{"joints":[{"p":"0.0,-0.0,-0.0,0.0,0.0,-0.0,-0.0","va":"0.0,0.0,-0.0,0.0,0.0,0.0","wva":"0.0,0.0,-0.0,-0.0,0,0"},{"p":"-0.0,0.0,-0.0,-0.0,0.0,0.0,-0.0","va":"-0.0,0.0,0.0,0.0,-0.0,0.0","wva":"0.0,-0.0,-1.0,-0.0,-0.0,-0"}],"len":2,"timeStampNs":1733287634681455104,"sn":PC2310MLJ6050513G}

key Type Description
joints Json Array, represents all Tracker data (currently supports up to 3)
timeStampNs int64 Unix timestamp (nanoseconds)
p string Current bone's Pose (position and rotation, seven values)
va string Position velocity (x,y,z) Unit: millimeter Angular velocity (x,y,z) Unit: meter
wva string Position acceleration (x,y,z) Unit: millimeter Angular acceleration (x,y,z) Unit: meter
sn string Tracker serial number, used to distinguish different trackers

C++ API Usage Example

  1. Integrate the SDK file path into the project's CMakeList.txt:

    target_include_directories(ConsoleDemo PUBLIC ${PROJECT_SOURCE_DIR}/../../../SDK/include)

    target_link_directories(ConsoleDemo PUBLIC ${PROJECT_SOURCE_DIR}/../../../SDK/linux/64)

#include <PXREARobotSDK.h>

// SDK message callback function inline void OnPXREAClientCallback(void* context,PXREAClientCallbackType type,int status,void* userData) { auto& sdkCaller = ((SDKCaller)context); switch (type) { case PXREAServerConnect: //qDebug() <<"server connect" << Qt::endl; case PXREAServerDisconnect: //qDebug() <<"server disconnect" << Qt::endl; break; case PXREADeviceFind: //qDebug() <<"device find"<<(const char*)userData<< Qt::endl; break; case PXREADeviceMissing: //qDebug() <<"device missing"<<(const char*)userData<< Qt::endl; break; case PXREADeviceStateJson: break; } }

// Initialize SDK and register callback function
void testInit()
{
    PXREAInit(this, OnPXREAClientCallback, PXREAFullMask);
}

// Release SDK
void testDeinit()
{
    PXREADeinit();
}

// Send message
void testDeviceControlJson(const QString& devID,const QString& parameterJson)
{
    PXREADeviceControlJson(devID.toUtf8().constData(),parameterJson.toUtf8().constData());
}