embodichain.toolkits

Contents

embodichain.toolkits#

Submodules

graspkit

urdf_assembly

GraspKit — Parallel-Gripper Grasp Sampling#

The embodichain.toolkits.graspkit.pg_grasp module provides a complete pipeline for generating antipodal grasp poses for parallel-jaw grippers. The pipeline consists of three stages:

  1. Antipodal sampling — Surface points are uniformly sampled on the mesh and rays are cast to find antipodal point pairs on opposite sides.

  2. Pose construction — For each antipodal pair, a 6-DoF grasp frame is built aligned with the approach direction.

  3. Filtering & ranking — Grasp candidates that cause the gripper to collide with the object are discarded; survivors are scored by a weighted cost.

Public API

The main entry point is GraspGenerator. It is configured via GraspGeneratorCfg and GripperCollisionCfg.

GraspGenerator

Antipodal grasp-pose generator for parallel-jaw grippers.

GraspGeneratorCfg

Configuration for GraspGenerator.

AntipodalSampler

AntipodalSampler samples antipodal point pairs on a given mesh.

AntipodalSamplerCfg

Configuration for AntipodalSampler.

GripperCollisionChecker

GripperCollisionCfg

Configuration for the GripperCollisionChecker.

ConvexCollisionChecker

ConvexCollisionChecker performs efficient collision checking between a batch of query point clouds and a convex decomposition of a mesh.

ConvexCollisionCheckerCfg

Configuration for ConvexCollisionChecker.

GraspGenerator#

class embodichain.toolkits.graspkit.pg_grasp.GraspGenerator[source]#

Bases: object

Antipodal grasp-pose generator for parallel-jaw grippers.

Given an object mesh, GraspGenerator produces feasible grasp poses through a three-stage pipeline:

  1. Antipodal sampling — Surface points are uniformly sampled and rays are cast along (and near) the inward normal to find antipodal point pairs on opposite sides of the mesh (generate()). Alternatively, an interactive Viser-based annotator lets a human select the graspable region (annotate()).

  2. Pose construction — For each antipodal pair, a 6-DoF grasp frame is built so that the gripper opening aligns with the pair axis and the approach direction is consistent with a user-specified vector (get_grasp_poses()).

  3. Filtering & ranking — Grasp candidates that would cause the gripper to collide with the object are discarded. Surviving poses are scored by a weighted cost that penalises angular deviation from the approach direction, narrow opening length, and distance to the mesh centroid.

Typical usage:

generator = GraspGenerator(vertices, triangles, cfg=cfg)

# Programmatic: sample on the whole mesh or a sub-region
generator.generate()                       # whole mesh
generator.generate(face_indices=some_idx)  # specific faces

# Interactive: pick region in a browser UI
generator.annotate()

# Then compute the best grasp pose
pose, open_length = generator.get_grasp_poses(object_pose, approach_dir)

Methods:

__init__(vertices, triangles[, cfg, ...])

Initialize the GraspGenerator with the given mesh vertices, triangles, and configuration.

__new__(**kwargs)

annotate()

Annotate antipodal grasp region on the mesh and return sampled antipodal point pairs.

generate([vertex_indices, face_indices])

Generate antipodal point pairs for grasping on the given mesh region.

get_grasp_poses(object_pose, approach_direction)

Get grasp pose given approach direction.

__init__(vertices, triangles, cfg=GraspGeneratorCfg(viser_port=15531, use_largest_connected_component=False, antipodal_sampler_cfg=AntipodalSamplerCfg(n_sample=20000, max_angle=0.2617993877991494, max_length=0.1, min_length=0.001), max_deviation_angle=0.2617993877991494), gripper_collision_cfg=GripperCollisionCfg(max_open_length=0.1, finger_length=0.08, y_thickness=0.03, x_thickness=0.01, root_z_width=0.08, point_sample_dense=0.01, max_decomposition_hulls=16, open_check_margin=0.01))[source]#

