lrfultisense_web_logo

LrfUltisense C++ library

v1.0.3

Table of contents

Overview

The LrfUltisense C++ library is a software controller for Safran Laser Range Finders. The library depends on: Lrf interface library (provides interface and data structures to control laser range finders, source code included, Apache 2.0 license), Logger library (provides function to print log information in console and files, source code included, Apache 2.0 license), SerialPort library (provides functions to work with serial ports, source code included, Apache 2.0 license) and LrfUltisenseParser library (provides functions to encode control commands and decode responses for Safran Laser Range Finders). After initialization, the library starts the internal data exchange thread with the laser range finder device, sends control commands and analyzes the responses (decodes the measurement results). The library repository (folder) is provided as source code and doesn’t have third-party dependencies to be specially installed in OS. It uses C++17 standard and is compatible with Linux and Windows.

Versions

Table 1 - Library versions.

Version Release date What’s new
1.0.0 31.07.2023 - First version.
1.0.1 07.08.2024 - CMake structure updated.
1.0.2 28.09.2024 - LrfUltisenseParser updated.
1.0.3 28.11.2024 - Fix Pointer mode.

Library files

The library is supplied only by source code. The user is given a set of files in the form of a CMake project (repository). The repository structure is shown below:

CMakeLists.txt ---------------- Main CMake file of the library.
3rdparty ---------------------- Folder with third-party libraries.
    CMakeLists.txt ------------ CMake file to include third-party libraries.
    Logger -------------------- Folder with Logger library source code.
	Lrf ----------------------- Folder with Lrf interface library source code.
    LrfUltisenseParser -------- Folder with LrfUltisenseParser library source code.
	SerialPort ---------------- Folder with SerialPort library source code.
src  -------------------------- Folder with library source code.
    CMakeLists.txt ------------ CMake file of the library.
    LrfUltisense.h ------------ Main library header file.
    LrfUltisenseVersion.h ----- Header file with library version.
    LrfUltisenseVersion.h.in -- CMake service file to generate version header.
    LrfUltisense.cpp ---------- C++ implementation file.
test -------------------------- Folder for test application files.
    CMakeLists.txt ------------ CMake file for test application.
    main.cpp ------------------ Source C++ file of test application.

LrfUltisense class description

LrfUltisense class declaration

namespace cr
{
namespace lrf
{
/// LrfUltisense class.
class LrfUltisense : public Lrf
{
public:

    /// Constructor.
    LrfUltisense();

    /// Destructor.
    ~LrfUltisense();

    /// Get string of current library version.
    static std::string getVersion();

    /// Open lrf controller.
    bool openLrf(std::string initString) override;

    /// Init lrf controller by set of parameters.
    bool initLrf(LrfParams& params) override;

    /// Close connection.
    void closeLrf() override;

    /// Get lrf open status.
    bool isLrfOpen() override;

    /// Get lrf connection status.
    bool isLrfConnected() override;

    /// Set the lrf controller parameter.
    bool setParam(LrfParam id, float value) override;

    /// Get the lrf controller parameter value.
    float getParam(LrfParam id) override;

    /// Get all lrf controller parameters.
    void getParams(LrfParams& params) override;

    /// Execute lrf command.
    bool executeCommand(LrfCommand id) override;

    /// Decode and execute command.
    bool decodeAndExecuteCommand(uint8_t* data, int size) override;
};
}
}

getVersion method

The getVersion() static method returns string of current version of LrfUltisense class. Method declaration:

static std::string getVersion();

Method can be used without LrfUltisense class instance. Example:

std::cout << "LrfUltisense version: " << cr::lrf::LrfUltisense::getVersion();

Console output:

LrfUltisense version: 1.0.2

openLrf method

The openLrf(…) opens serial port to communicate with laser range finder. If serial port already open the method will close it first and reopen. Range finder parameters will be initialized by default. If user want initialize range finder with not default parameters he can use initLrf(…) method. After successful initialization the library will run communication threads (thread to communicate with equipment via serial port). Method declaration:

bool openLrf(std::string initString) override;
Parameter Value
initString Initialization string contains full serial port name and baudrate (default 57600) separated by “;”. Example: “/dev/ttyUSB0;57600”.

