LrfUltisenseParser C++ library
v1.0.1
Table of contents
- Overview
- Versions
- Library files
- LrfUltisenseParser class description
- Data structures
- Test application
- Build and connect to your project
Overview
The LrfUltisenseParser C++ library is designed for encoding control commands and decoding responses for Safran Laser Range Finders. The library provides simple interface and doesn’t have third party dependencies to be installed in OS. It uses C++17 standard. Also, the library provides test application to check communication with the LRF via serial ports. Test application depends on SerialPort library (provides methods to work with serial ports, source code included, Apache 2.0 license).
Versions
Table 1 - Library versions.
Version | Release date | What’s new |
---|---|---|
1.0.0 | 30.07.2024 | - First version. |
1.0.1 | 27.09.2024 | - Fixed decoding distance reply. |
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.
src -------------------------------- Folder with library source code.
CMakeLists.txt ------------------ CMake file of the library.
LrfUltisenseParser.h ------------ Main library header file.
LrfUltisenseParserVersion.h ----- Header file with library version.
LrfUltisenseParserVersion.h.in -- CMake service file to generate version header.
LrfUltisenseParser.cpp ---------- C++ implementation file.
test -------------------------------- Folder for test application files.
3rdparty ------------------------ Folder with third-party libraries.
CMakeLists.txt -------------- CMake file to include third-party libraries.
SerialPort ------------------ Folder with SerialPort library source code.
CMakeLists.txt ------------------ CMake file for test application.
main.cpp ------------------------ Source C++ file of test application.
LrfUltisenseParser class description
LrfUltisenseParser class declaration
namespace cr
{
namespace lrf
{
class LrfUltisenseParser
{
public:
/// Get library version.
static std::string getVersion();
/// Encode command.
bool getCommand(uint8_t* data, int& size, LrfUltisenseCommand id, int arg = 0);
/// Decode response byte-by-byte.
LrfUltisenseResponse decodeResponse(uint8_t nextByte);
/// Get current distance.
float getDistance();
};
}
}
getVersion method
The getVersion() static method returns string of current LrfUltisenseParser class version. Method declaration:
static std::string getVersion();
Method can be used without LrfUltisenseParser class instance:
cout << "LrfUltisenseParser version: " << LrfUltisenseParser::getVersion();
Console output:
LrfUltisenseParser version: 1.0.1
getCommand method
The getCommand(…) method encodes (prepares data) control command for range finder. The Ultisense range finder does not send data on its own, but only responds to commands. Method declaration:
bool getCommand(uint8_t* data, int& size, LrfUltisenseCommand id, int arg = 0);
Parameter | Value |
---|---|
data | Pointer to buffer for encoded data (command). Buffer must have size >= 64. |
size | Size of encoded command. |
id | Command ID according to LrfUltisenseCommand enum. |
arg | Command argument. The value depends on command ID (see LrfUltisenseCommand enum). Some commands don’t have arguments. |
Returns: TRUE if commands encoded or FALSE if not (not valid ID or not valid parameters).
Example of encoding command:
// Encode command.
cr::lrf::LrfUltisenseParser parser;
uint8_t command[64];
int size = 0;
parser.getCommand(command, size, LrfUltisenseCommand::MEASURE_DISTANCE);
// Send command via serial port (pseudo code).
serialPort.write(command, size);
decodeResponse method
The decodeResponse(…) method decodes response from range finder. Once the data from the serial port has been read the user must pass it to the method byte-by-byte (each byte separately in sequence). The library has an internal ring buffer. When the user passes another byte, the library shifts the ring buffer by one byte and copies the new byte to the end of the buffer. If the library detects a valid response in the ring buffer, it returns the response ID (see LrfUltisenseResponse enum description) and returns the response arguments. In all other cases, the library returns a NONE identifier. Method declaration:
LrfUltisenseResponse decodeResponse(uint8_t nextByte);
Parameter | Value |
---|---|
nextByte | Next read byte from serial port. |
Returns: LrfUltisenseResponse (response ID) if response detected or NONE ID if not.
Example of decoding response:
// Read data from serial port (pseudo code).
uint8_t data[256];
int bytes = serialPort.read(data, 256);
// Decode response.
cr::lrf::LrfUltisenseParser parser;
for (int i = 0; i < bytes; ++i)
{
LrfUltisenseResponse response = parser.decodeResponse(data[i]);
if (response != cr::lrf::LrfUltisenseResponse::NONE)
{
std::cout << "Response: " << (int)response << std::endl;
}
}
getDistance method
The getDistance(…) method returns last decoded distance. The range finder can return multiple measurement but the library returns first valid measurement. Method declaration:
float getDistance();
Returns: Value of last measured distance, meters.
Data structures
LrfUltisenseCommand enum
LrfUltisenseCommand enum declared in the LrfUltisenseParser.h file and includes commands IDs. Enum declaration:
namespace cr
{
namespace lrf
{
enum class LrfUltisenseCommand
{
/// Measure distance command. No argument.
MEASURE_DISTANCE = 1,
/// Fake measure distance command. No argument.
FAKE_MEASURE_DISTANCE,
/// Set a continuous low power laser emission at a wavelength of
/// 1550 nm (typical). Argument:
/// arg: 0 - OFF.
/// 1 - Lowest power.
/// 2 - ...
/// 3 - ...
/// 4 - ...
/// 5 - ...
/// 6 - Highest power.
SET_CONTINUOUS_LOW_POWER_MODE,
/// Set a continuous laser emission at a wavelength of 830 nm (typical).
/// Argument:
/// arg: 0 - OFF.
/// 1 - ON.
SET_LASER_POINTER_MODE,
/// Arm. Enable laser emission. No argument.
ARM,
/// Disarm. Disable laser emission. No argument.
DISARM,
/// Set operating mode. Argument:
/// arg: 0 - OFF.
/// 1 - Stand-by-mode.
/// 2 - Normal mode.
SET_OPERATING_MODE,
/// Initiate a set of x range measurements with a repetition
/// frequency of 1 Hz. Argument:
/// arg - number of requests (2,3,4 ...).
SET_BLOCK_RANGE_REQUEST,
/// Set continuous range request. Argument:
/// arg: 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.
SET_CONTINUOUS_RANGE_REQUEST,
/// Set min gate range. Argument:
/// arg - distance in meters.
SET_MIN_GATE_RANGE,
/// Set max gate range. Argument:
/// arg - distance in meters.
SET_MAX_GATE_RANGE
};
}
}
Table 2 - Range finder commands IDs.
Command | Description |
---|---|
MEASURE_DISTANCE | Command to measure distance once. |
FAKE_MEASURE_DISTANCE | Command to provide fake measurements. Used to test control algorithms. |
SET_CONTINUOUS_LOW_POWER_MODE | Set a continuous low power laser emission at a wavelength of 1550 nm (typical). Argument: 0 - Off. 1 - Lowest power, 2 - …, 3 - …, 4 - …, 5 - …, 6 - Highest power. |
SET_LASER_POINTER_MODE | Set a continuous laser emission at a wavelength of 830 nm (typical). Argument: 0 - Off, 1 - On. |
ARM | Arm laser range finder. |
DISARM | Disarm laser range finder. |
SET_OPERATING_MODE | Set operating mode. Argument: 0 - Off (Note: after this command the range finder will be powered off), 1 - Stand-by-mode, 2 - Normal mode. |
SET_BLOCK_RANGE_REQUEST | Initiate a set of x range measurements with a repetition frequency of 1 Hz. Argument: number of requests (2, 3, 4, …). |
SET_CONTINUOUS_RANGE_REQUEST | Set continuous range request. Argument: 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. |
SET_MIN_GATE_RANGE | Set min gate range. Argument: minimum gate distance, meters. |
SET_MAX_GATE_RANGE | Set max gate range. Argument: maximum gate distance, meters. |
LrfUltisenseResponse enum
LrfUltisenseResponse enum declared in LrfUltisenseParser.h file and describes responses from range finder. Enum declaration:
namespace cr
{
namespace lrf
{
enum class LrfUltisenseResponse
{
/// No response.
NONE = 1,
/// Acknowledge frame. No arguments.
ACKNOWLEDGE,
/// Measured distance.
DISTANCE,
/// Fake measured distance.
FAKE_DISTANCE
};
}
}
Table 3 - LRF responses IDs description.
Command | Description |
---|---|
NONE | Response not detected. |
ACKNOWLEDGE | Command acknowledge detected. Range finder sends acknowledge message for each input command. |
DISTANCE | Distance data detected. |
FAKE_DISTANCE | Fake distance data detected (after command LrfUltisenseCommand::FAKE_MEASURE_DISTANCE). |
Test application
Folder LrfUltisenseParser/test contains the test application files. The test application allows you to generate any range finder command, send it to the range 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 115200):
================================================
Lrf Ultisense Parser Test v1.0.0
================================================
Set serial port name: /dev/ttyUSB0
Set baudrate (default : 115200): 115200
After user can chose command (enter command ID). If no necessary command has been displayed use can set ID according to LrfUltisenseCommand enum (test application supports all commands):
Serial port open!
===========================================
===========================================
Commands:
1 - MEASURE_DISTANCE
2 - FAKE_MEASURE_DISTANCE
3 - SET_CONTINUOUS_LOW_POWER_MODE
4 - SET_LASER_POINTER_MODE
5 - ARM
6 - DISARM
7 - SET_OPERATING_MODE
8 - SET_BLOCK_RANGE_REQUEST
9 - SET_CONTINUOUS_RANGE_REQUEST
10 - Just read data from serial port
==========================================
Chose command:
Then, corresponding command will be generated and sent to range finder.
Build and connect to your project
Typical commands to build LrfUltisenseParser library:
cd LrfUltisenseParser
mkdir build
cd build
cmake ..
make
If you want to connect LrfUltisenseParser 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 LrfUltisenseParser repository there. New structure of your repository:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
3rdparty
LrfUltisenseParser
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_ULTISENSE_PARSER ON CACHE BOOL "" FORCE)
if (${PARENT}_SUBMODULE_ULTISENSE_PARSER)
SET(${PARENT}ULTISENSE_PARSER ON CACHE BOOL "" FORCE)
SET(${PARENT}ULTISENSE_PARSER_TEST OFF CACHE BOOL "" FORCE)
endif()
################################################################################
## INCLUDING SUBDIRECTORIES
## Adding subdirectories according to the 3rd-party configuration
################################################################################
if (${PARENT}_SUBMODULE_ULTISENSE_PARSER)
add_subdirectory(LrfUltisenseParser)
endif()
File 3rdparty/CMakeLists.txt adds folder LrfUltisenseParser to your project and excludes test application from compiling (by default test application excluded from compiling if LrfUltisenseParser included as sub-repository). Your repository new structure:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
3rdparty
CMakeLists.txt
LrfUltisenseParser
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 Lens library in your src/CMakeLists.txt file:
target_link_libraries(${PROJECT_NAME} LrfUltisenseParser)
Done!