Initialize the GraspGenerator with the given mesh vertices, triangles, and configuration. :type vertices: Tensor :param vertices: A tensor of shape (V, 3) representing the vertex positions of the mesh. :type vertices: torch.Tensor :type triangles: Tensor :param triangles: A tensor of shape (F, 3) representing the triangle indices of the mesh. :type triangles: torch.Tensor :type cfg: GraspGeneratorCfg :param cfg: Configuration for the grasp annotator. Defaults to GraspGeneratorCfg(). :type cfg: GraspGeneratorCfg, optional

__new__(**kwargs)#
annotate()[source]#

Annotate antipodal grasp region on the mesh and return sampled antipodal point pairs.

Returns:

A tensor of shape (N, 2, 3) representing N antipodal point pairs.

Each pair consists of a hit point and its corresponding surface point.

Return type:

torch.Tensor

generate(vertex_indices=None, face_indices=None)[source]#

Generate antipodal point pairs for grasping on the given mesh region.

Exactly one of vertex_indices or face_indices must be provided to define the grasp region. When both are None, the whole mesh is used.

Results are cached to disk.

Parameters:
  • vertex_indices (Optional[Tensor]) – 1-D torch.Tensor of vertex indices defining the grasp region.

  • face_indices (Optional[Tensor]) – 1-D torch.Tensor of face indices defining the grasp region.

Raises:

ValueError – If both vertex_indices and face_indices are provided at the same time.

Returns:

A tensor of shape (N, 2, 3) representing N

antipodal point pairs. Each pair consists of a hit point and its corresponding surface point.

Return type:

torch.Tensor

get_grasp_poses(object_pose, approach_direction, visualize_collision=False, visualize_pose=False)[source]#

Get grasp pose given approach direction.

Uses the antipodal point pairs stored in self._hit_point_pairs (populated by generate() or annotate()).

Parameters:
  • object_pose (Tensor) – (4, 4) homogeneous transformation matrix representing the pose of the object in the world frame.

  • approach_direction (Tensor) – (3,) unit vector representing the desired approach direction of the gripper in the world frame.

  • visualize_collision (bool) – If True, enable visual collision checking.

  • visualize_pose (bool) – If True, visualize the best grasp pose using Open3D after computation.

Returns:

Whether a valid grasp pose is found. best_grasp_pose (torch.Tensor): If a valid grasp pose is found, a tensor of shape (4, 4) representing the homogeneous transformation matrix of the best grasp pose in the world frame. Otherwise, an identity matrix. best_open_length (float): If a valid grasp pose is found, a scalar representing the optimal gripper opening length. Otherwise, a zero tensor.

Return type:

is_success (bool)

Raises:

RuntimeError – If generate() or annotate() has not been called yet.

GraspGeneratorCfg#

class embodichain.toolkits.graspkit.pg_grasp.GraspGeneratorCfg[source]#

Bases: object

Configuration for GraspGenerator.

Controls the interactive grasp region annotation workflow, including the browser-based visualizer settings, antipodal sampling parameters, and grasp-pose filtering thresholds.

Methods:

__init__([viser_port, ...])

copy(**kwargs)

Return a new object replacing specified fields with new values.

replace(**kwargs)

Return a new object replacing specified fields with new values.

to_dict()

Convert an object into dictionary recursively.

validate([prefix])

Check the validity of configclass object.

Attributes:

antipodal_sampler_cfg

Nested configuration for the antipodal point sampler.

max_deviation_angle

Maximum allowed angle (in radians) between the specified approach direction and the axis connecting an antipodal point pair.

use_largest_connected_component

When True, only the largest connected component of the selected mesh region is retained.

viser_port

Port used by the Viser browser-based visualizer for interactive grasp region annotation.

__init__(viser_port=<factory>, use_largest_connected_component=<factory>, antipodal_sampler_cfg=<factory>, max_deviation_angle=<factory>)#
antipodal_sampler_cfg: AntipodalSamplerCfg#

Nested configuration for the antipodal point sampler. Controls the number of sampled surface points, ray perturbation angle, and gripper jaw distance limits. See AntipodalSamplerCfg for details.

copy(**kwargs)#

Return a new object replacing specified fields with new values.

This is especially useful for frozen classes. Example usage:

@configclass(frozen=True)
class C:
    x: int
    y: int

c = C(1, 2)
c1 = c.replace(x=3)
assert c1.x == 3 and c1.y == 2
Parameters:
  • obj (object) – The object to replace.

  • **kwargs – The fields to replace and their new values.