Returns: TRUE if the lrf controller is initialized or FALSE if not.

initLrf method

The initLrf(…) initializes range finder controller by set of parameters. The method will set given range finder parameters and after will call openLrf(…) method. After successful initialization the library will run communication threads (thread to communicate with equipment via serial port). Method declaration:

bool initLrf(LrfParams& params) override;
Parameter Value
params LrfParams parameters class object. LrfParams class includes initString which is used in openLrf(…) method.

Returns: TRUE if the range finder controller is initialized or FALSE if not.

closeLrf method

The closeLrf() closes serial port and stops communication thread. Method declaration:

void closeLrf() override;

isLrfOpen method

The isLrfOpen() method returns range finder controller initialization status. Open status shows if the controller initialized (serial port open) but doesn’t show if controller has communication with equipment. For example, if serial port is open (opens serial port file in OS) but equipment can be not active (no power). In this case open status just shows that the serial port is open. Method declaration:

bool isLrfOpen() override;

Returns: TRUE is the range finder controller is initialized or FALSE if not.

isLrfConnected method

The isLrfConnected() shows if the range finder controller receives responses from equipment. For example, if serial port open but equipment not active (no power). In this case methods isLrfOpen(…) will return TRUE but isLrfConnected() method will return FALSE. Method declaration:

bool isLrfConnected() override;

Returns: TRUE if the range finder controller has data exchange with equipment or FALSE if not.

setParam method

The setParam(…) method sets new range finder parameters value. LrfUltisense provides thread-safe setParam(…) method call. This means that the setParam(…) method can be safely called from any thread. Method declaration:

bool setParam(LrfParam id, float value) override;
Parameter Description
id Lrf parameter ID according to LrfParam enum.
value Lrf parameter value. Value depends on parameter ID.

Returns: TRUE if the parameter was set or FALSE if not.

getParam method

The getParam(…) method returns range finder parameter value. LrfUltisense provides thread-safe getParam(…) method call. This means that the getParam(…) method can be safely called from any thread. Method declaration:

float getParam(LrfParam id) override;
Parameter Description
id Lrf parameter ID according to LrfParam enum.

Returns: parameter value or -1 of the parameters doesn’t exist (not supported).

getParams method

The getParams(…) method returns all range finder parameters. LrfUltisense provides thread-safe getParams(…) method call. This means that the getParams(…) method can be safely called from any thread. Method declaration:

void getParams(LrfParams& params) override;
Parameter Description
params Reference to LrfParams class object which includes all range finder parameters.

executeCommand method

The executeCommand(…) method to execute range finder action command. LrfUltisense provides thread-safe executeCommand(…) method call. This means that the executeCommand(…) method can be safely called from any thread. Method declaration:

bool executeCommand(LrfCommand id) override;
Parameter Description
id Lrf action command ID according to LrfCommand enum.

Returns: TRUE is the command was executed (accepted by range finder controller) or FALSE if not.

decodeAndExecuteCommand method

The decodeAndExecuteCommand(…) method decodes and executes command on controller side. Method will decode commands which encoded by encodeCommand(…) and encodeSetParamCommand(…) methods of Lrf interface classes. If command decoded the method will call setParam(…) or executeCommand(…) methods. This method is thread-safe. This means that the method can be safely called from any thread. Method declaration:

bool decodeAndExecuteCommand(uint8_t* data, int size) override;
Parameter Description
data Pointer to input command. To generate input command you may use encodeCommand(…) and encodeSetParamCommand(…) methods.
size Size of command. Must be 11 bytes for SET_PARAM and 7 bytes for COMMAND.

Returns: TRUE if command decoded (SET_PARAM or COMMAND) and executed (action command or set param command).

encodeSetParamCommand method of Lrf class

The encodeSetParamCommand(…) static method designed to encode command to change any remote range finder parameter. To control a LRF remotely, the developer has to develop his own protocol and according to it encode the command and deliver it over the communication channel. To simplify this, the Lrf class contains static methods for encoding the control command. The Lrf class provides two types of commands: a parameter change command (SET_PARAM) and an action command (COMMAND). encodeSetParamCommand(…) designed to encode SET_PARAM command. Method declaration:

static void encodeSetParamCommand(uint8_t* data, int& size, LrfParam id, float value);
Parameter Description
data Pointer to data buffer for encoded command. Must have size >= 11.
size Size of encoded data. Will be 11 bytes.
id Parameter ID according to LrfParam enum.
value Parameter value.

encodeSetParamCommand(…) is static and used without Lrf class instance. This method used on client side (control system). Example:

// Buffer for encoded data.
uint8_t data[11];
// Size of encoded data.
int size = 0;
// Encode command.
Lrf::encodeSetParamCommand(data, size, LrfParam::OPERATING_MODE, 1);

encodeCommand method of Lrf class

The encodeCommand(…) static method designed to encode range finder action command (COMMAND). To control a LRF remotely, the developer has to develop his own protocol and according to it encode the command and deliver it over the communication channel. To simplify this, the Lrf class contains static methods for encoding the control command. The Lrf class provides two types of commands: a parameter change command (SET_PARAM) and an action command (COMMAND). encodeCommand(…) designed to encode COMMAND (action command). Method declaration:

static void encodeCommand(uint8_t* data, int& size, LrfCommand id);
Parameter Description
data Pointer to data buffer for encoded command. Must have size >= 7.
size Size of encoded data. Will be 7 bytes.
id Command ID according to LrfCommand enum.

encodeCommand(…) is static and used without Lrf class instance. This method used on client side (control system). Encoding example:

// Buffer for encoded data.
uint8_t data[7];
// Size of encoded data.
int size = 0;
// Encode command.
Lrf::encodeCommand(data, size, LrfCommand::DISARM);

decodeCommand method of Lrf class

The decodeCommand(…) static method designed to decode command on range finder controller side. To control a LRF remotely, the developer has to develop his own protocol and according to it decode the command on range finder controller side. To simplify this, the Lrf interface class contains static method to decode input command (commands should be encoded by methods encodeSetParamCommand(…) or encodeCommand(…) methods). The Lrf class provides two types of commands: a parameter change command (SET_PARAM) and an action command (COMMAND). Method declaration:

static int decodeCommand(uint8_t* data, int size, LrfParam& paramId, LrfCommand& commandId, float& value);
Parameter Description
data Pointer to input command.
size Size of command. Should be 11 bytes for SET_PARAM and 7 bytes for COMMAND.
paramId LRF parameter ID according to LrfParam enum. After decoding SET_PARAM command the method will return parameter ID.
commandId LRF command ID according to LrfCommand enum. After decoding COMMAND the method will return command ID.
value LRF parameter value after decoding SET_PARAM command.

Returns: 0 - in case decoding COMMAND (action command), 1 - in case decoding SET_PARAM command or -1 in case errors.

Data structures

LrfCommand enum

LrfCommand enum describes action LRF command. All commands must be supported by LRF controller. Enum declaration:

namespace cr
{
namespace lrf
{
enum class LrfCommand
{
    /// Arm.
    ARM = 1,
    /// Disarm.
    DISARM,
    /// Measure distance once.
    MEASURE_DISTANCE_ONCE
};
}
}

Table 2 - Range finder action commands description.

Command Description
ARM Enable laser emission (pointer). Before turning the laser pointer on, the laser pointer must be armed with setParam(…) method.
DISARM Disenable laser emission (pointer). Can be uses also setParam(…) method.
MEASURE_DISTANCE_ONCE Command initiates a range measurement (measurement once).

LrfParam enum

LrfParam enum describes LRF parameters. Enum declaration:

namespace cr
{
namespace lrf
{
enum class LrfParam
{
    /// [Read only] Current measured distance, meters.
    DISTANCE = 1,
    /// Time from last measurement, us.
    TIME_FROM_LAST_MEASUREMENT_US,
    /// Low power mode. Values depends on implementation. Default: 0 - OFF.
    LOW_POWER_MODE,
    /// Laser pointer mode: 0 - OFF, 1 - ON, 2 - ON timeout.
    POINTER_MODE,
    /// Pointer mode timeout, sec.
    POINTER_MODE_TIMEOUT_SEC,
    /// Arm mode: 0 - Disarmed, 1 - armed.
    ARM_MODE,
    /// Operating mode: 0 - OFF, 1 - Stand-by-mode, 2 - Normal mode.
    OPERATING_MODE,
    /// Continuous measuring mode: 0 - Stop, 1 - 0.5Hz, 2 - 1 - 1Hz, 3 - 3Hz, 4 - 5Hz, 5 - 10Hz.
    CONTINUOUS_MEASURING_MODE,
    /// Continuous mode timeout, sec.
    CONTINUOUS_MODE_TIMEOUT_SEC,
    /// Logging mode: 0 - Disabled, 1 - Console, 2 - File, 3 - Console and file.
    LOG_MODE,
    /// [Read only] Open status.
    IS_OPEN,
    /// [Read only] Connection status.
    IS_CONNECTED,
    /// Min gate distance, meters.
    MIN_GATE_DISTANCE,
    /// Max gate distance, meters.
    MAX_GATE_DISTANCE,
    /// Temperature, deg.
    TEMPERATURE_DEG,
    /// Custom parameter 1. Depends on implementation.
    CUSTOM_1,
    /// Custom parameter 2. Depends on implementation.
    CUSTOM_2,
    /// Custom parameter 3. Depends on implementation.
    CUSTOM_3
};
}
}

Table 3 - Range finder parameters description.

Parameter Access Description
DISTANCE read only Current measured distance, meters.
TIME_FROM_LAST_MEASUREMENT_US read only Time from last measurement, microseconds. Used to control how old last measurement.
LOW_POWER_MODE read / write Set a continuous low power laser emission at a wavelength of 1550 nm. Mode:
0 - Off
1 - Lowest power.
2 - …
3 - …
4 - …
5 - …
6 - Highest power.
POINTER_MODE read / write Pointer mode. Set a continuous laser emission at a wavelength of 830 nm.
0 - Off.
1 - On.
POINTER_MODE_TIMEOUT_SEC read / write Pointer mode timeout, sec. After timeous controller will disable pointer mode.
ARM_MODE read / write Arm mode, enable or disenable laser emission:
0 - Disarm (disable laser emission).
1 - Arm (enable laser emission).
OPERATING_MODE read / write Operating mode:
0 - Off (this parameter will turn off range finder).
1 - Stand-by-mode.
2 - Normal mode.
CONTINUOUS_MEASURING_MODE read / write Set continuous range request:
0 - Stop.
1 - Repetition rate of 0.5 Hz
2 - Repetition rate of 1 Hz.
3 - Repetition rate of 3 Hz.
4 - Repetition rate of 5 Hz.
5 - Repetition rate of 10 Hz.
CONTINUOUS_MODE_TIMEOUT_SEC read / write Continuous mode timeout, sec. After timeous controller will disable continuous measurement mode.
LOG_MODE read / write Logging mode. Values:
0 - Disable.
1 - Only file.
2 - Only terminal.
3 - File and terminal.
IS_OPEN read only LrfUltisense controller initialization status. Open status shows if the lrf controller initialized or not but doesn’t show if lrf controller has communication with lrf equipment. Values:
0 - not open (not initialized).
1 - open (initialized).
IS_CONNECTED read only LrfUltisense connection status. Connection status shows if the Lrf controller has data exchange with Lrf equipment. Values:
0 - no response from Lrf.
1 - connected.
MIN_GATE_DISTANCE read / write Min gate distance, meters. If parameter > 0 the LRF controller must ignore measured distance < MIN_GATE_DISTANCE.
MAX_GATE_DISTANCE read / write Max gate distance, meters. If parameter > 0 the LRF controller must ignore measured distance > MAX_GATE_DISTANCE.
TEMPERATURE_DEG read only Not supported by LrfUltisense class.
CUSTOM_1 read / write Not supported by LrfUltisense class.
CUSTOM_2 read / write Not supported by LrfUltisense class.
CUSTOM_3 read / write Not supported by LrfUltisense class.

LrfParams class description

LrfParams class used for LRF controller initialization (initLrf(…) method) or to get all actual params (getParams(…) method). Also LrfParams provides structure to write/read params from JSON files (JSON_READABLE macro) and provides methods to encode and decode params.

LrfParams class declaration

LrfParams interface class declared in Lrf.h file. Class declaration:

namespace cr
{
namespace lrf
{
class LrfParams
{
public:
    
