| Version | Revision Date | Modified By | Change Description |
|---|---|---|---|
| V1.0 | 20260415 | damon | Initial draft |
| V1.1 | 20260726 | damon | Upgrade update of main controller V2.1.24 and previous error corrections |
| V1.2 | 20260729 | damon | Information update for main controller V2.2.11 upgrade - Add compliance control switch and parameter setting interface - Add lifting bracket position control interface |
1 SDK Overview
Terminology:
- Low-Level Motion Control Interface: In low-level development mode, you can use the Python and C++ low-level APIs to perform operations such as direct joint control.
- High-Level Application Development Interface: In high-level development mode, you can use LimX's built-in motion-control algorithms to perform tasks such as dual-arm manipulation, forward and backward locomotion, and robot lighting management.
1.1 Communication Architecture Diagram
The following diagram shows the composition of the robot communication architecture and the interactions among its components. The motion-control computer contains motion-control algorithm nodes and application-logic modules, which communicate with the robot through the High-Level Application Development Interface and the Low-Level Motion Control Development Interface. The robot consists of a network switch, a main controller, and various hardware components. The motion-control computer coordinates the operation of these components.
1.2 View/Set the Robot Model
When compiling and running control algorithms and simulator programs, selecting the correct robot model is critical. You can check the robot model and assign it to the ROBOT_TYPE environment variable to ensure that the correct robot configuration is identified and used for different tasks. The following steps describe how to view and configure the robot model.
- Select and connect to your robot's Wi-Fi hotspot. The password is
12345678. Enterhttp://10.192.1.2:8080in a browser to open the "Robot Information" page. As shown below, the SN (serial number) isWF_TRON2A_001, whereWF_TRON2Ais the robot model.


