# JSON C++/Python SDK\_Angle Manual

## 1. Introduction

### 1.1. Feature

This SDK acquires hand joint angle data based on the JSON transmission format and supports both Windows and Linux environments.

### 1.2. File Download

&#x20;   (Download the Angle file which is open sourced)

* Windows:&#x20;

{% embed url="<https://drive.google.com/file/d/14urQvCe7j9YKM_1yPwurkpTL5jRuZxHK/view?usp=drive_link>" %}

* Linux (ARM is supported): You can refer to the example or compile and run it yourself&#x20;

{% embed url="<https://drive.google.com/drive/folders/16uS8CqG3d3ts3YCvBEgy6MSfyyUtyGlb?usp=drive_link>" %}

### 1.3. HandDriver Settings

* Check "Data Transmission" to turn on the data transmission.
* To transmit IMU data (only supported by gloves with IMU), select the IMU option; otherwise, IMU data will not be transmitted.
* Select the FPS, which supports 120Hz, 90Hz, or 60Hz. The default FPS is 120Hz.
* Click the "+" icon in the target address field, then enter the IP address and port number of the receiving side to enable data transmission (input 127.0.0.1 for local target).
* **The port number defaults to 5555. If modified, please keep it consistent with the SDK side.**
* After configuration, click the "Apply" button to save.

#### 1.3.1. HandDriver 2.2.2 or Above

Please select JSON as the Format. <mark style="color:red;">**When using this SDK, choose "Euler" for the Content and do not check the Old Plugin.**</mark>

<figure><img src="https://2082502898-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8s1Ia6TfFovgyJ5JsDJZ%2Fuploads%2FqvYakyVIq8v0FzzwOoXz%2Fimage.png?alt=media&#x26;token=d1f4d814-d539-42f7-8172-339b2324d593" alt="" width="563"><figcaption></figcaption></figure>

#### 1.3.2. HandDriver 2.2.1. and Earlier

