Skip to content

Multi-purpose hands (bt.tools)

A bracket carrying several tools — a gripper mount, pins, forks — each with its own tip frame, built as a joint-less robot model to weld on with Robot.attach_tool. See Machine tending.

bracket = bt.tools.multi_tool("hand", [bt.tools.Mount("gripper"), bt.tools.Pin("pusher"), bt.tools.Fork("fork")])
hand = bracket.attach_tool(coupling, flange="hand_gripper").attach_tool(gripper)
robot = arm.attach_tool(hand)

tools

Multi-purpose hands: one bracket, several tools, each with its own tip.

The end-effector in a machine-tending photograph is rarely one thing. A plate on the flange carries a gripper for the workpiece, a pin for the buttons and a fork for the door handle, and the robot switches between them by turning its wrist so the right one faces the job — no tool changer, no second robot. What the cell needs from such a hand is a tip frame per tool to aim at, and the bracket's own geometry in the collision check.

multi_tool builds that bracket as a robot model (a joint-less URDF welded on with Robot.attach_tool): a round plate on the flange, and on it any number of pins, forks and gripper mounts, placed in the plate's frame (+Z out of the flange). Each tool is a link with geometry and a <name>_<tool>_tip frame whose +Z points along the tool — the axis a press, a hook or a grasp approaches on — so the same idiom serves every tool: scene.set_tcp_target(pos, quat, link=tip).

bracket = bt.tools.multi_tool("hand", [bt.tools.Mount("gripper"),
                                       bt.tools.Pin("pusher"),
                                       bt.tools.Fork("fork")])
hand = bracket.attach_tool(coupling, flange="hand_gripper").attach_tool(gripper)
robot = arm.attach_tool(hand)          # tcp = the gripper's; the pin
                                       # and fork tips keep their names

The composite's tcp_link stays the gripper's, so motions and the studio gizmo behave as for any gripper; a pose taught for the pin or the fork just names its tip. IK asked for a tip moves only the arm — the gripper's fingers are off that chain and keep their value.

ALUMINIUM module-attribute

ALUMINIUM = (0.55, 0.56, 0.58)

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple. If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

BLACK_STEEL module-attribute

BLACK_STEEL = (0.06, 0.06, 0.07)

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple. If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

Fork

A door hook: two prongs gap apart reaching reach from a crossbar at at along direction, lying across across. The tip frame is the seat between the prongs, seat from the crossbar, +Z along the prongs — a handle bar is taken by driving the seat onto it along that axis, and the door goes wherever the fork then goes.

across class-attribute

across = (0.0, 1.0, 0.0)

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple. If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

at class-attribute

at = (-0.04, 0.0, 0.022)

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple. If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

color class-attribute

color = (0.06, 0.06, 0.07)

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple. If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

direction class-attribute

direction = (-1.0, 0.0, 0.0)

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple. If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

gap class-attribute

gap = 0.03

Convert a string or number to a floating-point number, if possible.

name class-attribute

name = 'fork'

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'.

prong class-attribute

prong = 0.01

Convert a string or number to a floating-point number, if possible.

reach class-attribute

reach = 0.08

Convert a string or number to a floating-point number, if possible.

seat class-attribute

seat = 0.05

Convert a string or number to a floating-point number, if possible.

Mount