    /// Initialization string. Format depends on implementation.
    std::string initString;
    /// Current measured distance, meters.
    float distance{0.0f};
    /// Time from last measurement, us.
    int timeFromLastMeasurementUs{0};
    /// Low power mode. Values depends on implementation. Default: 0 - OFF.
    int lowPowerMode{0};
    /// Laser pointer mode: 0 - OFF, 1 - ON, 2 - ON timeout.
    int pointerMode{0};
    /// Pointer mode timeout, sec.
    int pointerModeTimeoutSec{0};
    /// Arm mode: 0 - Disarmed, 1 - armed.
    int armMode{0};
    /// Operating mode: 0 - OFF, 1 - Stand-by-mode, 2 - Normal mode.
    int operatingMode{0};
    /// Continuous measuring mode: 0 - Stop, 1 - 0.5Hz, 2 - 1 - 1Hz, 3 - 3Hz, 4 - 5Hz, 5 - 10Hz.
    int continuousMeasuringMode{0};
    /// Continuous mode timeout, sec.
    int continuousModeTimeoutSec{0};
    /// Logging mode: 0 - Disabled, 1 - Console, 2 - File, 3 - Console and file.
    int logMode{0};
    /// Open status.
    bool isOpen{false};
    /// Connection status.
    bool isConnected{false};
    /// Min gate distance, meters.
    float minGateDistance{0};
    /// Max gate distance, meters.
    float maxGateDistance{0};
    /// Temperature, deg.
    float temperatureDeg{0.0f};
    /// Custom parameter 1. Depends on implementation.
    float custom1{0.0f};
    /// Custom parameter 2. Depends on implementation.
    float custom2{0.0f};
    /// Custom parameter 3. Depends on implementation.
    float custom3{0.0f};

    JSON_READABLE(LrfParams, initString, lowPowerMode, pointerModeTimeoutSec,
                  operatingMode, continuousModeTimeoutSec, logMode,
                  minGateDistance, maxGateDistance, custom1, custom2, custom3)

    /// operator =
    LrfParams& operator= (const LrfParams& src);

    /// Encode params.
    bool encode(uint8_t* data, int bufferSize, int& size,
                LrfParamsMask* mask = nullptr);

    /// Decode params.
    bool decode(uint8_t* data, int dataSize);
};
}
}

Table 4 - LrfParams class fields description (equivalent to LrfParam enum description).

Field type Description
initString string Initialization string contains full serial port name and baudrate (default 57600) separated by “;”. Example: “/dev/ttyUSB0;57600”.
distance float Current measured distance, meters.
timeFromLastMeasurementUs int Time from last measurement, microseconds. Used to control how old last measurement.
lowPowerMode int Continuous low power mode laser emission at a wavelength of 1550 nm. Mode:
0 - Off
1 - Lowest power.
2 - …
3 - …
4 - …
5 - …
6 - Highest power.
pointerMode int Pointer mode. Set a continuous laser emission at a wavelength of 830 nm.
0 - Off.
1 - On.
pointerModeTimeoutSec int Pointer mode timeout, sec. After timeous controller will disable pointer mode.
armMode int Arm mode, enable or disenable laser emission:
0 - Disarm (disable laser emission).
1 - Arm (enable laser emission).
operatingMode int Operating mode:
0 - Off.
1 - Stand-by-mode.
2 - Normal mode.
continuousMeasuringMode int Continuous range request mode:
0 - Stop.
1 - Repetition rate of 0.5 Hz
2 - Repetition rate of 1 Hz.
3 - Repetition rate of 3 Hz.
4 - Repetition rate of 5 Hz.
5 - Repetition rate of 10 Hz
continuousModeTimeoutSec int Continuous mode timeout, sec. After timeous controller will disable continuous measurement mode.
logMode int Logging mode. Values:
0 - Disable.
1 - Only file.
2 - Only terminal.
3 - File and terminal.
isOpen bool LrfUltisense controller initialization status. Open status shows if the lrf controller initialized or not but doesn’t show if lrf controller has communication with lrf equipment. Values:
FALSE - not open (not initialized).
TRUE - open (initialized).
isConnected bool LrfUltisense connection status. Connection status shows if the Lrf controller has data exchange with Lrf equipment. Values:
FALSE - no response from Lrf.
TRUE - connected.
minGateDistance float Minimum gate distance, meters.
maxGateDistance float Maximum gate distance, meters.
temperatureDeg float Not supported by LrfUltisense class.
custom1 float Not supported by LrfUltisense class.
custom2 float Not supported by LrfUltisense class.
custom3 float Not supported by LrfUltisense class.

