XGRIDSDocs
  • 简体中文
  • English
  • 繁體中文
  • 日本語
  • Deutsch
  • Español
  • Italiano
  • Français
  • Русский
  • Polski
  • Nederlands
  • 简体中文
  • English
  • 繁體中文
  • 日本語
  • Deutsch
  • Español
  • Italiano
  • Français
  • Русский
  • Polski
  • Nederlands
  • PortalCam

    • Product Overview
    • Basic Operation
    • Using the LCC Scan App
    • Maintenance and Care
    • FAQ
  • Lixel K Series

    • Lixel K1

      • Product Overview
      • Basic Operation
      • Device Activation and Connection
      • Scanning Workflow
      • Acquire Point Cloud Data with Absolute Coordinate
      • Map Fusion
      • Route Planning Suggestions for Typical Scenes
      • Precautions
      • FAQ
    • Lixel K2

      • Product Overview
      • Basic Operation
      • Device Activation and Connection
      • Scanning Workflow
      • Acquire Point Cloud Data with Absolute Coordinate
      • Map Fusion
      • Route Planning Suggestions for Typical Scenes
      • Precautions
      • FAQ
  • Lixel L Series

    • Lixel L2 Pro

      • Product Overview
      • Basic Operation
      • Device Activation and Connection
      • Scanning Workflow
      • Acquire Point Cloud Data with Absolute Coordinate
      • Measure Point
      • Appendix
      • FAQ
    • Lixel L3

      • Product Overview
      • Basic Device Functions
      • Device Activation and Connection
      • Data Capture
      • Capturing Absolute Coordinates
      • Appendix
  • Accessories

    • Stick Light

      • Installation Guide
      • Basic Operation
      • FAQ
  • Lixel Studio

    • Version and Copyright
    • Installation and Activation
    • Software Interface
    • File Operations
    • Project Processing
    • Tools
    • 2D Drawing
    • Applications
    • Settings
    • Device Connection
    • FAQ
  • Lixel CyberColor

    • LCC Studio

      • Getting Started
      • Version and Updates
      • Download and Installation
      • Interface Overview and Navigation
      • Before Reconstruction
      • Model Reconstruction
      • Single Model Reconstruction
      • Map Fusion
      • Aerial-Ground Fusion
      • Aerial Reconstruction
      • My Models
      • Other Features
      • Settings and Account
      • Converter
      • Video Reconstruction
      • FAQ
    • LCC Scene Editor

      • Version & Updates
      • Account & Login
      • Product Overview & Home
      • Editor Interface
      • Scene Navigation Modes
      • File
      • Settings
      • Edit Operations
      • Window
      • Global Toolbar
      • Assets & Properties
      • Left Toolbar
      • Viewpoints
      • Portal
      • Skybox
      • Annotations
      • Measurement
      • Flythrough
      • Scene Report
      • 3D Layout
      • Mini-Map
      • Preview Mode (Viewer)
      • Help
      • FAQ
      • Spawn Point
    • LCC Model Editor

      • Version and Updates
      • User Guide
      • Overview and Interface
      • File Operations
      • Selectors
      • Editing Models
      • Measurement
      • Color Grading
      • Asset Management
      • Settings and Help
      • FAQ
    • Capture Guide

      • Overview
      • Capture Devices Overview
      • General Capture Principles
      • Indoor Scene Capture
      • Outdoor Scene Capture
      • Large-Scale Capture (Map Fusion)
      • Aerial-Ground Map Fusion Capture
      • Object Capture
      • People Capture
      • Video Reconstruction Capture
      • HD Enhancement
      • Control Points (Lixel P1)
      • FAQ and Troubleshooting
    • LCC Studio Linux

      • Product Overview
      • Architecture Guide
      • Installation and Deployment Guide
      • Container Startup Parameters Guide
      • CodeMeter Offline Licensing Deployment Guide
      • API Reference
      • Appendix - Developer Data Guide
      • Appendix - Error Code List
      • Single-Machine Multi-GPU Cluster Deployment QuickStart
    • Best Practices

      • Merging Multiple Large 3DGS Models
    • Version History
  • Plugin & SDK

    • Unreal

      • Introduction
      • Quick Start - Windows
      • Quick Start - Linux
      • Quick Start - Quest3
      • Editions and Licensing
      • Rendering
      • Tiled Rasterization (Experimental)
      • Visual Settings
      • Normals and Lighting
      • Scene Editing
      • Performance Parameters
      • Performance Guide
      • Third-party and Engine Plugin Integration
      • Proxy Mesh
      • Loading Animation
      • Collision
      • Navigation System Support
      • Single Layer Water Support
      • Localization
      • FAQ
      • Troubleshooting
      • Logging and Diagnostics
      • Contact Us
      • Best Practices

        • Relighting 3DGS with a LixelStudio Mesh
      • API Reference

        • ALCCActorBase
        • ULCCComponentBase
        • ULCCComponent
        • ULCC2Component
        • SOG / SPZ / PLY Actors
        • ALCC2ProxyMesh
        • ALCCClippingVolume
        • ALCCSectionPlane
        • ALCCLoadVolume
        • ULCCUtilLibrary
        • Enums
        • Structs
      • Changelog

        • v3.4.0
        • 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
    • Web

      • Introduction
      • Rendering Performance Optimization Guide
      • Graphics Configuration
      • FAQ
      • API Reference

        • LCCRender::clearIndexDB
        • LCCRender::dispose
        • LCCRender::load
        • LCCRender::setCamera
        • LCCRender::unload
        • LCCRender::update
        • LCCObject::checkRenderNextFrame
        • LCCObject::clearRenderNextFrame
        • LCCObject::ecef2Prj
        • LCCObject::getBounds
        • LCCObject::getEnvInstancedMesh
        • LCCObject::getInstancedMesh
        • LCCObject::getLodInfos
        • LCCObject::getOriginPosition
        • LCCObject::getProjectionCoordinateSystemInfos
        • LCCObject::hasCollision
        • LCCObject::hasEnvironment
        • LCCObject::hasShcoef
        • LCCObject::intersectsCapsule
        • LCCObject::intersectsRayExt
        • LCCObject::intersectsRayFromOriginExt
        • LCCObject::intersectsSphere
        • LCCObject::lowerToBottom
        • LCCObject::prj2Ecef
        • LCCObject::raiseToTop
        • LCCObject::raycast
        • LCCObject::raycastFromOrigin
        • LCCObject::setAlpha
        • LCCObject::setClipBox
        • LCCObject::setClipPlane
        • LCCObject::setEndLod
        • LCCObject::setLodAutoLevelUp
        • LCCObject::setMaxDistance
        • LCCObject::setMaxNodeSplats
        • LCCObject::setMaxSplats
        • LCCObject::setOriginPosition
        • LCCObject::setPointsColor
        • LCCObject::setRenderState
        • LCCObject::setRotation
        • LCCObject::setScale
        • LCCObject::setSemantic
        • LCCObject::setSemanticColor
        • LCCObject::setSmooth
        • LCCObject::setStartLod
        • LCCObject::setTranslation
        • LCCObject::setVisible
        • LCCObject::togglePointsDisplayMode
        • LCCObject::useEnvironment
        • LCCObject::useShcoef
      • Changelog

        • v0.6.3
        • v0.6.2
        • v0.6.1
        • v0.6.0
        • v0.5.5
        • v0.5.4
        • v0.5.3
        • v0.5.2
        • v0.5.1
        • v0.5.0
        • v0.4.1
        • v0.4.0
        • v0.3.1
        • v0.3.0
        • v0.2.0
    • Lixel OpenAPI

      • Overview
      • Connection & Authentication
      • Message Model & Codec
      • Interface Catalog
      • Real-time Data
      • Project File Access
      • Error Codes
      • Python

        • Quick Start
        • Client Wrapper & Tools
        • FAQ
      • C++

        • Quick Start
        • Client & Examples
        • FAQ

