XGRIDS文档
  • 简体中文
  • English
  • 繁體中文
  • 日本語
  • Deutsch
  • Español
  • Italiano
  • Français
  • Русский
  • 简体中文
  • English
  • 繁體中文
  • 日本語
  • Deutsch
  • Español
  • Italiano
  • Français
  • Русский
  • 灵视 P1

    • 产品概述
    • 设备基本操作
    • 使用 LCC Scan App
    • 维护及保养
    • 常见问题
  • 灵光 K 系列

    • 灵光 K1

      • 产品概述
      • 设备基本操作
      • 设备激活与连接
      • 设备采集
      • 获取绝对坐标点云数据
      • 地图融合
      • 典型场景路线规划建议
      • 注意事项
      • 常见问题
    • 灵光 K2

      • 产品概述
      • 设备基本操作
      • 设备激活与连接
      • 设备采集
      • 获取绝对坐标点云数据
      • 地图融合
      • 典型场景路线规划建议
      • 注意事项
      • 常见问题
  • 灵光 L 系列

    • 灵光 L2 Pro

      • 产品概述
      • 设备基本操作
      • 设备激活与连接
      • 设备采集
      • 获取绝对坐标点云数据
      • 实时测量功能
      • 附录
      • 常见问题
  • Lixel Studio

    • 版权
    • 安装与激活
    • 界面说明
    • 文件
    • 工程处理
    • 工具
    • 平面绘制
    • 行业应用
    • 设置
    • 设备感知
  • Lixel CyberColor

    • LCC Studio

      • 入门
      • 版本与更新
      • 下载与安装
      • 界面概览与导航
      • 重建前工作
      • 模型重建
      • 单模型重建
      • 地图融合
      • 空地融合
      • 航拍重建
      • 我的模型
      • 其他功能
      • 设置与账号
      • 转换工具
      • 视频重建
      • 常见问题 / FAQ
    • LCC Scene Editor

      • 版本与更新
      • 账号与登录
      • 产品概览与主页
      • 编辑器界面介绍
      • 三种场景漫游快捷操作
      • 文件
      • 设置
      • 编辑操作
      • 窗口
      • 视图工具栏
      • 资产与属性
      • 左侧工具栏
      • 视点
      • 跳转点
      • 天空盒
      • 标注
      • 测量
      • 场景漫游
      • 场景报告
      • 智能户型图(3D Layout)
      • 小地图
      • 预览模式(Viewer)
      • 帮助
      • 常见问题 / FAQ
      • 出生点
    • LCC Model Editor

      • 版本与更新
      • 新手指引
      • 概览与界面
      • 文件操作
      • 选择器
      • 编辑操作
      • 测量
      • 调色
      • 资产管理
      • 设置与帮助
      • 常见问题 / FAQ
    • 采集指南

      • 概述
      • 采集设备总览
      • 通用采集原则
      • 室内场景采集
      • 室外场景采集
      • 大场景采集(地图融合)
      • 空地融合采集
      • 物体采集
      • 人物采集
      • 视频重建采集
      • 高清补拍
      • 控制点(灵视 P1)
      • 常见问题与排查
    • 历史版本
  • Plugin & SDK

    • Unreal

      • 介绍
      • 快速入门 - Windows
      • 快速入门 - Linux
      • 快速入门 - Quest3
      • 版本与授权
      • 渲染
      • 画面调节
      • 法线与光照
      • 场景编辑
      • 性能参数说明
      • 性能优化指南
      • 第三方与引擎插件集成
      • 代理网格
      • 加载动画
      • 碰撞
      • 寻路系统支持
      • 单层水支持
      • 本地化
      • 常见问题
      • 故障排查
      • 日志与诊断
      • 联系我们
      • API 参考

        • ALCCActorBase
        • ULCCComponentBase
        • ULCCComponent
        • ULCC2Component
        • SOG / SPZ / PLY Actors
        • ALCC2ProxyMesh
        • ALCCClippingVolume
        • ALCCSectionPlane
        • ULCCUtilLibrary
        • Enums
        • Structs
      • 更新日志

        • v3.3.1
        • v3.0.0
        • v2.2.1
        • v1.0.0
        • v0.9.0
        • v0.8.0
        • v0.7.1
        • v0.6.1
        • v0.5.2
        • v0.4.1
        • v0.4.0
        • v0.3.0
        • v0.0.5
        • v0.0.4
        • v0.0.3
        • v0.0.2
        • v0.0.1
    • X-Brain 系列

      • 产品概述
      • 快速开始
      • 核心概念
      • 集成指南
      • API 参考
      • 数据类型
      • ROS2 桥接
      • 示例程序
      • 部署与网络
      • 排障与 FAQ
      • 版本与发布

