Concept
This page uses terminology from the Force/Torque Sensors User Manual Gen A
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.
Key Concepts
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.
Configuration file
The JSON configuration required to construct a driver objects must have the following structure:
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)
Communication Interface Configuration
The communication_interface_params object requires the following fields based on the selected interface type under communication_interface_name:
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")
Hint: Interface names with _gen0 suffix are for Gen 0 sensors, while names without suffix correspond to Gen A sensors.
Sensor Operation Parameters
Depending on the sensor generation, the sensor_operation_params object requires the following fields:
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
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.
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 ToolSDK Examples
Templates for JSON configuration files are included in the examples provided with our SDKs.
Download driver configuration JSON files from the online configuration tool.
State Machine Description
The driver has been designed following the guidelines for lifecycle management proposed by ROS2 in this Design Article.
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.
Driver state machine (simplified) and mapping with sensor states
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.
Driver state machine full representation
State Machine Operation
Driver Object Instantiation
At instantiation time three actions take place:
- Parsing of the JSON configuration file.
- Communication establishment (opening and testing).
- Transitioning of sensor state to CONFIG
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.
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
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
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:
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) |
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.
Data reading mechanisms
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.
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.
Polling
The sensor does not send data by itself, and the application must request it.
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.
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.
define READING_PERIOD
while (!STOP)
bota_frame = bota_ft_sensor_driver.readFrame()
###################
## CONTROL LOGIC ##
###################
sleep(remaining of READING_PERIOD)
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.
Reading from the Stream: readFrameBlocking()
This function is only available in communication interfaces classified as Streaming.
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.
while (!STOP)
bota_frame = bota_ft_sensor_driver.readFrameBlocking()
###################
## CONTROL LOGIC ##
###################
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.