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.
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.
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.
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.
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).
Utility Functions¶
assignCurrentStateAsSeed¶
Set current environment state as seed for planning.
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.
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).
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.
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:
# 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
¶
PlannerResponse
¶
MotionPlanner
¶
checkRequestReason
staticmethod
¶
Why checkRequest(request) fails: the C++ reason, or an empty string for a valid request.
assignSolution
staticmethod
¶
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.
RobotConfig
¶
Bases: Enum
Six-axis arm configuration: wrist Flip/No-flip, elbow Up/Down, arm fronT/Back.
assignCurrentStateAsSeed
¶
assignCurrentStateAsSeed(composite_instructions: CompositeInstruction, env: Environment) -> None
Assign the current environment state as seed to all CartesianWaypoints in the program
formatProgram
¶
Reorder joint and state waypoints in place to the kinematic group's joint order. Returns True if the program needed formatting.
getRobotConfig
¶
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
¶
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
¶
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.