Low-level · C++ API
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;
}