集成指南

本篇讲如何把 X-Brain SDK 集成进你的 C/C++ 工程:编译链接、连接、订阅模型、回调内存管理、C 接口。

编译与链接

C++(推荐)

# <arch> 取 x86_64 或 aarch64,与目标机架构一致
g++ -std=c++17 my_app.cpp \
    -I<sdk>/include \
    -L<sdk>/lib/<arch> -llixel_sdk \
    -Wl,-rpath,'$ORIGIN/lib/<arch>' \
    -o my_app
  • -I<sdk>/include:头文件目录(两架构通用)。
  • -llixel_sdk + -L<sdk>/lib/<arch>:链接对应架构的动态库。
  • -Wl,-rpath,'$ORIGIN/lib/<arch>':让程序运行时按相对路径找到 liblixel_sdk.so。也可用绝对路径 -Wl,-rpath,/opt/x-brain-sdk/lib/<arch>,或运行前 export LD_LIBRARY_PATH=<sdk>/lib/<arch>。

C++11 即可编译,推荐 C++17。

校验库依赖

liblixel_sdk.so 只依赖 glibc 与 libstdc++(pthread、dl、m、rt 均属其中),常见 Linux 发行版自带。可自行核对:

readelf -d lib/<arch>/liblixel_sdk.so | grep NEEDED

动态库只导出 xg_ 前缀符号,第三方依赖已静态并入并隐藏,调用方工程即便自带同名库的其他版本也不会冲突:

nm -D --defined-only lib/<arch>/liblixel_sdk.so | grep -v ' xg_'

连接设备

xg::Options opts;
opts.deviceIp = "192.168.123.103";  // 必填
opts.port = 0;                      // 0 表示默认 7448
opts.connectTimeoutMs = 0;          // 0 表示默认 5000 毫秒

xg::Error err = xg::Error::Ok;
auto device = xg::Device::open(opts, &err);   // 失败返回 nullptr
if (!device) {
    std::fprintf(stderr, "连接失败: %s\n", xg::toString(err));
    return 1;
}
  • Device 由 std::unique_ptr 持有,析构时自动断开连接,无需手动 close。
  • 禁止拷贝与移动,避免句柄被重复释放。
  • 一个 Device 对应一台设备,本版本不支持同时连接多台设备。
  • open() 会实际访问一次设备作为连通性探测,返回成功即代表链路已通、设备端服务已就绪。同网段实测 open() 耗时约 10 毫秒。

关于 Options.port

直接填 modeling_app 的端口,默认 7448。 保持 0 即用默认,绝大多数设备无需改动。仅当设备端调整过端口时,才填其实际端口。

订阅数据

所有数据订阅共享相同模式:

// 注册回调,SDK 内部线程触发
device->subscribePose([](const xg::Pose& pose) {
    // 在此处理数据,须尽快返回
});

// 取消订阅
device->unsubscribePose();

关键约束:

  • 回调在 SDK 内部线程触发,不可阻塞;
  • 同一设备句柄每种数据类型最多一个活跃订阅(重复订阅返回 Rejected);
  • 图像按相机分三个独立订阅槽;
  • 不订阅时不消耗网络带宽;
  • Device 析构时自动取消所有订阅。

可订阅数据与坐标系见核心概念;逐接口契约见 API 参考。

回调内存与所有权模型(最易踩的坑)

SDK 对外结构体按内存所有权分两类,混淆二者是集成方最易犯的错误。

SDK 填充型(订阅回调)

Pose、Imu、CloudFrame、ImageFrame、ErrCodeFrame。

  • 结构体与其内部指针(points / jpegData / entries)全部由 SDK 拥有。
  • 变长数据(点数组、JPEG 码流、错误码数组)指向 SDK 内部的复用缓冲区:
    • 指针仅在本次回调执行期间有效;
    • 回调返回后,下一帧会覆盖同一块缓冲;
    • 因此跨回调持有该指针 = 悬垂 / 被改写,属未定义行为。

内存管理铁律:

  1. 回调内绝不保存裸指针。要留数据必须在回调内深拷贝:定长标量按值存;变长数据用 memcpy(点云 / JPEG)或 std::vector::assign(错误码)拷到自己的缓冲。
  2. 不要对回调里的任何指针调用 free / delete——不是你分配的。
  3. 回调不可阻塞(会拖住 SDK 会话线程,影响所有订阅)。要做重活,拷贝后转交自己的线程。

按值类型的差异:

  • Pose、Imu 是纯标量,回调参数本身可安全按值再存一份;
  • CloudFrame、ImageFrame 的 points / jpegData 仍是指向 SDK 缓冲的裸指针,须回调内拷贝;
  • ErrCodeFrame::entries(C++)是已拷出的 std::vector,回调内可随意读,但跨回调持有仍需再拷一份。