* Format: Euler, Quater, and VMC are three mutually exclusive options—choose only one. When using this SDK, please select "Euler"
* When "Old Plugin" is checked, angle values are transmitted according to versions prior to HandDriver 2.1.1. For details, [see here](https://udexreal.gitbook.io/udexreal-docs/glove-data-c++-python-sdk-for-robotics/hand-model-and-data-specification).

<figure><img src="https://2082502898-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8s1Ia6TfFovgyJ5JsDJZ%2Fuploads%2FyzwGICk9yddnBC9txfhF%2Fimage.png?alt=media&#x26;token=fe137dfa-17d0-4c5f-a5d2-f43fc19c8629" alt="" width="563"><figcaption></figcaption></figure>

## 2. Coordinate system and data definition

### 2.1. Coordinate System and Data Description

#### 2.1.1. HandDriver2.1.2 version after 2.1.2.

Please refer to this document:[Hand Model and Data Description](https://udexreal.gitbook.io/udexreal-docs/glove-data-c++-python-sdk-for-robotics/hand-model-and-data-specification)

#### 2.1.2. HandDriver2.1.1 version before 2.1.1

The data sent refers to the right-hand coordinate system standard, as shown in the figure below.

<figure><img src="https://2082502898-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8s1Ia6TfFovgyJ5JsDJZ%2Fuploads%2F5C0eUQwmuwZbBl8j8QRE%2Fimage.png?alt=media&#x26;token=60e6f67d-d58c-4cbf-9417-e6a46e022743" alt="" width="216"><figcaption></figcaption></figure>

### 2.2. Data Format

The sending data is shown in the figure below and includes information such as the character name, calibration status, finger joint rotation angles, IMU quaternion data (**only available when the glove is equipped with an IMU and IMU transmission is enabled**) and controllers data.

<figure><img src="https://2082502898-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8s1Ia6TfFovgyJ5JsDJZ%2Fuploads%2FGr6vBdn4YYsFk7GcHFE7%2Fimage.png?alt=media&#x26;token=54595c54-e1fa-469c-9bdd-df7ae6668878" alt="" width="375"><figcaption></figcaption></figure>

```json
{
    "Udhand": { //the corresponding Character name in HandDriver
        "Bones": [
            {
                "Name": "Head", 
                "Parent": 0,
                "Location": [ 0,0,0 ],
                "Rotation": [ 0,0,0 ],
                "Scale": [ 0,0,0 ]
            }
        ],
        "Parameter": [
                { "Name": "L_CalibrationStatus", "Value": 3 },//Left hand calibration status -1:Not calibrated，0:fist，1:fingers together，2:fingers spreading，3:Calibration completed
                { "Name": "l0", "Value": 0 },//Left hand Thumb IP pitch                        
                { "Name": "l1", "Value": 0 },//Left hand Thumb MP pitch                        
                { "Name": "l2", "Value": 0 },//Left hand Thumb CM pitch                        
                { "Name": "l3", "Value": 0 },//Left hand Thumb CM yaw                        
                { "Name": "l4", "Value": 0 },//Left hand Index DIP pitch                        
                { "Name": "l5", "Value": 0 },//Left hand Index PIP pitch
                { "Name": "l6", "Value": 0 },//Left hand Index MP pitch
                { "Name": "l7", "Value": 0 },//Left hand Index MP yaw
                { "Name": "l8", "Value": 0 },//Left hand Middle DIP pitch
                { "Name": "l9", "Value": 0 },//Left hand Middle PIP pitch
                { "Name": "l10", "Value": 0 },//Left hand Middle MP pitch
                { "Name": "l11", "Value": 0 },//Left hand Middle MP yaw
                { "Name": "l12", "Value": 0 },//Left hand Ring DIP pitch
                { "Name": "l13", "Value": 0 },//Left hand Ring PIP pitch
                { "Name": "l14", "Value": 0 },//Left hand Ring MP pitch
                { "Name": "l15", "Value": 0 },//Left hand Ring MP yaw
                { "Name": "l16", "Value": 0 },//Left hand Pinky DIP pitch
                { "Name": "l17", "Value": 0 },//Left hand Pinky PIP pitch
                { "Name": "l18", "Value": 0 },//Left hand Pinky MP pitch
                { "Name": "l19", "Value": 0 },//Left hand Pinky MP yaw
                { "Name": "l20", "Value": 0 },//Left hand Thumb CM roll
                { "Name": "l21", "Value": 0 },//Left hand Index MP roll
                { "Name": "l22", "Value": 0 },//Left hand Pinky MP roll
                { "Name": "l23", "Value": -1 },//Left hand Reserved for gesture recognition
                { "Name": "l24", "Value": -1 },//Left hand IMU quaternion-W
                { "Name": "l25", "Value": -1 },//Left hand IMU quaternion-X
                { "Name": "l26", "Value": -1 },//Left hand IMU quaternion-Y
                { "Name": "l27", "Value": -1 },//Left hand IMU quaternion-Z
                { "Name": "l_joyX", "Value": 0 },
                { "Name": "l_joyY", "Value": 0 },
                { "Name": "l_aButton", "Value": false },
                { "Name": "l_bButton", "Value": false },
                { "Name": "l_joyButton", "Value": false },
                { "Name": "l_menu", "Value": false },
                { "Name": "R_CalibrationStatus", "Value": 3 },////Right hand calibration status -1:Not calibrated，0:fist，1:fingers together，2:fingers spreading，3:Calibration completed
                { "Name": "r0", "Value": 0 },//Right hand Thumb IP pitch
                { "Name": "r1", "Value": 0 },//Right hand Thumb MP pitch
                { "Name": "r2", "Value": 0 },//Right hand Thumb CM pitch
                { "Name": "r3", "Value": 0 },//Right hand Thumb CM yaw
                { "Name": "r4", "Value": 0 },//Right hand Index DIP pitch
                { "Name": "r5", "Value": 0 },//Right hand Index PIP pitch
                { "Name": "r6", "Value": 0 },//Right hand Index MP pitch
                { "Name": "r7", "Value": 0 },//Right hand Index MP yaw
                { "Name": "r8", "Value": 0 },//Right hand Middle DIP pitch
                { "Name": "r9", "Value": 0 },//Right hand Middle PIP pitch
                { "Name": "r10", "Value": 0 },//Right hand Middle MP pitch
                { "Name": "r11", "Value": 0 },//Right hand Middle MP yaw
                { "Name": "r12", "Value": 0 },//Right hand Ring DIP pitch
                { "Name": "r13", "Value": 0 },//Right hand Ring PIP pitch
                { "Name": "r14", "Value": 0 },//Right hand Ring MP pitch
                { "Name": "r15", "Value": 0 },//Right hand Ring MP yaw
                { "Name": "r16", "Value": 0 },//Right hand Pinky DIP pitch
                { "Name": "r17", "Value": 0 },//Right hand Pinky PIP pitch
                { "Name": "r18", "Value": 0 },//Right hand Pinky MP pitch
                { "Name": "r19", "Value": 0 },//Right hand Pinky MP yaw
                { "Name": "r20", "Value": 0 },//Right hand Thumb CM roll
                { "Name": "r21", "Value": 0 },//Right hand Index MP roll
                { "Name": "r22", "Value": 0 },//Right hand Pinky MP roll
                { "Name": "r23", "Value": -1 },//Right hand Reserved for gesture recognition
                { "Name": "r24", "Value": -1 },//Right hand IMU quaternion-W
                { "Name": "r25", "Value": -1 },//Right hand IMU quaternion-X
                { "Name": "r26", "Value": -1 },//Right hand IMU quaternion-Y
                { "Name": "r27", "Value": -1 },//Right hand IMU quaternion-Z
                { "Name": "r_joyX", "Value": 0 },
                { "Name": "r_joyY", "Value": 0 },
                { "Name": "r_aButton", "Value": false },
                { "Name": "r_bButton", "Value": false },
                { "Name": "r_joyButton", "Value": false },
                { "Name": "r_menu", "Value": false }
        ]
    }
}
```

### 2.3. The Receiving Angle

Regarding the receiving angle value, please refer to the HandDriver data page. The data on this page is consistent with the SDK receiving data.

* Consistent positive and negative
* Specific values are expressed as integers when displayed in HandDriver
* For detailed instructions, please see here: UDEXREAL HandDriver Hand Model and Data Description

<figure><img src="https://2082502898-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8s1Ia6TfFovgyJ5JsDJZ%2Fuploads%2FqGZS9BjkeeL1sqfFJa7c%2Fimage.png?alt=media&#x26;token=350e3216-162e-465b-a84a-b65e00cf1244" alt=""><figcaption></figcaption></figure>

## 3. C++ Windows SDK

### 3.1. Data Structure Definition

#### 3.1.1. Character List

```cpp
vector<GloveData>gloveDataList;
```

**Data Structure Description:** Save received character data.

**Parameter Description:** `GloverData` contains information for a single character.

#### 3.1.2. Glove Data

```cpp
struct GloveData
{
    string deviceName;
    HandData handDatas;
};
```

**Data Structure Description:** Save the character's name and hand data.

**Parameter Description:** `handDatas` contains the hand data for a single character.

#### 3.1.3. Hand Data

```cpp
struct HandData
{
    Bone bones;
    handsfingerJoint fingerJoints;
};
```

**Data Structure Description:** Save the character's skeletal data and finger joint data.     &#x20;

**Parameter Description:** `bones` contain the glove skeletal data, while `fingerJoints` contain the glove finger joint data.

#### 3.1.4. Bone Data

```cpp
struct Bone
{
    string name;
    int parent = 0;
    vector<float> location = {};
    vector<float> rotation = {};
    vector<float> scale = {};        
};
```

**Data Structure Description:** Save skeletal data.

**Parameter Description:** Used for adapting data formats for Unreal Engine; the information is currently not in use.

#### 3.1.5. Finger Joint Data

```cpp
struct handsfingerJoint
{
    vector<Parameter> fingerJoint_L;
    vector<Parameter> fingerJoint_R;
};
```

**Data Structure Description:** Save the finger joint data for both hands of the character, including the hand calibration status.

**Parameter Description:** `fingerJoint_L` contains the data for the character's left hand, while `fingerJoint_R` contains the data for the character's right hand.

### 3.2. Data Calling

#### 3.2.1. Retrieve glove data

**3.2.1.1. Retrieve glove driver info**

Example for retrieving device information. You can obtain other device information in a similar manner.

```cpp
//Retrieve the character name for the device; "0" indicates the first device.
string name = glovePtr->gloveDataList[0].deviceName;

//Retrieve the left hand calibration status; note that this information is stored in the finger data array.
float L_CalibrationStatus= glovePtr->gloveDataList[0].handDatas.fingerJoints.fingerJoint_L[0].value;


```

**3.2.1.2. Retrieve Finger Joint Rotation Data from the Glove**

In the `GloveSDK` class, there is an array `gloveDataList` of type `GloveData`, which stores data for all gloves. Access it using the index, for example: `glovePtr->gloveDataList[0].handDatas.fingerJoints.fingerJoint_L[6].value` (Accessed the pitch data of the second phalanx of the l**eft hand index finger** for device **0**, where `fingerJoint_L[6]` corresponds to the image in The corresponding parameters are viewed in the data format.**）。**

{% code overflow="wrap" %}

```cpp
//Retrieve left hand Index intermediate pitch
float L_indexIntermediate pitch= glovePtr->gloveDataList[0].handDatas.fingerJoints.fingerJoint_L[6].value;
```

{% endcode %}

### 3.3. Definition of Interface

#### 3.3.1. Initialization

```cpp
bool Initialize(const char* udp_ip, unsigned short udp_port);
```

**Function description:** Create a Socket according to the parameters. If successful, start a thread to receive data.

**Parameter description:** `udp_ip` is the IP address for receiving data, `udp_port` is the port number, which can be the same as the sending HandDriver.

**Return value description:** Returns true if successful, false if failed.

#### 3.3.2. Close thread

```cpp
void Shutdown();
```

**Function description:** Used to close the receiving thread and clean up the Socket.     &#x20;

**Parameter description:** None.

**Return value description:** None.

#### 3.3.3. Registering callback function

```cpp
void RegisterGloveCallBack(GloveCallBack callback);
```

**Function description: Used to print all data for a character to check the data status.**   &#x20;

**Parameter Description:** `inputGloveData` is a function of type `GloveData`, which takes a `GloveData` object as input when called.

**Return value description:** None.

### 3.4. Windows Demo and Description

#### 3.4.1. Demo project description

The **`HandDriver_x64_Cpp_Angle`**&#x70;roject contains the **`HandDriver_x64_Cpp_Angle`**&#x66;older and the **`HandDriver_x64_Cpp_Angle.sln`** file. The **`HandDriver_x64_Cpp_Angle`**&#x66;older includes the library files, which can be copied for standalone use. The version of Visual Studio is VS2019(When using higher versions, follow the log changes), using C++14. To run the example program, open **`HandDriver_x64_Cpp_Angle.sln`** and select the x64 platform.

<figure><img src="https://2082502898-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8s1Ia6TfFovgyJ5JsDJZ%2Fuploads%2FYPJzxsmNPXi1CqzVZJsN%2Fimage.png?alt=media&#x26;token=6e7ab360-cff8-42e7-adad-0625aed2357a" alt="" width="563"><figcaption></figcaption></figure>

#### **3.4.2. Brief introduction to code flow**

1. **Declare a function to register the callback**

```cpp
void OnNewGloveData(GloveSDK* glovePtr)
{
        /*
        * 打印手数据
        * Print gloveData
        */
         
        //Print all data for character "0"
        glovePtr->ShowGloveData(glovePtr->gloveDataList[0]);
        cout << endl << endl;


}
```

2. **Create an instance of GloveSDK**

```cpp
GloveSDK glove_sdk;
```

3. **Register callback function**

```cpp
glove_sdk.RegisterGloveCallBack(OnNewGloveData);
```

4. **Create a socket and check if it is successful. If successful, start receiving and parsing data**

```cpp
if (!glove_sdk.Initialize("127.0.0.1", 5555))
        {
                cerr << "Failed to initialize GloveSDK." << endl;
                return -1;
        }
```

5. **Start the print thread and print the glove\_sdk data**

```cpp
thread print_th(print_control_thread, &glove_sdk);
```

6. **Calling the function to print only the frame number**

```cpp
while (true)
        {
                int a;
                cin >> a;

                switch (a)
                {

                case 1:
                        OnlyPrintFrame();
                        break;

                case 0:
                        glove_sdk.Shutdown();
                        printf("Shutdown");
                        break;
                }
        }
```

7. **Waiting for input save program**

```cpp
getchar();
```

8. **Close and clean up the socket**

```cpp
glove_sdk.Shutdown();
printf("Shutdown");
```

## 4. C++ Linux SDK

### 4.1. File Directory

The Linux Cpp SDK folder contains: the folder "include" (which contains the header files required for JSON parsing), the folder "lib" (which contains the necessary JSON dynamic libraries such as libjsoncpp.so and libjsoncpp.so.27), UDEServer.h (the SDK header file), UDEServer.cxx (the implementation of methods), main.cxx (an example), build.sh (an example build file), CMakeLists.txt, and ReadMe.txt.

<figure><img src="https://2082502898-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8s1Ia6TfFovgyJ5JsDJZ%2Fuploads%2FKt5FgeMsdmq9JW0l6jGk%2Fimage.png?alt=media&#x26;token=30bcef12-892d-4e93-88f5-8c0848138cb1" alt="" width="152"><figcaption></figcaption></figure>

### 4.2. Data Format

[Please click here for the format.](#id-2.2.-data-format)

### 4.3. Data Calling

Include the header file UDEServer.h first and complete the initialization of the server.The method for obtaining the received list of character names is as follows:

{% code overflow="wrap" %}

```cpp
#include "UDEServer.h"

//create new SDK instance
UDEGloveSDK sdk;
//initialization method
sdk.Initialize();

//start server listening
sdk.StartListening();

//Call the GetRoleNameList() method to get the list of received character names
vector<string> list = sdk.GetRoleNameList();
```

{% endcode %}

The default port number of the server is 5555. You can obtain the current port number or set the port through below method:

```cpp
int port = sdk.GetPortNum();

int newPort = 1234;
sdk.SetPortNum(newPort);
```

Close data reception or obtain current status in server listening.

```cpp
//Server status enumeration parameters
enum ServerStatus
{
    NO_INIT, 
    READY, 
    IN_LISTENING, 
    END
};

int status = sdk.GetStatus()

//close server listener
sdk.EndListening();
```

According to the specified character name, all knuckle data can be obtained with the type of vector. The names of the finger joints and the array of Euler angles can be obtained corresponding to the index order in GloveDataHeaders. The controller data can also be obtained. An array of the type float can be obtained according to the index order in ControllerHeaders, which corresponds to the controller parameters.

{% code overflow="wrap" %}

```cpp
//Vector3Float struct
struct Vector3Float
{
    float x;
    float y;
    float z;

    Vector3Float(float X, float Y, float Z)
    {
        this->x = X;
        this->y = Y;
        this->z = Z;
    }
};

//The name index corresponding to the return value of the finger joint
string GloveDataHeaders[30] = 
{
    "LeftThumb1", 
    "LeftThumb2", 
    "LeftThumb3", 
    "LeftIndex1", 
    "LeftIndex2", 
    "LeftIndex3", 
    "LeftMiddle1",
    "LeftMiddle2",
    "LeftMiddle3",
    "LeftRing1",
    "LeftRing2",
    "LeftRing3",
    "LeftPinky1", 
    "LeftPinky2", 
    "LeftPinky3", 
    "RightThumb1", 
    "RightThumb2", 
    "RightThumb3", 
    "RightIndex1", 
    "RightIndex2", 
    "RightIndex3",
    "RightMiddle1",
    "RightMiddle2",
    "RightMiddle3",
    "RightRing1",
    "RightRing2",
    "RightRing3",
    "RightPinky1", 
    "RightPinky2", 
    "RightPinky3", 
};

//The name index corresponding to the controller return value
string ControllerHeaders[12] = 
{
    "Left Joy X",
    "Left Joy Y",
    "Left A Button",
    "Left B Button",
    "Left Joy Button",
    "Left Menu Button",
    "Right Joy X",
    "Right Joy Y",
    "Right A Button",
    "Right B Button",
    "Right Joy Button",
    "Right Menu Button"
};

vector<string> list = sdk.GetRoleNameList();
if(list.size() > 0)
{
    //Get the data of the first character by default
    auto FingerData = sdk.GetVecFingerData(list[0]);
    
    //Controller parameters
    auto ControllerData = sdk.GetVecControllerData(list[0]);
}
```

{% endcode %}

The corresponding entries obtained are as follows:

```cpp
{
    "LeftThumb1", {0, 0, 0};
    "LeftThumb2", {0, 0, 0};
    "LeftThumb3", {0, 0, 0};
    ...
    "RightThumb1", {0, 0, 0};
    "RightThumb2", {0, 0, 0};
    "RightThumb3", {0, 0, 0};
    ...
    "Left Joy X", 0;
    "Left Joy Y", 0;
    "Left A Button", 0;
    "Left B Button", 0;
    ...
}
```

The rules for knuckle names are Left/Right + Thumb/Index/Middle/Ring/Pinky + 1/2/3 (joint 1/joint 2/joint 3). The order of the angle array is {pitch, yaw, roll}.

Joy X and Joy Y in the controller data correspond to joystick parameters, ranging from (-1,1) as floating numbers. All other button parameters are also set to floating numbers 0 or 1 for consistency, corresponding to untriggered or triggered.

### 4.4. Definition of Interface

* **Initialization**

```cpp
int Initialize();
```

**Function description:** Socket initialization, including the required declaration and calling to create a server.

**Return value description:** If successful, return 0; if failed, return -1.

* **Set Port Number**

```cpp
void SetPortNum(int port);
```

**Function description:** Set the server listener port number.

**Parameter description:** The port number is integer type.

* **Get Port Number**

```cpp
int GetPortNum();
```

**Function description:** Get the server listener port number.

**Return value description:** The port number is integer type.

* **Start server listener**

```cpp
void StartListening();
```

**Function Description:** The start server listener method can obtain parameters in the loop.

* **Shut down server listener**

```cpp
void EndListening();
```

**Function description:** Close the server listener.

* **Get server status**

```cpp
ServerStatus GetStatus();
```

&#x20;**Function description:** Get the current server status.

**Return value description:** ServerStatus enumeration parameter, 0 means NO\_INIT (not initialized), 1 means READY, 2 means IN\_LISTENING (listening), 3 means END (listening terminated).

* **Get a list of character names**

```cpp
vector<string> GetRoleNameList();
```

**Function description:** Get a string list of all received character names.

**Return value description:** name string array.

* **Get knuckle data**

```cpp
map<string, vector<float>> GetFingerData(string RoleName);
```

**Function description:** Get the knuckle data of the specified character.

**Parameter description:** Character name in String type.

**Return value description:** Euler angle array sorted in the same order as the character index in GloveDataHeaders.

* **Get controller data**

```cpp
map<string, float> GetControllerData(string RoleName);
```

**Function description:** Get controller data for the specified character.&#x20;

**Parameter description:** Character name in String type.&#x20;

**Return value description:** A float array sorted in the same order as the character index in ControlHeaders.

### 4.5. Example

The main.cxx provides an example of calling the SDK interface within the main method to receive and print data. An executable file can be generated by running build.sh.

1. Start the "Terminal", enter the root folder of the SDK, run the following command:

```bash
$ sudo sh ./build.sh
```

2. This can generate an executable example ServerSample, which can be run in the same directory using the following command:

```bash
$ ./ServerSample
```

And then the link library libUDEServer.so of the project can be found in the folder "build".

## 5. Python Linux SDK

### 5.1. Data Format

[Please click here for the format.](#id-2.2.-data-format)

### 5.2. Data Calling

The method for obtaining the received list of character names is as follows:

```python
sdk = UDEGloveSDK()  # Create an instance of the SDK
sdk.initialize()  # Initialize the SDK
sdk.start_listening()  # Start listening for data
role_list = sdk.get_role_name_list()  # Get the list of role names
```

The default port number of the server is 5555. You can obtain the current port number or set the port through below method:

```python
self.port = 5555  # Port number for the server
self.sock = None  # Socket object for communication
self.server_addr = ("0.0.0.0", self.port)  # Server address and port
```

Close data reception or obtain current status in server listening.

```python
# Enum-like class to represent server status
class ServerStatus:
    NO_INIT = 0  # Server not initialized
    READY = 1  # Server ready
    IN_LISTENING = 2  # Server is listening for data
    END = 3  # Server has stopped
    
status = sdk.cur_status  # Get the current server status

sdk.end_listening()  # Stop listening
```

According to the specified character name, all knuckle data can be obtained with the type of vector. The names of the finger joints and the array of Euler angles can be obtained corresponding to the index order in GloveDataHeaders. The controller data can also be obtained. An array of the type float can be obtained according to the index order in ControllerHeaders, which corresponds to the controller parameters.

{% code overflow="wrap" %}

```python
# Class representing a 3D vector with float values
class Vector3Float:
    def __init__(self, x: float, y: float, z: float):
        self.x = x
        self.y = y
        self.z = z
        
# Headers for glove data
GloveDataHeaders = [
    "LeftThumb1", "LeftThumb2", "LeftThumb3", "LeftIndex1", "LeftIndex2", "LeftIndex3",
    "LeftMiddle1", "LeftMiddle2", "LeftMiddle3", "LeftRing1", "LeftRing2", "LeftRing3",
    "LeftPinky1", "LeftPinky2", "LeftPinky3", "RightThumb1", "RightThumb2", "RightThumb3",
    "RightIndex1", "RightIndex2", "RightIndex3", "RightMiddle1", "RightMiddle2", "RightMiddle3",
    "RightRing1", "RightRing2", "RightRing3", "RightPinky1", "RightPinky2", "RightPinky3"
]

# Headers for controller data
ControllerHeaders = [
    "Left Joy X", "Left Joy Y", "Left A Button", "Left B Button", "Left Joy Button",
    "Left Menu Button", "Right Joy X", "Right Joy Y", "Right A Button", "Right B Button",
    "Right Joy Button", "Right Menu Button"
]

role_list = sdk.get_role_name_list()  # Get the list of role names
if len(role_list) > 0: 
    for role_name in role_list:
        finger_data = sdk.get_vec_finger_data(role_name)  # Get finger data
        controller_data = sdk.get_vec_controller_data(role_name)  # Get controller data
```

{% endcode %}

The corresponding entry examples obtained are as follows:

```python
{
    "LeftThumb1", {0, 0, 0};
    "LeftThumb2", {0, 0, 0};
    "LeftThumb3", {0, 0, 0};
    ...
    "RightThumb1", {0, 0, 0};
    "RightThumb2", {0, 0, 0};
    "RightThumb3", {0, 0, 0};
    ...
    "Left Joy X", 0;
    "Left Joy Y", 0;
    "Left A Button", 0;
    "Left B Button", 0;
    ...
}
```

The rules for knuckle names are Left/Right + Thumb/Index/Middle/Ring/Pinky + 1/2/3 (joint 1/joint 2/joint 3). The order of the angle array is {pitch, yaw, roll}.

Joy X and Joy Y in the controller data correspond to joystick parameters, ranging from (-1,1) as floating numbers. All other button parameters are also set to floating numbers 0 or 1 for consistency, corresponding to untriggered or triggered.

### 5.3. Definition of Interface

* **Initialization**

```python
def initialize(self):
```

**Function description:** Socket initialization, including the required declaration and calling to create a server.&#x20;

**Return value description:** If successful, return 0; if failed, return -1.

* **Set Port Number**

```python
def __init__(self):
    self.port = 5555
```

**Function description:** Set the port number of server listener.

**Parameter description:** The port number is integer type.

* **Get Port Number**

```python
Port = sdk.port
```

**Function description:** Get the port number of server listener.

**Return value description:** The port number is integer type.

* **Start service listener**

```python
def start_listening(self):
```

**Function description:** start service listener.

* **Shut down server listener**

```python
def end_listening(self):
```

**Function description:** Close the server listener.

* **Get server status**

```python
status = sdk.cur_status
```

**Function description:** Get the current server status.

**Return value description:** ServerStatus enumeration parameter, 0 means NO\_INIT (not initialized), 1 means READY, 2 means IN\_LISTENING (listening), 3 means END (listening terminated).

* **Get a list of character names**

```python
def get_role_name_list(self) -> List[str]:
```

**Function description:** Get a string list of all received character names.

**Return value description:** name string array.

* **Get knuckle data**

```python
def get_vec_finger_data(self, role_name: str) -> List[Vector3Float]:
```

**Function description:** Get the knuckle data of the specified character.

**Parameter description:** Character name in String type.

**Return value description:** Euler angle array sorted in the same order as the character index in GloveDataHeaders.

* **Get controller data**

```python
def get_vec_controller_data(self, role_name: str) -> List[float]:
```

**Function description:** Get the controller data of the specified character.

**Parameter description:** Character name in String type.

**Return value description:** A float array sorted in the same order as the character index in ControlHeaders.

### 5.4. Example

Start "Terminal" in the directory where the .py file is located and run the following command:

```python
$ python3 HandDriver_Linux_Py_Angle_20250402.py
```