- Set the robot model: open a Bash terminal and run the following command. The RL training, control-algorithm, and simulator programs can then obtain the correct robot model information during compilation and execution.
echo 'export ROBOT_TYPE=WF_TRON2A' >> ~/.bashrc && source ~/.bashrc
1.3 Development Expansion Module Computer
The computer built into the development expansion module is primarily used to develop robot-related algorithms and applications. You can connect to the robot's onboard system through Wi-Fi or a wired network and log in to the development computer as follows:
- Select and connect to your robot's Wi-Fi hotspot. The password is
12345678. - Log in to the development computer via SSH:
-
Login address:
10.192.1.4 -
Login password:
123456 -
Run the following command in a terminal. Confirm the host key when connecting for the first time:
ssh guest@10.192.1.4 -
Developer computer system configuration:
- Operating system: Ubuntu 22.04.6 LTS
- ROS 2: ROS 2 Humble is installed by default.
- ROS 1: ROS 1 Noetic is installed by default.
-
2 Low-Level Motion Control Interface
The cross-platform low-level motion-control development interface library provides a unified C++/Python API that is compatible with ROS 1, ROS 2, and non-ROS systems, enabling rapid porting and deployment of motion-control algorithms.
2.1 C++ Motion Control Development Interface
2.1.1 Overview
Through a hardware abstraction layer and standardized communication protocols, the Low-Level Motion Control Development Interface allows developers to switch seamlessly between simulation and physical hardware, significantly reducing the effort required for multi-platform adaptation.
2.1.2 Install the Motion Control Development Library
- Linux x86_64 environment
git clone https://github.com/limxdynamics/limxsdk-lowlevel.git
pip install limxsdk-lowlevel/python3/amd64/limxsdk-*-py3-none-any.whl
- Linux aarch64 environment
git clone https://github.com/limxdynamics/limxsdk-lowlevel.git
pip install limxsdk-lowlevel/python3/aarch64/limxsdk-*-py3-none-any.whl
- Windows environment
git clone https://github.com/limxdynamics/limxsdk-lowlevel.git
pip install limxsdk-lowlevel/python3/win/limxsdk-*-py3-none-any.whl
2.1.3 getInstance Interface Description
| Item | Description |
|---|---|
| Function Name | getInstance |
| Function Prototype | static Tron2* getInstance(); |
| Function Overview | Gets a pointer to the singleton instance of the Tron2 robot class |
| Parameters | None |
| Return Value | Tron2*, pointer to a Tron2 instance |
| Remarks | Uses the singleton pattern to ensure that only one Tron2 instance exists in the program |
Code Example:
#include <thread>
// Include the limxsdk::Tron2 header file to use the Tron2 class
#include "limxsdk/tron2.h"
// Use the limxsdk namespace
using namespace limxsdk;
int main(int argc, char *argv[]){
// Gets the singleton instance of the TRON2 class
Tron2* robot = Tron2::getInstance();
// Infinite loop to keep the program running
while (true)
{
// Sleep for 1000 milliseconds
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
return 0;
}
2.1.4 init Interface Description
| Item | Description |
|---|---|
| Function Name | init |
| Function Prototype | bool init(const std::string& robot_ip_address = "127.0.0.1"); |
| Function Overview | Initializes the communication runtime environment for the low-level SDK. Call this function in the main function before calling any other interface. |
| Parameters | robot_ip_address: the robot IP address. For simulation, it is usually set to "127.0.0.1"; for a physical robot, set it to "10.192.1.2". |
| Return Value | Returns true on successful initialization; otherwise, returns false. |
| Remarks | None |
Code Example:
#include <thread>
// Include the limxsdk::Tron2 header file to introduce the Tron2 class
#include "limxsdk/tron2.h"
// Use the limxsdk namespace to simplify references to the Tron2 class
using namespace limxsdk;
int main(int argc, char *argv[]){
// Gets the singleton instance of the Tron2 class
Tron2* robot = Tron2::getInstance();
// Default robot IP address
std::string robot_ip = "127.0.0.1";
if (argc > 1)
{
// If a command-line argument is provided, use it as the robot IP address
robot_ip = argv[1];
}
// Initialize the communication runtime environment for the motion-control algorithm program
if (!robot->init(robot_ip))
{
// If initialization fails, exit the program
exit(1);
}
// Infinite loop to keep the program running
while (true)
{
// Sleep for 1000 milliseconds
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
return 0;
}
2.1.5 getMotorNumber Interface Description
| Item | Description |
|---|---|
| Function Name | getMotorNumber |
| Function Prototype | uint32_t getMotorNumber(); |
| Function Overview | Gets the number of robot motors. |
| Parameters | None |
| Return Value | Returns an unsigned integer representing the total number of motors in the robot. |
| Remarks | For example, the dual-wheel-leg configuration has 10 motors. |
Code Example:
#include <thread>
// Include the limxsdk::Tron2 header file to introduce the Tron2 class
#include "limxsdk/tron2.h"
// Use the limxsdk namespace to simplify references to the Tron2 class
using namespace limxsdk;
int main(int argc, char *argv[]){
// Gets the singleton instance of the Tron2 class
Tron2* robot = Tron2::getInstance();
// Default robot IP address
std::string robot_ip = "10.192.1.2";
if (argc > 1)
{
// If a command-line argument is provided, use it as the robot IP address
robot_ip = argv[1];
}
// Initialize the communication runtime environment for the motion-control algorithm program
if (!robot->init(robot_ip))
{
// If initialization fails, exit the program
exit(1);
}
// Get the number of motors in the robot
uint32_t motor_num = robot->getMotorNumber();
// Infinite loop to keep the program running
while (true)
{
// Sleep for 1000 milliseconds
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
return 0;
}
2.1.6 subscribeImuData Interface Description
| Item | Description |
|---|---|
| Function Name | subscribeImuData |
| Function Prototype | void subscribeImuData(std::function<void(const ImuDataConstPtr&)> cb); |
| Function Overview | Subscribes to robot IMU data and calls the specified callback function when new IMU data is received. |
| Parameters | cb: callback function used to process new IMU data. |
| Return Value | None |
Remarks - ImuData data structure prototype is as follows:
/**
* @struct ImuData
*
* @brief Structure representing robot IMU data based on sensor feedback.
*
* This structure encapsulates IMU data, including accelerometer data, gyroscope data, and quaternions.
*/
struct ImuData {
uint64_t stamp; // Timestamp in nanoseconds, usually indicating when the data was recorded or generated.
float acc[3]; // Stores IMU accelerometer data to track linear acceleration along the three axes (X, Y, Z).
float gyro[3]; // Stores IMU gyroscope data to track angular velocity or rotational velocity around the three axes (X, Y, Z).
float quat[4]; // Stores IMU quaternion data representing orientation in 3D space (w, x, y, z).
};
// Smart pointer type aliases
typedef std::shared_ptr<ImuData> ImuDataPtr;
typedef std::shared_ptr<ImuData const> ImuDataConstPtr;
Code Example:
#include <thread>
// Include the limxsdk::Tron2 header file to introduce the Tron2 class
#include "limxsdk/tron2.h"
// Use the limxsdk namespace to simplify references to the Tron2 class
using namespace limxsdk;
int main(int argc, char *argv[]){
// Gets the singleton instance of the Tron2 class
Tron2* robot = Tron2::getInstance();
// Default robot IP address
std::string robot_ip = "10.192.1.2";
if (argc > 1)
{
// If a command-line argument is provided, use it as the robot IP address
robot_ip = argv[1];
}
// Initialize the communication runtime environment for the motion-control algorithm program
if (!robot->init(robot_ip))
{
// If initialization fails, exit the program
exit(1);
}
// Subscribe to robot IMU data and specify the callback function
robot->subscribeImuData([](const ImuDataConstPtr& msg) {
// Process the received IMU data here
// For example: read acceleration, angular velocity, or quaternion information
});
// Infinite loop to keep the program running
while (true)
{
// Sleep for 1000 milliseconds
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
return 0;
}
2.1.7 subscribeRobotState Interface Description
| Item | Description |
|---|---|
| Function Name | subscribeRobotState |
| Function Prototype | void subscribeRobotState(std::function<void(const RobotStateConstPtr&)> cb); |
| Function Overview | Subscribes to and receives robot state updates. |
| Parameters | cb: callback function that is called when a robot state update is received. The callback parameter points to RobotState constant pointer to the object. |
| Return Value | None |
Remarks - RobotState data structure prototype is as follows:
/**
* @struct RobotState
*
* @brief Structure representing robot state based on sensor feedback.
*
* This structure encapsulates various data points for monitoring and controlling the robot, including IMU data (accelerometer, gyroscope, quaternion), output torque, current angle, velocity, etc.
*/
struct RobotState {
// Default constructor
RobotState() { }
// Parameterized constructor used to initialize tau, q, and dq vectors with size motor_num, all initialized to 0.0
RobotState(int motor_num)
: tau(motor_num, 0.0)
, q(motor_num, 0.0)
, dq(motor_num, 0.0) { }
uint64_t stamp; // Timestamp, usually indicating when the data was recorded or generated, in nanoseconds
std::vector<float> tau; // Vector storing the current estimated output torque in N·m
std::vector<float> q; // Vector storing the current angle in radians
std::vector<float> dq; // Vector storing the current velocity in rad/s
};
// Smart pointer type aliases
typedef std::shared_ptr<RobotState> RobotStatePtr;
typedef std::shared_ptr<RobotState const> RobotStateConstPtr;
Code Example:
#include <thread>
// Include the limxsdk::Tron2 header file to introduce the Tron2 class
#include "limxsdk/tron2.h"
// Use the limxsdk namespace to simplify references to the Tron2 class
using namespace limxsdk;
int main(int argc, char *argv[]){
// Gets the singleton instance of the Tron2 class
Tron2* robot = Tron2::getInstance();
// Default robot IP address
std::string robot_ip = "10.192.1.2";
if (argc > 1)
{
// If a command-line argument is provided, use it as the robot IP address
robot_ip = argv[1];
}
// Initialize the communication runtime environment for the motion-control algorithm program
if (!robot->init(robot_ip))
{
// If initialization fails, exit the program
exit(1);
}
// Subscribe to robot state updates and specify the callback function
robot->subscribeRobotState([](const RobotStateConstPtr& msg) {
// Process the received RobotState data here
// For example: read joint angle, velocity, torque, IMU, and other state information
});
// Infinite loop to keep the program running
while (true)
{
// Sleep for 1000 milliseconds
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
return 0;
}
2.1.8 publishRobotCmd Interface Description
| Item | Description |
|---|---|
| Function Name | publishRobotCmd |
| Function Prototype | bool publishRobotCmd(const RobotCmd& cmd); |
| Function Overview | Publishes a command to control the robot's joints. |
| Parameters | cmd: the required robot command RobotCmd object. |
| Return Value | bool: indicates whether the command was published successfully. |
| Remarks |
Code Example:
#include <thread>
// Include the limxsdk::Tron2 header file to introduce the Tron2 class
#include "limxsdk/tron2.h"
// Use the limxsdk namespace to simplify references to the Tron2 class
using namespace limxsdk;
int main(int argc, char *argv[]){
// Gets the singleton instance of the Tron2 class
Tron2* robot = Tron2::getInstance();
// Default robot IP address
std::string robot_ip = "10.192.1.2";
if (argc > 1)
{
// If a command-line argument is provided, use it as the robot IP address
robot_ip = argv[1];
}
// Initialize the communication runtime environment for the motion-control algorithm program
if (!robot->init(robot_ip))
{
// If initialization fails, exit the program
exit(1);
}
// Get the number of motors in the robot
uint32_t motor_num = robot->getMotorNumber();
// Create a RobotCmd object containing the number of robot motors
RobotCmd cmd(motor_num);
// Publish the control command
robot->publishRobotCmd(cmd);
// Infinite loop to keep the program running
while (true)
{
// Sleep for 1000 milliseconds
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
return 0;
}
2.1.9 subscribeSensorJoy Interface Description
| Item | Description |
|---|---|
| Function Name | subscribeSensorJoy |
| Function Prototype | void subscribeSensorJoy(std::function<void(const SensorJoyConstPtr&)> cb); |
| Function Overview | On a physical robot, this method subscribes to data from the robot's remote controller. When new remote-controller data is received, the specified callback is invoked with a constant SensorJoy pointer containing the data. |
| Parameters | cb: callback used to receive remote-controller data. Its parameter type is SensorJoyConstPtr, a shared pointer to a constant SensorJoy structure. |
| Return Value | None |
| Remarks |
Code Example:
#include <thread>
// Include the limxsdk::Tron2 header file to introduce the Tron2 class
#include "limxsdk/tron2.h"
// Use the limxsdk namespace to simplify references to the Tron2 class
using namespace limxsdk;
int main(int argc, char *argv[]){
// Gets the singleton instance of the Tron2 class
Tron2* robot = Tron2::getInstance();
// Default robot IP address
std::string robot_ip = "10.192.1.2";
if (argc > 1)
{
// If a command-line argument is provided, use it as the robot IP address
robot_ip = argv[1];
}
// Initialize the communication runtime environment for the motion-control algorithm program
if (!robot->init(robot_ip))
{
// If initialization fails, exit the program
exit(1);
}
// Subscribe to robot remote-controller data
robot->subscribeSensorJoy([](const SensorJoyConstPtr& joy) {
// L1 and R1 pressed
if (joy->buttons[4] == 1 && joy->buttons[7] == 1)
{
// Perform related operations here
}
// Process joystick data
double axes_left_horizontal = joy->axes[0];
double axes_left_vertical = joy->axes[1];
double axes_right_horizontal = joy->axes[2];
double axes_right_vertical = joy->axes[3];
});
// Infinite loop to keep the program running
while (true)
{
// Sleep for 1000 milliseconds
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
return 0;
}
2.1.10 subscribeDiagnosticValue Interface Description
| Item | Description |
|---|---|
| Function Name | subscribeDiagnosticValue |
| Function Prototype | void subscribeDiagnosticValue(std::function<void(const DiagnosticValueConstPtr&)> cb); |
| Function Overview | On a physical robot, this method subscribes to diagnostic values and status information. When the robot publishes diagnostic data, the specified callback is invoked with a constant DiagnosticValue pointer containing the diagnostic data. This allows applications to monitor robot health in real time and respond promptly to possible issues. |
| Parameters | cb: callback function used to receive robot diagnostic values, whose parameter type is DiagnosticValueConstPtr, i.e., a shared pointer to DiagnosticValue constant structure. DiagnosticValue structure contains robot diagnostic-value information, including timestamp, level, name, code, and message fields. |
| Return Value | None |
| Remarks |
Code Example:
#include <thread>
#include <iostream>
// Include the limxsdk::Tron2 header file to introduce the Tron2 class
#include "limxsdk/tron2.h"
// Use the limxsdk namespace to simplify references to the Tron2 class
using namespace limxsdk;
int main(int argc, char *argv[]){
// Gets the singleton instance of the Tron2 class
Tron2* robot = Tron2::getInstance();
// Default robot IP address
std::string robot_ip = "10.192.1.2";
if (argc > 1)
{
// If a command-line argument is provided, use it as the robot IP address
robot_ip = argv[1];
}
// Initialize the communication runtime environment for the motion-control algorithm program
if (!robot->init(robot_ip))
{
// If initialization fails, exit the program
exit(1);
}
// Subscribe to robot diagnostic data
robot->subscribeDiagnosticValue([](const DiagnosticValueConstPtr& msg) {
// Process robot diagnostic values here
// For example, print or process them according to the diagnostic level and message content
std::cout << "Diagnostic Value: " << msg->name << std::endl;
std::cout << "Level: " << msg->level << std::endl;
std::cout << "Code: " << msg->code << std::endl;
std::cout << "Message: " << msg->message << std::endl;
});
// Infinite loop to keep the program running
while (true)
{
// Sleep for 1000 milliseconds
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
return 0;
}
2.1.11 setRobotLightEffect Interface Description
| Item | Description |
|---|---|
| Function Name | setRobotLightEffect |
| Function Prototype | bool setRobotLightEffect(int effect); |
| Function Overview | On a physical robot, this method sets the robot's lighting effect. |
| Parameters | effect: an integer representing the required robot light effect. See Tron2::LightEffect enumeration. |
| Return Value | bool: indicates whether the robot light effect was set successfully. |
Remarks - Light effect enumeration description:
enum LightEffect : int {
STATIC_RED = 0, // static red light
STATIC_GREEN, // static green light
STATIC_BLUE, // static blue light
STATIC_CYAN, // static cyan light
STATIC_PURPLE, // static purple light
STATIC_YELLOW, // static yellow light
STATIC_WHITE, // static white light
LOW_FLASH_RED, // red flashing (slow)
LOW_FLASH_GREEN, // green flashing (slow)
LOW_FLASH_BLUE, // blue flashing (slow)
LOW_FLASH_CYAN, // cyan flashing (slow)
LOW_FLASH_PURPLE, // purple flashing (slow)
LOW_FLASH_YELLOW, // yellow flashing (slow)
LOW_FLASH_WHITE, // white flashing (slow)
FAST_FLASH_RED, // red flashing (fast)
FAST_FLASH_GREEN, // green flashing (fast)
FAST_FLASH_BLUE, // blue flashing (fast)
FAST_FLASH_CYAN, // cyan flashing (fast)
FAST_FLASH_PURPLE, // purple flashing (fast)
FAST_FLASH_YELLOW, // yellow flashing (fast)
FAST_FLASH_WHITE // white flashing (fast)
};
Code Example:
#include <thread>
// Include the limxsdk::Tron2 header file to introduce the Tron2 class
#include "limxsdk/tron2.h"
// Use the limxsdk namespace to simplify references to the Tron2 class
using namespace limxsdk;
int main(int argc, char *argv[]){
// Gets the singleton instance of the Tron2 class
Tron2* robot = Tron2::getInstance();
// Default robot IP address
std::string robot_ip = "10.192.1.2";
if (argc > 1)
{
// If a command-line argument is provided, use it as the robot IP address
robot_ip = argv[1];
}
// Initialize the communication runtime environment for the motion-control algorithm program
if (!robot->init(robot_ip))
{
// If initialization fails, exit the program
exit(1);
}
// Set the robot light effect to static red light
robot->setRobotLightEffect(limxsdk::Tron2::STATIC_RED);
// Infinite loop to keep the program running
while (true)
{
// Sleep for 1000 milliseconds
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
return 0;
}
2.1.12 Reference Examples (Coming Soon)
2.2 Python Motion Control Development Interface
2.2.1 Overview
The Python Motion Control Development Interface provides the same functionality as the C++ interface, allowing developers who are unfamiliar with C++ to develop motion-control algorithms in Python.
Python is easy to learn and offers concise syntax and a rich collection of third-party libraries, allowing developers to get started quickly and implement algorithms efficiently. Through the Python interface, developers can use Python's dynamic features for rapid prototyping and experimental validation, accelerating algorithm iteration and optimization. Python's cross-platform capabilities and extensive ecosystem also make motion-control algorithms easier to deploy across different platforms and environments.
Python's flexibility also simplifies rapid deployment to simulation and physical-robot environments. Developers can integrate algorithm models with simulation platforms and physical hardware for rapid iteration and performance validation.
2.2.2 Install the Motion Control Development Library
- Linux x86_64 environment
git clone https://github.com/limxdynamics/limxsdk-lowlevel.git
pip install limxsdk-lowlevel/python3/amd64/limxsdk-*-py3-none-any.whl
- Linux aarch64 environment
git clone https://github.com/limxdynamics/limxsdk-lowlevel.git
pip install limxsdk-lowlevel/python3/aarch64/limxsdk-*-py3-none-any.whl
- Windows environment
git clone https://github.com/limxdynamics/limxsdk-lowlevel.git
pip install limxsdk-lowlevel/python3/win/limxsdk-*-py3-none-any.whl
2.2.3 __init__ Interface Description
| Item | Description |
|---|---|
| Function Name | __init__ |
| Function Prototype | def __init__(self, robot_type: robot.RobotType) |
| Function Overview | Specifies the robot type during initialization and creates a local robot instance of the corresponding type. |
| Parameters | robot_type: enumeration value representing the robot type, type is RobotType.Tron2. |
| Return Value | None |
| Remarks | None |
Code Example:
import sys
import limxsdk.robot.Robot as Robot
import limxsdk.robot.RobotType as RobotType
if __name__ == '__main__':
# Create a Robot instance of type Tron2
robot = Robot(RobotType.Tron2)
2.2.4 init Interface Description
| Item | Description |
|---|---|
| Function Name | init |
| Function Prototype | def init(self, robot_ip: str = "127.0.0.1") |
| Function Overview | Initializes the communication runtime environment for the motion-control algorithm program. Call this function before calling any other interface. |
| Parameters | robot_ip: the robot IP address. For simulation, it is usually set to "127.0.0.1"; for a physical robot, set it to "10.192.1.2". |
| Return Value | Returns True on successful initialization and False on failure. |
| Remarks | None |
Code Example:
import sys
import limxsdk.robot.Robot as Robot
import limxsdk.robot.RobotType as RobotType
if __name__ == '__main__':
# Create a Robot instance of type Tron2
robot = Robot(RobotType.Tron2)
robot_ip = "10.192.1.2"
# Check whether a command-line argument is provided as the robot IP
if len(sys.argv) > 1:
robot_ip = sys.argv[1]
# Initialize the robot communication runtime environment using the IP address
if not robot.init(robot_ip):
sys.exit()
2.2.5 getMotorNumber Interface Description
| Item | Description |
|---|---|
| Function Name | getMotorNumber |
| Function Prototype | def getMotorNumber(self, timeout: float = -1.0) |
| Function Overview | Gets the number of motors in the robot. |
| Parameters | timeout: timeout in seconds. The default value -1.0 means to wait indefinitely. |
| Return Value | Returns an unsigned integer representing the total number of motors in the robot. |
| Remarks | The dual-arm configuration normally has 14 motors. |
Code Example:
import sys
import limxsdk.robot.Robot as Robot
import limxsdk.robot.RobotType as RobotType
if __name__ == '__main__':
# Create a Robot instance of type Tron2
robot = Robot(RobotType.Tron2)
robot_ip = "10.192.1.2"
# Check whether a robot IP command-line argument is provided
if len(sys.argv) > 1:
robot_ip = sys.argv[1]
# Initialize the robot with robot_ip
if not robot.init(robot_ip):
sys.exit()
# Get the number of motors in the robot
motor_number = robot.getMotorNumber()
2.2.6 subscribeImuData Interface Description
| Item | Description |
|---|---|
| Function Name | subscribeImuData |
| Function Prototype | def subscribeImuData(self, callback: Callable[[datatypes.ImuData], Any]) |
| Function Overview | Subscribes to robot IMU data and calls the specified callback function when new IMU data is received. |
| Parameters | callback: callback function used to process new IMU data. |
| Return Value | Returns True on success and continuously outputs IMU data; returns False on failure. |
Remarks - datatypes.ImuData data structure prototype is as follows:
import sys
from functools import partial
import limxsdk.robot.Robot as Robot
import limxsdk.robot.RobotType as RobotType
import limxsdk.datatypes as datatypes
class RobotReceiver:
# Subscribe to robot IMU data
def imuDataCallback(self, imu: datatypes.ImuData):
print("\n------\nrobot_state:" + \
"\n stamp: " + str(imu.stamp) + \
"\n acc: " + str(imu.acc) + \
"\n gyro: " + str(imu.gyro) + \
"\n quat: " + str(imu.quat))
if __name__ == '__main__':
# Create a Robot instance of type Tron2
robot = Robot(RobotType.Tron2)
robot_ip = "10.192.1.2"
# Check whether a robot IP command-line argument is provided
if len(sys.argv) > 1:
robot_ip = sys.argv[1]
# Initialize the robot with robot_ip
if not robot.init(robot_ip):
sys.exit()
# Create a RobotReceiver instance to handle callbacks
receiver = RobotReceiver()
# Create a partial function for the callback
imuDataCallback = partial(receiver.imuDataCallback)
# Subscribe to robot IMU data
robot.subscribeImuData(imuDataCallback)
# Sleep for 1 second to prevent the program from exiting
import time
while True:
time.sleep(1)
2.2.7 subscribeRobotState Interface Description
| Item | Description |
|---|---|
| Function Name | subscribeRobotState |
| Function Prototype | def subscribeRobotState(self, callback: Callable[[datatypes.RobotState], Any]) |
| Function Overview | Subscribes to and receives robot state updates. |
| Parameters | callback: callback function that is called when a robot state update is received. The callback parameter points to datatypes.RobotState object. |
| Return Value | Returns True on success and False on failure. |
| Remarks | None |
Code Example:
import sys
from functools import partial
import limxsdk.robot.Robot as Robot
import limxsdk.robot.RobotType as RobotType
import limxsdk.datatypes as datatypes
class RobotReceiver:
# callback function used to receive robot state
def robotStateCallback(self, robot_state: datatypes.RobotState):
print("\n------\nrobot_state:" + \
"\n stamp: " + str(robot_state.stamp) + \
"\n tau: " + str(robot_state.tau) + \
"\n q: " + str(robot_state.q) + \
"\n dq: " + str(robot_state.dq))
if __name__ == '__main__':
# Create a Robot instance of type Tron2
robot = Robot(RobotType.Tron2)
robot_ip = "10.192.1.2"
# Check whether a robot IP command-line argument is provided
if len(sys.argv) > 1:
robot_ip = sys.argv[1]
# Initialize the robot with robot_ip
if not robot.init(robot_ip):
sys.exit()
# Create a RobotReceiver instance to handle callbacks
receiver = RobotReceiver()
# Create a partial function for the callback
robotStateCallback = partial(receiver.robotStateCallback)
# Subscribe to robot state
robot.subscribeRobotState(robotStateCallback)
# Sleep for 1 second to prevent the program from exiting
import time
while True:
time.sleep(1)
2.2.8 publishRobotCmd Interface Description
| Item | Description |
|---|---|
| Function Name | publishRobotCmd |
| Function Prototype | def publishRobotCmd(self, cmd: datatypes.RobotCmd) |
| Function Overview | Publishes a command to control robot motion. |
| Parameters | cmd: the required robot command datatypes.RobotCmd object. |
| Return Value | Returns True on success and False on failure. |
| Remarks | None |
Code Example:
import sys
import time
import limxsdk.robot.Rate as Rate
import limxsdk.robot.Robot as Robot
import limxsdk.robot.RobotType as RobotType
import limxsdk.datatypes as datatypes
if __name__ == '__main__':
# Create a Robot instance
robot = Robot(RobotType.Tron2)
# For simulation, use "127.0.0.1"; for a physical robot, use "10.192.1.2"
robot_ip = "10.192.1.2"
# Check whether a robot IP command-line argument is provided
if len(sys.argv) > 1:
robot_ip = sys.argv[1]
# Initialize the robot with robot_ip
if not robot.init(robot_ip):
sys.exit()
# Get motor-count information
motor_number = robot.getMotorNumber()
# Main loop to continuously publish robot commands
rate = Rate(300) # 300Hz
cmd_msg = datatypes.RobotCmd()
while True:
# Set default values for timestamp, control mode, joint position, velocity, torque, Kp, and Kd
# motor_names corresponds to the joint names you want to control
# Note: the following is only a format example. Fill in specific parameters during actual use.
cmd_msg.stamp = time.time_ns()
cmd_msg.mode = [0.0 for _ in range(16)] # No change is required in actual use
cmd_msg.q = [0.0 for _ in range(16)] # Fill in the planned angles; control frequency is 300 Hz
cmd_msg.dq = [0.0 for _ in range(16)] # No change is required in actual use
cmd_msg.tau = [0.0 for _ in range(16)] # No change is required in actual use
cmd_msg.Kp = [420,420,300,300,200,200,200,420,420,300,300,200,200,200]
cmd_msg.Kd = [12,12,15,15,10,10,10,12,12,15,15,10,10,10,3,3]
cmd_msg.motor_names = ["" for _ in range(16)] # No change is required in actual use
robot.publishRobotCmd(cmd_msg) # Publish robot command
rate.sleep() # Control loop frequency
2.2.9 subscribeSensorJoy Interface Description
| Item | Description |
|---|---|
| Function Name | subscribeSensorJoy |
| Function Prototype | def subscribeSensorJoy(self, callback: Callable[[datatypes.SensorJoy], Any]) |
| Function Overview | On a physical robot, this method subscribes to data from the robot's remote controller. When new data is received, the specified callback is invoked with a datatypes.SensorJoy object containing the remote-controller data. |
| Parameters | callback: callback used to receive remote-controller data. Its parameter type is datatypes.SensorJoy. |
| Return Value | Returns True on success and False on failure. |
| Remarks | None |
Code Example:
import sys
import time
from functools import partial
import limxsdk.robot.Robot as Robot
import limxsdk.robot.RobotType as RobotType
import limxsdk.datatypes as datatypes
class RobotReceiver:
# callback function used to receive remote-controller data
def sensorJoyCallback(self, sensor_joy: datatypes.SensorJoy):
print("\n------\nsensor_joy:" + \
"\n stamp: " + str(sensor_joy.stamp) + \
"\n axes: " + str(sensor_joy.axes) + \
"\n buttons: " + str(sensor_joy.buttons))
if __name__ == '__main__':
# Create a Robot instance of type Tron2
robot = Robot(RobotType.Tron2)
robot_ip = "10.192.1.2"
# Check whether a robot IP command-line argument is provided
if len(sys.argv) > 1:
robot_ip = sys.argv[1]
# Initialize the robot with robot_ip
if not robot.init(robot_ip):
sys.exit()
# Create a RobotReceiver instance to handle callbacks
receiver = RobotReceiver()
# Create a partial function for the callback
sensorJoyCallback = partial(receiver.sensorJoyCallback)
# Subscribe to robot remote-control data
robot.subscribeSensorJoy(sensorJoyCallback)
# Sleep for 1 second to prevent the program from exiting
import time
while True:
time.sleep(1)
2.2.10 subscribeDiagnosticValue Interface Description
| Item | Description |
|---|---|
| Function Name | subscribeDiagnosticValue |
| Function Prototype | def subscribeDiagnosticValue(self, callback: Callable[[datatypes.DiagnosticValue], Any]) |
| Function Overview | On a physical robot, this method subscribes to diagnostic values and status information. When diagnostic data is published, the specified callback is invoked with a datatypes.DiagnosticValue object containing the diagnostic data. This allows applications to monitor robot health in real time and respond promptly to possible issues. |
| Parameters | callback: callback function used to receive robot diagnostic values, whose parameter type is datatypes.DiagnosticValue. datatypes.DiagnosticValue structure contains robot diagnostic-value information, including timestamp, level, name, code, and message fields. |
| Return Value | Returns True on success and False on failure. |
| Remarks | None |
Code Example:
import sys
from functools import partial
import limxsdk.robot.Robot as Robot
import limxsdk.robot.RobotType as RobotType
import limxsdk.datatypes as datatypes
class RobotReceiver:
# callback function used to receive diagnostic values
def diagnosticValueCallback(self, diagnostic_value: datatypes.DiagnosticValue):
print("\n------\ndiagnostic_value:" + \
"\n stamp: " + str(diagnostic_value.stamp) + \
"\n name: " + diagnostic_value.name + \
"\n level: " + str(diagnostic_value.level) + \
"\n code: " + str(diagnostic_value.code) + \
"\n message: " + diagnostic_value.message)
if __name__ == '__main__':
# Create a Robot instance of type Tron2
robot = Robot(RobotType.Tron2)
robot_ip = "10.192.1.2"
# Check whether a robot IP command-line argument is provided
if len(sys.argv) > 1:
robot_ip = sys.argv[1]
# Initialize the robot with robot_ip
if not robot.init(robot_ip):
sys.exit()
# Create a RobotReceiver instance to handle callbacks
receiver = RobotReceiver()
# Create a partial function for the callback
diagnosticValueCallback = partial(receiver.diagnosticValueCallback)
# Subscribe to robot diagnostic information
robot.subscribeDiagnosticValue(diagnosticValueCallback)
# Sleep for 1 second to prevent the program from exiting
import time
while True:
time.sleep(1)
Return Value: |
/home/damon/PyCharmMiscProject/.venv/bin/python /home/damon/PyCharmMiscProject/testsdk.py
INFO: RobotIPAddress - "10.192.1.2"
------
diagnostic_value:
stamp: 980020701021
name: battery
level: 0
code: 100
message: 100
------
diagnostic_value:
stamp: 980016991896
name: battery_charge
level: 0
code: 0
message: 1
------
diagnostic_value:
stamp: 980016965062
name: battery_cost
level: 0
code: 0
message: 100
------
diagnostic_value:
stamp: 980016998021
name: battery_voltage
level: 0
code: 0
message: 56
------
diagnostic_value:
stamp: 590572955807
name: controller
level: 0
code: 1
message: manipulation_damping controller is ready
------
diagnostic_value:
stamp: 980017064521
name: current_12v
level: 0
code: 0
message: 0
------
diagnostic_value:
stamp: 980017054604
name: current_15v
level: 0
code: 0
message: 2
------
diagnostic_value:
stamp: 980017043229
name: current_24v
level: 0
code: 0
message: 0
------
diagnostic_value:
stamp: 13302781672
name: ecm_version
level: 0
code: 0
message: 1.0.25
------
diagnostic_value:
stamp: 24524362677
name: ethercat
level: 0
code: 0
message: ethercat ok!
------
diagnostic_value:
stamp: 14114416512
name: imu
level: 0
code: 0
message: OK
------
diagnostic_value:
stamp: 14059836923
name: lan_index
level: 0
code: 0
message: 1
------
diagnostic_value:
stamp: 24534264177
name: left end-effector
level: 0
code: 3
message: limx 2F gripper
------
diagnostic_value:
stamp: 980017021646
name: motor1_current
level: 0
code: 0
message: 0
------
diagnostic_value:
stamp: 980017015812
name: motor1_voltage
level: 0
code: 0
message: 55
------
diagnostic_value:
stamp: 980017032437
name: motor2_current
level: 0
code: 0
message: 0
------
diagnostic_value:
stamp: 980017027187
name: motor2_voltage
level: 0
code: 0
message: 55
------
diagnostic_value:
stamp: 980017010854
name: motor_current
level: 0
code: 0
message: 0
------
diagnostic_value:
stamp: 23464742635
name: motor_version
level: 0
code: 0
message: 1: 1.2.23; 2: 1.2.23; 3: 1.2.23; 4: 1.2.23; 5: 1.2.23; 6: 1.2.23; 7: 1.2.23; 8: 1.2.23; 9: 1.2.23; 10: 1.2.23; 11: 1.2.23; 12: 1.2.23; 13: 1.2.23; 14: 1.2.23; 15: 1.2.18; 16: 1.2.18;
------
diagnostic_value:
stamp: 980017005604
name: motor_voltage
level: 0
code: 0
message: 55
------
diagnostic_value:
stamp: 24543136677
name: right end-effector
level: 0
code: 3
message: limx 2F gripper
------
diagnostic_value:
stamp: 13993435499
name: rotate_status
level: 0
code: 0
message: 0
------
diagnostic_value:
stamp: 13983715707
name: version
level: 0
code: 0
message: robot-tron2-r-1.2.20.20251225182226
------
diagnostic_value:
stamp: 980017059562
name: voltage_12v
level: 0
code: 0
message: 12
------
diagnostic_value:
stamp: 980017049646
name: voltage_15v
level: 0
code: 0
message: 16
------
diagnostic_value:
stamp: 980017037687
name: voltage_24v
level: 0
code: 0
message: 25
------
diagnostic_value:
stamp: 14044807630
name: vr_follow_head
level: 0
code: 0
message: disable vr follow head
------
diagnostic_value:
stamp: 50767494403
name: working_mode
level: 0
code: 0
message: developer_mode
------
diagnostic_value:
stamp: 1010017039577
name: battery_cost
level: 0
code: 0
message: 100
------
diagnostic_value:
stamp: 1010017068743
name: battery_charge
level: 0
code: 0
message: 1
------
diagnostic_value:
stamp: 1010017076910
name: battery_voltage
level: 0
code: 0
message: 56
------
diagnostic_value:
stamp: 1010017083035
name: motor_voltage
level: 0
code: 0
message: 55
------
diagnostic_value:
stamp: 1010017088577
name: motor_current
level: 0
code: 0
message: 0
------
diagnostic_value:
stamp: 1010017093243
name: motor1_voltage
level: 0
code: 0
message: 55
------
diagnostic_value:
stamp: 1010017099077
name: motor1_current
level: 0
code: 0
message: 0
------
diagnostic_value:
stamp: 1010017104327
name: motor2_voltage
level: 0
code: 0
message: 55
------
diagnostic_value:
stamp: 1010017108993
name: motor2_current
level: 0
code: 0
message: 0
------
diagnostic_value:
stamp: 1010017114243
name: voltage_24v
level: 0
code: 0
message: 25
------
diagnostic_value:
stamp: 1010017119785
name: current_24v
level: 0
code: 0
message: 0
------
diagnostic_value:
stamp: 1010017125618
name: voltage_15v
level: 0
code: 0
message: 16
------
diagnostic_value:
stamp: 1010017130285
name: current_15v
level: 0
code: 0
message: 2
------
diagnostic_value:
stamp: 1010017134952
name: voltage_12v
level: 0
code: 0
message: 12
------
diagnostic_value:
stamp: 1010017139618
name: current_12v
level: 0
code: 0
message: 0
------
diagnostic_value:
stamp: 1010020746952
name: battery
level: 0
code: 100
message: 100
------
diagnostic_value:
stamp: 1040017682549
name: battery_cost
level: 0
code: 0
message: 100
------
diagnostic_value:
stamp: 1040017712591
name: battery_charge
level: 0
code: 0
message: 1
------
diagnostic_value:
stamp: 1040017719008
name: battery_voltage
level: 0
code: 0
message: 56
------
diagnostic_value:
stamp: 1040017725424
name: motor_voltage
level: 0
code: 0
message: 55
------
diagnostic_value:
stamp: 1040017730966
name: motor_current
level: 0
code: 0
message: 0
------
diagnostic_value:
stamp: 1040017736216
name: motor1_voltage
level: 0
code: 0
message: 55
------
diagnostic_value:
stamp: 1040017741758
name: motor1_current
level: 0
code: 0
message: 0
------
diagnostic_value:
stamp: 1040017747299
name: motor2_voltage
level: 0
code: 0
message: 55
------
diagnostic_value:
stamp: 1040017752549
name: motor2_current
level: 0
code: 0
message: 0
------
diagnostic_value:
stamp: 1040017758674
name: voltage_24v
level: 0
code: 0
message: 25
------
diagnostic_value:
stamp: 1040017763924
name: current_24v
level: 0
code: 0
message: 0
------
diagnostic_value:
stamp: 1040017769174
name: voltage_15v
level: 0
code: 0
message: 16
------
diagnostic_value:
stamp: 1040017774133
name: current_15v
level: 0
code: 0
message: 1
------
diagnostic_value:
stamp: 1040017779091
name: voltage_12v
level: 0
code: 0
message: 12
------
diagnostic_value:
stamp: 1040017783758
name: current_12v
level: 0
code: 0
message: 0
------
diagnostic_value:
stamp: 1040021298341
name: battery
level: 0
code: 100
message: 100
------
diagnostic_value:
stamp: 1070017263855
name: battery_cost
level: 0
code: 0
message: 100
------
diagnostic_value:
stamp: 1070017288647
name: battery_charge
level: 0
code: 0
message: 1
------
diagnostic_value:
stamp: 1070017295064
name: battery_voltage
level: 0
code: 0
message: 56
------
diagnostic_value:
stamp: 1070017301480
name: motor_voltage
level: 0
code: 0
message: 55
------
diagnostic_value:
stamp: 1070017307022
name: motor_current
level: 0
code: 0
message: 0
------
diagnostic_value:
stamp: 1070017311980
name: motor1_voltage
level: 0
code: 0
message: 55
------
diagnostic_value:
stamp: 1070017317522
name: motor1_current
level: 0
code: 0
message: 0
------
diagnostic_value:
stamp: 1070017323939
name: motor2_voltage
level: 0
code: 0
message: 55
------
diagnostic_value:
stamp: 1070017328605
name: motor2_current
level: 0
code: 0
message: 0
------
diagnostic_value:
stamp: 1070017333855
name: voltage_24v
level: 0
code: 0
message: 25
------
diagnostic_value:
stamp: 1070017339105
name: current_24v
level: 0
code: 0
message: 0
------
diagnostic_value:
stamp: 1070017344064
name: voltage_15v
level: 0
code: 0
message: 16
------
diagnostic_value:
stamp: 1070017348730
name: current_15v
level: 0
code: 0
message: 1
------
diagnostic_value:
stamp: 1070017353980
name: voltage_12v
level: 0
code: 0
message: 12
------
diagnostic_value:
stamp: 1070017358939
name: current_12v
level: 0
code: 0
message: 0
------
diagnostic_value:
stamp: 1070020944689
name: battery
level: 0
code: 100
message: 100
Process finished with exit code 130 (interrupted by signal 2:SIGINT)
2.2.11 setRobotLightEffect Interface Description
| Item | Description |
|---|---|
| Function Name | setRobotLightEffect |
| Function Prototype | def setRobotLightEffect(self, effect: datatypes.LightEffect) |
| Function Overview | On a physical robot, this method sets the robot's lighting effect. |
| Parameters | effect: enumeration value representing the required robot light effect. See datatypes.LightEffect. |
| Return Value | Returns True on success and False on failure. |
Remarks - Tron2::LightEffect enumeration definition:
enum LightEffect : int {
STATIC_RED = 0, // static red light
STATIC_GREEN, // static green light
STATIC_BLUE, // static blue light
STATIC_CYAN, // static cyan light
STATIC_PURPLE, // static purple light
STATIC_YELLOW, // static yellow light
STATIC_WHITE, // static white light
LOW_FLASH_RED, // red flashing (slow)
LOW_FLASH_GREEN, // green flashing (slow)
LOW_FLASH_BLUE, // blue flashing (slow)
LOW_FLASH_CYAN, // cyan flashing (slow)
LOW_FLASH_PURPLE, // purple flashing (slow)
LOW_FLASH_YELLOW, // yellow flashing (slow)
LOW_FLASH_WHITE, // white flashing (slow)
FAST_FLASH_RED, // red flashing (fast)
FAST_FLASH_GREEN, // green flashing (fast)
FAST_FLASH_BLUE, // blue flashing (fast)
FAST_FLASH_CYAN, // cyan flashing (fast)
FAST_FLASH_PURPLE, // purple flashing (fast)
FAST_FLASH_YELLOW, // yellow flashing (fast)
FAST_FLASH_WHITE // white flashing (fast)
};
Code Example:
import sys
from functools import partial
import limxsdk.robot.Robot as Robot
import limxsdk.robot.RobotType as RobotType
import limxsdk.datatypes as datatypes
class RobotReceiver:
if __name__ == '__main__':
# Create a Robot instance of type Tron2
robot = Robot(RobotType.Tron2)
robot_ip = "10.192.1.2"
# Check whether a robot IP command-line argument is provided
if len(sys.argv) > 1:
robot_ip = sys.argv[1]
# Initialize the robot with robot_ip
if not robot.init(robot_ip):
sys.exit()
# Set the robot light effect to static red light
robot.setRobotLightEffect(datatypes.LightEffect.STATIC_RED)
2.2.12 Reference Examples (Coming Soon)
3 High-Level Application Development Interface
3.1 Overview
In High-Level Developer Mode, the robot receives client requests through WebSocket port 5000. These requests can command the robot to stand up, sit down, or walk. WebSocket establishes a persistent, real-time connection between the robot and the client, enabling fast and efficient transmission of control commands and data.

3.2 Communication Protocol Format
When the robot receives client commands through WebSocket, it exchanges information in JSON format. WebSocket is a full-duplex communication protocol that establishes a real-time, low-latency connection between the client and server, making it especially suitable for applications that require frequent interaction. JSON provides a concise, readable structure and offers cross-platform and cross-language compatibility. Together, WebSocket and JSON support a wide range of devices and systems while improving development flexibility and maintainability.
- The request data format contains the following fields:
accid: robot serial number; replace it with your robot's serial number;title: command name prefixed withrequest_;timestamp: command transmission timestamp, in milliseconds;guid: unique command identifier used to distinguish requests. For a synchronous interface, the same value must be returned in theguidfield of the correspondingresponse_xxxmessage. The client can compare the responseguidwith the requestguidto determine whether command execution is complete;data: stores the data content of the request command. Multiple subfields may be included as needed, to store the data required by the request command, such as action parameters or text content to be sent;- Example:
{
"accid": "WF_TRON2A_001", // robot serial number; modify it to your robot serial number
"title": "request_xxx", // command name prefixed with"request_"
"timestamp": 1672373633989, // command transmission timestamp, in milliseconds
"guid": "746d937cd8094f6a98c9577aaf213d98", // unique command identifier used to distinguish different request commands
"data": {} // stores the data content of the request command
}
- The response data format contains the following fields:
accid: robot serial number; replace it with your robot's serial number;title: command name prefixed withresponse_;timestamp: command transmission timestamp, in milliseconds;guid: the same value as theguidin the corresponding request;data: must contain at least aresultsubfield that stores the request result. It may also contain other subfields, such as an error code or error message;- Example:
{
"accid": "WF_TRON2A_001", // robot serial number; modify it to your robot serial number
"title": "response_xxx", // command name prefixed with"response_"
"timestamp": 1672373633989, // command transmission timestamp, in milliseconds
"guid": "746d937cd8094f6a98c9577aaf213d98", // same as the corresponding request commandguidvalue
"data": { // stores the specific data content of the response message
"result": "success" // "result" used to store whether request command processing succeeded, its value is: "success or fail_xxx"
}
}
- Notification: A notification is information sent proactively by the robot to the client. It may include the robot serial number, current operating state, or executed operations. Its data format contains the following fields:
accid: robot serial number; replace it with your robot's serial number;title: message name prefixed withnotify_;timestamp: message transmission timestamp, in milliseconds;guid: message guid value, uniquely identifying the message;data: stores message data content. Multiple subfields may be included as needed, to store the data required by the request command;- Example:
{
"accid": "WF_TRON2A_001", // robot serial number; modify it to your robot serial number
"title": "notify_xxx", // message name prefixed with"notify_"
"timestamp": 1672373633989, // message transmission timestamp, in milliseconds
"guid": "746d937cd8094f6a98c9577aaf213d98", // message guid value, uniquely identifying this message
"data": { } // stores message data content
}
3.3 View the Software Serial Number (ACCID)
- Connect to the robot wireless network
-
After the robot has finished booting, use a personal computer to connect to the robot's Wi-Fi network. Its name is usually in the format
WF_TRON2A_xxx. -
Enter the Wi-Fi password:
12345678
-
- Enter
http://10.192.1.2:8080in a browser to open the "Robot Information" page. As shown below, the displayed SN (serial number) isSF_TRON2A_127;SF_TRON2A_127is the robot's software serial number.

3.4 Communication Test Method
Postman is a popular API testing tool that can be used to test WebSocket interfaces. Follow these steps:
- Install Postman from the official download page.
- Open Postman and create a WebSocket request.
- Connect to the robot wireless network
- After the robot has finished booting, connect a personal computer to the robot's Wi-Fi network. Its name is usually in the format
TRON2A_xxx. - Enter the Wi-Fi password:
12345678.
- After the robot has finished booting, connect a personal computer to the robot's Wi-Fi network. Its name is usually in the format
- Enter the WebSocket address in the request URL, for example,
ws://10.192.1.2:5000. - Enter the request message in the "Message" field.
- Click "Send" to transmit the request.
- After sending the request, view the server response in the Postman response pane and verify that it matches the expected result.

3.5 Common Protocol Interface Definitions
The robot interface design follows the same process and state transitions as remote-controller operation, ensuring that call order, response timing, and state transitions strictly align with remote-controller control logic. Users can obtain an intuitive experience similar to using the remote controller through interface calls, while supporting seamless switching between the remote controller and the interfaces, to achieve unified and stable robot control.
3.5.1 Global Messages
3.5.1.1 Robot Basic Information
Basic robot information is reported once per second and contains the following fields:
- accid: robot serial number
- title: notify_robot_info
- timestamp: message transmission timestamp, in milliseconds
- guid: message guid value, uniquely identifying this message
- data: stores message content, Example:
Example:
{
"accid": "WF_TRON2A_001",
"title": "notify_robot_info",
"timestamp": 1672373633989,
"guid": "746d937cd8094f6a98c9577aaf213d98",
"data": {
"accid": "WF_TRON2A_001",
"sw_version": "robot-tron2-2.0.10.20241111103012",
"imu": "OK", // robot IMU diagnostic information
"camera": "OK", // robot camera diagnostic information
"motor": "OK", // robot motor diagnostic information
"battery": 95, // robot battery level
"status": "WALK" // robot operating mode
}
}
| Field | Description |
|---|---|
accid |
robot serial number |
sw_version |
robot onboard software version |
imu |
robot IMU diagnostic information |
camera |
robot camera diagnostic information |
motor |
robot motor diagnostic information |
battery |
robot battery level |
status |
robot operating mode, such as STAND, WALK, SIT, DAMPING, ROTATE, STAIR, ERROR_FALLOVER(fallen), RECOVER(fall recovery in progress), ERROR_RECOVER(fall recovery failed) |
3.5.1.2 Invalid Command Message
When the robot receives a request command with an invalid format, it sends this message containing the following content:
- accid: robot serial number
- title: notify_invalid_request
- timestamp: message transmission timestamp, in milliseconds
- guid: message guid value, uniquely identifying this message
- data: stores message content
- Example:
{
"accid": "WF_TRON2A_001",
"title": "notify_invalid_request",
"timestamp": 1672373633989,
"guid": "746d937cd8094f6a98c9577aaf213d98",
"data": "Returns the original request command content to help the client troubleshoot the problem"
}
3.5.2 Connect to a Wi-Fi Hotspot
3.5.2.1 Request: request_connect_wifi
This protocol sends a request to the robot router, instructing it to connect to a Wi-Fi hotspot with the specified SSID and return the connection result.
{
"accid": "WF_TRON2A_001",
"title": "request_connect_wifi",
"timestamp": 1672373633989,
"guid": "746d937cd8094f6a98c9577aaf213d98",
"data": {
"wifi_band": 0, // Wi-Fi band: 0=5GHz, 1=2.4GHz
"wifi_ssid": "Limx-Guests", // Target Wi-Fi SSID (Wi-Fi name), case-sensitive and must match the actual hotspot
"wifi_password": "LimX2024", // Target Wi-Fi password, using WPA2-PSK encryption
"router_admin_password": "12345678" // robot router administrator password
}
}
3.5.2.2 Response: response_connect_wifi
{
"accid": "WF_TRON2A_001",
"title": "response_connect_wifi",
"timestamp": 1672373633989,
"guid": "746d937cd8094f6a98c9577aaf213d98",
"data": {
"result": "success" // success: success
// fail_no_wifi_band: Wi-Fi band not specified
// fail_no_wifi_ssid: SSID not specified
// fail_no_wifi_password: password not specified
// fail_no_router_admin_password: password not specified
}
}
3.5.2.3 Notification Push: None
3.5.3 Query Wi-Fi Connection Status
3.5.3.1 Request: request_wifi_connection_status
This protocol allows the client to query the Wi-Fi connection status from the robot router. The router returns the connected SSID, signal strength, and connection result, allowing the client to monitor the device's network connection in real time. The request must include the robot router administrator password for authentication.
{
"accid": "WF_TRON2A_001",
"title": "request_wifi_connection_status",
"timestamp": 1672373633989,
"guid": "746d937cd8094f6a98c9577aaf213d98",
"data": {
"router_admin_password": "12345678" // robot router administrator password
}
}
3.5.3.2 Response: response_wifi_connection_status
After receiving the query request, the robot router returns the actual current Wi-Fi connection status for client parsing, display, or subsequent business processing.
{
"accid": "WF_TRON2A_001",
"title": "response_wifi_connection_status",
"timestamp": 1672373633989,
"guid": "746d937cd8094f6a98c9577aaf213d98",
"data": {
"ssid": "Limx-Guests",
"signal": -56, // unit: dBm
"result": "success" // success: success
// fail_disconnected
}
}
3.5.3.3 Notification Push: None
3.5.4 Set Light Effect
3.5.4.1 Request: request_light_effect
{
"accid": "WF_TRON2A_001",
"title": "request_light_effect",
"timestamp": 1672373633989,
"guid": "746d937cd8094f6a98c9577aaf213d98",
"data": {
"effect": 1
}
}
Request Parameter Description:
| Parameter Name | Type | Description |
|---|---|---|
data.effect |
Number |
Light effect ID corresponding to different light display modes. The mapping is as follows: 1: STATIC_RED(static red)2: STATIC_GREEN(static green)3: STATIC_BLUE(static blue)4: STATIC_CYAN(static cyan)5: STATIC_PURPLE(static purple)6: STATIC_YELLOW(static yellow)7: STATIC_WHITE(static white)8: LOW_FLASH_RED(low-frequency flashing red)9: LOW_FLASH_GREEN(low-frequency flashing green)10: LOW_FLASH_BLUE(low-frequency flashing blue)11: LOW_FLASH_CYAN(low-frequency flashing cyan)12: LOW_FLASH_PURPLE(low-frequency flashing purple)13: LOW_FLASH_YELLOW(low-frequency flashing yellow)14: LOW_FLASH_WHITE(low-frequency flashing white)15: FAST_FLASH_RED(high-frequency flashing red)16: FAST_FLASH_GREEN(high-frequency flashing green)17: FAST_FLASH_BLUE(high-frequency flashing blue)18: FAST_FLASH_CYAN(high-frequency flashing cyan)19: FAST_FLASH_PURPLE(high-frequency flashing purple)20: FAST_FLASH_YELLOW(high-frequency flashing yellow)21: FAST_FLASH_WHITE(high-frequency flashing white)
|
3.5.4.2 Response: response_light_effect
{
"accid": "DACH_TRON2A_001",
"title": "response_light_effect",
"timestamp": 1672373633989,
"guid": "746d937cd8094f6a98c9577aaf213d98",
"data": {
"result": "success" // success: success, fail_light_effect: failure
}
}
3.5.4.3 Notification Push: None
3.5.5 Emergency Stop
Note:
Must be called in idle mode; it cannot respond during motion
3.5.5.1 Request: request_emgy_stop
{
"accid": "DACH_TRON2A_001", // robot serial number; replace it with your robot's serial number
"title": "request_emgy_stop",
"timestamp": 1672373633989,
"guid": "746d937cd8094f6a98c9577aaf213d98",
"data": {}
}
3.5.5.2 Response: response_emgy_stop
{
"accid": "DACH_TRON2A_001",
"title": "response_emgy_stop",
"timestamp": 1672373633989,
"guid": "746d937cd8094f6a98c9577aaf213d98",
"data": {
"result": "success" // success: success, fail_imu: IMU error, fail_motor: motor error
}
}
3.5.5.3 Notification Push: None
3.6 Dual-Arm Configuration Protocol Interface Definitions
3.6.1 MoveJ Interface Description
3.6.1.1 Request: request_movej
Note:
when moveJ is called, each joint angle is checked against its limit. If a limit is exceeded, an over-limit error is reported and this moveJ call is not executed.
moveJ joint limits are ordered from the upper to lower joints of the left arm, then the upper to lower joints of the right arm, unit: rad.
Upper limit: [2.6005, 3.1940, 1.4835, 0.2618, 1.3963, 0.7854, 1.5708, 2.6005, 0.2618, 3.6652, 0.2618, 1.7453, 0.7854, 1.5708]
Lower limit: [-3.1416, -0.2618, -3.6652, -2.6180, -1.7453, -0.7854, -1.5708, -3.1416, -3.1940, -1.4835, -2.6180, -1.3963, -0.7854, -1.5708]
{
"accid": "DACH_TRON2A_001", // robot serial number; replace it with your robot's serial number
"title": "request_movej",
"timestamp": 1672373633989,
"guid": "746d937cd8094f6a98c9577aaf213d98",
"data": {
"time": 2, // move to the specified position in 2 seconds
"joint": [] //14 joint values, unit: rad
}
}
3.6.1.2 Response: response_movej
{
"accid": "DACH_TRON2A_001",
"title": "response_movej",
"timestamp": 1672373633989,
"guid": "746d937cd8094f6a98c9577aaf213d98",
"data": {
"result": "success" // success: success, fail_invalid_cmd:invalid command (missing field)
}
}
3.6.1.3 Example
{
"accid": "DACH_TRON2A_026",
"title": "request_movej",
"timestamp": 1672373633989,
"guid": "746d937cd8094f6a98c9577aaf213d98",
"data": {
"time": 5,
"joint": [0,0,0,-1.6,0,0,0,0,0,0,-1.6,0,0,0]
}
}
3.6.2 MoveH Interface Description
This interface controls the head's two degrees of freedom.
Upper limit: [1.04 ,1.57]
Lower limit: [-0.78, -1.57]
3.6.2.1 Request: request_moveh
{
"accid": "DACH_TRON2A_026",
"title": "request_moveh",
"timestamp": 1672373633989,
"guid": "746d937cd8094f6a98c9577aaf213d98",
"data": {
"time": 5,
"joint": [0.5,0.5] //pitch,yaw
}
}
3.6.2.2 Response: response_moveh
{
"accid": "DACH_TRON2A_001",
"title": "response_moveh",
"timestamp": 1672373633989,
"guid": "746d937cd8094f6a98c9577aaf213d98",
"data": {
"result": "success" // success: success, fail_invalid_cmd:invalid command (missing field)
}
}
3.6.3 MoveP Interface Description
3.6.3.1 Request: request_movep
The reference coordinate system is as follows. The coordinate origin is located at the center of the lower plane of the base, and the arm end-effector reference is located at the center of the last joint of the arm.