Return type:

object

Returns:

The new object.

max_deviation_angle: float#

Maximum allowed angle (in radians) between the specified approach direction and the axis connecting an antipodal point pair. Pairs that deviate more than this threshold from perpendicular to the approach are discarded during grasp pose computation.

replace(**kwargs)#

Return a new object replacing specified fields with new values.

This is especially useful for frozen classes. Example usage:

@configclass(frozen=True)
class C:
    x: int
    y: int

c = C(1, 2)
c1 = c.replace(x=3)
assert c1.x == 3 and c1.y == 2
Parameters:
  • obj (object) – The object to replace.

  • **kwargs – The fields to replace and their new values.

Return type:

object

Returns:

The new object.

to_dict()#

Convert an object into dictionary recursively.

Note

Ignores all names starting with “__” (i.e. built-in methods).

Parameters:

obj (object) – An instance of a class to convert.

Raises:

ValueError – When input argument is not an object.

Return type:

dict[str, Any]

Returns:

Converted dictionary mapping.

use_largest_connected_component: bool#

When True, only the largest connected component of the selected mesh region is retained. Useful for meshes that contain disconnected fragments or when selecting a local feature such as a handle.

validate(prefix='')#

Check the validity of configclass object.

This function checks if the object is a valid configclass object. A valid configclass object contains no MISSING entries.

Parameters:
  • obj (object) – The object to check.

  • prefix (str) – The prefix to add to the missing fields. Defaults to ‘’.

Return type:

list[str]

Returns:

A list of missing fields.

Raises:

TypeError – When the object is not a valid configuration object.

viser_port: int#

Port used by the Viser browser-based visualizer for interactive grasp region annotation.

AntipodalSampler#

class embodichain.toolkits.graspkit.pg_grasp.AntipodalSampler[source]#

Bases: object

AntipodalSampler samples antipodal point pairs on a given mesh. It uses Open3D’s raycasting functionality to find points on the mesh that are visible along the negative normal direction from uniformly sampled points on the mesh surface. The sampler can also apply a random disturbance to the ray direction to increase the diversity of sampled antipodal points. The resulting antipodal point pairs can be used for grasp generation and annotation tasks.

Methods:

__init__([cfg])

__new__(**kwargs)

sample(vertices, faces)

Get sample Antipodal point pair

__init__(cfg=AntipodalSamplerCfg(n_sample=20000, max_angle=0.2617993877991494, max_length=0.1, min_length=0.001))[source]#
__new__(**kwargs)#
sample(vertices, faces)[source]#

Get sample Antipodal point pair

Parameters:
  • vertices (Tensor) – [V, 3] vertex positions of the mesh

  • faces (Tensor) – [F, 3] triangle indices of the mesh

Returns:

[N, 2, 3] tensor of N antipodal point pairs. Each pair consists of a hit point and its corresponding surface point.

Return type:

hit_point_pairs

AntipodalSamplerCfg#

class embodichain.toolkits.graspkit.pg_grasp.AntipodalSamplerCfg[source]#

Bases: object

Configuration for AntipodalSampler.

Methods:

__init__([n_sample, max_angle, max_length, ...])

copy(**kwargs)

Return a new object replacing specified fields with new values.

replace(**kwargs)

Return a new object replacing specified fields with new values.

to_dict()

Convert an object into dictionary recursively.

validate([prefix])

Check the validity of configclass object.

Attributes:

max_angle

maximum angle (in radians) to randomly disturb the ray direction for antipodal point sampling, used to increase the diversity of sampled antipodal points.

max_length

maximum gripper open width, used to filter out antipodal points that are too far apart to be grasped

min_length

minimum gripper open width, used to filter out antipodal points that are too close to be grasped

n_sample

surface point sample number

__init__(n_sample=<factory>, max_angle=<factory>, max_length=<factory>, min_length=<factory>)#
copy(**kwargs)#

Return a new object replacing specified fields with new values.

This is especially useful for frozen classes. Example usage:

@configclass(frozen=True)
class C:
    x: int
    y: int

