.. _driver_concept: Concept ============= .. raw:: html
i

This page uses terminology from the Force/Torque Sensors User Manual Gen A

.. raw:: html

The driver is implemented as a class, designed for use in Object-Oriented Programming (OOP) frameworks. Implementations are available for C++, Python and ROS2, each with corresponding SDKs.

.. raw:: html

Key Concepts

.. raw:: html

Communication Abstraction

The driver abstracts multiple communication interfaces into a single, consistent API.

JSON-Based Configuration

Driver configuration is handled through a JSON file passed to the class constructor.

.. raw:: html
---- Configuration file ---------------- The JSON configuration required to construct a driver objects must have the following structure: .. raw:: html

Configuration JSON File Structure

Basic Sensor Information
product_name string

Technical product name (e.g., BFT-SENS-SER-M8)

serial_number string

Sensor serial number (e.g., SN000853)

Communication Interface Configuration
communication_interface_name string

Interface type (see supported interfaces below)

communication_interface_params object

Interface-specific parameters (click to view details)

Sensor Operation Configuration
sensor_operation_params object

Generation-specific sensor parameters (click to view details)

Driver Operation Configuration
driver_operation_params object

Driver behavior settings (click to view details)

.. raw:: html

Communication Interface Configuration

The communication_interface_params object requires the following fields based on the selected interface type under communication_interface_name:

.. raw:: html
Binary Communication
communication_interface_name string
Bota_Binary_gen0 or Bota_Binary

Required fields in communication_interface_params object:

com_port string

Serial communication port (e.g., "/dev/ttyUSB0")

baudrate string

Communication speed (e.g., 460800)

EtherCAT Communication
communication_interface_name string
CANopen_over_EtherCAT_gen0 or CANopen_over_EtherCAT

Required fields in communication_interface_params object:

network_interface string

Ethernet interface name (e.g., "eth0")

Socket Communication
communication_interface_name string
Bota_Socket

Required fields in communication_interface_params object:

sensor_ip_address string

IP address of the sensor (e.g., "192.168.1.100")

.. raw:: html
!

Hint: Interface names with _gen0 suffix are for Gen 0 sensors, while names without suffix correspond to Gen A sensors.

.. raw:: html

Sensor Operation Parameters

Depending on the sensor generation, the sensor_operation_params object requires the following fields:

.. raw:: html
Gen 0
sinc_length int

Filter length (sets update rate)

wrench_offset float[6]

[fx, fy, fz, tx, ty, tz] offset values

Gen A
app_mode int

Application mode (wrench/IMU data)

app_submode int

Filter/update rate settings

wrench_offset float[6]

[fx, fy, fz, tx, ty, tz] offset values

.. raw:: html

Driver Operation Parameters

The driver_operation_params object requires the following fields:

runtime_verbosity bool

default: true - Prints to the console metrics about duplicates, sensor update rate, etc.

.. raw:: html
.. raw:: html

JSON File Templates

JSON configuration files can be generated using these methods:

โš™
Online Configuration Tool

Generate JSON files with your sensor's current settings through our web-based configuration interface

Launch Tool
๐Ÿ“‹
SDK Examples

Templates for JSON configuration files are included in the examples provided with our SDKs.

.. figure:: /_static/images/configuration_tool.png :alt: Description of the image :align: center :width: 600px Download driver configuration JSON files from the online configuration tool. .. raw:: html
---- State Machine Description ---------------- .. raw:: html

The driver has been designed following the guidelines for lifecycle management proposed by ROS2 in this Design Article.

.. raw:: html

The driver implements, as shown in the figure below, a state machine with 3 primary states: UNCONFIGURED, INACTIVE and ACTIVE. The figure also shows how these driver states are mapped to the sensor states CONFIG and RUN.

UNCONFIGURED

Sensor in CONFIG state, but no sensor operation parameters are applied.

INACTIVE

Sensor in CONFIG state, sensor operation parameters are applied.

ACTIVE

Sensor in RUN state.

.. figure:: /_static/images/driver_state_machine_summary.png :alt: Description of the image :align: center :width: 400px Driver state machine (simplified) and mapping with sensor states .. raw:: html

The state machine logic is implemented using intermediate transition states, each responsible for executing specific actions. Progression to the next state is dependent upon the successful completion of these actions. The full state machine implementation is shown in the figure below.

.. figure:: /_static/images/driver_state_machine_full.png :alt: Description of the image :align: center :width: 700px Driver state machine full representation .. raw:: html
---- State Machine Operation ---------------- .. raw:: html

Driver Object Instantiation

At instantiation time three actions take place:

If all of this is successful, the driver will be in UNCONFIGURED state. Otherwise, it will raise an error and proceed with destruction of the object.

.. raw:: html

UNCONFIGURED โ†’ INACTIVE

Triggered with: configure()