None: LrfParams class fields listed in above reflect params set/get by methods setParam(…) and getParam(…).

Serialize range finder params

LrfParams class provides method encode(…) to serialize LRF params (fields of LrfParams class, see Table 4). Serialization of LRF params necessary in case when you need to send LRF params via communication channels. Method doesn’t encode initString string field. Method provides options to exclude particular parameters from serialization. To do this method inserts binary mask (3 bytes) where each bit represents particular parameter and decode(…) method recognizes it. Method declaration:

bool encode(uint8_t* data, int bufferSize, int& size, LrfParamsMask* mask = nullptr);
Parameter Value
data Pointer to data buffer.
size Size of encoded data.
bufferSize Data buffer size. Buffer size must be >= 72 bytes.
mask Parameters mask - pointer to LrfParamsMask structure. LrfParamsMask (declared in Lrf.h file) determines flags for each field (parameter) declared in LrfParams class. If the user wants to exclude any parameters from serialization, he can put a pointer to the mask. If the user wants to exclude a particular parameter from serialization, he should set the corresponding flag in the LrfParamsMask structure.

LrfParamsMask structure declaration:

typedef struct LrfParamsMask
{
    bool distance{true};
    bool timeFromLastMeasurementUs{true};
    bool lowPowerMode{true};
    bool pointerMode{true};
    bool pointerModeTimeoutSec{true};
    bool armMode{true};
    bool operatingMode{true};
    bool continuousMeasuringMode{true};
    bool continuousModeTimeoutSec{true};
    bool logMode{true};
    bool isOpen{true};
    bool isConnected{true};
    bool minGateDistance{true};
    bool maxGateDistance{true};
    bool temperatureDeg{true};
    bool custom1{true};
    bool custom2{true};
    bool custom3{true};
} LrfParamsMask;

Example without parameters mask:

// Encode data.
LrfParams in;
in.logMode = 3;
uint8_t data[1024];
int size = 0;
in.encode(data, 1024, size);
cout << "Encoded data size: " << size << " bytes" << endl;

Example with parameters mask:

// Prepare params.
LrfParams in;
in.logMode = 3;

// Prepare mask.
LrfParamsMask mask;
mask.logMode = false; // Exclude logMode. Others by default.

// Encode.
uint8_t data[1024];
int size = 0;
in.encode(data, 1024, size, &mask);
cout << "Encoded data size: " << size << " bytes" << endl;

Deserialize range finder params

LrfParams class provides method decode(…) to deserialize LRF params (fields of LrfParams class, see Table 4). Deserialization of LRF params necessary in case when you need to receive LRF params via communication channels. Method automatically recognizes which parameters were serialized by encode(…) method. Method doesn’t decode fields: initString. Method declaration:

bool decode(uint8_t* data, int dataSize);
Parameter Value
data Pointer to data buffer.
dataSize Size of data.

Returns: TRUE if data decoded (deserialized) or FALSE if not.

Example:

// Encode data.
LrfParams in;
uint8_t data[1024];
int size = 0;
in.encode(data, 1024, size);
cout << "Encoded data size: " << size << " bytes" << endl;

// Decode data.
LrfParams out;
if (!out.decode(data, size))
    cout << "Can't decode data" << endl;

Read params from JSON file and write to JSON file

Lrf interface class library depends on ConfigReader library which provides method to read params from JSON file and to write params to JSON file. Example of writing and reading params to JSON file:

// Write default params to file.
LrfParams in;
cr::utils::ConfigReader inConfig;
inConfig.set(in, "LrfParams");
inConfig.writeToFile("TestLrfParams.json");

// Read params from file.
cr::utils::ConfigReader outConfig;
if(!outConfig.readFromFile("TestLrfParams.json"))
{
    cout << "Can't open config file" << endl;
    return false;
}
// Parse params.
LrfParams out;
if(!outConfig.get(out, "LrfParams"))
{
    cout << "Can't read params from file" << endl;
    return false;
}