c = C(1, 2)
c1 = c.replace(x=3)
assert c1.x == 3 and c1.y == 2
Parameters:
  • obj (object) – The object to replace.

  • **kwargs – The fields to replace and their new values.

Return type:

object

Returns:

The new object.

max_angle: float#

maximum angle (in radians) to randomly disturb the ray direction for antipodal point sampling, used to increase the diversity of sampled antipodal points. Note that setting max_angle to 0 will disable the random disturbance and sample antipodal points strictly along the surface normals, which may result in less diverse antipodal points and may not be ideal for all objects or grasping scenarios.

max_length: float#

maximum gripper open width, used to filter out antipodal points that are too far apart to be grasped

min_length: float#

minimum gripper open width, used to filter out antipodal points that are too close to be grasped

n_sample: int#

surface point sample number

replace(**kwargs)#

Return a new object replacing specified fields with new values.

This is especially useful for frozen classes. Example usage:

@configclass(frozen=True)
class C:
    x: int
    y: int

c = C(1, 2)
c1 = c.replace(x=3)
assert c1.x == 3 and c1.y == 2
Parameters:
  • obj (object) – The object to replace.

  • **kwargs – The fields to replace and their new values.

Return type:

object

Returns:

The new object.

to_dict()#

Convert an object into dictionary recursively.

Note

Ignores all names starting with “__” (i.e. built-in methods).

Parameters:

obj (object) – An instance of a class to convert.

Raises:

ValueError – When input argument is not an object.

Return type:

dict[str, Any]

Returns:

Converted dictionary mapping.

validate(prefix='')#

Check the validity of configclass object.

This function checks if the object is a valid configclass object. A valid configclass object contains no MISSING entries.

Parameters:
  • obj (object) – The object to check.

  • prefix (str) – The prefix to add to the missing fields. Defaults to ‘’.

Return type:

list[str]

Returns:

A list of missing fields.

Raises:

TypeError – When the object is not a valid configuration object.

GripperCollisionChecker#

class embodichain.toolkits.graspkit.pg_grasp.GripperCollisionChecker[source]#

Bases: object

Methods:

__init__(object_mesh_verts, object_mesh_faces)

__new__(**kwargs)

__init__(object_mesh_verts, object_mesh_faces, cfg=GripperCollisionCfg(max_open_length=0.1, finger_length=0.08, y_thickness=0.03, x_thickness=0.01, root_z_width=0.08, point_sample_dense=0.01, max_decomposition_hulls=16, open_check_margin=0.01))[source]#
__new__(**kwargs)#

GripperCollisionCfg#

class embodichain.toolkits.graspkit.pg_grasp.GripperCollisionCfg[source]#

Bases: object

Configuration for the GripperCollisionChecker. This class defines various parameters related to the gripper geometry, point cloud generation, and collision checking process. Users can customize these parameters based on the specific gripper being modeled and the requirements of the application.

Methods:

__init__([max_open_length, finger_length, ...])

copy(**kwargs)

Return a new object replacing specified fields with new values.

replace(**kwargs)

Return a new object replacing specified fields with new values.

to_dict()

Convert an object into dictionary recursively.

validate([prefix])

Check the validity of configclass object.

Attributes:

finger_length

Length of the gripper fingers from the root to the tip, in z axis.

max_decomposition_hulls

Maximum number of convex hulls to decompose the object mesh into for collision checking.

max_open_length

Maximum opening length of the gripper fingers.

open_check_margin

Additional margin added to the gripper open length when checking for collisions.

point_sample_dense

Approximate number of points per unit length for the gripper point cloud.

root_z_width

Width of the gripper root along the Z-axis (the axis along the finger length direction).

x_thickness

Thickness of the gripper along the X-axis (the axis parallel to the finger opening direction).

y_thickness

Thickness of the gripper along the Y-axis (the axis perpendicular to the finger opening direction).

__init__(max_open_length=<factory>, finger_length=<factory>, y_thickness=<factory>, x_thickness=<factory>, root_z_width=<factory>, point_sample_dense=<factory>, max_decomposition_hulls=<factory>, open_check_margin=<factory>)#
copy(**kwargs)#

Return a new object replacing specified fields with new values.

