Skip to content

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. Returns GDKRes::kSuccess on success, and the imu parameter 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
struct Vector3 {
  double x{};
  double y{};
  double z{};
};

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. Returns GDKRes::kSuccess on success, and the imu parameter 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. Returns GDKRes::kSuccess on success, and the fps parameter 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. Returns GDKRes::kSuccess on success, and the latency parameter 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. Returns GDKRes::kSuccess on 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

  1. GDK Initialization: Before using IMU functionality, you must first call agibot::gdk::GDKInit() to initialize the GDK system
  2. GDK Release: Before the program ends, you must call agibot::gdk::GDKRelease() to release the GDK system resources
  3. Initialization Wait: After creating the Imu object, it is recommended to wait 1 second to ensure the DDS connection is established
  4. Timeout Setting: Set an appropriate timeout according to actual needs to avoid long blocking
  5. Return Value Check: Before use, check whether the GDKRes return value is kSuccess
  6. Smart Pointer Management: The ImuData object is managed using shared_ptr; pay attention to its lifecycle
  7. Timestamp Precision: The timestamp unit is nanoseconds, which can be used for precise time synchronization
  8. Data Fusion: IMU data typically needs to be fused with other sensor data to improve accuracy
  9. Resource Release: After use, call CloseImu() to release resources
  10. Error Handling: Always check the GDKRes return value to ensure the operation succeeded
  11. Unimplemented Methods: GetImuFps() and GetImuLatency() 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