tesseract_robotics.tesseract_environment¶
Environment management and scene modification commands.
Environment¶
Central class containing robot model, collision, and kinematics.
from pathlib import Path
from tesseract_robotics.tesseract_environment import Environment
# Create empty environment
env = Environment()
# From URDF + SRDF files (+ ResourceLocator for mesh resolution)
env.init(Path(urdf_path), Path(srdf_path), locator)
# Or from raw XML strings
env.init(urdf_xml, srdf_xml, locator)
# Or use the high-level Robot helper (takes BOTH URDF and SRDF)
from tesseract_robotics.planning import Robot
robot = Robot.from_urdf(
"package://my_robot/urdf/robot.urdf",
"package://my_robot/urdf/robot.srdf",
)
env = robot.env
A str is URDF content, never a path
init binds the native overloads: init(str, locator) and init(str, str, locator) parse
URDF/SRDF content; init(Path, locator) and init(Path, Path, locator) load files.
A path passed as str is parsed as XML and init returns False. Mixing one Path with
one content str raises TypeError. initFromUrdf / initFromUrdfSrdf and
tesseract_common.FilesystemPath were removed (gh-165); see the CHANGELOG for the migration.
Scene Graph Access¶
# Get scene graph (read-only)
scene = env.getSceneGraph()
links = scene.getLinks()
joints = scene.getJoints()
# Get specific elements
link = env.getLink("base_link")
joint = env.getJoint("joint_1")
State Management¶
# Current state
state = env.getState()
joint_positions = state.joints
# State at other joint values, without changing the environment
at_dict = env.getState({"joint_1": 0.5, "joint_2": -0.3})
at_values = env.getState(["joint_1", "joint_2"], np.array([0.5, -0.3]))
# Set joint state: dict, or names + values
env.setState({"joint_1": 0.5, "joint_2": -0.3})
env.setState(["joint_1", "joint_2"], np.array([0.5, -0.3]))
# Floating joints: every getState / setState form takes a {joint_name: Isometry3d} dict,
# either as the trailing floating_joints argument or on its own
env.setState({"base_joint": base_pose})
env.setState({"joint_1": 0.5}, {"base_joint": base_pose})
moved = env.getState(["joint_1"], np.array([0.5]), {"base_joint": base_pose})
# Current values of chosen joints, in the order given
q = env.getCurrentJointValues(["joint_2", "joint_1"])
# Get link transform
tcp = env.getLinkTransform("tool0")
# All link transforms: current state (list), or for given joint values (dict, state unchanged)
current = env.getLinkTransforms()
at_values = env.getLinkTransforms(["joint_1", "joint_2"], np.array([0.5, -0.3]))
tcp_at_values = at_values["tool0"]
# Floating joints: current joint-origin transforms, keyed by joint name
floating = env.getCurrentFloatingJointValues()
getState, setState and getLinkTransforms validate their input before the state solver
sees it: an unknown or non-active joint name, or a names/values length mismatch, raises
ValueError. So does a floating_joints key that is not a floating joint; a rejected
setState leaves the state unchanged. getCurrentJointValues(names) raises KeyError for a
name that is not an active joint.
An empty dict
{} converts to both a joint-value dict and a floating-joint dict, so getState({}) and
setState({}) take the joint-value form. Both forms do the same thing for an empty dict.
getStateByMap, getStateByNamesAndValues, setStateByNamesAndValues and
getCurrentJointValuesByNames are the older Python-only names for the same overloads. They
still work, with the same validation.
Per-link and per-joint lookups¶
limits = env.getJointLimits("joint_1") # JointLimits copy: lower, upper, velocity, ...
enabled = env.getLinkCollisionEnabled("link_1") # bool
visible = env.getLinkVisibility("link_1") # bool
A name that is not in the scene graph raises KeyError, also for
getCurrentFloatingJointValues(names).
Kinematics¶
# Get kinematic group (for FK/IK)
manip = env.getKinematicGroup("manipulator")
# Get joint group (FK only, no IK): an SRDF group, or any joints under a name of your choice
group = env.getJointGroup("manipulator")
wrist = env.getJointGroup("wrist", ["joint_5", "joint_6"])
# Links moved by the given joints, and the links they leave fixed
moving = env.getActiveLinkNames(["joint_5", "joint_6"])
fixed = env.getStaticLinkNames(["joint_5", "joint_6"])
# Available groups
groups = env.getGroupNames()
These three take joints of any type and raise ValueError for a name that is not in the scene
graph. getJointGroup also needs every joint to move: a fixed joint raises RuntimeError.
TCP offsets¶
findTCPOffset(manip_info) resolves manip_info.tcp_offset, in this order
(environment.cpp:832–862, tesseract 0.35.0):
- an
Isometry3dis returned as is; - a name that is a link of the scene raises
RuntimeError: use it astcp_frameinstead; - a name in the SRDF group TCPs of
manip_info.manipulator(named TCPs) returns that transform; there is no fallback to another group; - any other name goes to the find-TCP callbacks, in registration order;
- if none returns a transform,
RuntimeError: Could not find tcp by name ….
Every planner calls findTCPOffset itself and composes the result the same way
(tesseract_planning 0.35.0):
| Quantity | Composition | Source |
|---|---|---|
| TCP pose in world | T_world_{tcp_frame}(q) * offset |
simple/src/interpolation.cpp:108, core/src/utils.cpp:73 |
Cartesian waypoint C |
relative to working_frame: T_world_{working_frame} * C is the TCP pose |
core/src/utils.cpp:90, trajopt/src/trajopt_utils.cpp:83–87 |
| IK target | the tcp_frame pose, C * offset.inverse(), in working_frame |
ompl/src/profile/ompl_real_vector_move_profile.cpp:187, descartes/include/tesseract/motion_planners/descartes/impl/descartes_robot_sampler.hpp:92 |
FK (calcFwdKin) returns link poses and IK (KinGroupIKInput) takes a link pose: neither
applies the offset, so a caller doing FK/IK by hand multiplies or strips it as above. When a
move instruction carries its own ManipulatorInfo, it overrides the program's field by field,
but tcp_offset only together with a non-empty tcp_frame
(ManipulatorInfo::getCombined, manipulator_info.cpp:54–58): an instruction that sets only
tcp_offset keeps the program's offset.
import numpy as np
from tesseract_robotics.tesseract_common import Isometry3d, ManipulatorInfo
def tool_offsets(manip_info):
if manip_info.tcp_offset != "nozzle":
raise LookupError(manip_info.tcp_offset) # "not located": the next callback is asked
matrix = np.eye(4)
matrix[:3, 3] = [0.0, 0.0, 0.12]
return Isometry3d(matrix)
env.addFindTCPOffsetCallback(tool_offsets)
tcp = env.findTCPOffset(ManipulatorInfo("manipulator", "base_link", "tool0", "nozzle"))
A raising callback means \"not located\"
findTCPOffset catches every exception a callback raises, including a bug in it, and asks
the next callback. Returning anything but an Isometry3d (None included) counts the same.
When no callback returns a transform, it raises
RuntimeError: Could not find tcp by name <name>'!, and the callback's own traceback is not
shown. Test a callback by calling it directly.
clone() copies the callbacks, and the environment keeps them alive, so the Python function may
go out of scope. A callback can run on any thread (task-composer workers call findTCPOffset)
and takes the GIL itself. It runs under the environment's lock, so it must not call into the
same environment, and it must not keep that environment alive itself (a closure over it, or
an object attribute holding it): the environment keeps the callback alive from C++, so the
garbage collector cannot see that cycle and neither is ever freed. A module-level function that
reaches the environment only as a global is fine.
Callbacks cannot be listed or removed: getFindTCPOffsetCallbacks is not bound, since a C++
std::function has nothing Python could inspect.
Collision¶
# Get a copy of the active collision managers
discrete = env.getDiscreteContactManager()
continuous = env.getContinuousContactManager()
# Or a copy built from any registered plugin; the active manager is unchanged
simple = env.getDiscreteContactManager("BulletDiscreteSimpleManager")
# Allowed collision matrix
acm = env.getAllowedCollisionMatrix()
The registered names are the keys of
env.getContactManagersPluginInfo().discrete_plugin_infos.plugins (and
continuous_plugin_infos.plugins). Any other name raises KeyError. A manager keeps its
Environment alive, because its code lives in a plugin library the environment loaded.
Contact allowed validator¶
Every contact manager the environment creates or clones gets the same
EnvironmentContactAllowedValidator. It allows a link pair to collide only if the scene graph's
allowed collision matrix allows it. It holds the scene graph by shared pointer, so it follows later
ACM changes (ModifyAllowedCollisionsCommand, RemoveAllowedCollisionLinkCommand) and keeps the
graph alive after the environment is gone.
from tesseract_robotics.tesseract_common import (
ACMContactAllowedValidator,
CombinedContactAllowedValidator,
CombinedContactAllowedValidatorType,
)
from tesseract_robotics.tesseract_environment import EnvironmentContactAllowedValidator
validator = env.getDiscreteContactManager().getContactAllowedValidator()
assert isinstance(validator, EnvironmentContactAllowedValidator)
validator("link_1", "link_2") # True: the SRDF disables this pair
# Build one for any scene graph, e.g. to combine it with an extra ACM
own = EnvironmentContactAllowedValidator(env.getSceneGraph())
extra = ACMContactAllowedValidator(extra_acm)
combined = CombinedContactAllowedValidator([own, extra], CombinedContactAllowedValidatorType.OR)
env.getDiscreteContactManager().setContactAllowedValidator(combined)
A scene graph is required
The only constructor takes a SceneGraph. EnvironmentContactAllowedValidator() and
EnvironmentContactAllowedValidator(None) raise TypeError: the C++ default constructor
exists for serialization and leaves the scene graph null.
Single-state collision checks¶
checkTrajectoryState places every active collision object of a manager at one set of link
transforms and runs a contact test; checkTrajectorySegment casts each object from state0 to
state1 (continuous manager only). Both are the C++ functions from
tesseract/environment/utils.h, except that C++ fills a ContactResultMap& out-parameter and
Python gets the map back as the return value. Each call returns a new map, so results never
carry over from an earlier call; C++ appends to the map it is given.
from tesseract_robotics.tesseract_collision import ContactRequest
from tesseract_robotics.tesseract_environment import checkTrajectorySegment, checkTrajectoryState
names = env.getGroupJointNames("manipulator")
start = env.getState(names, start_joints).link_transforms # dict[str, Isometry3d]
end = env.getState(names, end_joints).link_transforms
# One state, either manager
contacts = checkTrajectoryState(env.getDiscreteContactManager(), end, ContactRequest())
contacts = checkTrajectoryState(env.getContinuousContactManager(), end, ContactRequest())
# One swept segment, continuous manager
contacts = checkTrajectorySegment(env.getContinuousContactManager(), start, end, ContactRequest())
if contacts.count() > 0:
print(contacts.getSummary())
The state maps must hold a transform for every name in manager.getActiveCollisionObjects();
extra keys are ignored. A missing one raises KeyError naming every missing link, before the
manager is moved. (C++ throws std::out_of_range partway through, after it has already moved the
links before the missing one.) The GIL is released during the contact test.
Environment Info¶
# Check initialization
if env.isInitialized():
print(f"Root link: {env.getRootLinkName()}")
print(f"Revision: {env.getRevision()}")
print(f"Revision after init: {env.getInitRevision()}")
# Last change to anything / to the current state, as naive local datetime.datetime
changed = env.getTimestamp()
state_changed = env.getCurrentStateTimestamp()
# Contact-manager plugin config loaded from the SRDF
info = env.getContactManagersPluginInfo()
print(info.discrete_plugin_infos.default_plugin)
Timestamps are naive local time
nanobind converts std::chrono::system_clock::time_point to a datetime.datetime
without tzinfo, in local time. Compare against datetime.datetime.now(), not
datetime.datetime.now(datetime.timezone.utc).
Commands¶
Modify the environment with commands. Commands are tracked for undo/redo.
AddLinkCommand¶
Add a new link to the scene.
from tesseract_robotics.tesseract_environment import AddLinkCommand
from tesseract_robotics.tesseract_scene_graph import Link, Joint, JointType
link = Link("obstacle")
# ... configure link with visual/collision
joint = Joint("obstacle_joint")
joint.type = JointType.FIXED
joint.parent_link_name = "world"
joint.child_link_name = "obstacle"
cmd = AddLinkCommand(link, joint)
env.applyCommand(cmd)
RemoveLinkCommand¶
from tesseract_robotics.tesseract_environment import RemoveLinkCommand
cmd = RemoveLinkCommand("obstacle")
env.applyCommand(cmd)
MoveLinkCommand¶
Move a link to a new parent.
from tesseract_robotics.tesseract_environment import MoveLinkCommand
joint = Joint("new_joint")
# ... configure joint
cmd = MoveLinkCommand(joint)
env.applyCommand(cmd)
ChangeJointOriginCommand¶
Change a joint's transform.
from tesseract_robotics.tesseract_environment import ChangeJointOriginCommand
from tesseract_robotics.tesseract_common import Isometry3d
import numpy as np
mat = np.eye(4)
mat[:3, 3] = [0.1, 0, 0]
new_origin = Isometry3d(mat)
cmd = ChangeJointOriginCommand("obstacle_joint", new_origin)
env.applyCommand(cmd)
Joint Limit Commands¶
from tesseract_robotics.tesseract_environment import (
ChangeJointPositionLimitsCommand,
ChangeJointVelocityLimitsCommand,
ChangeJointAccelerationLimitsCommand,
)
# Position limits
cmd = ChangeJointPositionLimitsCommand("joint_1", -2.0, 2.0)
# Velocity limits
cmd = ChangeJointVelocityLimitsCommand("joint_1", 1.5)
# Acceleration limits
cmd = ChangeJointAccelerationLimitsCommand("joint_1", 5.0)
ChangeLinkCollisionEnabledCommand¶
Enable/disable collision for a link.
from tesseract_robotics.tesseract_environment import ChangeLinkCollisionEnabledCommand
cmd = ChangeLinkCollisionEnabledCommand("gripper", False) # disable
env.applyCommand(cmd)
ModifyAllowedCollisionsCommand¶
Update the allowed collision matrix.
from tesseract_robotics.tesseract_environment import (
ModifyAllowedCollisionsCommand, ModifyAllowedCollisionsType
)
from tesseract_robotics.tesseract_common import AllowedCollisionMatrix
acm = AllowedCollisionMatrix()
acm.addAllowedCollision("link_a", "link_b", "custom reason")
cmd = ModifyAllowedCollisionsCommand(acm, ModifyAllowedCollisionsType.ADD)
env.applyCommand(cmd)
| ModifyAllowedCollisionsType | Description |
|---|---|
ADD |
Add entries to existing ACM |
REMOVE |
Remove entries from ACM |
REPLACE |
Replace entire ACM |
ChangeCollisionMarginsCommand¶
Update collision margins.
from tesseract_robotics.tesseract_environment import ChangeCollisionMarginsCommand
# Simplified 0.34 constructor — just pass the new default margin
cmd = ChangeCollisionMarginsCommand(0.05)
env.applyCommand(cmd)
# Or override per-pair margins via CollisionMarginPairData
from tesseract_robotics.tesseract_common import (
CollisionMarginPairData, CollisionMarginPairOverrideType
)
pair_data = CollisionMarginPairData()
pair_data.setCollisionMargin("link_a", "link_b", 0.1)
cmd = ChangeCollisionMarginsCommand(pair_data, CollisionMarginPairOverrideType.REPLACE)
env.applyCommand(cmd)
AddContactManagersPluginInfoCommand¶
Add contact manager plugin configuration to a live environment.
from tesseract_robotics.tesseract_common import ContactManagersPluginInfo
from tesseract_robotics.tesseract_environment import AddContactManagersPluginInfoCommand
info = ContactManagersPluginInfo()
info.search_paths = ["/opt/my_plugins"]
cmd = AddContactManagersPluginInfoCommand(info)
env.applyCommand(cmd)
getContactManagersPluginInfo() returns a copy, so editing it does not change a command
already applied.
AddTrajectoryLinkCommand¶
Add a link, attached to parent_link_name, whose collision geometry covers the robot's
links over a JointTrajectory (for example to keep a planned motion clear of other
moving objects). Each state names the joints it sets.
import numpy as np
from tesseract_robotics.tesseract_common import JointState, JointTrajectory
from tesseract_robotics.tesseract_environment import AddTrajectoryLinkCommand
names = ["joint_1", "joint_2"]
traj = JointTrajectory([JointState(names, np.array([0.0, 0.0])),
JointState(names, np.array([0.5, -0.5]))])
Method = AddTrajectoryLinkCommand.Method
cmd = AddTrajectoryLinkCommand("swept_volume", "world", traj, method=Method.GLOBAL_CONVEX_HULL)
env.applyCommand(cmd)
AddTrajectoryLinkCommand.Method |
Collision geometry |
|---|---|
PER_STATE_OBJECTS (default) |
every active link's collision objects, for every state |
PER_STATE_CONVEX_HULL |
one convex hull per state |
GLOBAL_PER_LINK_CONVEX_HULL |
one convex hull per active link, over all states |
GLOBAL_CONVEX_HULL |
one convex hull over all active links and all states |
The table follows the enum's comments in add_trajectory_link_command.h; the tests check
only that each method adds the link. getTrajectory() returns a copy.
All commands, and Environment, compare by value (==) and are unhashable. env ==
env.clone(); two environments built separately differ (their timestamps), and commands holding
geometry from two separate parses differ (geometry compares by uuid).
SetActiveDiscreteContactManagerCommand / SetActiveContinuousContactManagerCommand¶
Switch the active contact manager plugin, as a command that the history records.
from tesseract_robotics.tesseract_environment import (
SetActiveContinuousContactManagerCommand,
SetActiveDiscreteContactManagerCommand,
)
env.applyCommand(SetActiveDiscreteContactManagerCommand("BulletDiscreteBVHManager"))
env.applyCommand(SetActiveContinuousContactManagerCommand("BulletCastBVHManager"))
Environment.setActiveDiscreteContactManager(name) (and its continuous twin) switches the
manager without recording a command, as upstream does, so init(env.getCommandHistory())
does not replay it. Use the command when the switch must survive a replay.
Command history¶
Every command an environment applied, its own initialisation included, is in
getCommandHistory(). Each element comes back as its own class, and getType() returns a
CommandType. applyCommands applies a list in one call, and init(commands) rebuilds an
environment from a history.
from tesseract_robotics.tesseract_environment import (
ChangeLinkVisibilityCommand, CommandType, Environment, RemoveLinkCommand
)
env.applyCommands([RemoveLinkCommand("obstacle"), ChangeLinkVisibilityCommand("link_1", False)])
history = env.getCommandHistory()
assert history[0].getType() == CommandType.ADD_SCENE_GRAPH
assert isinstance(history[-1], ChangeLinkVisibilityCommand)
replay = Environment()
assert replay.init(history) # the list must start with an AddSceneGraphCommand
assert replay.getRevision() == env.getRevision()
applyCommands and init(commands) keep the Python command objects themselves, without
copying them.
Events¶
Subscribe to environment changes. A callback receives each event as its own class,
CommandAppliedEvent or SceneStateChangedEvent, so it can read revision or state
directly; event.type says which one it is.
from tesseract_robotics.tesseract_environment import EventCallbackFn, Events
def on_event(event):
if event.type == Events.COMMAND_APPLIED:
print(f"Command applied: revision {event.revision}, "
f"last command {type(event.commands[-1]).__name__}")
elif event.type == Events.SCENE_STATE_CHANGED:
print(f"State changed: {len(event.state.joints)} joints")
env.addEventCallback(1, EventCallbackFn(on_event)) # 1: any int key, for removeEventCallback(1)
An event is valid only inside its callback
The event refers to C++ data that is gone once the callback returns. Copy what you
need (event.revision, dict(event.state.joints)); never store the event itself.
event.commands is already a copy, so the list stays valid.
cast_CommandAppliedEvent(event) and cast_SceneStateChangedEvent(event) remain for
existing code. They return the same object they are given, and raise EventTypeError
(a TypeError) when event.type is the other kind:
from tesseract_robotics.tesseract_environment import EventTypeError, cast_CommandAppliedEvent
try:
cast_CommandAppliedEvent(state_event)
except EventTypeError as e:
print(e) # cast_CommandAppliedEvent: event type is Events.SCENE_STATE_CHANGED, expected Events.COMMAND_APPLIED
Auto-generated API Reference¶
tesseract_environment Python bindings
Events
¶
CommandAppliedEvent
¶
EventTypeError
¶
Bases: TypeError
cast_CommandAppliedEvent / cast_SceneStateChangedEvent got an event of the other type.
CommandType
¶
Bases: Enum
CHANGE_LINK_COLLISION_ENABLED
class-attribute
instance-attribute
¶
REMOVE_ALLOWED_COLLISION_LINK
class-attribute
instance-attribute
¶
CHANGE_JOINT_POSITION_LIMITS
class-attribute
instance-attribute
¶
CHANGE_JOINT_VELOCITY_LIMITS
class-attribute
instance-attribute
¶
CHANGE_JOINT_ACCELERATION_LIMITS
class-attribute
instance-attribute
¶
ADD_KINEMATICS_INFORMATION
class-attribute
instance-attribute
¶
ADD_CONTACT_MANAGERS_PLUGIN_INFO
class-attribute
instance-attribute
¶
SET_ACTIVE_DISCRETE_CONTACT_MANAGER
class-attribute
instance-attribute
¶
SET_ACTIVE_CONTINUOUS_CONTACT_MANAGER
class-attribute
instance-attribute
¶
Command
¶
RemoveJointCommand
¶
RemoveLinkCommand
¶
AddTrajectoryLinkCommand
¶
Bases: Command
__init__
¶
__init__(link_name: str, parent_link_name: str, trajectory: JointTrajectory, replace_allowed: bool = False, method: Method = AddTrajectoryLinkCommand.Method.PER_STATE_OBJECTS) -> None
getTrajectory
¶
AddKinematicsInformationCommand
¶
AddContactManagersPluginInfoCommand
¶
ModifyAllowedCollisionsType
¶
ModifyAllowedCollisionsCommand
¶
ChangeJointPositionLimitsCommand
¶
ChangeJointVelocityLimitsCommand
¶
ChangeJointAccelerationLimitsCommand
¶
ChangeCollisionMarginsCommand
¶
Bases: Command
getCollisionMarginPairData
¶
getCollisionMarginPairData() -> tesseract_robotics.tesseract_common._tesseract_common.CollisionMarginPairData
getCollisionMarginPairOverrideType
¶
getCollisionMarginPairOverrideType() -> tesseract_robotics.tesseract_common._tesseract_common.CollisionMarginPairOverrideType
EnvironmentContactAllowedValidator
¶
Bases: ContactAllowedValidator
Environment
¶
getTimestamp
¶
Last update time (any change to the environment), as a naive local datetime.datetime.
getCurrentStateTimestamp
¶
Last update time of the current state, as a naive local datetime.datetime.
getSceneGraph
¶
getStateByMap
¶
getStateByMap(joints: Mapping[str, float], floating_joints: Mapping[str, Isometry3d] = {}) -> tesseract_robotics.tesseract_state_solver._tesseract_state_solver.SceneState
getStateByNamesAndValues
¶
getStateByNamesAndValues(joint_names: Sequence[str], joint_values: Annotated[NDArray[float64], dict(shape=(None,), writable=False)] | Sequence[float], floating_joints: Mapping[str, Isometry3d] = {}) -> tesseract_robotics.tesseract_state_solver._tesseract_state_solver.SceneState
setStateByNamesAndValues
¶
setStateByNamesAndValues(joint_names: Sequence[str], joint_values: Annotated[NDArray[float64], dict(shape=(None,), writable=False)] | Sequence[float], floating_joints: Mapping[str, Isometry3d] = {}) -> None
getStateSolver
¶
getStateSolver() -> tesseract_robotics.tesseract_state_solver._tesseract_state_solver.StateSolver
getCurrentJointValuesByNames
¶
getCurrentJointValuesByNames(joint_names: Sequence[str]) -> Annotated[NDArray[numpy.float64], dict(shape=(None,), order=C)]
getLinkTransform
¶
getLinkTransform(link_name: str) -> tesseract_robotics.tesseract_common._tesseract_common.Isometry3d
getRelativeLinkTransform
¶
getRelativeLinkTransform(from_link_name: str, to_link_name: str) -> tesseract_robotics.tesseract_common._tesseract_common.Isometry3d
getJointLimits
¶
getJointLimits(joint_name: str) -> tesseract_robotics.tesseract_scene_graph._tesseract_scene_graph.JointLimits
getContactManagersPluginInfo
¶
getContactManagersPluginInfo() -> tesseract_robotics.tesseract_common._tesseract_common.ContactManagersPluginInfo
getLink
¶
getJoint
¶
getKinematicGroup
¶
getKinematicGroup(group_name: str, ik_solver_name: str = '') -> tesseract_robotics.tesseract_kinematics._tesseract_kinematics.KinematicGroup
findTCPOffset
¶
findTCPOffset(manip_info: ManipulatorInfo) -> tesseract_robotics.tesseract_common._tesseract_common.Isometry3d
addFindTCPOffsetCallback
¶
Register fn(manip_info) -> Isometry3d as a source of TCP offsets for findTCPOffset.
findTCPOffset asks the callbacks, in registration order, only for a tcp_offset name that is neither an Isometry3d, a link, nor a group TCP of manip_info.manipulator. clone() copies the callbacks, and the environment keeps fn alive.
A callback that raises, or returns anything but an Isometry3d (None included), counts as "not located": findTCPOffset tries the next one and raises RuntimeError ("Could not find tcp by name ...") when none returns a transform. The callback's own exception is not reported (upstream catches it with catch (...)).
fn may run on any thread, under this environment's lock: it must not call into this environment, and must not keep it alive itself (a closure over it, or an attribute holding it): the environment keeps fn alive from C++, so the garbage collector cannot see that cycle.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fn
|
Callable[[ManipulatorInfo], Isometry3d]
|
Callable taking the |
required |
getAllowedCollisionMatrix
¶
getAllowedCollisionMatrix() -> tesseract_robotics.tesseract_common._tesseract_common.AllowedCollisionMatrix
getCollisionMarginData
¶
getCollisionMarginData() -> tesseract_robotics.tesseract_common._tesseract_common.CollisionMarginData
getResourceLocator
¶
getKinematicsInformation
¶
getKinematicsInformation() -> tesseract_robotics.tesseract_srdf._tesseract_srdf.KinematicsInformation
cast_CommandAppliedEvent
¶
Downcast an Event to CommandAppliedEvent. Raises EventTypeError if evt.type is not COMMAND_APPLIED.
cast_SceneStateChangedEvent
¶
Downcast an Event to SceneStateChangedEvent. Raises EventTypeError if evt.type is not SCENE_STATE_CHANGED.
checkTrajectorySegment
¶
checkTrajectorySegment(manager: ContinuousContactManager, state0: Mapping[str, Isometry3d], state1: Mapping[str, Isometry3d], contact_request: ContactRequest) -> tesseract_robotics.tesseract_collision._tesseract_collision.ContactResultMap