This is especially useful for frozen classes. Example usage:

@configclass(frozen=True)
class C:
    x: int
    y: int

c = C(1, 2)
c1 = c.replace(x=3)
assert c1.x == 3 and c1.y == 2
Parameters:
  • obj (object) – The object to replace.

  • **kwargs – The fields to replace and their new values.

Return type:

object

Returns:

The new object.

finger_length: float#

Length of the gripper fingers from the root to the tip, in z axis. This should be set according to the specific gripper being modeled, and it defines how far the fingers extend from the gripper root frame.

max_decomposition_hulls: int#

Maximum number of convex hulls to decompose the object mesh into for collision checking. This should be set based on the complexity of the object geometry and the desired accuracy of collision checking. More hulls can provide a tighter approximation of the object shape but will increase computational cost.

max_open_length: float#

Maximum opening length of the gripper fingers. This should be set according to the specific gripper being modeled, and it defines the maximum distance between the two fingers when fully open.

open_check_margin: float#

Additional margin added to the gripper open length when checking for collisions. This can help account for uncertainties in the gripper pose or object geometry, and can be set based on the specific requirements of the application.

point_sample_dense: float#

Approximate number of points per unit length for the gripper point cloud. Higher values will yield denser point clouds, which can improve collision checking accuracy but also increase computational cost. This should be set based on the desired balance between accuracy and efficiency for the specific application.

replace(**kwargs)#

Return a new object replacing specified fields with new values.

This is especially useful for frozen classes. Example usage:

@configclass(frozen=True)
class C:
    x: int
    y: int

c = C(1, 2)
c1 = c.replace(x=3)
assert c1.x == 3 and c1.y == 2
Parameters:
  • obj (object) – The object to replace.

  • **kwargs – The fields to replace and their new values.

Return type:

object

Returns:

The new object.

root_z_width: float#

Width of the gripper root along the Z-axis (the axis along the finger length direction). This should be set according to the specific gripper being modeled, and it defines how far the root extends along the Z direction.

to_dict()#

Convert an object into dictionary recursively.

Note

Ignores all names starting with “__” (i.e. built-in methods).

Parameters:

obj (object) – An instance of a class to convert.

Raises:

ValueError – When input argument is not an object.

Return type:

dict[str, Any]

Returns:

Converted dictionary mapping.

validate(prefix='')#

Check the validity of configclass object.

This function checks if the object is a valid configclass object. A valid configclass object contains no MISSING entries.

Parameters:
  • obj (object) – The object to check.

  • prefix (str) – The prefix to add to the missing fields. Defaults to ‘’.

Return type:

list[str]

Returns:

A list of missing fields.

Raises:

TypeError – When the object is not a valid configuration object.

x_thickness: float#

Thickness of the gripper along the X-axis (the axis parallel to the finger opening direction). This should be set according to the specific gripper being modeled, and it defines the thickness of the fingers and the root in the X direction.

y_thickness: float#

Thickness of the gripper along the Y-axis (the axis perpendicular to the finger opening direction). This should be set according to the specific gripper being modeled, and it defines the width of the gripper’s main body and fingers in the Y direction.

ConvexCollisionChecker#

class embodichain.toolkits.graspkit.pg_grasp.ConvexCollisionChecker[source]#

Bases: object

ConvexCollisionChecker performs efficient collision checking between a batch of query point clouds and a convex decomposition of a mesh. The convex decomposition is represented by plane equations of the convex hulls, which are precomputed and cached for efficiency. The collision checking is done by computing the signed distance from each query point to the convex hulls using the plane equations, and determining if any points are colliding based on a specified collision threshold. This class can be used

Methods:

__init__(base_mesh_verts, base_mesh_faces[, ...])

Initialize the ConvexCollisionChecker by performing convex decomposition on the input mesh and extracting plane equations for the convex hulls.

__new__(**kwargs)

__init__(base_mesh_verts, base_mesh_faces, max_decomposition_hulls=32)[source]#

Initialize the ConvexCollisionChecker by performing convex decomposition on the input mesh and extracting plane equations for the convex hulls. The plane equations are cached to disk to avoid redundant computation in future runs.