Where a gripper (or any catalog tool) bolts on: a link whose +Z is the tool's mounting axis. at is the mounting face's centre in the plate frame, direction its outward normal, spin turns the tool about that normal (the finger pads' axis, on a parallel gripper).

at class-attribute

at = (0.0, 0.0, 0.012)

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple. If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

direction class-attribute

direction = (0.0, 0.0, 1.0)

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple. If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

name class-attribute

name = 'gripper'

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'.

spin class-attribute

spin = 0.0

Convert a string or number to a floating-point number, if possible.

Pin

A pusher: a round pin of length and diameter from at along direction. Its tip frame sits at the free end, +Z along the pin — a button is pressed by putting the tip the button's travel into the cap along that axis.

at class-attribute

at = (0.04, 0.0, 0.022)

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple. If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

color class-attribute

color = (0.06, 0.06, 0.07)

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple. If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

diameter class-attribute

diameter = 0.012

Convert a string or number to a floating-point number, if possible.

direction class-attribute

direction = (1.0, 0.0, 0.0)

Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple. If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

length class-attribute

length = 0.06

Convert a string or number to a floating-point number, if possible.

name class-attribute

name = 'pusher'

str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'.

Robot

A parsed robot model (kinematic tree + geometry). Immutable.

dof property

dof
flange_link

Declared tool-mounting face (catalog frames.flange_frame; after attach_tool, the mounted tool's onward flange if it has one). attach_tool uses it when flange is omitted.

grasp_frames property

grasp_frames

Declared grasp-surface frames (catalog frames.grasp_frames): the fingertips of a hand, the pads of a gripper — where the product says it holds things. Empty when the source declares none; after attach_tool the mounted tool's ride along.

joint_limits property

joint_limits

Per actuated joint: (lower, upper) or None for continuous joints.

joint_names property

joint_names

Actuated joint names in q-vector order.

link_names

mimic_joints property

mimic_joints

Joints that follow another joint (URDF <mimic>, USD PhysxMimicJointAPI) instead of carrying a DOF of their own: {joint: (source joint, multiplier, offset)}. Their value is multiplier * <source position> + offset, and they never appear in joint_names or in a joint position vector.

mount_link

Declared mounting face when this model is a tool (catalog frames.mount_frame). attach_tool uses it when mount is omitted, falling back to the tool's root link.

name property

name
tcp_link

Default end-effector link name: the TCP declared by a tool attachment or catalog manifest when present, otherwise the deepest leaf in the kinematic tree.

attach_tool method descriptor

attach_tool(
    tool,
    flange=None,
    mount=None,
    offset_position=None,
    offset_quaternion=None,
    tcp=None,
    prefix=None,
)

Welds a tool (end-effector) onto this robot's flange and returns the composite robot; neither input is modified. The DOF vector becomes this robot's joints followed by the tool's, mimic joints included.

flange defaults to the robot's declared flange_link and mount to the tool's declared mount_link (catalog manifests declare both), falling back to the tool's root — so catalog parts attach with no arguments, and a coupling's outward face becomes the composite's flange for the next attach_tool in the stack. offset places the mount relative to the flange (e.g. a coupling's thickness); the mount must resolve to the tool's root link. tcp names a tool link to become the composite's tcp_link — otherwise a TCP declared on the tool carries over, falling back to the deepest-leaf heuristic. When both models share a link/joint name, pass prefix to namespace the tool's names.

robot = ur5e.attach_tool(coupling).attach_tool(gripper)  # catalog parts
robot = ur5e.attach_tool(
    gripper, flange="flange", mount="robotiq_arg2f_base_link",
    offset_position=(0, 0, 0.0139), tcp="tcp",
)

from_catalog staticmethod

from_catalog(id, revision=None, format=None)

Loads a robot or tool from the botrail model catalog (the Hugging Face dataset botrail/botrail-catalog) by id — exact (robotiq/2f/2f-85/r1) or any unambiguous shorthand (2f-85, robotiq/2f-85). Needs the optional dependency huggingface_hub (pip install botrail[catalog]).

revision pins a dataset commit SHA; without it the newest catalog is fetched and the resolved SHA is recorded in the robot's source, so saved projects and generated scripts replay bit-identically. Downloads land in the standard Hugging Face cache. format forces "urdf" or "usd"; by default the URDF is preferred. A TCP the package manifest declares (frames.tcp_default) becomes tcp_link. Packages distributed as recipe_only/metadata_only raise with a pointer to building them locally.

from_urdf staticmethod

from_urdf(path)

Loads a robot from a URDF file. Mesh paths are resolved relative to the file; package:// URIs are resolved heuristically.

from_usd staticmethod

from_usd(path, articulation_root=None, search_paths=None)

Imports a robot from a USD articulation (UsdPhysics joints and rigid bodies, e.g. Isaac Sim assets). Link/joint names are the prim paths; revolute limits are converted from degrees, distances from the stage's metersPerUnit, and Y-up stages are re-modeled as Z-up. articulation_root defaults to the first prim carrying PhysicsArticulationRootAPI; search_paths resolve external (omniverse://) references against local directories.

from_xacro staticmethod

from_xacro(path)

Expands a Xacro file (no ROS required) and loads the resulting URDF.

ik method descriptor

ik(
    position,
    quaternion=None,
    link=None,
    seed=None,
    max_iters=100,
    restarts=None,
)

Solves inverse kinematics. With quaternion=None only the position is matched. link defaults to the TCP link, seed to the neutral configuration. When the seeded solve does not converge, up to restarts further attempts run from deterministically generated seeds (limits midpoint first, then fixed-seed uniform samples within the limits) — the same call always returns the same answer. Pass restarts=0 to solve strictly from the given seed. Always returns the best configuration found; check result.converged.

joint_values method descriptor

joint_values(positions)

Value of every joint at positions, keyed by joint name: the DOF value for actuated joints, the mimic relation for driven ones, and 0 for fixed joints.

multi_tool

multi_tool(
    name: str,
    tools: Sequence[Union],
    *,
    plate: tuple[float, float] = (0.08, 0.012),
    color: tuple = (0.55, 0.56, 0.58),
) -> Robot

The bracket as a robot model — multi_tool_urdf loaded. See there.

multi_tool_urdf

multi_tool_urdf(
    name: str,
    tools: Sequence[Union],
    *,
    plate: tuple[float, float] = (0.08, 0.012),
    color: tuple = (0.55, 0.56, 0.58),
) -> str

The bracket as URDF text — what multi_tool loads, and what a catalog asset of the hand is written from, so the made part and the catalogued one are the same geometry.

A round plate plate = (diameter, thickness) whose root link <name>_plate sits on the robot's flange (+Z outward), with the tools on it. Every tool becomes links under <name>_:

  • a Mount — the link <name>_<mount> at its face, +Z along its normal: the flange= to attach_tool the gripper on;
  • a Pin — the pin's body <name>_<pin> and the frame <name>_<pin>_tip at its end, +Z along the pin;
  • a Fork — the crossbar and prongs under <name>_<fork> and the frame <name>_<fork>_tip at the seat between the prongs, +Z along them.

Returns a joint-less Robot to weld on with attach_tool; attach_tool a gripper onto a mount first and the composite's TCP is the gripper's. A tool drawn through the plate's own axis is not refused — a hand is its author's business — but a Mount whose face lies inside the plate would bolt a gripper into the bracket, and that is.

tip

tip(name: str, tool: str) -> str

The tip frame's link name for tool on the hand name.