Python

Download and Installation

The Python bindings are available as a PyPI package for easy installation.

Supported platforms:

  • Linux: x86_64 and aarch64 (Python ≥ 3.10)
  • Windows: x86_64 (Python ≥ 3.12)
  • macOS: arm64 (Python ≥ 3.12)

Installation using pip:

pip install bota-tactile-sensing-utils

Usage Examples

We provide a demo to get yourself started with the Python Tactile Sensing Utilities.

What you'll find in the examples:

  • Contact point and slip detector setup and configuration
  • Contact detection, contact localisation and slip detection
  • Real-time pipeline setup in Python

API Description

All classes are imported from the bota_tactile_sensing_utils module. BotaContactPoint and BotaSlipDetector can be constructed either with a JSON configuration file or with a configuration object populated in user code (see Concept for the configuration structure).

from bota_tactile_sensing_utils import (
    BotaContactPoint,
    BotaContactPointConfig,
    BotaSlipDetector,
    BotaSlipDetectorConfig,
    ContactFrictionCoefficients,
    ContactGeometry,
    ContactGeometryType,
)

Note

The two blocks are meant to be chained: the slip detector consumes the contact wrench produced by the contact point block, not the raw input wrench.


Contact Point

Estimates the point of application of a measured wrench [fx, fy, fz, tx, ty, tz] on a known contact surface.

Configuration Types

class bota_tactile_sensing_utils.ContactGeometryType

Shape of the surface the contact point lies on.

PLANE

Plane parallel to the xy-plane of the wrench frame, offset by dz along +z.

class bota_tactile_sensing_utils.ContactGeometry(type: ContactGeometryType = ContactGeometryType.PLANE, dz: float = 0.0)

Geometry of the contact surface, expressed in the frame the wrench is measured in.

type: ContactGeometryType

Contact surface type. Default: ContactGeometryType.PLANE.

dz: float

[m] Plane offset along +z. Used when type is PLANE. Must be finite. Default: 0.0.

class bota_tactile_sensing_utils.BotaContactPointConfig

Configuration object used to construct BotaContactPoint directly from code, without a JSON file. Every attribute has a usable default.

name: str

Name of the block. Optional, and reported by name() only for JSON configs.

policy

Policy for handling non-OK conditions. Defaults to BotaControlBlockPolicy.BestEffort.

geometry: ContactGeometry

Contact surface the line of action of the wrench is intersected with.

force_threshold: float

[N] Force threshold. Applied to \(\lVert \mathbf{f} \rVert\) it decides whether a contact is reported at all; applied to \(\lvert f_z \rvert\) it decides whether the contact can be localised. Must be finite and greater than zero. Default: 0.3.


BotaContactPoint

class bota_tactile_sensing_utils.BotaContactPoint

Constructor

__init__(config_file: str = '') → None

Constructs the block from a JSON config file (section key "contact_point_config"). If config_file is empty, the block starts from the defaults and must be configured via the setters below.

Parameters:

config_file (str) – Path to the JSON configuration file (may be empty).

Configuration Methods

set_geometry(geometry: ContactGeometry) → bool

Sets the contact surface geometry.

Parameters:

geometry (ContactGeometry) – The contact surface.

Returns:

False when the value came from a JSON config, which cannot be overridden from code, or when the geometry is invalid. True otherwise.

Return type:

bool

set_force_threshold(force_threshold: float) → bool

[N] Sets the force threshold.

Parameters:

force_threshold (float) – Must be finite and greater than zero.

Returns:

False when the value came from a JSON config, which cannot be overridden from code, or when the value is invalid. True otherwise.

Return type:

bool

Runtime Update Method

update(wrench: numpy.ndarray, contact_point: numpy.ndarray) → BotaControlReturnCode

Computes the contact point of the given wrench and writes the result into contact_point in place.

Parameters:
  • wrench (numpy.ndarray) – Input wrench [fx, fy, fz, tx, ty, tz] in N and Nm. Shape (6,), dtype float64.

  • contact_point (numpy.ndarray) – Output contact point [x, y, z] in m. Shape (3,), dtype float64. Written in place.

Returns:

A return code indicating the status of the update operation.

Returns OK both when a contact point was computed and when no contact is present; use in_contact() to tell the two apart. The contact point is zeroed on every non-OK outcome, so a caller that only checks the return code never sees a stale position.

Query Methods

in_contact() → bool
Returns:

True when the last update() found a force above the configured threshold.

Return type:

bool

contact_force_magnitude() → float
Returns:

[N] Force magnitude \(\lVert \mathbf{f} \rVert\) seen by the last update().

Return type:

float

contact_wrench() → numpy.ndarray
Returns:

The wrench of the last update() moved to the contact point: the input forces, and the residual torsion about the contact normal. Shape (6,), dtype float64. This is the input expected by BotaSlipDetector.

Return type:

numpy.ndarray

name() → str
Returns:

Name of the block as specified in the JSON config. Empty when the block was configured from code only.

Return type:

str

Important

Check the return code and in_contact() before using the point. A return code of OK with in_contact() == False means the sensor is untouched, and the contact point has been zeroed accordingly.

Note

update() writes into the array you pass in, it does not return a new one. Allocate contact_point once outside the loop and reuse it, so that no allocation happens per cycle.


Slip Detector

Compares the wrench at the contact point against the friction limits of the contact, and reports whether the contact is slipping.

Configuration Types

class bota_tactile_sensing_utils.ContactFrictionCoefficients(linear: float, torsional: float)

Friction coefficients of the contact pair, i.e. of the tool material against the object material.

linear: float

Linear friction coefficient, dimensionless. The tangential-to-normal force ratio above which the contact is declared to be slipping. Must be finite and greater than zero.

torsional: float

[m] Torsional friction coefficient. The torsion-to-normal-force ratio above which the contact is declared to be slipping. Must be finite and greater than zero.

class bota_tactile_sensing_utils.BotaSlipDetectorConfig

Configuration object used to construct BotaSlipDetector directly from code, without a JSON file. Every attribute has a usable default.

name: str

Name of the block. Optional, and reported by name() only for JSON configs.

policy

Policy for handling non-OK conditions. Defaults to BotaControlBlockPolicy.BestEffort.

friction_coefficients: ContactFrictionCoefficients

Friction limits the measured ratios are compared against.

force_threshold: float

[N] Force threshold. Below it the contact is considered released and no slip verdict is produced. Must be finite and greater than zero. Default: 0.3.


BotaSlipDetector

class bota_tactile_sensing_utils.BotaSlipDetector

Constructor

__init__(config_file: str = '') → None

Constructs the block from a JSON config file (section key "slip_detector_config"). If config_file is empty, the block starts from the defaults and must be configured via the setters below.

Parameters:

config_file (str) – Path to the JSON configuration file (may be empty).

Configuration Methods

set_friction_coefficients(friction_coefficients: ContactFrictionCoefficients) → bool

Sets the friction limits of the contact pair.

Parameters:

friction_coefficients (ContactFrictionCoefficients) – The linear and torsional coefficients.

Returns:

False when the value came from a JSON config, which cannot be overridden from code, or when a coefficient is invalid. True otherwise.

Return type:

bool

set_force_threshold(force_threshold: float) → bool

[N] Sets the force threshold.

Parameters:

force_threshold (float) – Must be finite and greater than zero.

Returns:

False when the value came from a JSON config, which cannot be overridden from code, or when the value is invalid. True otherwise.

Return type:

bool

Runtime Update Method

update(contact_wrench: numpy.ndarray, slip_status: numpy.ndarray) → BotaControlReturnCode

Evaluates both friction conditions for the given contact wrench and writes the result into slip_status in place.

Parameters:
  • contact_wrench (numpy.ndarray) – The wrench at the contact point, as returned by BotaContactPoint.contact_wrench(), in N and Nm. Shape (6,), dtype float64. Its z axis is the contact normal.

  • slip_status (numpy.ndarray) – Output [is_linear_slipping, is_torsional_slipping, linear_slip_ratio, torsional_slip_ratio]. Shape (4,), dtype float64. Written in place. The two flags are 0.0 or 1.0; the linear ratio is dimensionless and the torsional ratio is in m.

Returns:

A return code indicating the status of the update operation.

Returns OK both when a verdict was produced and when no contact is present; use in_contact() to tell the two apart. slip_status is zeroed on every non-OK outcome and whenever no contact is present.

Query Methods

in_contact() → bool
Returns:

True when the last update() found a force above the configured threshold.

Return type:

bool

name() → str
Returns:

Name of the block as specified in the JSON config. Empty when the block was configured from code only.

Return type:

str

Important

Prefer the ratios over the flags in a control loop. The flags tell you the contact has already given way; the ratios tell you how much margin is left before it does.

Note

update() writes into the array you pass in, it does not return a new one. Allocate slip_status once outside the loop and reuse it, so that no allocation happens per cycle.