Parameters:
  • base_mesh_verts (Tensor) – [N, 3] vertex positions of the input mesh.

  • base_mesh_faces (Tensor) – [M, 3] triangle indices of the input mesh.

  • max_decomposition_hulls (int) – maximum number of convex hulls to decompose into. A higher number allows for a more accurate approximation of the original mesh but increases computation time and memory usage. The optimal number may depend on the complexity of the mesh and the required precision of collision checking.

__new__(**kwargs)#

ConvexCollisionCheckerCfg#

class embodichain.toolkits.graspkit.pg_grasp.ConvexCollisionCheckerCfg[source]#

Bases: object

Configuration for ConvexCollisionChecker.

Methods:

__init__([collision_threshold, ...])

copy(**kwargs)

Return a new object replacing specified fields with new values.

replace(**kwargs)

Return a new object replacing specified fields with new values.

to_dict()

Convert an object into dictionary recursively.

validate([prefix])

Check the validity of configclass object.

Attributes:

collision_threshold

Collision threshold in meters.

debug

Whether to visualize the collision checking results for debugging purposes.

n_query_mesh_samples

Number of points to sample from the query mesh surface for collision checking.

__init__(collision_threshold=<factory>, n_query_mesh_samples=<factory>, debug=<factory>)#
collision_threshold: float#

Collision threshold in meters. A point is considered colliding if its signed distance to the hull interior is <= this threshold. This allows for a margin of error in collision checking, where a small positive threshold can be used to consider points near the surface as colliding, and a small negative threshold can be used to allow for slight penetration without considering it a collision.

copy(**kwargs)#

Return a new object replacing specified fields with new values.

This is especially useful for frozen classes. Example usage:

@configclass(frozen=True)
class C:
    x: int
    y: int

c = C(1, 2)
c1 = c.replace(x=3)
assert c1.x == 3 and c1.y == 2
Parameters:
  • obj (object) – The object to replace.

  • **kwargs – The fields to replace and their new values.

Return type:

object

Returns:

The new object.

debug: bool#

Whether to visualize the collision checking results for debugging purposes. If set to True, the code will generate visualizations of the query points colored by their collision status (e.g., red for colliding points and green for non-colliding points) along with the original mesh. This can help in understanding and verifying the collision checking process, especially during development and testing.

n_query_mesh_samples: int#

Number of points to sample from the query mesh surface for collision checking. A higher number of samples can provide a more accurate collision check at the cost of increased computation time. The optimal number may depend on the complexity of the mesh and the required precision of collision detection.

replace(**kwargs)#

Return a new object replacing specified fields with new values.

This is especially useful for frozen classes. Example usage:

@configclass(frozen=True)
class C:
    x: int
    y: int

c = C(1, 2)
c1 = c.replace(x=3)
assert c1.x == 3 and c1.y == 2
Parameters:
  • obj (object) – The object to replace.

  • **kwargs – The fields to replace and their new values.

Return type:

object

Returns:

The new object.

to_dict()#

Convert an object into dictionary recursively.

Note

Ignores all names starting with “__” (i.e. built-in methods).

Parameters:

obj (object) – An instance of a class to convert.

Raises:

ValueError – When input argument is not an object.

Return type:

dict[str, Any]

Returns:

Converted dictionary mapping.

validate(prefix='')#

Check the validity of configclass object.

This function checks if the object is a valid configclass object. A valid configclass object contains no MISSING entries.

Parameters:
  • obj (object) – The object to check.

  • prefix (str) – The prefix to add to the missing fields. Defaults to ‘’.

Return type:

list[str]

Returns:

A list of missing fields.

Raises:

TypeError – When the object is not a valid configuration object.

URDF Assembly Tool#

Classes:

URDFAssemblyManager

A class to manage the assembly of URDF files and their components.

class embodichain.toolkits.urdf_assembly.URDFAssemblyManager[source]#

Bases: object

A class to manage the assembly of URDF files and their components.

Attributes:

SUPPORTED_COMPONENTS

SUPPORTED_MESH_TYPES

SUPPORTED_SENSORS

SUPPORTED_WHEEL_TYPES

component_order_and_prefix

Get the internal component order with their name prefixes.

component_prefix

Configure name prefixes per component type.