The driver transitions to CONFIGURING and executes onConfigure() to apply sensor operation parameters.

if onConfigure() result is:
Success: driver state โ†’ INACTIVE
Failure: driver state โ†’ UNCONFIGURED

INACTIVE โ†’ ACTIVE

Triggered with: activate()

The driver transitions to ACTIVATING and executes onActivate(), which brings the sensor to RUN state.

if onActivate() result is:
Success: driver state โ†’ ACTIVE
Failure: driver state โ†’ INACTIVE

.. raw:: html

ACTIVE โ†’ INACTIVE

Triggered with: deactivate()

The driver transitions to DEACTIVATING and executes onDeactivate(), which brings the sensor to CONFIG state.

if onDeactivate() result is:
Success: driver state โ†’ INACTIVE
Failure: driver state โ†’ ACTIVE

INACTIVE โ†’ UNCONFIGURED

Triggered with: cleanup()

The driver transitions to CLEANING_UP and executes onCleanup(). No specific action is performed in this state.

onCleanup() always succeeds:
Always: driver state โ†’ UNCONFIGURED

.. raw:: html

Data Reading in ACTIVE State

From the ACTIVE state the user can call the readFrame() or readFrameBlocking() methods, which return the measurements from the sensor. More information about these methods in the data reading mechanisms section below.

The return object from these methods is of the type BotaFrame:

.. raw:: html
.. list-table:: **BotaFrame Fields** :widths: 20 50 30 :header-rows: 1 :class: table table-hover * - **Field** - **Description** - **Units** * - Status - [throttled, overrange, invalid, raw] - boolean flags * - Force - [Fx, Fy, Fz] - newtons (N) * - Torque - [Mx, My, Mz] - newton-meters (Nm) * - Acceleration - [Ax, Ay, Az] - meters per second squared (m/sยฒ) * - Angular rate - [Wx, Wy, Wz] - radians per second (rad/s) * - Temperature - [T] - degrees Celsius (ยฐC) * - Timestamp - [t] - microseconds (ยตs) .. raw:: html
.. raw:: html
.. raw:: html

Tare Functionality in INACTIVE State

From the INACTIVE state, the user can trigger the tare() method to zero the wrench output.

This method overwrites the wrench_offset values in the sensor configuration with the current sensor readings, effectively setting the current state as the zero reference point for force and torque measurements.

.. raw:: html
---- Data reading mechanisms ---------------- .. raw:: html

The driver provides two main methods for reading sensor data when in the ACTIVE state: readFrame() and readFrameBlocking().

Both methods return a BotaFrame object containing sensor measurements. The choice between the reading mechanisms depends on your application's requirements for timing and control flow.

.. raw:: html

Communication Interface Types

The communication interfaces available in Bota Systems FT sensors can be classified into two categories:

Streaming

The sensor continuously sends data, timing this by itself.

Bota Binary
Bota Socket
Polling

The sensor does not send data by itself, and the application must request it.

CANopen over EtherCAT
.. raw:: html

Reading from the Buffer: readFrame()

This function is available in both **Streaming** and **Polling** communication interfaces. In the case of Streaming interfaces, the driver maintains a buffer with the most recent frame received. This emulates the behavior of a polling interface, where the holding buffer is implemented directly on the sensor side. .. raw:: html

When calling readFrame() the function will return the most recent frame available in the buffer.

The right way of using this reading data mechanism is as presented in the example below, in a loop that is spinning at a controlled rate. This type of control loop will be timed by the master application. .. code-block:: text define READING_PERIOD while (!STOP) bota_frame = bota_ft_sensor_driver.readFrame() ################### ## CONTROL LOGIC ## ################### sleep(remaining of READING_PERIOD) .. raw:: html
โœ“
Recommended for Real-Time Applications

Reading data from the buffer is the preferred method for real-time applications, as it allows the application to control the rate of data processing and avoid blocking the execution flow.

.. raw:: html

Reading from the Stream: readFrameBlocking()

This function is only available in communication interfaces classified as **Streaming**. .. raw:: html

When calling readFrameBlocking() the execution will be blocked until a new frame has been received from the sensor, returning then that received frame. In this way the reading is performed directly from the sensor stream, and frame arrival will time the return of the function.

The right way of using this reading data mechanism is as presented in the example below, in an infinite loop spinning as fast as possible, in which the control logic is executed after each frame is received. This type of control loop will be timed by the sensor frame arrival. .. code-block:: text while (!STOP) bota_frame = bota_ft_sensor_driver.readFrameBlocking() ################### ## CONTROL LOGIC ## ################### .. raw:: html
โœ“
Recommended for Measuring Applications

Reading data from the stream is the preferred method for measuring applications, as it ensures data consistency and avoids returning duplicates or dropping packages.

.. raw:: html
.. raw:: html

Ready to Get Started?

Choose your development platform

C++ Python ROS2
โ†’ SDKs homepage