Skip to content

tesseract_robotics.tesseract_motion_planners

Base motion planner types and request/response structures.

Overview

This module provides the base interfaces for motion planners. Specific planners (OMPL, TrajOpt, etc.) are in separate modules.

PlannerRequest

Input to a motion planner.

Python
from tesseract_robotics.tesseract_motion_planners import PlannerRequest

request = PlannerRequest()
request.env = env                    # Environment
request.instructions = program       # CompositeInstruction
request.profiles = profile_dict      # ProfileDictionary
request.plan_profile_remapping = {}  # Optional profile overrides
Attribute Type Description
env Environment Robot environment
instructions CompositeInstruction Motion program
profiles ProfileDictionary Planner profiles
plan_profile_remapping dict Profile name overrides

PlannerResponse

Output from a motion planner.

Python
from tesseract_robotics.tesseract_motion_planners import PlannerResponse

response = planner.solve(request)

if response.successful:
    result = response.results  # CompositeInstruction with solution
else:
    print(f"Failed: {response.message}")
Attribute Type Description
successful bool Planning succeeded
message str Status/error message
results CompositeInstruction Solved trajectory

MotionPlanner

Base class for all planners.

Python
from tesseract_robotics.tesseract_motion_planners import MotionPlanner

# MotionPlanner is abstract - use concrete implementations:
# - OMPLMotionPlanner
# - TrajOptMotionPlanner
# - DescartesMotionPlanner
# - SimpleMotionPlanner

response = planner.solve(request)

Every concrete planner derives from MotionPlanner, so isinstance(planner, MotionPlanner) holds and MotionPlanner.solve(planner, request) dispatches to the concrete planner.

Checking a request

checkRequest(request) is the C++ predicate; checkRequestReason(request) says why it fails.

Python
from tesseract_robotics.tesseract_motion_planners import MotionPlanner, PlannerRequest

request = PlannerRequest()
MotionPlanner.checkRequest(request)        # False
MotionPlanner.checkRequestReason(request)  # "PlannerRequest environment is nullptr"

checkRequestReason returns "" for a valid request.

assignSolution

Writes a joint solution into a move instruction in place, the way every planner fills its results: a state waypoint, or with format_result_as_input=True the seed of a Cartesian waypoint (the position of an unconstrained joint waypoint).

Python
MotionPlanner.assignSolution(move_instruction, joint_names, joint_values, False)

Utility Functions

assignCurrentStateAsSeed

Set current environment state as seed for planning.

Python
from tesseract_robotics.tesseract_motion_planners import assignCurrentStateAsSeed

# Modifies program in-place to use current state as seed
assignCurrentStateAsSeed(program, env)

formatProgram

Reorders joint and state waypoints in place to the kinematic group's joint order. Returns True if the program needed formatting.

Python
from tesseract_robotics.tesseract_motion_planners import formatProgram

changed = formatProgram(program, env)

toToolpath

World-frame TCP poses of a program; the working frame in the ManipulatorInfo does not change them. Takes a CompositeInstruction, MoveInstructionPoly or InstructionPoly; returns a list with one VectorIsometry3d per sub-composite (one for a flat program).

Python
from tesseract_robotics.tesseract_motion_planners import toToolpath

toolpath = toToolpath(program, env)
first_tcp_pose = toolpath[0][0]  # Isometry3d

contactCheckProgram

Collision-checks a planned program. Pass a discrete or continuous contact manager; the C++ out-parameter comes back as the second element of the result, one ContactResultMap per step.

Python
from tesseract_robotics.tesseract_collision import CollisionCheckConfig
from tesseract_robotics.tesseract_motion_planners import contactCheckProgram

results, contacts = contactCheckProgram(
    env.getDiscreteContactManager(), env.getStateSolver(), response.results, CollisionCheckConfig()
)
if results:
    print(results.condensedSummary())

Robot configuration

RobotConfig, getRobotConfig, getJointTurns and isWithinJointLimits classify a six-axis arm's joint solution by wrist, elbow and arm configuration. See Filtering IK solutions by configuration.

Usage with TaskComposer

Motion planners are typically used via TaskComposer pipelines rather than directly:

Python
# Direct planner usage (lower level)
from tesseract_robotics.tesseract_motion_planners_ompl import OMPLMotionPlanner

planner = OMPLMotionPlanner()
request = PlannerRequest()
request.env = env
request.instructions = program
request.profiles = profiles

response = planner.solve(request)