name_case

Get the current name case policy for joints and links.

Methods:

__init__([component_registry, ...])

add_component(component_type, urdf_path[, ...])

Add a URDF component to the component registry.

attach_sensor(sensor_name, sensor_source, ...)

Attach a sensor to a specific component and link, and register it in the sensor registry.

get_attached_sensors()

Get all attached sensors from the sensor registry.

get_component(component_type)

Retrieve a component from the registry by its type/name.

merge_urdfs([output_path, use_signature_check])

Merge URDF files according to single base link, connection point naming, and type compatibility matrix rules.

SUPPORTED_COMPONENTS = ['chassis', 'legs', 'torso', 'head', 'left_arm', 'right_arm', 'left_hand', 'right_hand', 'arm', 'hand']#
SUPPORTED_MESH_TYPES = ['stl', 'obj', 'ply', 'dae', 'glb']#
SUPPORTED_SENSORS = ['camera', 'lidar', 'imu', 'gps', 'force']#
SUPPORTED_WHEEL_TYPES = ['omni', 'differential', 'tracked']#
__init__(component_registry=None, sensor_registry=None, mesh_manager=None, component_manager=None, sensor_manager=None)[source]#
add_component(component_type, urdf_path, transform=None, **params)[source]#

Add a URDF component to the component registry.

This method creates a URDFComponent object and registers it in the component registry.

Parameters:
  • component_type (str) – The type/name of the component (e.g., ‘chassis’, ‘head’).

  • urdf_path (str or Path) – Path to the URDF file for this component.

  • transform (np.ndarray, optional) – 4x4 transformation matrix for positioning the component.

  • **params – Additional component-specific parameters (e.g., wheel_type for chassis).

Returns:

True if component added successfully, False otherwise.

Return type:

bool

attach_sensor(sensor_name, sensor_source, parent_component, parent_link, transform=None, **kwargs)[source]#

Attach a sensor to a specific component and link, and register it in the sensor registry.

This method creates a SensorAttachment object and registers it in the sensor registry.

Parameters:
  • sensor_name (str) – Unique name for the sensor (e.g., ‘camera’).

  • sensor_source (str or ET.Element) – Path to the sensor’s URDF file or an XML element.

  • parent_component (str) – Name of the component to which the sensor is attached.

  • parent_link (str) – Name of the link within the parent component for attachment.

  • **kwargs – Additional keyword arguments (e.g., transform, sensor_type).

Returns:

True if sensor attached successfully, False otherwise.

Return type:

bool

property component_order_and_prefix#

Get the internal component order with their name prefixes.

Note

This exposes the internal list of (component_name, prefix) pairs used when assembling URDFs. In most user code it is recommended to use component_prefix instead, which focuses on configuring prefixes rather than ordering.

Returns:

A list of tuples specifying component names and their prefixes.

Return type:

list[tuple[str, str | None]]

property component_prefix#

Configure name prefixes per component type.

This is a user-facing alias over component_order_and_prefix.

Semantics:

This setter is patch-only: it updates prefixes for components that already exist in the current internal order and does not allow introducing new component names.

Returns:

The internal list of (component_name, prefix) pairs.

Return type:

list[tuple[str, str | None]]

get_attached_sensors()[source]#

Get all attached sensors from the sensor registry.

Returns:

A dictionary mapping sensor names to SensorAttachment objects.

Return type:

dict

get_component(component_type)[source]#

Retrieve a component from the registry by its type/name.

Parameters:

component_type (str) – The type/name of the component to retrieve.

Returns:

The registered component object, or None if not found.

Return type:

URDFComponent or None

merge_urdfs(output_path='./assembly_robot.urdf', use_signature_check=True)[source]#

Merge URDF files according to single base link, connection point naming, and type compatibility matrix rules.

Parameters:
  • output_path (str) – Path where the merged URDF file will be saved.

  • use_signature_check (bool) – Whether to check signatures to avoid redundant processing.

Returns:

The root element of the merged URDF.

Return type:

ET.Element

property name_case#

Get the current name case policy for joints and links.

Returns:

A dictionary mapping ‘joint’ and ‘link’ to their respective case modes.

Return type:

dict[str, str]