Client & Examples

The C++ client library lives in the lixel::openapi namespace, with public headers in cpp/include/lixel/openapi/. This page covers what it offers and how to use it.

Headers at a glance

HeaderWhat it gives you
client.hClient: Connect, Request, Publish, Subscribe, SubscribeMessage, RemoveSubscription
scan.hRunScan: start a scan, wait until the device is really scanning, stop, wait for standby
pointcloud.hDecodePointCloud: decode the lio_pcl payload into scaled points
codec.hmessage by name, protobuf to and from JSON
catalog.hthe table of 18 interfaces and their 34 topics
codes.h, result.hdevice status codes, Result and Errc

The Client

Connect

lixel::openapi::ClientOptions options;
options.transport.host = "192.168.55.1";
options.openapi_key = "<provided by XGRIDS>";

lixel::openapi::Client client(options);
lixel::openapi::Result r = client.Connect();   // blocks until connected

A failed Connect() returns Errc::ConnectFailed or Errc::ConnectTimeout, and the client can be used for another Connect() afterwards.

Request-response

openapi::aiot_msgs::DeviceInfoRequest req;
openapi::aiot_msgs::DeviceInfoResponse rsp;
lixel::openapi::Result r = client.Request(
    "lixel/application/request/device_info", req,
    "lixel/application/response/device_info", &rsp);