拷贝示例

// 点云:整帧拷贝
device->subscribeCloud([](const xg::CloudFrame& f) {
    std::vector<xg_point_t> saved(f.points, f.points + f.count);  // 深拷贝
    // 把 saved 转交自己的处理线程/队列
});

// 图像:拷出 JPEG 字节
device->subscribeImage(xg::Device::CameraId::Left,
    [](const xg::Device::ImageFrame& f) {
        std::vector<uint8_t> jpeg(f.jpegData, f.jpegData + f.jpegSize);
    });

// 位姿/IMU:直接按值存
device->subscribePose([](const xg::Pose& p) {
    xg::Pose saved = p;   // 纯标量,安全
});

调用方分配型(同步查询 / 入参)

Options、RecordStatus、各 *Calib、DeviceInfo、InitPose。

  • 内存由调用方分配,字符串是定长内嵌数组,SDK 只写内容不接管内存。
  • 无需、也不允许对这些结构体调用 free / delete。
  • C++ 封装已把定长字段转成 std::string,由 C++ 对象自行管理。

录制控制

// 下发开始
if (dev->startRecord() == xg::Error::Timeout) {
    // 命令可能已送达,先确认实际状态再决定是否重发
    xg::RecordStatus st;
    if (dev->queryRecordStatus(&st) == xg::Error::Ok && st.state != xg::RecordState::Idle) {
        // 已在准备或已开始,转入正常轮询即可
    }
}

// 轮询确认
xg::RecordStatus st;
while (true) {
    std::this_thread::sleep_for(
        std::chrono::milliseconds(XG_RECOMMENDED_POLL_INTERVAL_MS));
    if (dev->queryRecordStatus(&st) != xg::Error::Ok) continue;  // 抖动重试
    if (st.state == xg::RecordState::Recording) break;
    if (st.state == xg::RecordState::Error)     break;
}

Timeout 表示没收到设备应答,命令是否送达无从判断,不要直接重试,应先查询确认。语义详见核心概念。

标定与设备状态查询

xg::Device::CameraCalib cam;
if (device->getCameraCalib(0, &cam) == xg::Error::Ok) {   // 0..3 标定索引
    std::printf("fx=%.2f fy=%.2f model=%s\n", cam.fx, cam.fy, cam.model.c_str());
}

xg::Device::DeviceInfo info;
if (device->getDeviceInfo(&info) == xg::Error::Ok) {
    std::printf("battery=%.1f%% disk=%ld/%ld KB\n",
                info.batteryLevel, info.diskUsedKb, info.diskTotalKb);
}

标定/状态查询可在未录制时调用(读设备文件)。逐字段见数据类型。

C 接口

需要 C 接口或封装到其他语言时,直接使用 xg/robot_sdk_c.h。C++ 接口是它的 header-only 封装,两者能力完全一致。

#include "xg/robot_sdk_c.h"
#include <string.h>

xg_options_t opts;
memset(&opts, 0, sizeof(opts));
opts.struct_size = sizeof(opts);          /* 必填 */
snprintf(opts.device_ip, sizeof(opts.device_ip), "192.168.123.103");

xg_device_t* dev = NULL;
if (xg_device_open(&opts, &dev) != XG_OK) {
    return 1;
}

if (xg_record_start(dev) != XG_OK) {      /* 只下发, 不等待 */
    xg_device_close(dev);
    return 1;
}

/* 轮询确认 */
xg_record_status_t st;
for (;;) {
    usleep(XG_RECOMMENDED_POLL_INTERVAL_MS * 1000);
    memset(&st, 0, sizeof(st));
    st.struct_size = sizeof(st);          /* 每次调用前必填 */
    if (xg_record_query(dev, &st) != XG_OK) continue;
    if (st.state == XG_REC_RECORDING) break;
    if (st.state == XG_REC_ERROR) break;
}

xg_device_close(dev);

注:所有由调用方分配的结构体都必须先填 struct_size = sizeof(...),否则接口返回 XG_ERR_INVALID_ARG。这个字段用于后续版本新增字段时保持二进制兼容。C++ 封装已代为处理。

安全须知

本版本不含身份认证,设备控制接口对同网段完全开放。 同一交换机上的任何主机都能连接设备并控制录制。

因此:

  • 设备不得接入不可信网络(公共网络、访客网络、直连互联网);
  • 建议设备与调用方主机使用独立交换机或专用 VLAN,与办公网隔离。

详见部署与网络。

上一页
核心概念
下一页
API 参考