TestLrfParams.json will look like:

{
    "LrfParams": {
        "continuousModeTimeoutSec": 35,
        "custom1": 2.490000009536743,
        "custom2": 1.5,
        "custom3": 2.5199999809265137,
        "initString": "17108",
        "logMode": 61,
        "lowPowerMode": 226,
        "maxGateDistance": 2.2300000190734863,
        "minGateDistance": 0.38999998569488525,
        "operatingMode": 207,
        "pointerModeTimeoutSec": 180
    }
}

Build and connect to your project

Typical commands to build LrfUltisense library:

cd LrfUltisense
mkdir build
cd build
cmake ..
make

If you want to connect LrfUltisense library to your CMake project as source code you can make follow. For example, if your repository has structure:

CMakeLists.txt
src
    CMakeList.txt
    yourLib.h
    yourLib.cpp

Create folder 3rdparty and copy folder of LrfUltisense repository there. New structure of your repository:

CMakeLists.txt
src
    CMakeList.txt
    yourLib.h
    yourLib.cpp
3rdparty
    LrfUltisense

Create CMakeLists.txt file in 3rdparty folder. CMakeLists.txt should contain:

cmake_minimum_required(VERSION 3.13)

################################################################################
## 3RD-PARTY
## dependencies for the project
################################################################################
project(3rdparty LANGUAGES CXX)

################################################################################
## SETTINGS
## basic 3rd-party settings before use
################################################################################
# To inherit the top-level architecture when the project is used as a submodule.
SET(PARENT ${PARENT}_YOUR_PROJECT_3RDPARTY)
# Disable self-overwriting of parameters inside included subdirectories.
SET(${PARENT}_SUBMODULE_CACHE_OVERWRITE OFF CACHE BOOL "" FORCE)

################################################################################
## CONFIGURATION
## 3rd-party submodules configuration
################################################################################
SET(${PARENT}_SUBMODULE_LRF_ULTISENSE                   ON  CACHE BOOL "" FORCE)
if (${PARENT}_SUBMODULE_LRF_ULTISENSE)
    SET(${PARENT}_LRF_ULTISENSE                         ON  CACHE BOOL "" FORCE)
    SET(${PARENT}_LRF_ULTISENSE_TEST                    OFF CACHE BOOL "" FORCE)
endif()

################################################################################
## INCLUDING SUBDIRECTORIES
## Adding subdirectories according to the 3rd-party configuration
################################################################################
if (${PARENT}_SUBMODULE_LRF_ULTISENSE)
    add_subdirectory(LrfUltisense)
endif()

File 3rdparty/CMakeLists.txt adds folder LrfUltisense to your project and excludes test application from compiling (by default test application is excluded from compiling if LrfUltisense is included as sub-repository). The new structure of your repository:

CMakeLists.txt
src
    CMakeList.txt
    yourLib.h
    yourLib.cpp
3rdparty
    CMakeLists.txt
    LrfUltisense

Next you need include folder 3rdparty in main CMakeLists.txt file of your repository. Add string at the end of your main CMakeLists.txt:

add_subdirectory(3rdparty)

Next you have to include LrfUltisense library in your src/CMakeLists.txt file:

target_link_libraries(${PROJECT_NAME} LrfUltisense)

Done!

Test application

Folder LrfUltisense/test contains the test application files. The test application allows you to generate any command, send it to the range finder over the serial port, receive and decode the response. Once started, the user must enter the serial port name (full name for Linux or just the port number for Windows) and baud rate (default 57600):

======================================
LRFUltisense v1.0.3 test
======================================
Set serial port name: /dev/serial/by-id/usb-FTDI_USB-RS232_Cable_SAFRAN_LRF_6019-if00-port0

After user can see status of LRF and chose option:

======================================
======================================
STATUS << O:1 C:0 ARM:0 LPM:0 OM:0 PM:0 MM:0 Distance:0
Commands:
1 - Arm
2 - Disarm
3 - Set low power mode
4 - Set pointer mode
5 - Set continuous measuring mode
6 - Set operating mode
7 - Measure distance once
8 - Measure fake distance once
======================================
Option:

Then, corresponding command will be generated and sent to range finder.