rplensparser_web_logo

RpLensParser C++ library

v1.0.1

Table of contents

Overview

The RpLensParser is a C++ library designed for encoding control commands and decoding responses from RP zoom lenses. The library includes basic methods for preparing commands (encoding) and interpreting the lens responses (decoding). It utilizes C++17 standard. The library provides simple interface and doesn’t have third party dependencies. Also, the library provides test application to check communication with the lens via a serial port. 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 06.08.2024 - First version.
1.0.1 12.09.2024 - Update response decoding.

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.
    RpLensParser.h ------------ Main library header file.
    RpLensParserVersion.h ----- Header file with library version.
    RpLensParserVersion.h.in -- CMake service file to generate version header.
    RpLensParser.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.

RpLensParser class description

Class declaration

namespace cr
{
namespace rp
{
/// RP protocol parser.
class RpLensParser
{
public:

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

    /// Encode Rp lens command.
    bool getCommand(uint8_t *data, int &size, RpCommand id,
                    int arg1 = 0, int arg2 = 0, int arg3 = 0);

    /// Decode Rp lens response.
    RpResponse decodeResponse(uint8_t nextByte, std::vector<int> &responseArgs);
};
}
}

getVersion method

The getVersion() method return string of current RpLensParser class version. Method declaration:

static std::string getVersion();

Method can be used without RpLensParser class instance:

cout << "RpLensParser version: " << cr::rp::RpLensParser::getVersion();

Console output:

RpLensParser version: 1.0.0

getCommand method

The getCommand(…) method encodes (prepares) control command for lens. Command encoding example shows usage of command. Method declaration:

bool getCommand(uint8_t *data, int &size, RpCommand id,
                int arg1 = 0, int arg2 = 0, int arg3 = 0);
Parameter Value
data Address of buffer for encoded data. Must have size >= 12.
size Size of encoded command.
id Command id according to RpCommand enum.
arg1 First command argument. The value of arguments depends on command id. Some commands don’t have arguments.

Returns: TRUE if commands encoded or FALSE if not (not valid id, not valid parameters or not valid address).

Below is an example of encoding command:

// Init variables.
uint8_t buffer[128];
int size;
int zoomPosition = 1000; // In range 0-64000.
int focusPosition = 2000; // In range 0-64000.

parser.getCommand(buffer, size, RpCommand::SET_POSITIONS, zoomPosition, focusPosition);

// Send data.
serialPort.write(buffer, size);

decodeResponse method

The decodeResponse(…) method decodes response from lens hardware. See the Response decoding example. 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 buffer. When the user passes another byte to the method, the library shifts the buffer by one byte and copies the new byte to the end of the buffer. If the library detects a valid response in internal buffer, it returns the response id (see RpResponse enum) and returns the response arguments. In all other cases, the library returns a NONE identifier. Method declaration:

RpResponse decodeResponse(uint8_t nextByte, std::vector<int> &responseArgs);
Parameter Value
nextByte Next read byte from serial port.
responseArgs Response arguments from lens. The number of arguments and their values depend on response ID (see RpResponse enum). Some responses don’t have arguments.

Returns: Response RpResponse if response detected or NONE id if not.

Below is an example of decoding response from lens:


// Get data from serial port.
uint8_t buffer[128];
int bytes = serialPort.readData(buffer, 128);

// Decoding response byte-by-byte.
std::vector<int> readArguments;
for (int i = 0; i < bytes; ++i)
{
    response = parser.decodeResponse(buffer[i], readArguments);
    switch (response)
    {

    case RpResponse::GENERAL:
    {
        std::cout << "Zoom encoder value: " << readArguments[0] << std::endl;
        std::cout << "Focus encoder value: " << readArguments[1] << std::endl;
        std::cout << "Temperature value: " << readArguments[2] << std::endl;
        std::cout << "Current FOV: " << readArguments[3] << std::endl;
    }
        
        ///...
    }
}

Data structures

RpCommand enum

The command id’s are described in the RpCommand enum in the RpLensParser.h file. The definition of the enum is as follows :

enum class RpCommand
{
    /**
     * @brief Built in test command. No arguments.
     */
    BIT,

    /**
     * @brief Get built in test command status. No arguments.
     */
    GET_BIT_STATUS,

    /**
     * @brief Report lens parameters. No arguments.
     */
    REPORT_PARAMETERS,

    /**
     * @brief Get lens position. No arguments.
     */
    GET_POSITION,

    /**
     * @brief Get FW version. No arguments.
     */
    GET_FW_VERSION,

    /**
     * @brief Get lens serial number. No arguments.
     */
    GET_SERIAL_NUMBER,

    

    * * *



    /**
     * @brief Read EEPROM data.
     * @param arg1 N number of bytes to read.
     */
    READ_EEPROM_DATA
};

RpResponse enum

The response id’s are described in the RpResponse enum in the RpLensParser.h file. The definition of the enum is as follows:

enum class RpResponse
{
    /**
     * @brief General response. Arguments (list elements):
     * [0] Zoom encoder value. Value in range 0-64000.
     * [1] Focus encoder value. Value in range 0-64000.
     * [2] Temperature value. Value Celsius + 100.
     * [3] Current FOV.
     */
    GENERAL,

    /**
     * @brief General response with additional info. Arguments (list elements):
     * [0] Zoom encoder value. Value in range 0-64000.
     * [1] Focus encoder value. Value in range 0-64000.
     * [2] Temperature value. Value Celsius + 100.
     * [3] Current FOV.
     * [4] Shutter/filter/iris/pan/azimuth encoder value.
     * [5] Either Shutter state : (0 - open, 1 - close, 
     * 2 - unknown, 3 - optical close) or filter number: 
     * (1 - 7 filter number, 8 is unknown).
     */
    FULL_GENERAL,

    /**
     * @brief Get lens position response. Arguments (list elements):
     * [0] Zoom encoder value. Value in range 0-64000.
     * [1] Focus encoder value. Value in range 0-64000.
     * [2] Temperature value. Value Celsius + 100.
     * [3] Current FOV. 
     */
    END_OF_ACTION,

    

    * * *



    /**
     * @brief EEPROM No infinity focus direction. Arguments (list elements):
     * [0] No infinity focus direction.
     */
    EEPROM_NO_INFINITY_FOCUS_DIRECTION,

    /**
     * @brief EEPROM No infinity focus option function breakpoint. Arguments (list elements):
     * [0] No infinity focus option function breakpoint.
     */
    EEPROM_NO_INFINITY_FOCUS_FUNCTION_BREAKPOINT
};

Test application

Folder RpLensParser/test contains the test application files. The test application allows you to generate any command, send it to the lens 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 baudrate (default 9600):

===========================================
RpLensParser v1.0.0
===========================================

Enter serial port name : (Serial port name)
Enter baud rate : (Baud rate)

Serial port open!
===========================================

Commands:

0 - BIT
1 - GET_BIT_STATUS
2 - REPORT_PARAMETRS
3 - GET_POSITION
4 - GET_FW_VERSION
5 - GET_SERIAL_NUMBER
6 - GET_WORKING_HOURS
7 - SET_BAUDRATE
8 - ZOOM_INCREMENT
9 - ZOOM_DECREMENT
10 - ZOOM_INCREMENT_CONTINUOUS
11 - ZOOM_DECREMENT_CONTINUOUS
12 - ZOOM_STOP
13 - SET_ZOOM_POSITION
14 - FOCUS_INCREMENT
15 - FOCUS_DECREMENT
16 - FOCUS_INCREMENT_CONTINUOUS
17 - FOCUS_DECREMENT_CONTINUOUS
18 - FOCUS_STOP
19 - MOVE_FOV1
20 - MOVE_FOV2
21 - MOVE_FOV3
22 - MOVE_FOV4
23 - MOVE_FOV5
24 - MOVE_FAST_FOV1
25 - MOVE_FAST_FOV2
26 - MOVE_FAST_FOV3
27 - MOVE_FAST_FOV4
28 - MOVE_FAST_FOV5
29 - MOVE_NUC1
30 - MOVE_NUC2
31 - SET_POSITIONS
32 - SET_TARGET_POSITION
33 - MOVE_TARGET_POSITION
34 - QUICK_ON
35 - BIT_IRIS
36 - OPEN_IRIS
37 - CLOSE_IRIS
38 - OPEN_IRIS_CONTINUOUS
39 - CLOSE_IRIS_CONTINUOUS
40 - STOP_IRIS
41 - SET_IRIS_POSITION
42 - BIT_SHUTTER
43 - OPEN_SHUTTER
44 - CLOSE_SHUTTER
45 - CLOSE_OPTICAL_SHUTTER
46 - OPEN_SHUTTER_NUC
47 - CLOSE_SHUTTER_NUC
48 - SET_SHUTTER_POSITION
49 - BIT_FILTERS
50 - SET_FILTER_POSITION
51 - SET_FILTER_NUMBER
52 - PAN_INCREMENT
53 - PAN_DECREMENT
54 - PAN_INCREMENT_CONTINUOUS
55 - PAN_DECREMENT_CONTINUOUS
56 - PAN_STOP
57 - SET_PAN_POSITION
58 - SET_PAN_POSITION_DEGREE
59 - SET_PAN_SPEED
60 - BIT_PAN
61 - GET_SHUTTER_FILTER_IRIS_PAN_DATA
62 - GET_FOCAL_LENGTH
63 - SET_FOCAL_LENGTH
64 - SET_SPEED
65 - GET_ADDITIONAL_INFO
66 - SET_EXT_TEMPRATURE
67 - GET_MEASURED_TEMPERATURE
68 - GET_INFINITY_CALIBRATION
69 - SET_LENS_POSITION_HOST_CONTROL
70 - RESTORE_FACTORY_SETTINGS
71 - SET_EEPROM_ADDRESS
72 - WRITE_EEPROM_DATA
73 - READ_EEPROM_DATA
Choose command: 31

Enter zoom position (0 - 64000): 1000

Enter focus position (0 - 64000): 2000

Then, corresponding command will be generated and sent to lens. Lens will return related response and it will be decoded and printed on the screen.

Build and connect to your project

Typical commands to build RpLensParser library:

cd RpLensParser
mkdir build
cd build
cmake ..
make

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

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

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

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

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_RP_LENS_PARSER                  ON  CACHE BOOL "" FORCE)
if (${PARENT}_SUBMODULE_RP_LENS_PARSER)
    SET(${PARENT}_RP_LENS_PARSER                        ON  CACHE BOOL "" FORCE)
    SET(${PARENT}_RP_LENS_PARSER_TEST                   OFF CACHE BOOL "" FORCE)
endif()

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

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

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

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} RpLensParser)

Done!