GDK IMU API Reference (C++)¶
Overview¶
The IMU (Inertial Measurement Unit) module provides the G02 robot with the ability to acquire real-time inertial data. Through the C++ interface, developers can conveniently obtain the robot's orientation, angular velocity, and linear acceleration information, suitable for scenarios such as attitude detection, motion analysis, and navigation.
Interface Description¶
Imu Class¶
This class encapsulates the main data acquisition interfaces of the IMU sensor.
1. GetLatestImu()¶
- Function: Get the latest IMU data
- Parameters:
| Parameter | Type | Description |
|---|---|---|
imu_type |
const ImuType& |
IMU type enum value |
timeout_ms |
const float |
Timeout (milliseconds) |
imu |
std::shared_ptr<ImuData>& |
Output parameter, IMU data pointer |
- Return value:
GDKRes, the operation result status code. ReturnsGDKRes::kSuccesson success, and theimuparameter contains the IMU data
Detailed Description of the ImuData Object¶
The ImuData struct contains the following members:
struct ImuData {
Vector3 angular_velocity{}; ///< imu current angular velocity
Vector3 linear_acceleration{}; ///< imu current linear acceleration
uint64_t timestamp_ns{0}; ///< imu timestamp(ns)
};
| Member | Type | Description | Unit |
|---|---|---|---|
angular_velocity |
Vector3 |
Angular velocity, the robot's angular velocity on the three axes | rad/s |
linear_acceleration |
Vector3 |
Linear acceleration, the robot's linear acceleration on the three axes | m/s² |
timestamp_ns |
uint64_t |
Timestamp of data acquisition, with nanosecond precision | nanoseconds |
| Vector3 Struct Description: |
| Member | Type | Description |
|---|---|---|
x |
double |
X-axis component |
y |
double |
Y-axis component |
z |
double |
Z-axis component |
IMU Types:
- ImuType::kImuFront: Front IMU
- ImuType::kImuBack: Rear IMU
- ImuType::kImuChassis: Chassis IMU
- Example:
#include <iostream>
#include <chrono>
#include <thread>
#include "gdk/gdk.h"
int main()
{
// Initialize the GDK system
if (agibot::gdk::GDKInit() != agibot::gdk::GDKRes::kSuccess) {
std::cout << "GDK initialization failed" << std::endl;
return -1;
}
std::cout << "GDK initialization succeeded" << std::endl;
std::cout<< "IMU example program" << std::endl;
agibot::gdk::Imu imu;
std::this_thread::sleep_for(std::chrono::seconds(1)); // Wait 1 second to ensure the DDS connection is established
std::shared_ptr<agibot::gdk::ImuData> imu_data;
imu.GetLatestImu(agibot::gdk::ImuType::kImuChassis, 500.0, imu_data);
if (imu_data != nullptr) {
std::cout << "\n--- IMU Data ---" << std::endl;
std::cout << "Timestamp: " << imu_data->timestamp_ns << std::endl;
// Angular velocity
std::cout << "Angular velocity: x=" << imu_data->angular_velocity.x << ", "
<< "y=" << imu_data->angular_velocity.y << ", "
<< "z=" << imu_data->angular_velocity.z << std::endl;
// Linear acceleration
std::cout << "Linear acceleration: x=" << imu_data->linear_acceleration.x << ", "
<< "y=" << imu_data->linear_acceleration.y << ", "
<< "z=" << imu_data->linear_acceleration.z << std::endl;
} else {
std::cout << "No IMU data received" << std::endl;
}
// Release GDK system resources
if (agibot::gdk::GDKRelease() != agibot::gdk::GDKRes::kSuccess) {
std::cout << "GDK release failed" << std::endl;
return -1;
}
std::cout << "GDK release succeeded" << std::endl;
return 0;
}
2. GetNearestImu()¶
- Function: Get the IMU data nearest to a specified timestamp
- Parameters:
| Parameter | Type | Description |
|---|---|---|
imu_type |
const ImuType& |
IMU type enum value |
timestamp_ns |
const uint64_t |
Target timestamp (nanoseconds) |
timeout_ms |
const float |
Timeout (milliseconds) |
imu |
std::shared_ptr<ImuData>& |
Output parameter, IMU data pointer |
-
Return value:
GDKRes, the operation result status code. ReturnsGDKRes::kSuccesson success, and theimuparameter contains the IMU data -
Example:
#include <iostream>
#include <iomanip>
#include <chrono>
#include <thread>
#include "gdk/gdk.h"
int main()
{
// Initialize the GDK system
if (agibot::gdk::GDKInit() != agibot::gdk::GDKRes::kSuccess) {
std::cout << "GDK initialization failed" << std::endl;
return -1;
}
std::cout << "GDK initialization succeeded" << std::endl;
std::cout << "IMU example program" << std::endl;
agibot::gdk::Imu imu;
std::this_thread::sleep_for(std::chrono::seconds(1)); // Wait 1 second to ensure the DDS connection is established
agibot::gdk::ImuType imu_type = agibot::gdk::ImuType::kImuChassis;
std::shared_ptr<agibot::gdk::ImuData> imu_data;
imu.GetLatestImu(imu_type, 500.0, imu_data);
if (imu_data != nullptr) {
std::cout << "\n--- IMU Data ---" << std::endl;
std::cout << "Timestamp: " << imu_data->timestamp_ns << std::endl;
// Angular velocity
std::cout << "Angular velocity: x=" << imu_data->angular_velocity.x << ", "
<< "y=" << imu_data->angular_velocity.y << ", "
<< "z=" << imu_data->angular_velocity.z << std::endl;
// Linear acceleration
std::cout << "Linear acceleration: x=" << imu_data->linear_acceleration.x << ", "
<< "y=" << imu_data->linear_acceleration.y << ", "
<< "z=" << imu_data->linear_acceleration.z << std::endl;
// Find the nearest IMU data
for (int i = 0; i < 10; ++i) {
std::shared_ptr<agibot::gdk::ImuData> imu_data_nearest;
agibot::gdk::GDKRes res = imu.GetNearestImu(
imu_type,
imu_data->timestamp_ns - 1000000000LL, // 1 second earlier
1000.0,
imu_data_nearest
);
if (res == agibot::gdk::GDKRes::kSuccess && imu_data_nearest != nullptr) {
std::cout << "✅ Nearest IMU data: " << imu_data_nearest->timestamp_ns << std::endl;
std::cout << std::fixed << std::setprecision(4);
std::cout << "Angular velocity: x=" << imu_data_nearest->angular_velocity.x
<< ", y=" << imu_data_nearest->angular_velocity.y
<< ", z=" << imu_data_nearest->angular_velocity.z << std::endl;
std::cout << "Linear acceleration: x=" << imu_data_nearest->linear_acceleration.x
<< ", y=" << imu_data_nearest->linear_acceleration.y
<< ", z=" << imu_data_nearest->linear_acceleration.z << std::endl;
} else {
std::cout << "❌ Nearest IMU data not found" << std::endl;
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
} else {
std::cout << "No IMU data received" << std::endl;
}
// Release GDK system resources
if (agibot::gdk::GDKRelease() != agibot::gdk::GDKRes::kSuccess) {
std::cout << "GDK release failed" << std::endl;
return -1;
}
std::cout << "GDK release succeeded" << std::endl;
return 0;
}
3. GetImuFps()¶
- Function: Get the IMU data acquisition frame rate
- Parameters:
| Parameter | Type | Description |
|---|---|---|
imu_type |
const ImuType& |
IMU type enum value |
fps |
int& |
Output parameter, IMU frame rate (FPS) |
-
Return value:
GDKRes, the operation result status code. ReturnsGDKRes::kSuccesson success, and thefpsparameter contains the frame rate value -
Example:
#include <iostream>
#include <chrono>
#include <thread>
#include "gdk/gdk.h"
int main() {
// Initialize the GDK system
if (agibot::gdk::GDKInit() != agibot::gdk::GDKRes::kSuccess) {
std::cout << "GDK initialization failed" << std::endl;
return -1;
}
std::cout << "GDK initialization succeeded" << std::endl;
agibot::gdk::Imu imu;
std::this_thread::sleep_for(std::chrono::seconds(1)); // Wait 1 second to ensure the DDS connection is established
agibot::gdk::ImuType imu_type = agibot::gdk::ImuType::kImuChassis;
float fps;
if (imu.GetImuFps(imu_type, fps) != agibot::gdk::GDKRes::kSuccess) {
std::cout << "Failed to get imu fps" << std::endl;
} else {
std::cout << "IMU fps: " << fps << std::endl;
}
// Release GDK system resources
if (agibot::gdk::GDKRelease() != agibot::gdk::GDKRes::kSuccess) {
std::cout << "GDK release failed" << std::endl;
return -1;
}
std::cout << "GDK release succeeded" << std::endl;
return 0;
}
4. GetImuLatency()¶
- Note: Before getting IMU data latency statistics, time synchronization must be performed first; otherwise the latency statistics will be inaccurate
- Function: Get IMU data latency statistics
- Parameters:
| Parameter | Type | Description |
|---|---|---|
imu_type |
const ImuType& |
IMU type enum value |
window_seconds |
const float |
Statistics window duration (seconds) |
latency |
LatencyStats& |
Output parameter, latency statistics |
-
Return value:
GDKRes, the operation result status code. ReturnsGDKRes::kSuccesson success, and thelatencyparameter contains the latency statistics -
LatencyStats Struct Description:
struct LatencyStats {
double max_latency_ms{0.0}; ///< max latency(ms)
double avg_latency_ms{0.0}; ///< average latency(ms)
double p99_latency_ms{0.0}; ///< 99th percentile latency(ms)
double p999_latency_ms{0.0}; ///< 99.9th percentile latency(ms)
double p9999_latency_ms{0.0}; ///< 99.99th percentile latency(ms)
};
| Member | Type | Description | Unit |
|---|---|---|---|
max_latency_ms |
double |
Maximum latency | milliseconds |
avg_latency_ms |
double |
Average latency | milliseconds |
p99_latency_ms |
double |
99th percentile latency | milliseconds |
p999_latency_ms |
double |
99.9th percentile latency | milliseconds |
p9999_latency_ms |
double |
99.99th percentile latency | milliseconds |
- Example:
#include <iostream>
#include <chrono>
#include <thread>
#include "gdk/gdk.h"
int main() {
// Initialize the GDK system
if (agibot::gdk::GDKInit() != agibot::gdk::GDKRes::kSuccess) {
std::cout << "GDK initialization failed" << std::endl;
return -1;
}
std::cout << "GDK initialization succeeded" << std::endl;
agibot::gdk::Imu imu;
std::this_thread::sleep_for(std::chrono::seconds(1)); // Wait 1 second to ensure the DDS connection is established
agibot::gdk::ImuType imu_type = agibot::gdk::ImuType::kImuChassis;
agibot::gdk::LatencyStats latency;
if (imu.GetImuLatency(imu_type, 1.0, latency) != agibot::gdk::GDKRes::kSuccess) {
std::cout << "Failed to get imu latency" << std::endl;
} else {
std::cout << "IMU latency stats:" << std::endl;
std::cout << " Max latency: " << latency.max_latency_ms << "ms" << std::endl;
std::cout << " Average latency: " << latency.avg_latency_ms << "ms" << std::endl;
std::cout << " P99 latency: " << latency.p99_latency_ms << "ms" << std::endl;
std::cout << " P99.9 latency: " << latency.p999_latency_ms << "ms" << std::endl;
std::cout << " P99.99 latency: " << latency.p9999_latency_ms << "ms" << std::endl;
}
// Release GDK system resources
if (agibot::gdk::GDKRelease() != agibot::gdk::GDKRes::kSuccess) {
std::cout << "GDK release failed" << std::endl;
return -1;
}
std::cout << "GDK release succeeded" << std::endl;
return 0;
}
5. CloseImu()¶
- Function: Close the IMU DDS connection
- Parameters: None
-
Return value:
GDKRes, the operation result status code. ReturnsGDKRes::kSuccesson success -
Example:
#include <iostream>
#include <chrono>
#include <thread>
#include "gdk/gdk.h"
int main() {
// Initialize the GDK system
if (agibot::gdk::GDKInit() != agibot::gdk::GDKRes::kSuccess) {
std::cout << "GDK initialization failed" << std::endl;
return -1;
}
std::cout << "GDK initialization succeeded" << std::endl;
agibot::gdk::Imu imu;
std::cout << "IMU init" << std::endl;
// Use the IMU...
// Close the IMU
if (imu.CloseImu() != agibot::gdk::GDKRes::kSuccess) {
std::cout << "Failed to close imu" << std::endl;
} else {
std::cout << "IMU closed successfully" << std::endl;
}
// Release GDK system resources
if (agibot::gdk::GDKRelease() != agibot::gdk::GDKRes::kSuccess) {
std::cout << "GDK release failed" << std::endl;
return -1;
}
std::cout << "GDK release succeeded" << std::endl;
return 0;
}
Usage Notes¶
- GDK Initialization: Before using IMU functionality, you must first call
agibot::gdk::GDKInit()to initialize the GDK system - GDK Release: Before the program ends, you must call
agibot::gdk::GDKRelease()to release the GDK system resources - Initialization Wait: After creating the Imu object, it is recommended to wait 1 second to ensure the DDS connection is established
- Timeout Setting: Set an appropriate timeout according to actual needs to avoid long blocking
- Return Value Check: Before use, check whether the GDKRes return value is kSuccess
- Smart Pointer Management: The ImuData object is managed using shared_ptr; pay attention to its lifecycle
- Timestamp Precision: The timestamp unit is nanoseconds, which can be used for precise time synchronization
- Data Fusion: IMU data typically needs to be fused with other sensor data to improve accuracy
- Resource Release: After use, call
CloseImu()to release resources - Error Handling: Always check the GDKRes return value to ensure the operation succeeded
- Unimplemented Methods:
GetImuFps()andGetImuLatency()are currently not implemented; be aware of this when using them
Application Scenarios¶
- Motion Analysis: Use angular velocity and linear acceleration to analyze the robot's motion state
- Navigation and Positioning: Combine with other sensors for robot positioning and navigation
- Balance Control: Used for the robot's balance and stability control
- Data Fusion: Fusion algorithms such as Kalman filtering with other sensor data
- Motion Prediction: Predict the robot's motion trajectory based on historical data
- Anomaly Detection: Detect abnormal motion states of the robot
- Calibration and Compensation: Perform sensor calibration and error compensation
- Vibration Monitoring: Monitor the robot's vibration and impact conditions