Return codes of Request:

CodeMeaning
OkA response arrived and its Error.code is a success code
DeviceErrorA response arrived but with an error code (see Result::device_code, desc); response is filled
RequestTimeoutNo response with the same seq within the timeout. The device may still have carried out the request; confirm with it before assuming otherwise
NotConnectedNot connected, or the connection dropped while waiting
CalledFromCallbackRequest was called from a subscription callback

Subscribe to reports

client.SubscribeMessage(
    "lixel/application/report/device_status", "DeviceStatusReport",
    [](const std::string& topic, const google::protobuf::Message& msg) {
      // msg is already parsed into the matching protobuf message
    });

Note: subscription callbacks run on the MQTT layer's thread, one message at a time; keep them short. A callback must not call Connect or Disconnect; calling Request returns Errc::CalledFromCallback instead of blocking. The strings passed to a callback are valid only for the duration of the call; copy what you need.

Point cloud decoding

The real-time point cloud (report/lio_pcl, MqttCompressMsg) is decoded with DecodePointCloud, which decompresses and deserializes in one step:

#include "lixel/openapi/pointcloud.h"

lixel::openapi::PointCloud cloud;
lixel::openapi::Result r = lixel::openapi::DecodePointCloud(payload, &cloud);
// On success, each point's x/y/z in cloud.points is reconstructed by header.scaler (the device sends scaler as 1000).

The compression is LZ4 block (not frame). A Zstd-compressed point cloud and a negative scaler return Errc::Unsupported. A point's rgbi is passed through unchanged (the proto only notes R+G+B+Intensity, with no further byte-order convention).

Scan flow

Starting and stopping a scan are asynchronous on the device: the response to AC_START only means the request was accepted, and the device then goes standby → starting → scanning. RunScan wraps the whole flow — subscribe to the device status, wait for standby, start, wait until really scanning, watch for a while, stop, and wait for standby:

#include "lixel/openapi/scan.h"

lixel::openapi::ScanOptions options;
options.project_name = "demo";
options.watch = std::chrono::seconds(8);

lixel::openapi::ScanReport report = lixel::openapi::RunScan(client, options);
return report.exit_code();   // 0 success, others see ScanOutcome

RunScan blocks the calling thread, requires a connected client, and must not be called from a subscription callback. The ScanOutcome result: Completed (0), Timeout (1), NotStandby (2), StartRejected (3), NoResponse (4), Error (5), Interrupted (130).

The 18 command line examples

cpp/examples/ has one C++ program for each script in python/example/usage/, with the same name and options, built with the library (on by default) into cpp/build/examples/:

./cpp/build/examples/heartbeat --seconds 5                 # no key needed
./cpp/build/examples/device_info --key <provided by XGRIDS>
./cpp/build/examples/modeling --key <provided by XGRIDS> --project demo --watch 8
./cpp/build/examples/lio_pcl --key <provided by XGRIDS> --seconds 20   # while the device scans

Common options: --host (default 192.168.55.1), --port, --tls, --username, --password, --key, --timeout; for TLS also --ca-file and --insecure. Exit codes: 0 success, 1 could not connect or no answer, 2 bad option (modeling: the device was not in standby), 3 the device answered with an error code, 130 interrupted.

The 18 examples: control_point, data_unpack, device_config, device_control, device_info, device_status, get_ntrip_profile, get_rtk_advance, heartbeat, lio_pcl, lio_pose, measure_point, modeling, modeling_status, project_list, set_ntrip_profile, set_rtk_advance, system_error.

Note: among them, device_control, device_config, set_ntrip_profile, set_rtk_advance, control_point, and measure_point change the device, and device_control can power it off or format the disk — confirm before use.

Differences from the Python client

The C++ client intentionally differs in a few places:

AspectC++Python
Response matchingBy header.seq, which the device copies backThe first message on the response topic
JSON conversionStrict: a misspelled field or enum name is an errorDropped silently
MQTTS certificateVerifies the server certificate by default; the self-signed device certificate needs --ca-file, or --insecure to turn verification offNever verifies
Calling Request in a callbackReturns Errc::CalledFromCallbackBlocks

Other limits:

  • Several Client objects in one process share one MQTT worker thread; opening a second connection takes about 2 seconds. Each example uses one Client and is not affected.
  • A Request that is waiting cannot be cancelled; it ends within request_timeout.

Next steps

  • For the build, dependencies, and integration, see Quick Start.
  • For the protocol itself, see the shared chapters Interface Catalog, Real-time Data, and Error Codes.