# TaskComposer usage (recommended)
from tesseract_robotics.tesseract_task_composer import (
    TaskComposerPluginFactory, TaskflowTaskComposerExecutor
)

# TaskComposer handles planner selection, sequencing, and post-processing

Planner Modules

Module Planner Description
tesseract_motion_planners_ompl OMPL Sampling-based (RRT, PRM, etc.)
tesseract_motion_planners_trajopt TrajOpt Trajectory optimization
tesseract_motion_planners_descartes Descartes Graph-based Cartesian
tesseract_motion_planners_simple Simple Joint interpolation

Auto-generated API Reference

tesseract_motion_planners Python bindings

PlannerRequest

name property writable

Python
name: str

env property writable

Python
env: Environment

profiles property writable

Python
profiles: ProfileDictionary

instructions property writable

Python
instructions: CompositeInstruction

verbose property writable

Python
verbose: bool

format_result_as_input property writable

Python
format_result_as_input: bool

__init__

Python
__init__() -> None

PlannerResponse

results property writable

Python
results: CompositeInstruction

successful property writable

Python
successful: bool

message property writable

Python
message: str

__init__

Python
__init__() -> None

__bool__

Python
__bool__() -> bool

MotionPlanner

getName

Python
getName() -> str

solve

Python
solve(request: PlannerRequest) -> PlannerResponse

terminate

Python
terminate() -> bool

clear

Python
clear() -> None

checkRequest staticmethod

Python
checkRequest(request: PlannerRequest) -> bool

checkRequestReason staticmethod

Python
checkRequestReason(request: PlannerRequest) -> str

Why checkRequest(request) fails: the C++ reason, or an empty string for a valid request.

assignSolution staticmethod

Python
assignSolution(mi: MoveInstructionPoly, joint_names: Sequence[str], joint_values: Annotated[NDArray[float64], dict(shape=(None,), writable=False)] | Sequence[float], format_result_as_input: bool) -> None

Write a joint solution into mi in place: a state waypoint, or with format_result_as_input the seed of a Cartesian / the position of a joint waypoint.

clone

Python
clone() -> MotionPlanner

RobotConfig

Bases: Enum

Six-axis arm configuration: wrist Flip/No-flip, elbow Up/Down, arm fronT/Back.

NUT class-attribute instance-attribute

Python
NUT = 0

FUT class-attribute instance-attribute

Python
FUT = 1

NDT class-attribute instance-attribute

Python
NDT = 2

FDT class-attribute instance-attribute

Python
FDT = 3

NDB class-attribute instance-attribute

Python
NDB = 4

FDB class-attribute instance-attribute

Python
FDB = 5

NUB class-attribute instance-attribute

Python
NUB = 6

FUB class-attribute instance-attribute

Python
FUB = 7

assignCurrentStateAsSeed

Python
assignCurrentStateAsSeed(composite_instructions: CompositeInstruction, env: Environment) -> None

Assign the current environment state as seed to all CartesianWaypoints in the program

formatProgram

Python
formatProgram(composite_instructions: CompositeInstruction, env: Environment) -> bool

Reorder joint and state waypoints in place to the kinematic group's joint order. Returns True if the program needed formatting.

getRobotConfig

Python
getRobotConfig(joint_group: JointGroup, base_link: str, tcp_frame: str, joint_values: Annotated[NDArray[float64], dict(shape=(None,), writable=False)] | Sequence[float], sign_correction: Annotated[NDArray[int32], dict(shape=2, order=C)] | Sequence[int] = [1, 1]) -> RobotConfig

Configuration of a six-axis arm. The last six joint values are the arm's; sign_correction flips the sign of joint 3 and joint 5 for the manufacturer's convention.

getJointTurns

Python
getJointTurns(joint_values: Annotated[NDArray[float64], dict(shape=(None,), writable=False)] | Sequence[float]) -> Annotated[NDArray[numpy.int32], dict(shape=(None,), order=C)]

Whole half-turns per joint, int(q / pi): non-zero beyond +-pi.

isWithinJointLimits

Python
isWithinJointLimits(joint_values: Annotated[NDArray[float64], dict(shape=(None,), writable=False)] | Sequence[float], limits: Annotated[NDArray[float64], dict(shape=(None, 2), order=F)] | Sequence[Sequence[float]], coupling_limits: Annotated[NDArray[float64], dict(shape=2, order=C)] | Sequence[float]) -> bool

True if joint_values are within limits and joint 4 + joint 6 (third and first from the end) are within coupling_limits.