EduArt Sensor Ring Library 3.0.1
Loading...
Searching...
No Matches
Software

1. Public Interface of the Sensor Ring Library

1.1 Measurement Interface

The public interface has three measurement related components:

  • The MeasurementManager:
    This class executes the measurements, collects them and distributes them to all registered clients. It is responsible for the timing of the measurement process. The measurements can either be run asynchronously in a separate thread with the startMeasuring() and stopMeasuring() methods, or in the users thread by repeatedly calling the measureSome() method.
  • The MeasurementClient
    The MeasurementClient is the observer interface, which gets notified by the Logger when new measurements are available. All MeasurementClient instances that should receive measurements must be registered with the MeasurementManager.
  • The ManagerParams
    This is the parameter set that configures the system. The ManagerParams are a cascaded structure, that represents the topology of the system as shown in the diagram below..

1.1 Logger Interface

In addition to the measurement related interface the library provides a logger interface:

  • The Logger
    The Logger collects all debug, info and error messages that are raised internally and forwards them to the registered LoggerClients.
  • The LoggerClient
    The LoggerClient is the observer interface, which gets notified by the Logger when new log messages are available. All LoggerClient instances that should receive log messages must be registered with the Logger.

2. Topology of the System

The EduArt Sensor Ring is a system that collects and combines measurements from multiple individual sensors. The individual sensors are daisy chained together in series and share a communication interface and a power supply. The chain of sensor is terminated by a master device at one end e.g. a Raspberry Pi or a CAN to USB converter. It is possible to use multiple communication interfaces to distribute the sensor data and enable the use of more sensors simultaneously. The following class diagram illustrates the topology and the reflection of the hardware layers in the library.

3. Input Parameters

Each of the core classes of the library has its own parameter set which is shown in the above class diagram. The parameters are designed to mirror the private internal structure of the library. This means the ManagerParams has one element RingParams and the RingParams has a vector of BusParams which mirrors the 1 to n relationship between SensorRing and SensorBus. Each SensorBus has a vector of BoardParams, which again represents the real system where multiple boards can be connected on one interface.

The parameters have to be initialized and configured externally and passed to the MeasurementManager as constructor argument upon creation. Once a MeasurementManager has been instantiated the parameters can no longer be changed.

⚠️ Be careful to configure the actual number of connected communication interfaces (where each interface is one SensorBus) and the correct number of sensor boards per interface. If the ManagerParams parameter enforceTopology is set to true the system will only start if the configuration matches the connected hardware exactly.

4. Minimal Examples for the Supported Languages

The Sensor Ring library includes both C++ examples and Python examples that show how to use it in custom projects.

4.1 C++ C++

The library is written in C++ and it is recommended to use the C++ interface of the library for performance reasons.

The following examples show how to use the Sensor Ring library in your own C++ project:

⚠️ To use the depth_map C++ example on Windows you might first need to enable UTF-8 support for your current terminal session with this command: $OutputEncoding = [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding.

4.2 Python Python

ℹ️ The library can be built with -DSENSORRING_BUILD_PYTHON_BINDINGS=ON option to generate python bindings.

⚠️ To use the sensorring python package you have to append the location of the package to your PYTHONPATH environment variable.

  • Linux

    export PYTHONPATH=$PYTHONPATH:/usr/local/lib/python3/dist-packages
  • Windows

    $env:PYTHONPATH = "${env:PYTHONPATH};C:\Program Files\EduArt Robotik GmbH\Sensor Ring\bindings\python3"
    $env:EDU_SENSORRING_DIR = "C:\Program Files\EduArt Robotik GmbH\Sensor Ring\"
    Alternatively you can use the Windows Edit the System Environment Variables tool to add the python package location to the environment variable PYTHONPATH.

The following examples show how to use the Sensor Ring library in your own Python project:


The depth_map example

The depth_view example.

The use of the Python interface is similar to that of the C++ interface with a few exceptions that are explained below.

C++ has the two client interface classes MeasurementClient and LoggerClient. With the generated Python bindings it is not possible to inherit from both base classes in one python class simultaneously. Only the first base class is handled correctly, the second one is not recognized correctly and throws an error when trying to registering it. For this reason the Python interface has the additional SensorringClient class, which combines the callbacks from both MeasurementClient and LoggerClient in one class.

⚠️ Use the SensorringClient base class in Python to inherit from both MeasurementClient and LoggerClient.

⚠️ It is strongly recommended to clone measurements to numyp arrays before manipulating them. This is shown in the onRawTofMeasurement() callback below.

Below is a minimal example that shows the Python specialities discussed above:

import numpy as np
import eduart.sensorring as sensorring
class MeasurementProxy(sensorring.SensorringClient):
def __init__(self):
# Initialize base class
super().__init__()
self._points_np = np.zeros((64, 6), dtype=np.float64)
# Base class callback
def onRawTofMeasurement(self, measurement_vec):
measurement_vec[0].point_cloud.copyTo(self._points_np)
# Base class callback
def onOutputLog(self, verbosity, msg):
print("[" + sensorring.LogVerbosityToString(verbosity) + "] " + msg)
def main():
# Create the parameter structure that is used to instantiate the sensorring
params = sensorring.ManagerParams()
# (Actually configure the parameters here...)
# Instantiate a Measurement proxy
proxy = MeasurementProxy()
# Register the proxy with the Logger to get the log output
sensorring.Logger.getInstance().registerClient(proxy)
try:
# Instantiate a MeasurementManager with the parameters from above
manager = sensorring.MeasurementManager(params)
# Register the proxy with the LogMeasurementManager to get the measurements
manager.registerClient(proxy)
# Start the measurements
manager.startMeasuring()
while (manager.isMeasuring()):
# (Actually do something useful here ...)
pass
# Stop the measurements
manager.stopMeasuring()
except Exception as e:
print("Caught: ", e)
if __name__ == "__main__":
main()

5. Wrappers for Other Frameworks

In addition the the examples, the Sensor Ring library has provides for ROS and ROS2 which make the integration of the EduArt Sensor Ring in existing projects easy.

5.1 ROS Wrapper ROS

The Ros1 wrapper publishes the Time of Flight Sensor measurements as PointCloud2 message and the thermal measurements as Image message. In addition the pose of each sensor is published as a static transformation.

ℹ️ Using the ROS Wrapper does not require you to install the Sensor Ring Library manually. The ROS build will automatically fetch the library if it is not detected by CMake.

  • ROS Native

    mkdir catkin_ws/src -p
    cd catkin_ws
    git clone https://github.com/EduArt-Robotik/edu_sensorring_ros1.git ./src
    catkin_make -DCATKIN_WHITELIST_PACKAGES="edu_sensorring_ros1"
    source devel/setup.bash
    roslaunch edu_sensorring_ros1 usb_sensorring.launch

    ℹ️ The parameters of the Sensor Ring are defined in the native ROS parameter file and have to be adjusted to match the actual sensor configuration.

  • ROS in Docker

    git clone https://github.com/EduArt-Robotik/edu_sensorring_ros1.git
    cd edu_sensorring_ros1/docker/
    docker compose build
    docker compose up -d

    ℹ️ The parameters of the Sensor Ring are defined in the Docker parameter file and have to be adjusted to match the actual sensor configuration.

5.2 ROS2 Wrapper ROS2

The Ros2 wrapper publishes the Time of Flight Sensor measurements as PointCloud2 message and the thermal measurements as Image message. In addition to the sensor messages the pose of each sensor is published as a static transformation.

ℹ️ Using the ROS2 Wrapper does not require you to install the Sensor Ring Library manually. The ROS2 build will automatically fetch the library if it is not detected by CMake.

  • ROS2 Native

    mkdir ros2_ws/src -p
    cd ros2_ws
    git clone https://github.com/EduArt-Robotik/edu_sensorring_ros2.git ./src
    colcon build --packages-select edu_sensorring_ros2 --symlink-install --event-handlers console_direct+
    source install/setup.bash
    ros2 launch edu_sensorring_ros2 usb_sensorring.launch.py

    ℹ️ The parameters of the Sensor Ring are defined in the native ROS2 parameter file and have to be adjusted to match the actual sensor configuration.

  • ROS2 in Docker

    git clone https://github.com/EduArt-Robotik/edu_sensorring_ros2.git
    cd edu_sensorring_ros2/docker/
    docker compose build
    docker compose up -d

    ℹ️ The parameters of the Sensor Ring are defined in the Docker parameter file and have to be adjusted to match the actual sensor configuration.


3D point cloud from the sensor system on a mobile robot visualized with Rviz

3D map of a corridor recorded with the sensor system using Octomap.
Read Previous
Installation