Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Getting Started with OpenZen

OpenZen allows to access many different sensor models which are connected via different transports layers with one unified programming interface. This allows to develop applications which support a wide range of sensors and allows to easily adapt your application to new or additional sensors.

A must-have part of an OpenZen client program is:

  • Creating an OpenZen client

  • Connecting to a sensor

  • Accessing sensor components

  • Receiving events from OpenZen (for retrieving available sensors, or accessing sensor data)

  • Closing the sensor connection

Optional parts:

  • Listing available sensors (rely on Receiving events from OpenZen)

  • Reading and modifying sensor properties

The best way to learn how OpenZen client program works is to take a look at our example source file.

For this page, example code are written in C++.

IO Systems

To communicate with the sensor hardware, OpenZen provides multiple so-called IO systems. Each of these can establish the communication to sensors and can list the available sensor hardware. Here are some examples of IO systems available in OpenZen:

  • USB virtual COM port

    Code Block
    // Windows
    auto sensorPair = client.obtainSensorByName("WindowsDevice", "//./COM40", 921600);
    // Linux
    auto sensorPair = client.obtainSensorByName("LinuxDevice", "devicefile:/dev/ttyUSB0", 921600);
  • USB Express (on Windows only)

    Code Block
    auto sensorPair = client.obtainSensorByName("SiUsb", "ig1pcan000028", 921600);
  • Bluetooth

    Code Block
    auto sensorPair = client.obtainSensorByName("Bluetooth", "00:04:3E:53:E9:9F", 115200);
  • Network streaming

You can find the full list of available IO systems in the section io-systems.

Sensor Components

A sensor can have multiple components which supply various types of sensor data. Once the connection
to a sensor has been established, the available components can be queried and their properties can
be access and modified. Furthermore, the streaming of measurement data can be started for each component.

At this time OpenZen supports the following components under a sensor:

Inertial Measurement Unit (IMU)

Provides accelerometer and gyroscope measurements and the orientation result from the sensor fusion running on the connected sensor. All our sensors provide IMU components in OpenZen.

Global Navigation Satellite System (GNSS)

Provides global position measurements via GPS, BeiDou, GLONASS and Galileo, the associated error estimates and information on the quality and mode of the GNSS fix. Only IG1P sensor has GNSS component.

Keys for Sensor Data Access

Most of the keys listed in imuData and gnssData are available for access. Note that there are a few limitations on specific data fields:

“o”: available, “x”: not available

...

Field name (explanation)

...

IG1 / IG1P

...

LPMS3

...

NAV3

...

BE / ME

...

g1
(high-precision on the vertical)

...

o

...

x

...

o

...

x

...

g2

(general-purpose)

...

o

...

o

...

x

...

o

...

Getting Started with OpenZen

OpenZen allows to access many different sensor models which are connected via different transports layers with one unified programming interface. This allows to develop applications which support a wide range of sensors and allows to easily adapt your application to new or additional sensors.

A list of the must-have parts of an OpenZen client program is:

  • Creating an OpenZen client

  • Connecting to a sensor

  • Accessing sensor components

  • Receiving events from OpenZen (for retrieving available sensors, or accessing sensor data)
    ⚠️ Do not add wait or sleep here as it would cause OpenZen client to read in outdated data.

  • Closing the sensor connection

Optional parts:

  • Listing available sensors (rely on Receiving events from OpenZen)

  • Reading and modifying sensor properties

The best way to learn how OpenZen client program works is to take a look at our example source file.

For this page, the example codes are written in C++. We also have Python, C and C# examples in our repo, please check the side navbar for more details (compilations and programming languages support).

IO Systems

To communicate with the sensor hardware, please specify through which IO systems OpenZen should access your sensor.

Note

Permissions and settings required for Linux user

COM port: In the terminal execute sudo adduser <username> dialout, log out and log back in to your user.

Bluetooth: To be able to connect to any Bluetooth sensor, it first needs to be paired via the operating system’s device manager.

Sensor Names

IG1 / IG1P

Except RS485

U3 / U2

CU / URS / UTTL

B2

IG1 / IG1P

RS485

NAV3

BE / ME

Connection Baudrate

921600

115200

  • USB virtual COM port

    Code Block
    // Windows
    auto sensorPair = client.obtainSensorByName("WindowsDevice", "//./COM40", 921600);
    // Linux
    auto sensorPair = client.obtainSensorByName("LinuxDevice", "devicefile:/dev/ttyUSB0", 921600);
  • USB Express (on Windows only)

    Code Block
    auto sensorPair = client.obtainSensorByName("SiUsb", "ig1pcan000028", 921600);
  • Bluetooth (only for B2 sensor)

    Code Block
    auto sensorPair = client.obtainSensorByName("Bluetooth", "00:04:3E:53:E9:9F", 115200);
  • Network streaming

You can find the full list of available IO systems in the section io-systems.

Sensor Components

A sensor can have multiple components which supply various types of sensor data. Once the connection
to a sensor has been established, the available components can be queried. Sensor data and their properties can be access / modified.

Inertial Measurement Unit (IMU)

Provides accelerometer and gyroscope measurements and the orientation result from the sensor fusion running on the connected sensor. All our sensors provide IMU components in OpenZen.

Global Navigation Satellite System (GNSS)

Provides global position measurements via GPS, BeiDou, GLONASS and Galileo, the associated error estimates and information on the quality and mode of the GNSS fix. Only IG1P sensor has GNSS component.

Keys for Sensor Data Access

Sensor data are collected as events in by the client program. Most of the keys listed in imuData and gnssData are available for access. Note that there are a few limitations on specific data fields:

“o”: available, “x”: not available

Field name (explanation)

IG1 / IG1P

U3
CU3 / URS3 / UTTL3

NAV3

U2
CU2 / URS2 / UTTL2

B2

BE / ME

g1
high-precision

low range

o

3 axes high-precision gyro

x

o

vertical axis high-precision gyro

o

o

x

g2

general-purpose

high range

o

o

x

x

x

o

Info

To debug your OpenZen program, we have a Windows GUI client to work with sensors.

There are 2 communications that our sensors follows. They are categorized as follows:

  • LPMS2 sensors: LPMS-U2 series, LPMS-B2, LPMS-ME, LPMS-BE.

  • LPMS3 sensors: LPMS-IG1, LPMS-IG1P, LPMS-U3 series, LPMS-NAV3.

LPMSControl2 for LPMS3 sensors, OpenMAT for LPMS2 sensors.

For detailed information of all our sensors, please visit our Knowledge Base.

...

Note

Information above should have already given you a pretty nice illustration of the OpenZen library’s compositions. You can skip reading the following sections if you understand the sample program.

The old OpenZen docs can be found at https://lpresearch.bitbucket.io/openzen/latest/getting_started.html

Creating an OpenZen Client

The following description will use the C++ interface to OpenZen but other language bindings use the same concepts described here. To see the description how to use the other language bindings, please have a look at the respective section for the language you are interested in.

...

Code Block
auto clientPair = zen::make_client();
auto& clientError = clientPair.first;
auto& client = clientPair.second;

if (clientError)
    // error when creating OpenZen client
    return clientError;

Receiving Events from OpenZen

Every ZenClient instance contains its own event queue which accumulates events from all sensors that were obtained on that client. Events can either be polled using ZenClient::pollNextEvent or waited for using ZenClient::waitForNextEvent.
The only way to terminate a client that is waiting for an event, is by destroying the client or preemptively calling ZenClient::close.

Listing Available Sensors

The IO systems available on your platform can automatically list all available sensors connected to the system. In order to do this, you need to call the method ZenClient::listSensorsAsync to start the query for available sensors. Depending on the IO systems, it can take a couple of seconds for the listing to be complete.

...

Code Block
bool listingComplete = false;
while (!listingComplete) {
    const auto pair = client.waitForNextEvent();
    const bool success = pair.first;
    auto& event = pair.second;
    if (!success)
        break;

    if (!event.component.handle)
    {
        switch (event.eventType)
        {
        case ZenEventType_SensorFound:
            std::cout << "Found sensor " << event.data.sensorFound.name << std::endl;
            break;

        case ZenEventType_SensorListingProgress:
            std::cout << "Sensor listing progress " << event.data.sensorListingProgress.progress
                << " %" << std::endl;
            if (event.data.sensorListingProgress.complete) {
                listingComplete = true;
            }
            break;
        }
    }
}

Connecting to a Sensor

A sensor found by the ZenClient::listSensorsAsync call can be connected via the OpenZen client using the ZenSensorDesc which is contained in the event.data.sensorFound of the ZenSensorEvent_SensorFound. The method call to ZenClient::obtainSensor returns a std::pair where the first entry is a possible error code and the second entry is an instance of the object zen::ZenSensor which can be used to access the Sensor's
properties.

...

You can connect multiple sensor via one ZenClient and the events of all sensor will be available on the event queue of the ZenClient instance.

Reading and Modifying Sensor Properties

OpenZen allows to read an modify the properties of connected sensors. Which properties are available depends on the concrete sensor connected. You can find more information on sensor properties in the section supported-sensors-label.

...

Code Block
auto sensorModelPair = sensor.getStringProperty(ZenSensorProperty_SensorModel);
auto & sensorModelError = sensorModelPair.first;
auto & sensorModelName = sensorModelPair.second;
if (sensorModelError) {
    // error while reading the string property from the sensor
    return sensorModelError;
}
std::cout << "Sensor Model: " << sensorModelName << std::endl;

Accessing Sensor Components

To access a specific component of a sensor, the method call ZenSensor::getAnyComponentOfType can be used to retrieve the component of a specific type. If this component is not available on this sensor, an error will be returned.

...

As with the ZenSensor class the ZenSensorComponent returned by ZenSensor::getAnyComponentOfType call can be used to access and modify the properties of the sensor component.

Reading Sensor Values

To start receiving data from a connected sensor, you need to ensure that the sensor is in streaming mode to send out data on its own:

...

Code Block
if (event.component.handle == g_gnssHandle)
{
    switch (event.eventType)
    {
    case ZenEventType_GnssData:
            std::cout << "> GPS Fix Type: \\t = " << event.data.gnssData.fixType << std::endl;
            std::cout << "> Longitude: \\t = " << event.data.gnssData.longitude
                << "   Latitude: \\t = " << event.data.gnssData.latitude << std::endl;
        break;
    }
}

Closing the Sensor Connection

Once you are done with sampling sensor values, you can release the connection to the sensor and close the connection with the client:

...