From b3d3759216dca1a1f7dd5f7101367ffd7c3394c1 Mon Sep 17 00:00:00 2001 From: Arthur Mougin Date: Thu, 12 Feb 2026 12:49:06 +0100 Subject: [PATCH 1/9] wip: documentation progress by adding doxygen to protocol and filling up the readme --- README.md | 183 ++++++++++++++++++++++++++++++++++ include/AugmentaClientSDK.hpp | 58 ++++++++++- 2 files changed, 238 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 273d845..2eb1abc 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,189 @@ cmake --build build The SDK revolves around creating an `Augmenta::Client` object and using it to parse data blobs and messages received. See [examples/Example.cpp](examples/Example.cpp) for a full usage example. +### Start connection +When starting a connection, call `client.initialize(MyClientName,Options)`. +When disconnecting, during closing or when changing urls, call `client.shutdown();`. + +## Websocket Protocol +The SDK implement the following protocol : [Augmenta Websocket V2](https://augmentatech.notion.site/WebSocket-Protocol-Specification-v2-637551d8e04a4015a56526d80e1b10f0?pvs=74) + +## Option +Here are all the available options for the client initialization: + +```c++ + struct ProtocolOptions + { + + /// @brief Specifies the mode for representing rotations for all non-streamed objects + enum class RotationMode + { + Radians, + Degrees, + Quaternions, + }; + + /// @brief Defines a coordinate system transformation configuration, including axis orientation, origin placement, axis flipping, and coordinate space type. + /// + /// Augmenta internally use a left handed Y-up coordinate system with the origin at the bottom left of the scene, but + /// you can specify a different configuration here. Augmenta will take care of transforming all the data to match it. + struct AxisTransform + { + /// @brief Defines the coordinate system axis mode. + enum class AxisMode + { + ZUpRightHanded, + ZUpLeftHanded, + YUpRightHanded, + YUpLeftHanded, + }; + + /// @brief Specifies the origin position for coordinate system or layout calculations. + enum class OriginMode + { + BottomLeft, + BottomRight, + TopLeft, + TopRight, + }; + + /// @brief Defines the coordinate space in which scenes, zones, cluster and point + /// cloud data will be provided. + /// + /// - Absolute referes to World space coordinates in relation + /// to the origin visible in Augmenta's front-end ui. + /// - Relative give coordinates to the parent. Clusters are + /// considered childs of the scene they are computed in and are then + /// placed based on that scene's origin. + /// - Normalized gives coordinates relative between 0 and 1 based on + /// the scene dimensions. + enum class CoordinateSpace + { + Absolute, + Relative, + Normalized, + }; + + AxisMode axis = AxisMode::ZUpRightHanded; + OriginMode origin = OriginMode::BottomLeft; + + /// @brief finer controls to flip specific axis if needed. + bool flipX = false; + bool flipY = false; + bool flipZ = false; + CoordinateSpace coordinateSpace = CoordinateSpace::Absolute; + // public originOffset; // TODO + // public customMatrix; // TODO + + bool operator==(const AxisTransform& other) const; + bool operator!=(const AxisTransform& other) const; + }; + + /// @brief Protocol version 2 + int version = 2; + + /// @brief tags are used to filter what content to be streamed by the server. + /// You may add tags to scenes in the backend GUI and have only one scene's + /// clusters, zone events and point clouds streamed by adding the + /// corresponding tag to this list. If the list is empty, all content + /// will be streamed. + std::vector tags; + + /// @brief Downsampling factor for point clouds. + /// + /// It is very usefull when you want to reduce the number of points + /// received for performance reasons. You may even cap your global + /// cluster size by dynamically changing this property. + /// + /// For example, a value of 2 means that only every 2nd point will be + /// streamed. Must be superior or equal to 1. + int downSample = 1; + + /// @brief Whether the server should send the scene Point Cloud data. + bool streamClouds = true; + + /// @brief Whether the server should send the scene Clusters data. + bool streamClusters = true; + + /// @brief Whether the server should add the points that make up a cluster to each cluster packet. + bool streamClusterPoints = true; + + /// @brief Whether the server should add the points included in a zone to each zone packet. + bool streamZonePoints = false; + + RotationMode boxRotationMode = RotationMode::Quaternions; + AxisTransform axisTransform; // TODO: Default ? + + /// @brief enable ZSTD compression on the binary data's stream + bool useCompression = true; + + // @brief By default, Augmenta will send data as soon as it is + // available. If that's overwelming your application, you can enable + // this option to only receive data only on demand (by sending a poll request) + bool usePolling = false; + + }; +``` + +> Note: To change any parameter after initialization, shutdown the client, change the options and re-initialize it. +> +> This will ensure that the server is correctly updated with the new options. Id and names will persist as long as +> the server is not restarted. Though, changes may have occured during the shutdown, so you may want to do a full +> removal on shutdown to prevent client-side ghosts. + +## Data types +The SDK will not provide fixed types for the received Object to allow for implementor's discretion regarding about math libraries or features to use. +Instead, here is an optional abstract representation of the data types used in the SDK: + +```md +// V1 Full data structure. Match Augmenta's protocol but might be overkill for some use cases. + +Type AugmentaPointCloud : Vector3 array + +Type AugmentaCluster : + - stat : Enum { 0 = Enter, 1 = Update, 2 = Will Leave, 3 = Ghost } + - Centroid: Vector3 + - Velocity: Vector3 + - BoundingBoxCenter: Vector3 + - BoundingBoxSize: Vector3 + - weight: Quaternion or Vector3 (Quaternion, degree or radian based on boxRotationMode option) + - LookAt: Vector3 + +type AugmentaStreamObject + - id: int + - hasCluster: boolean + - hasPointCloud: Boolean + - pointCloud: Optional (streamClusterPoints result in Objects with cluster also having pointClouds, streamClouds can result in Objects with pointClouds but no cluster) + - cluster: Optional (setting streamClusters to false will result in no Object having clusters) + +type AugmentaArborescenceNode : + - type: string ("Scene", "Shape", "Container") + - name: string + - address: string (OSC Path exposed by hovering the element in the backend GUI) + - position: Vector3 + - rotation: Quaternion or Vector3 (Quaternion, degree or radian based on RotationMode option) + - children: array of AugmentaArborescenceNode + +type AugmentaScene extend AugmentaArborescenceNode : + - type: "Scene" + - size: Vector3 + - pointCloud: Optional set using streamClouds + +type zone : AugmentaArborescenceNode : + - type: "zone" + - sliderValue: float + - xpad: float + - ypad:float + - presence: int + - onEnterCallback: function + - onLeaveCallback: function + - pointCloud: Optional only if streamZonePoints is On + - shape: + - type: string ("box", "cylinder", "sphere + ... shape parameters + +``` + ## Dependencies - [zstd](https://github.com/facebook/zstd) - [nlohmann::json](https://github.com/nlohmann/json) \ No newline at end of file diff --git a/include/AugmentaClientSDK.hpp b/include/AugmentaClientSDK.hpp index 89f64a1..61d1525 100644 --- a/include/AugmentaClientSDK.hpp +++ b/include/AugmentaClientSDK.hpp @@ -13,6 +13,8 @@ namespace Augmenta { struct ProtocolOptions { + + /// @brief Specifies the mode for representing rotations for all non-streamed objects enum class RotationMode { Radians, @@ -20,8 +22,13 @@ namespace Augmenta Quaternions, }; + /// @brief Defines a coordinate system transformation configuration, including axis orientation, origin placement, axis flipping, and coordinate space type. + /// + /// Augmenta internally use a left handed Y-up coordinate system with the origin at the bottom left of the scene, but + /// you can specify a different configuration here. Augmenta will take care of transforming all the data to match it. struct AxisTransform { + /// @brief Defines the coordinate system axis mode. enum class AxisMode { ZUpRightHanded, @@ -30,6 +37,7 @@ namespace Augmenta YUpLeftHanded, }; + /// @brief Specifies the origin position for coordinate system or layout calculations. enum class OriginMode { BottomLeft, @@ -38,6 +46,16 @@ namespace Augmenta TopRight, }; + /// @brief Defines the coordinate space in which scenes, zones, cluster and point + /// cloud data will be provided. + /// + /// - Absolute referes to World space coordinates in relation + /// to the origin visible in Augmenta's front-end ui. + /// - Relative give coordinates to the parent. Clusters are + /// considered childs of the scene they are computed in and are then + /// placed based on that scene's origin. + /// - Normalized gives coordinates relative between 0 and 1 based on + /// the scene dimensions. enum class CoordinateSpace { Absolute, @@ -47,6 +65,8 @@ namespace Augmenta AxisMode axis = AxisMode::ZUpRightHanded; OriginMode origin = OriginMode::BottomLeft; + + /// @brief finer controls to flip specific axis if needed. bool flipX = false; bool flipY = false; bool flipZ = false; @@ -58,20 +78,52 @@ namespace Augmenta bool operator!=(const AxisTransform& other) const; }; + /// @brief Protocol version 2. int version = 2; + + /// @brief tags are used to filter what content to be streamed by the server. + /// You may add tags to scenes in the backend GUI and have only one scene's + /// clusters, zone events and point clouds streamed by adding the + /// corresponding tag to this list. If the list is empty, all content + /// will be streamed. std::vector tags; + + /// @brief Downsampling factor for point clouds. + /// + /// It is very usefull when you want to reduce the number of points + /// received for performance reasons. You may even cap your global + /// cluster size by dynamically changing this property. + /// + /// For example, a value of 2 means that only every 2nd point will be + /// streamed. Must be superior or equal to 1. int downSample = 1; + + /// @brief Whether the server should send the scene Point Cloud data. bool streamClouds = true; + /// @brief Whether the server should send the scene Clusters data. bool streamClusters = true; + /// @brief Whether the server should add the points that make up a cluster to each cluster packet. bool streamClusterPoints = true; - bool streamSkeletonData = true; - bool streamMetadata = true; + + // bool streamSkeletonData = true; // @TODO: Not implemented yet + // bool streamMetadata = true; // @TODO: Not implemented yet + + /// @brief Whether the server should add the points included in a zone to each zone packet. bool streamZonePoints = false; + RotationMode boxRotationMode = RotationMode::Quaternions; AxisTransform axisTransform; // TODO: Default ? + + /// @brief enable ZSTD compression on the binary data's stream bool useCompression = true; + + // @brief By default, Augmenta will send data as soon as it is + // available. If that's overwelming your application, you can enable + // this option to only receive data only on demand (by sending a poll request) bool usePolling = false; - bool displayPointIntensity = false; + + // TODO: Not implemented yet, may need v3? + bool displayPointIntensity = false; bool operator==(const ProtocolOptions& other) const; bool operator!=(const ProtocolOptions& other) const; From 60086a3adc6a395da2d56f65e7b3f306b2b943b1 Mon Sep 17 00:00:00 2001 From: Arthur Mougin Date: Thu, 12 Feb 2026 15:13:55 +0100 Subject: [PATCH 2/9] wip: improve documentation and add clarification --- README.md | 24 ++++++++++++------------ include/AugmentaClientSDK.hpp | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 2eb1abc..44d3511 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,8 @@ The SDK implement the following protocol : [Augmenta Websocket V2](https://augme ## Option Here are all the available options for the client initialization: -```c++ +```cpp + struct ProtocolOptions { @@ -54,7 +55,7 @@ Here are all the available options for the client initialization: ZUpRightHanded, ZUpLeftHanded, YUpRightHanded, - YUpLeftHanded, + YUpLeftHanded, // used in the front-end GUI of Augmenta }; /// @brief Specifies the origin position for coordinate system or layout calculations. @@ -70,12 +71,12 @@ Here are all the available options for the client initialization: /// cloud data will be provided. /// /// - Absolute referes to World space coordinates in relation - /// to the origin visible in Augmenta's front-end ui. + /// to the origin visible in Augmenta's front-end ui. /// - Relative give coordinates to the parent. Clusters are - /// considered childs of the scene they are computed in and are then - /// placed based on that scene's origin. + /// considered childs of the scene they are computed in and are then + /// placed based on that scene's origin. /// - Normalized gives coordinates relative between 0 and 1 based on - /// the scene dimensions. + /// the scene dimensions. enum class CoordinateSpace { Absolute, @@ -91,8 +92,6 @@ Here are all the available options for the client initialization: bool flipY = false; bool flipZ = false; CoordinateSpace coordinateSpace = CoordinateSpace::Absolute; - // public originOffset; // TODO - // public customMatrix; // TODO bool operator==(const AxisTransform& other) const; bool operator!=(const AxisTransform& other) const; @@ -144,17 +143,16 @@ Here are all the available options for the client initialization: }; ``` -> Note: To change any parameter after initialization, shutdown the client, change the options and re-initialize it. +> **Note:** To change any parameter after initialization, shutdown the client re-initialize it with the new options. > -> This will ensure that the server is correctly updated with the new options. Id and names will persist as long as -> the server is not restarted. Though, changes may have occured during the shutdown, so you may want to do a full -> removal on shutdown to prevent client-side ghosts. +> Id and names will persist as long as the server is not restarted. Beware that changes may have occured during the downtime. ## Data types The SDK will not provide fixed types for the received Object to allow for implementor's discretion regarding about math libraries or features to use. Instead, here is an optional abstract representation of the data types used in the SDK: ```md +Pseudo-code // V1 Full data structure. Match Augmenta's protocol but might be overkill for some use cases. Type AugmentaPointCloud : Vector3 array @@ -203,6 +201,8 @@ type zone : AugmentaArborescenceNode : ``` +> **Note:** Points Cloud attached to a Zone or cluster are positionned relative to the parent Scene when *CoordinateSpace::Relative* is used. + ## Dependencies - [zstd](https://github.com/facebook/zstd) - [nlohmann::json](https://github.com/nlohmann/json) \ No newline at end of file diff --git a/include/AugmentaClientSDK.hpp b/include/AugmentaClientSDK.hpp index 61d1525..de02c76 100644 --- a/include/AugmentaClientSDK.hpp +++ b/include/AugmentaClientSDK.hpp @@ -112,7 +112,7 @@ namespace Augmenta bool streamZonePoints = false; RotationMode boxRotationMode = RotationMode::Quaternions; - AxisTransform axisTransform; // TODO: Default ? + AxisTransform axisTransform; // @TODO: Default ? /// @brief enable ZSTD compression on the binary data's stream bool useCompression = true; From 79afb56f7c1d9c1eeabb6fd0c949576458c94ff8 Mon Sep 17 00:00:00 2001 From: Arthur Mougin Date: Mon, 16 Feb 2026 15:46:07 +0100 Subject: [PATCH 3/9] fix typos and clearer documentation --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 44d3511..6094000 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ The SDK revolves around creating an `Augmenta::Client` object and using it to pa See [examples/Example.cpp](examples/Example.cpp) for a full usage example. ### Start connection -When starting a connection, call `client.initialize(MyClientName,Options)`. +When starting a connection, call `client.initialize(MyClientName: string, Options: ProtocolOptions)`. When disconnecting, during closing or when changing urls, call `client.shutdown();`. ## Websocket Protocol @@ -97,7 +97,7 @@ Here are all the available options for the client initialization: bool operator!=(const AxisTransform& other) const; }; - /// @brief Protocol version 2 + /// @brief Protocol version 1 or 2 (better use 2) int version = 2; /// @brief tags are used to filter what content to be streamed by the server. @@ -137,7 +137,7 @@ Here are all the available options for the client initialization: // @brief By default, Augmenta will send data as soon as it is // available. If that's overwelming your application, you can enable - // this option to only receive data only on demand (by sending a poll request) + // this option to only receive data on demand (by sending a poll request) bool usePolling = false; }; @@ -153,7 +153,7 @@ Instead, here is an optional abstract representation of the data types used in t ```md Pseudo-code -// V1 Full data structure. Match Augmenta's protocol but might be overkill for some use cases. +// Full data structure. Match Augmenta's protocol but might be overkill for some use cases. Type AugmentaPointCloud : Vector3 array From b8b93823ecb152800a9e234f8594a1a50c8b9d61 Mon Sep 17 00:00:00 2001 From: Arthur Mougin Date: Mon, 16 Feb 2026 15:49:19 +0100 Subject: [PATCH 4/9] better polling phrasing --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 6094000..da4eada 100644 --- a/README.md +++ b/README.md @@ -135,8 +135,7 @@ Here are all the available options for the client initialization: /// @brief enable ZSTD compression on the binary data's stream bool useCompression = true; - // @brief By default, Augmenta will send data as soon as it is - // available. If that's overwelming your application, you can enable + // @brief By default, Augmenta will send data as soon as possible. you can enable // this option to only receive data on demand (by sending a poll request) bool usePolling = false; From 036bc39f27be8756a042368bdaae9e96cb3352a0 Mon Sep 17 00:00:00 2001 From: Arthur Mougin Date: Tue, 17 Feb 2026 10:27:06 +0100 Subject: [PATCH 5/9] feat: adding feature list --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index da4eada..a1120d4 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,16 @@ The goal of this library is to make consuming the stream output of an Augmenta server as easy as possible. As of right now this only refers to the data emitted through websocket by the Websocket Output node, but other network protocols might be added later on. +## Features +The features currently implemented are: +- **Tracking of clusters** : Augmenta send a list of objects with their id, centroid position, bounding box and velocity (with optional point cloud data). +- **Volumetric data** : Optional global point cloud of the whole scene. Richness of the point cloud is controled in the Augmenta software, though you can control downsampling through the sdk. +- **Zones** : You can define zones in the Augmenta software and receive events like entering, leaving, presence, and other dynamic values. + +Fteaures yet to be implemented are: +- **Bi-directional communication** : While you can use OSC to control Augmenta, the same is not yet possible through the websocket protocol. +- **Skeleton tracking** : We plan to add support for receiving skeleton data from the server in the future. + ## Building We use CMake as our buildsystem. From 6927385ade7dbf7a81683405d0c4b661d13cc74e Mon Sep 17 00:00:00 2001 From: Arthur Mougin Date: Tue, 17 Feb 2026 10:31:08 +0100 Subject: [PATCH 6/9] feat: mentionning augmenta's downtime --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index a1120d4..db02895 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,9 @@ cmake --build build The SDK revolves around creating an `Augmenta::Client` object and using it to parse data blobs and messages received. See [examples/Example.cpp](examples/Example.cpp) for a full usage example. +Augmenta's server is designed to run perpetually. This include handling automatic restarts in case of crashes, reboot or any kind of downtime. +When Implementing the SDK, you must take this into account and make sure to handle the connection lifecycle properly. For exmaple, you must try to reconnect in case of disconnection and make sure to shutdown the client properly when closing the application or changing urls. + ### Start connection When starting a connection, call `client.initialize(MyClientName: string, Options: ProtocolOptions)`. When disconnecting, during closing or when changing urls, call `client.shutdown();`. From 4254540b61ab268e5cb9b3c2f6f5239cb61740d4 Mon Sep 17 00:00:00 2001 From: David-Alexandre Chanel Date: Tue, 17 Feb 2026 10:54:56 +0100 Subject: [PATCH 7/9] Fix typos and enhance README content Corrected typos and improved clarity in the README. --- README.md | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index db02895..4badaff 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,13 @@ The goal of this library is to make consuming the stream output of an Augmenta s ## Features The features currently implemented are: -- **Tracking of clusters** : Augmenta send a list of objects with their id, centroid position, bounding box and velocity (with optional point cloud data). -- **Volumetric data** : Optional global point cloud of the whole scene. Richness of the point cloud is controled in the Augmenta software, though you can control downsampling through the sdk. -- **Zones** : You can define zones in the Augmenta software and receive events like entering, leaving, presence, and other dynamic values. +- **Tracking data** : Augmenta sends a list of objects with their id, centroid position, bounding box and velocity (with optional point cloud data). +- **Volumetric data** : The point cloud of the whole scene. Richness of the point cloud can be controled through the Augmenta software or through the sdk. Point cloud from only specific zones can be requested. +- **Zones events** : You can define 3D zones in the Augmenta software and receive events like entering, leaving, presence, and other dynamic values. 3D zones are sent through the SDK to synchronize and display them, manipulating them from the SDK is planned but not yet available. -Fteaures yet to be implemented are: +Features yet to be implemented are: - **Bi-directional communication** : While you can use OSC to control Augmenta, the same is not yet possible through the websocket protocol. -- **Skeleton tracking** : We plan to add support for receiving skeleton data from the server in the future. +- **Skeleton tracking** : We plan to add support for receiving skeleton data in the future. ## Building We use CMake as our buildsystem. @@ -30,16 +30,13 @@ cmake --build build The SDK revolves around creating an `Augmenta::Client` object and using it to parse data blobs and messages received. See [examples/Example.cpp](examples/Example.cpp) for a full usage example. -Augmenta's server is designed to run perpetually. This include handling automatic restarts in case of crashes, reboot or any kind of downtime. -When Implementing the SDK, you must take this into account and make sure to handle the connection lifecycle properly. For exmaple, you must try to reconnect in case of disconnection and make sure to shutdown the client properly when closing the application or changing urls. +Augmenta's server and software are designed to run perpetually. This include handling automatic restarts in case of crashes, reboot or any kind of downtime. +When Implementing the SDK, you must take this into account and make sure to handle the connection lifecycle properly. For example, you must try to reconnect regularly in case of disconnection and make sure to shutdown the client properly when closing the application or changing urls. ### Start connection When starting a connection, call `client.initialize(MyClientName: string, Options: ProtocolOptions)`. When disconnecting, during closing or when changing urls, call `client.shutdown();`. -## Websocket Protocol -The SDK implement the following protocol : [Augmenta Websocket V2](https://augmentatech.notion.site/WebSocket-Protocol-Specification-v2-637551d8e04a4015a56526d80e1b10f0?pvs=74) - ## Option Here are all the available options for the client initialization: @@ -215,6 +212,7 @@ type zone : AugmentaArborescenceNode : > **Note:** Points Cloud attached to a Zone or cluster are positionned relative to the parent Scene when *CoordinateSpace::Relative* is used. -## Dependencies +## Dependencies and ressources - [zstd](https://github.com/facebook/zstd) - - [nlohmann::json](https://github.com/nlohmann/json) \ No newline at end of file + - [nlohmann::json](https://github.com/nlohmann/json) + - [Augmenta Websocket protocol V2](https://augmentatech.notion.site/WebSocket-Protocol-Specification-v2-637551d8e04a4015a56526d80e1b10f0?pvs=74) From 6931a12af56294d2020fb7f23ffd804a29f41d43 Mon Sep 17 00:00:00 2001 From: Arthur Mougin Date: Thu, 19 Feb 2026 14:08:31 +0100 Subject: [PATCH 8/9] change protocol reference --- README.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4badaff..87cc92a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Augmenta Client C++ SDK -The goal of this library is to make consuming the stream output of an Augmenta server as easy as possible. As of right now this only refers to the data emitted through websocket by the Websocket Output node, but other network protocols might be added later on. +The goal of this library is to make consuming the stream output of an Augmenta server as easy as possible. +As of right now this only refers to the data emitted through websocket by the Websocket Output node, but other network protocols might be added later on. ## Features The features currently implemented are: @@ -33,11 +34,17 @@ See [examples/Example.cpp](examples/Example.cpp) for a full usage example. Augmenta's server and software are designed to run perpetually. This include handling automatic restarts in case of crashes, reboot or any kind of downtime. When Implementing the SDK, you must take this into account and make sure to handle the connection lifecycle properly. For example, you must try to reconnect regularly in case of disconnection and make sure to shutdown the client properly when closing the application or changing urls. +### Websocket +This SDK does not come with a specific Websocket client. +The intention is to allow for implementor's discretion regarding Math library, Network sdk, and other dependencies. + +It works with any client by forwarding the stream to the `client.parseDataBlob(blob, blobSize)` method, and the messages to `client.parseControlMessage(rawMessage)`. + ### Start connection When starting a connection, call `client.initialize(MyClientName: string, Options: ProtocolOptions)`. When disconnecting, during closing or when changing urls, call `client.shutdown();`. -## Option +### Options Here are all the available options for the client initialization: ```cpp @@ -215,4 +222,5 @@ type zone : AugmentaArborescenceNode : ## Dependencies and ressources - [zstd](https://github.com/facebook/zstd) - [nlohmann::json](https://github.com/nlohmann/json) - - [Augmenta Websocket protocol V2](https://augmentatech.notion.site/WebSocket-Protocol-Specification-v2-637551d8e04a4015a56526d80e1b10f0?pvs=74) + +> Please reach out to us if you have any questions - Augmenta Team \ No newline at end of file From 852f91223e861fedc11421fa21064f1acb4605d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9on?= Date: Fri, 27 Feb 2026 10:19:11 +0100 Subject: [PATCH 9/9] Documentation update --- README.md | 229 +++++----------------------------- examples/Example.cpp | 99 +++++++++++---- include/AugmentaClientSDK.hpp | 129 ++++++++++--------- 3 files changed, 178 insertions(+), 279 deletions(-) diff --git a/README.md b/README.md index 87cc92a..38aee72 100644 --- a/README.md +++ b/README.md @@ -4,221 +4,56 @@ The goal of this library is to make consuming the stream output of an Augmenta s As of right now this only refers to the data emitted through websocket by the Websocket Output node, but other network protocols might be added later on. ## Features -The features currently implemented are: -- **Tracking data** : Augmenta sends a list of objects with their id, centroid position, bounding box and velocity (with optional point cloud data). -- **Volumetric data** : The point cloud of the whole scene. Richness of the point cloud can be controled through the Augmenta software or through the sdk. Point cloud from only specific zones can be requested. -- **Zones events** : You can define 3D zones in the Augmenta software and receive events like entering, leaving, presence, and other dynamic values. 3D zones are sent through the SDK to synchronize and display them, manipulating them from the SDK is planned but not yet available. +The SDK can be used to parse different type of data received from Augmenta: +- **Tracking data** : A list of tracked objects/persons with their ID, position, bounding box and velocity +- **Volumetric data** : Filtered point cloud data, either per-cluster, per-zone, or from the whole scene +- **Zones events** : Be notified of events like enter, leave, presence... affecting a specific zone in the world +- **World hierarchy** : The structure of the world as set up on Augmenta's side: scenes, zones, etc. Features yet to be implemented are: -- **Bi-directional communication** : While you can use OSC to control Augmenta, the same is not yet possible through the websocket protocol. -- **Skeleton tracking** : We plan to add support for receiving skeleton data in the future. +- **Skeleton tracking** +- **Custom cluster data** -## Building -We use CMake as our buildsystem. - - -To build a standalone version of the lib: - -``` -git clone https://github.com/Augmenta-tech/augmenta-server-lib-cpp -cd augmenta-server-lib-cpp -mkdir build -cmake -B build -S . -cmake --build build -``` +## Protocol +This SDK can help you parse data received from the server, but you'll still need to respect the [Augmenta Websocket Protocol Specification](https://augmentatech.notion.site/Augmenta-WebSocket-Protocol-Specification-v2-637551d8e04a4015a56526d80e1b10f0?pvs=74). Make sure to give it a read ! ## Using the SDK +### Integrate in your project +The SDK is composed of a single header/implementation file pair. We provide support for CMake. You can integrate it the way you see fit: +- using CMake +- as a git submodule +- by dropping the files directly in your project + +### Implement in your codebase The SDK revolves around creating an `Augmenta::Client` object and using it to parse data blobs and messages received. See [examples/Example.cpp](examples/Example.cpp) for a full usage example. -Augmenta's server and software are designed to run perpetually. This include handling automatic restarts in case of crashes, reboot or any kind of downtime. -When Implementing the SDK, you must take this into account and make sure to handle the connection lifecycle properly. For example, you must try to reconnect regularly in case of disconnection and make sure to shutdown the client properly when closing the application or changing urls. - -### Websocket -This SDK does not come with a specific Websocket client. -The intention is to allow for implementor's discretion regarding Math library, Network sdk, and other dependencies. - -It works with any client by forwarding the stream to the `client.parseDataBlob(blob, blobSize)` method, and the messages to `client.parseControlMessage(rawMessage)`. +### Websocket implementation +This SDK does not come with a websocket implementation, as we expect most users' environments to contain one already. If that is not the case we can recommend the [websocketpp](https://github.com/zaphoyd/websocketpp) library. -### Start connection -When starting a connection, call `client.initialize(MyClientName: string, Options: ProtocolOptions)`. -When disconnecting, during closing or when changing urls, call `client.shutdown();`. +### Lifetime +Augmenta's servers and software are designed to run perpetually. They will automatically restarts in case of crashes, reboot, power loss, etc. +Make sure to take this into account and handle the connection lifecycle properly. For example, you should try to reconnect to the server automatically in case the connection is lost (which could happen in cases of network outage for example). ### Options -Here are all the available options for the client initialization: - -```cpp - - struct ProtocolOptions - { - - /// @brief Specifies the mode for representing rotations for all non-streamed objects - enum class RotationMode - { - Radians, - Degrees, - Quaternions, - }; - - /// @brief Defines a coordinate system transformation configuration, including axis orientation, origin placement, axis flipping, and coordinate space type. - /// - /// Augmenta internally use a left handed Y-up coordinate system with the origin at the bottom left of the scene, but - /// you can specify a different configuration here. Augmenta will take care of transforming all the data to match it. - struct AxisTransform - { - /// @brief Defines the coordinate system axis mode. - enum class AxisMode - { - ZUpRightHanded, - ZUpLeftHanded, - YUpRightHanded, - YUpLeftHanded, // used in the front-end GUI of Augmenta - }; - - /// @brief Specifies the origin position for coordinate system or layout calculations. - enum class OriginMode - { - BottomLeft, - BottomRight, - TopLeft, - TopRight, - }; - - /// @brief Defines the coordinate space in which scenes, zones, cluster and point - /// cloud data will be provided. - /// - /// - Absolute referes to World space coordinates in relation - /// to the origin visible in Augmenta's front-end ui. - /// - Relative give coordinates to the parent. Clusters are - /// considered childs of the scene they are computed in and are then - /// placed based on that scene's origin. - /// - Normalized gives coordinates relative between 0 and 1 based on - /// the scene dimensions. - enum class CoordinateSpace - { - Absolute, - Relative, - Normalized, - }; - - AxisMode axis = AxisMode::ZUpRightHanded; - OriginMode origin = OriginMode::BottomLeft; - - /// @brief finer controls to flip specific axis if needed. - bool flipX = false; - bool flipY = false; - bool flipZ = false; - CoordinateSpace coordinateSpace = CoordinateSpace::Absolute; - - bool operator==(const AxisTransform& other) const; - bool operator!=(const AxisTransform& other) const; - }; +Using the SDK, you can select options to control the format and kind of data that the Augmenta server will send (see the implementation for descriptions). - /// @brief Protocol version 1 or 2 (better use 2) - int version = 2; - - /// @brief tags are used to filter what content to be streamed by the server. - /// You may add tags to scenes in the backend GUI and have only one scene's - /// clusters, zone events and point clouds streamed by adding the - /// corresponding tag to this list. If the list is empty, all content - /// will be streamed. - std::vector tags; +While implementing a client, keep in mind that some of those options should be controllable by your users (which type of data will be sent) while some other might be locked by you, the developper (things like your software's coordinate system). - /// @brief Downsampling factor for point clouds. - /// - /// It is very usefull when you want to reduce the number of points - /// received for performance reasons. You may even cap your global - /// cluster size by dynamically changing this property. - /// - /// For example, a value of 2 means that only every 2nd point will be - /// streamed. Must be superior or equal to 1. - int downSample = 1; +> **Note:** Changed options will only be taken into account after re-initializing the client. - /// @brief Whether the server should send the scene Point Cloud data. - bool streamClouds = true; - - /// @brief Whether the server should send the scene Clusters data. - bool streamClusters = true; - - /// @brief Whether the server should add the points that make up a cluster to each cluster packet. - bool streamClusterPoints = true; - - /// @brief Whether the server should add the points included in a zone to each zone packet. - bool streamZonePoints = false; - - RotationMode boxRotationMode = RotationMode::Quaternions; - AxisTransform axisTransform; // TODO: Default ? - - /// @brief enable ZSTD compression on the binary data's stream - bool useCompression = true; - - // @brief By default, Augmenta will send data as soon as possible. you can enable - // this option to only receive data on demand (by sending a poll request) - bool usePolling = false; +## Contribute to the SDK +We use CMake as our buildsystem. +To build a standalone version of the lib: - }; ``` - -> **Note:** To change any parameter after initialization, shutdown the client re-initialize it with the new options. -> -> Id and names will persist as long as the server is not restarted. Beware that changes may have occured during the downtime. - -## Data types -The SDK will not provide fixed types for the received Object to allow for implementor's discretion regarding about math libraries or features to use. -Instead, here is an optional abstract representation of the data types used in the SDK: - -```md -Pseudo-code -// Full data structure. Match Augmenta's protocol but might be overkill for some use cases. - -Type AugmentaPointCloud : Vector3 array - -Type AugmentaCluster : - - stat : Enum { 0 = Enter, 1 = Update, 2 = Will Leave, 3 = Ghost } - - Centroid: Vector3 - - Velocity: Vector3 - - BoundingBoxCenter: Vector3 - - BoundingBoxSize: Vector3 - - weight: Quaternion or Vector3 (Quaternion, degree or radian based on boxRotationMode option) - - LookAt: Vector3 - -type AugmentaStreamObject - - id: int - - hasCluster: boolean - - hasPointCloud: Boolean - - pointCloud: Optional (streamClusterPoints result in Objects with cluster also having pointClouds, streamClouds can result in Objects with pointClouds but no cluster) - - cluster: Optional (setting streamClusters to false will result in no Object having clusters) - -type AugmentaArborescenceNode : - - type: string ("Scene", "Shape", "Container") - - name: string - - address: string (OSC Path exposed by hovering the element in the backend GUI) - - position: Vector3 - - rotation: Quaternion or Vector3 (Quaternion, degree or radian based on RotationMode option) - - children: array of AugmentaArborescenceNode - -type AugmentaScene extend AugmentaArborescenceNode : - - type: "Scene" - - size: Vector3 - - pointCloud: Optional set using streamClouds - -type zone : AugmentaArborescenceNode : - - type: "zone" - - sliderValue: float - - xpad: float - - ypad:float - - presence: int - - onEnterCallback: function - - onLeaveCallback: function - - pointCloud: Optional only if streamZonePoints is On - - shape: - - type: string ("box", "cylinder", "sphere - ... shape parameters - +git clone https://github.com/Augmenta-tech/augmenta-server-lib-cpp +cd augmenta-server-lib-cpp +mkdir build +cmake -B build -S . +cmake --build build ``` -> **Note:** Points Cloud attached to a Zone or cluster are positionned relative to the parent Scene when *CoordinateSpace::Relative* is used. - ## Dependencies and ressources - [zstd](https://github.com/facebook/zstd) - [nlohmann::json](https://github.com/nlohmann/json) diff --git a/examples/Example.cpp b/examples/Example.cpp index 6c1c75b..7b82857 100644 --- a/examples/Example.cpp +++ b/examples/Example.cpp @@ -4,13 +4,41 @@ #include #include -// Sample data types. Replace with your own types ! using Vector3f = std::array; +using String = std::string; + +// Sample data types. Replace with your own ! using PointCloud = std::vector; -struct Cluster { + +struct Cluster +{ + Vector3f boundingBoxPosition; + Vector3f boundingBoxSize; + Vector3f centroid; + Vector3f velocity; + float weight; + PointCloud pointCloud; +}; + +struct ZoneEvent +{ + std::array xyPad; + int presence; + float sliderValue; + int enters; + int leaves; + PointCloud pointCloud; +}; + +struct HierarchyObject +{ + String type; + String name; + String address; Vector3f position; + Vector3f orientation; + std::vector children; }; -using String = std::string; struct ExampleWebSocketClient { @@ -63,65 +91,88 @@ struct ExampleWebSocketClient // 4 (cont.) ------ void OnDataBlobReceived(const std::vector &dataBlob) { + // You might want to keep that somewhere else + std::vector frameClusters; + std::vector frameScenePointClouds; + std::vector frameZoneEvents; + auto parsedData = augmentaClient.parseDataBlob(dataBlob.data(), dataBlob.size()); // Scene info const auto &sceneInfo = parsedData.getSceneInfo(); - String scenePath; - scenePath.resize(sceneInfo.getAddressLength()); - sceneInfo.getAddress(scenePath.data()); + String scenePath = sceneInfo.getAddress(); - // Objects + // Objects (Clusters and Point Clouds) for (auto &object : parsedData.getObjects()) { const auto &objectID = object.getID(); if (object.hasCluster()) { auto &clusterInfo = object.getCluster(); - - if (clusterInfo.getState() == Augmenta::ClusterState::Entered) + + Cluster& cluster = frameClusters.emplace_back(); + cluster.boundingBoxPosition = clusterInfo.getBoundingBoxCenter(); + cluster.boundingBoxSize = clusterInfo.getBoundingBoxSize(); + cluster.centroid = clusterInfo.getCentroid(); + cluster.velocity = clusterInfo.getVelocity(); + cluster.weight = clusterInfo.getWeight(); + + if (object.hasPointCloud()) { - // This is a new cluster, add it to our list - } + // If the object has both a cluster and point cloud property, + // it is the cluster's contained point cloud + auto& pcInfo = object.getPointCloud(); - if (clusterInfo.getState() == Augmenta::ClusterState::WillLeave) - { - // Clean up leaving clusters + cluster.pointCloud.resize(pcInfo.getPointCount()); + pcInfo.getPointsData(cluster.pointCloud.data()); } } - - if (object.hasPointCloud()) + else if (object.hasPointCloud()) { auto &pcInfo = object.getPointCloud(); // Do something with the data // For example you can copy the point data to your own data structure. - PointCloud pc; + PointCloud &pc = frameScenePointClouds.emplace_back(); pc.resize(pcInfo.getPointCount()); pcInfo.getPointsData(pc.data()); } } - // Zones - for (const auto &zone : parsedData.getZones()) + // Zone Events + for (const auto &zoneEventInfo : parsedData.getZoneEvents()) { - for (const auto &property : zone.getProperties()) + const auto emitterZoneAddress = zoneEventInfo.getEmitterZoneAddress(); + // You could use that to map the event to your zone struct + + ZoneEvent& zoneEvent = frameZoneEvents.emplace_back(); + zoneEvent.enters = zoneEventInfo.getEnters(); + zoneEvent.leaves = zoneEventInfo.getLeaves(); + zoneEvent.presence = zoneEventInfo.getPresence(); + + for (const auto &property : zoneEventInfo.getProperties()) { switch (property.getType()) { case Augmenta::DataBlob::ZoneEventPacket::Property::Type::Slider: { const auto &sliderData = property.getSliderParameters(); - auto value = sliderData->getValue(); + zoneEvent.sliderValue = sliderData->getValue(); + break; } case Augmenta::DataBlob::ZoneEventPacket::Property::Type::XYPad: { const auto &xyData = property.getXYPadParameters(); - auto x = xyData->getX(); - auto y = xyData->getY(); + zoneEvent.xyPad = {xyData->getX(), xyData->getY()}; + break; + } + case Augmenta::DataBlob::ZoneEventPacket::Property::Type::PointCloud: + { + const auto& pcParams = property.getPointCloudParameters(); + zoneEvent.pointCloud.resize(pcParams->getPointCount()); + pcParams->getPointsData(zoneEvent.pointCloud.data()); } - // ... } } } diff --git a/include/AugmentaClientSDK.hpp b/include/AugmentaClientSDK.hpp index de02c76..18d5f5a 100644 --- a/include/AugmentaClientSDK.hpp +++ b/include/AugmentaClientSDK.hpp @@ -13,8 +13,6 @@ namespace Augmenta { struct ProtocolOptions { - - /// @brief Specifies the mode for representing rotations for all non-streamed objects enum class RotationMode { Radians, @@ -22,13 +20,8 @@ namespace Augmenta Quaternions, }; - /// @brief Defines a coordinate system transformation configuration, including axis orientation, origin placement, axis flipping, and coordinate space type. - /// - /// Augmenta internally use a left handed Y-up coordinate system with the origin at the bottom left of the scene, but - /// you can specify a different configuration here. Augmenta will take care of transforming all the data to match it. struct AxisTransform { - /// @brief Defines the coordinate system axis mode. enum class AxisMode { ZUpRightHanded, @@ -37,7 +30,6 @@ namespace Augmenta YUpLeftHanded, }; - /// @brief Specifies the origin position for coordinate system or layout calculations. enum class OriginMode { BottomLeft, @@ -46,31 +38,28 @@ namespace Augmenta TopRight, }; - /// @brief Defines the coordinate space in which scenes, zones, cluster and point - /// cloud data will be provided. - /// - /// - Absolute referes to World space coordinates in relation - /// to the origin visible in Augmenta's front-end ui. - /// - Relative give coordinates to the parent. Clusters are - /// considered childs of the scene they are computed in and are then - /// placed based on that scene's origin. - /// - Normalized gives coordinates relative between 0 and 1 based on - /// the scene dimensions. enum class CoordinateSpace { - Absolute, - Relative, - Normalized, + Absolute, // Augmenta's world space coordinates + Relative, // Coordinates relative to the parent object. Clusters are considered as children of the scene + Normalized, // Coordinates are normalized between 0 and 1 based on scene dimensions and origin mode }; + /// @brief Your desired coordinate system + /// @todo Should be renamed to something more specific AxisMode axis = AxisMode::ZUpRightHanded; + + /// @brief Defines the coordinate space in which coordinates sent by augmenta will be + CoordinateSpace coordinateSpace = CoordinateSpace::Absolute; + + /// @brief In Relative coordinates mode, the position of the scene's origin OriginMode origin = OriginMode::BottomLeft; - /// @brief finer controls to flip specific axis if needed. + /// @brief Finer controls to flip specific axis, useful if the client software uses an uncommon coordinate system. bool flipX = false; bool flipY = false; bool flipZ = false; - CoordinateSpace coordinateSpace = CoordinateSpace::Absolute; + // public originOffset; // TODO // public customMatrix; // TODO @@ -78,51 +67,48 @@ namespace Augmenta bool operator!=(const AxisTransform& other) const; }; - /// @brief Protocol version 2. + /// @brief Specify the protocol version which Augmenta will use to encode outgoing packets + /// You should probably leave that to default unless you now what you are doing ! int version = 2; - /// @brief tags are used to filter what content to be streamed by the server. - /// You may add tags to scenes in the backend GUI and have only one scene's - /// clusters, zone events and point clouds streamed by adding the - /// corresponding tag to this list. If the list is empty, all content - /// will be streamed. + /// @brief Tags can be used to filter the data sent by the server. Leave empty to receive everything. std::vector tags; - /// @brief Downsampling factor for point clouds. - /// - /// It is very usefull when you want to reduce the number of points - /// received for performance reasons. You may even cap your global - /// cluster size by dynamically changing this property. - /// - /// For example, a value of 2 means that only every 2nd point will be - /// streamed. Must be superior or equal to 1. + /// @brief Downsampling factor for point clouds. + /// For example, a value of 2 means that only every 2nd point will be sent + /// Must be >= 1 int downSample = 1; - /// @brief Whether the server should send the scene Point Cloud data. + /// @brief Whether the server should send the scene Point Cloud data bool streamClouds = true; - /// @brief Whether the server should send the scene Clusters data. + /// @brief Whether the server should send the scene Cluster data bool streamClusters = true; - /// @brief Whether the server should add the points that make up a cluster to each cluster packet. + /// @brief Whether the server should send the points that make up a Cluster along with it bool streamClusterPoints = true; // bool streamSkeletonData = true; // @TODO: Not implemented yet // bool streamMetadata = true; // @TODO: Not implemented yet - /// @brief Whether the server should add the points included in a zone to each zone packet. + /// @brief Whether the server should send the points included in a zone along with zone packets. bool streamZonePoints = false; + /// @brief Specify the orientation represention in which cluster rotations should be sent. RotationMode boxRotationMode = RotationMode::Quaternions; - AxisTransform axisTransform; // @TODO: Default ? - /// @brief enable ZSTD compression on the binary data's stream + /// @brief Specify how coordinates sent by Augmenta should be represented. + /// Augmenta will take care of transforming outgoing data in your desired coordinate system. + AxisTransform axisTransform; + + /// @brief Enable ZSTD compression on the binary data stream. The SDK will handle decompression. bool useCompression = true; - // @brief By default, Augmenta will send data as soon as it is - // available. If that's overwelming your application, you can enable - // this option to only receive data only on demand (by sending a poll request) + /// @brief By default, Augmenta will send a new frame as soon as it is available. + /// If that is overwhelming your application, you can enable this option to only receive + /// data on demand (by sending a poll request). + /// Note that this should be a last resort option. bool usePolling = false; - // TODO: Not implemented yet, may need v3? + /// @todo Not implemented yet bool displayPointIntensity = false; bool operator==(const ProtocolOptions& other) const; @@ -131,12 +117,14 @@ namespace Augmenta enum class ClusterState : int { - Entered = 0, - Updated = 1, - WillLeave = 2, - Ghost = 3, + Entered = 0, // First frame the cluster is present + Updated = 1, // Normal state of a cluster + WillLeave = 2, // Last frame the cluster is present, it will not be here on the next + Ghost = 3, // If ghosting is enabled, clusters will be kept a few frames in this state after being lost. From there they can either be picked back up (Update) or disappear (WillLeave). }; + /// @brief Used to query specific information from data frames received from the server + /// @warning Keeps references to the parsed buffer. Users are responsible for keeping the buffer available as long as they are using the DataBlob. class DataBlob { friend class DataBlobParser; @@ -153,6 +141,7 @@ namespace Augmenta std::string sceneAddress; }; + /// @brief A cluster represents a tracked group of points. This is often an objet or a person. class ClusterProperty { friend class DataBlobParser; @@ -279,11 +268,9 @@ namespace Augmenta std::array centroid; std::array velocity; std::array boundingBoxCenter; + std::array boundingBoxRotation; std::array boundingBoxSize; float weight; - - std::array boundingBoxRotation; - std::array lookAt; }; @@ -294,7 +281,7 @@ namespace Augmenta public: int getPointCount() const { return pointsCount; } - /// @brief Copy all the cloud points at once. outData should be a contiguous container of Vector3f type (3*float = 12 bytes) + /// @brief Copy all the cloud points at once. outData should point to a contiguous container of Vector3f type (3*float = 12 bytes) template void getPointsData(Vector3f *outData) const { @@ -307,12 +294,31 @@ namespace Augmenta Vector3f getPoint(size_t pointIdx) const { static_assert(sizeof(Vector3f) == 12); + assert(pointsCount < pointIdx); Vector3f outPoint; std::memcpy(&outPoint, pointsPtr + (pointIdx * sizeof(Vector3f)), sizeof(Vector3f)); return outPoint; } + float getPointX(size_t pointIdx) const + { + assert(pointsCount < pointIdx); + return pointsPtr + (pointIdx * sizeof(float) * 3); + } + + float getPointY(size_t pointIdx) const + { + assert(pointsCount < pointIdx); + return pointsPtr + (pointIdx * sizeof(float) * 3) + sizeof(float); + } + + float getPointZ(size_t pointIdx) const + { + assert(pointsCount < pointIdx); + return pointsPtr + (pointIdx * sizeof(float) * 3) + sizeof(float) * 2; + } + private: int pointsCount; const std::byte *pointsPtr = nullptr; @@ -388,8 +394,8 @@ namespace Augmenta enum class Type : uint8_t { Unknown = UINT8_MAX, - Slider = 0, - XYPad = 1, + Slider = 0, // 1D slider. Axis is defined by the zone's configuration in Augmenta + XYPad = 1, // 2D slider PointCloud = 2, }; @@ -478,6 +484,7 @@ namespace Augmenta std::vector zoneEvents; }; + /// @brief Used to query information from a Message (Setup/Update) received from the server class ControlMessage { friend class ControlMessageParser; @@ -702,7 +709,10 @@ namespace Augmenta class Client { public: + /// @brief Initialize the client with a name and a set of options void initialize(const std::string &clientName, const ProtocolOptions &options); + + /// @brief Clear internal state void shutdown(); /// @brief Clear requested tags list @@ -715,9 +725,12 @@ namespace Augmenta std::string getPollMessage() const; const ProtocolOptions& getCurrentOptions() const { return options; } - /// @brief Parse a data blob and return a DataBlob object that can be used to query relevant information from it. + /// @brief Parse a binary message received from the server and return a DataBlob object that can be used to query relevant information from it. /// @warning The DataBlob keeps references to the parsed buffer. Users are responsible for keeping the buffer available as long as they are using the DataBlob. DataBlob parseDataBlob(const std::byte *blob, size_t blobSize); + + /// @brief Parse a text message received from the server and return a ControlMessage object + /// that can be used to retrieve the information. ControlMessage parseControlMessage(const char *rawMessage); private: