embodichain.lab.sim.motion.workspace.visualizers#
Workspace result visualizers deriving from BaseVisualizer.
Built-in visualizers: point-cloud, voxel, sphere, axis, and manipulability, plus a VisualizerFactory and create_visualizer helper.
The manipulability path additionally exports its pure mapping helpers
(align_manipulability_scores(), normalize_manipulability(),
map_manipulability_colors(), select_inspection_indices(),
inspect_points(), translational_manipulability_ellipsoid()) so score
mapping can be reused and tested without a renderer.
Classes:
Visualizer for coordinate axes/frames at specified poses. |
|
Abstract base class for all visualizers. |
|
Interface for all visualizers. |
|
Indices chosen for detailed (ellipsoid) inspection. |
|
Colors and normalization for manipulability visualization. |
|
Colors, sizes and normalization metadata for a point set. |
|
Outcome of robust manipulability normalization. |
|
Per-point scores aligned with the points of an analysis result. |
|
Render workspace points colored by manipulability. |
|
Point cloud visualizer using SimulationManager, Viser, or local tools. |
|
Detail record for a single inspected workspace point. |
|
Sphere-based visualizer using Open3D or matplotlib. |
|
Factory class for creating visualizers (Singleton pattern). |
|
Voxel grid visualizer using Open3D or matplotlib. |
Functions:
|
Align a manipulability score vector with the points of an analysis result. |
|
Convenience function to create a visualizer. |
|
Tessellate one ellipsoid for surface plotting. |
|
Build detail records for the selected points only. |
|
Map manipulability scores to RGBA colors and marker sizes. |
|
Normalize manipulability scores to |
|
Choose the few points that deserve a detailed inspection. |
|
Derive translational manipulability ellipsoids from spatial Jacobians. |
- class embodichain.lab.sim.motion.workspace.visualizers.AxisVisualizer[source]#
Bases:
BaseVisualizerVisualizer for coordinate axes/frames at specified poses.
This visualizer creates coordinate axes (X, Y, Z) at given transformation matrices, useful for visualizing robot end-effector poses, workspace reference frames, etc.
Supports multiple backends: - ‘sim_manager’: Uses SimulationManager.draw_marker() with MarkerCfg - ‘open3d’: Creates coordinate frames using Open3D - ‘matplotlib’: Draws axis lines in 3D matplotlib plot - ‘data’: Returns axis data without visualization
Methods:
__init__([backend, axis_length, axis_size, ...])Initialize the axis visualizer.
Return the type name for this visualizer.
visualize(poses[, colors])Visualize coordinate axes at specified poses or points.
- __init__(backend='sim_manager', axis_length=0.15, axis_size=0.005, config=None, sim_manager=None, control_part_name=None, reference_pose=None, arena_index=0)[source]#
Initialize the axis visualizer.
- Parameters:
backend (
str) – Visualization backend (‘sim_manager’, ‘open3d’, ‘matplotlib’, or ‘data’). Defaults to ‘sim_manager’.axis_length (
float) – Length of each axis. Defaults to 0.15.axis_size (
float) – Thickness/size of axes. Defaults to 0.005.config (
Optional[Dict[str,Any]]) – Optional configuration dictionary. Defaults to None.sim_manager (
Any|None) – SimulationManager instance for ‘sim_manager’ backend. Defaults to None.control_part_name (
str|None) – Control part name for naming (compatibility). Defaults to None.reference_pose (
Union[ndarray,Tensor,None]) – Reference pose (4x4 matrix) for orientation. Defaults to None.arena_index (
int) – Arena index for sim_manager markers. Defaults to 0.
- visualize(poses, colors=None, **kwargs)[source]#
Visualize coordinate axes at specified poses or points.
- Parameters:
poses (
Tensor|ndarray) – Either transformation matrices of shape (4, 4) or (N, 4, 4), or point coordinates of shape (N, 3) which will be converted to poses.colors (
Tensor|ndarray|None) – Optional colors (not used for axes but kept for interface compatibility).**kwargs (
Any) – Additional visualization parameters: - axis_length: Override default axis length - axis_size: Override default axis size - name_prefix: Prefix for axis names (default: “axis”) - arena_index: Arena index for sim_manager (default: 0)
- Return type:
Any- Returns:
Backend-specific axis representation.
Examples
>>> import numpy as np >>> visualizer = AxisVisualizer(backend='sim_manager', sim_manager=sim) >>> # Using transformation matrix >>> pose = np.eye(4) >>> pose[:3, 3] = [1.0, 0.5, 1.2] # Set position >>> result = visualizer.visualize(pose) >>> >>> # Using point coordinates >>> points = np.array([[1.0, 0.5, 1.2], [2.0, 1.0, 0.8]]) >>> result = visualizer.visualize(points) >>> visualizer.show()
- class embodichain.lab.sim.motion.workspace.visualizers.BaseVisualizer[source]#
Bases:
ABCAbstract base class for all visualizers.
This class provides common functionality and enforces the implementation of the visualization method in all derived classes.
- backend#
Visualization backend (‘open3d’, ‘matplotlib’, etc.).
- config#
Configuration dictionary for visualization parameters.
Methods:
__init__([backend, config])Initialize the base visualizer.
clear()Clear the current visualization.
from_config(config[, backend])Create a visualizer instance from a VisualizationConfig.
Get the name of the visualization type.
save(filepath, **kwargs)Save the last visualization to file.
show(**kwargs)Display the visualization interactively.
visualize(points[, colors])Visualize the workspace data.
- __init__(backend='open3d', config=None)[source]#
Initialize the base visualizer.
- Parameters:
backend (
str) – Visualization backend to use. Defaults to “open3d”.config (
Optional[Dict[str,Any]]) – Optional configuration dictionary. Defaults to None.
- classmethod from_config(config, backend='open3d')[source]#
Create a visualizer instance from a VisualizationConfig.
- Parameters:
config (
VisualizationConfig) – VisualizationConfig instance with visualization settings.backend (
str) – Visualization backend to use.
- Returns:
Configured visualizer instance.
- abstract get_type_name()[source]#
Get the name of the visualization type.
- Return type:
str- Returns:
String identifier for the visualization type.
- save(filepath, **kwargs)[source]#
Save the last visualization to file.
- Parameters:
filepath (
Union[str,Path]) – Path to save the visualization.**kwargs (
Any) – Additional save parameters.
- Raises:
RuntimeError – If no visualization has been created yet.
- Return type:
None
- show(**kwargs)[source]#
Display the visualization interactively.
- Parameters:
**kwargs (
Any) – Backend-specific display parameters.- Raises:
RuntimeError – If no visualization has been created yet.
- Return type:
None
- abstract visualize(points, colors=None, **kwargs)[source]#
Visualize the workspace data.
This method must be implemented by all derived classes.
- Parameters:
points (
Tensor|ndarray) – Array of shape (N, 3) containing point positions.colors (
Tensor|ndarray|None) – Optional array of shape (N, 3) or (N, 4) containing colors.**kwargs (
Any) – Additional visualization parameters.
- Return type:
Any- Returns:
Visualization object.
- Raises:
NotImplementedError – If the method is not implemented in the derived class.
- class embodichain.lab.sim.motion.workspace.visualizers.IVisualizer[source]#
Bases:
ProtocolInterface for all visualizers.
This protocol defines the contract that all visualizers must follow.
Methods:
__init__(*args, **kwargs)Get the name of the visualization type.
save(filepath, **kwargs)Save visualization to file.
visualize(points[, colors])Visualize the workspace data.
- __init__(*args, **kwargs)#
- get_type_name()[source]#
Get the name of the visualization type.
- Return type:
str- Returns:
String identifier for the visualization type.
- save(filepath, **kwargs)[source]#
Save visualization to file.
- Parameters:
filepath (
Union[str,Path]) – Path to save the visualization.**kwargs (
Any) – Additional save parameters.
- Return type:
None
- visualize(points, colors=None, **kwargs)[source]#
Visualize the workspace data.
- Parameters:
points (
Tensor|ndarray) – Array of shape (N, 3) containing point positions.colors (
Tensor|ndarray|None) – Optional array of shape (N, 3) or (N, 4) containing colors.**kwargs (
Any) – Additional visualization parameters.
- Return type:
Any- Returns:
Visualization object (e.g., Open3D geometry, matplotlib figure).
- class embodichain.lab.sim.motion.workspace.visualizers.InspectionSelection[source]#
Bases:
objectIndices chosen for detailed (ellipsoid) inspection.
- indices#
Point indices, shape
(K,); ordered explicit selection first, then descending-wpicks, then ascending-wpicks.
- labels#
Per-index origin, one of
"selected","top","bottom".
Methods:
__init__(indices, labels)Attributes:
- __init__(indices, labels)#
-
indices:
ndarray#
-
labels:
tuple[str,...]#
- class embodichain.lab.sim.motion.workspace.visualizers.ManipulabilityColorCfg[source]#
Bases:
objectColors and normalization for manipulability visualization.
Methods:
__init__([colormap, percentile_clip, ...])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:
Matplotlib colormap name used for reachable points.
Lower clamp applied before
log10so exact zeros stay finite.Normalize
log10(w)instead ofw.Lower/upper percentile used as color-scale bounds.
Marker size for reachable points.
Alpha applied to colormap output for reachable points.
RGBA for unreachable points; deliberately desaturated and translucent.
Marker size for unreachable points; smaller so they recede visually.
- __init__(colormap=<factory>, percentile_clip=<factory>, log_scale=<factory>, log_epsilon=<factory>, unreachable_color=<factory>, reachable_alpha=<factory>, point_size=<factory>, unreachable_point_size=<factory>)#
-
colormap:
str# Matplotlib colormap name used for reachable points.
- 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.
-
log_epsilon:
float# Lower clamp applied before
log10so exact zeros stay finite.
-
log_scale:
bool# Normalize
log10(w)instead ofw.Manipulability spans orders of magnitude near singularities; the log scale keeps the interior of the workspace from saturating to a single color.
-
percentile_clip:
tuple[float,float]# Lower/upper percentile used as color-scale bounds.
Robust against the heavy tails of manipulability distributions: a handful of near-singular (
wclose to zero) or exceptionally well-conditioned points would otherwise flatten the whole color range. Use(0.0, 100.0)for a plain min/max scale.
-
point_size:
float# Marker size for reachable points.
-
reachable_alpha:
float# Alpha applied to colormap output for reachable points.
- 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.
-
unreachable_color:
tuple[float,float,float,float]# RGBA for unreachable points; deliberately desaturated and translucent.
-
unreachable_point_size:
float# Marker size for unreachable points; smaller so they recede visually.
- 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.
- class embodichain.lab.sim.motion.workspace.visualizers.ManipulabilityColorMapping[source]#
Bases:
objectColors, sizes and normalization metadata for a point set.
- colors#
RGBA colors, shape
(N, 4).
- sizes#
Marker sizes, shape
(N,).
- reachable_mask#
Boolean mask, shape
(N,).
- normalization#
The normalization that produced
colors.
- colormap#
Colormap name used for reachable points.
Methods:
__init__(colors, sizes, reachable_mask, ...)Attributes:
Color-scale bounds in raw units, forwarded from
normalization.Raw score range, forwarded from
normalization.RGB view of
colors, shape(N, 3).- __init__(colors, sizes, reachable_mask, normalization, colormap)#
- property clip_range: tuple[float, float]#
Color-scale bounds in raw units, forwarded from
normalization.
-
colormap:
str#
-
colors:
ndarray#
-
normalization:
ManipulabilityNormalization#
- property raw_range: tuple[float, float]#
Raw score range, forwarded from
normalization.
-
reachable_mask:
ndarray#
-
sizes:
ndarray#
- class embodichain.lab.sim.motion.workspace.visualizers.ManipulabilityNormalization[source]#
Bases:
objectOutcome of robust manipulability normalization.
- normalized#
Values in
[0, 1], shape(N,);NaNfor entries that carry no score.
- raw_range#
(min, max)of the raw scores over valid entries, before any clipping or log transform.(nan, nan)when nothing is valid.
- clip_range#
(low, high)color-scale bounds expressed in raw score units, i.e. the values that map to normalized0and1.
- log_scale#
Whether the normalization ran on
log10(w).
- num_valid#
Number of entries that contributed to the statistics.
- num_clipped#
Number of valid entries that fell outside
clip_range.
Methods:
__init__(normalized, raw_range, clip_range, ...)Attributes:
- __init__(normalized, raw_range, clip_range, log_scale, num_valid, num_clipped)#
-
clip_range:
tuple[float,float]#
-
log_scale:
bool#
-
normalized:
ndarray#
-
num_clipped:
int#
-
num_valid:
int#
-
raw_range:
tuple[float,float]#
- class embodichain.lab.sim.motion.workspace.visualizers.ManipulabilityPointSet[source]#
Bases:
objectPer-point scores aligned with the points of an analysis result.
- points#
Point positions, shape
(P, 3).
- scores#
Per-point manipulability, shape
(P,).NaNwhere the point is unreachable and therefore has no joint configuration.
- reachable_mask#
Boolean mask, shape
(P,).
- score_indices#
Row of the raw score vector each point maps to, shape
(P,);-1for unreachable points. Use it to indexjoint_configurations.
- joint_configurations#
Joint configurations of the scored points, shape
(M, DOF)withM = reachable_mask.sum(), orNone.
- mode#
Analysis mode string the alignment was derived from.
Methods:
__init__(points, scores, reachable_mask, ...)Attributes:
Number of reachable (scored) points.
Number of points shown but not scored.
- __init__(points, scores, reachable_mask, score_indices, joint_configurations=None, mode='')#
-
joint_configurations:
ndarray|None= None#
-
mode:
str= ''#
- property num_reachable: int#
Number of reachable (scored) points.
- property num_unreachable: int#
Number of points shown but not scored.
-
points:
ndarray#
-
reachable_mask:
ndarray#
-
score_indices:
ndarray#
-
scores:
ndarray#
- class embodichain.lab.sim.motion.workspace.visualizers.ManipulabilityVisualizer[source]#
Bases:
BaseVisualizerRender workspace points colored by manipulability.
The visualizer owns no numerics of its own: it calls
map_manipulability_colors()and then either draws a Matplotlib figure with a visible color bar, forwards the colors to a point-cloud backend, or returns the mapping arrays.- color_cfg#
Color and normalization configuration.
- sim_manager#
Simulation manager used by the forwarding backends.
- control_part_name#
Control part name used to name forwarded point clouds.
- scores#
Default score vector used when
visualizeis called without one, so generic callers such asWorkspaceAnalyzer.visualizecan supply the scores at construction time.
Methods:
__init__([backend, color_cfg, config, ...])Initialize the manipulability visualizer.
Return the registered visualization type name.
map_colors(scores[, reachable_mask])Map scores to colors using this visualizer's configuration.
visualize(points[, colors])Visualize points colored by manipulability.
visualize_inspection(inspections, **kwargs)Draw the detail view for inspected points.
- __init__(backend='matplotlib', color_cfg=None, config=None, sim_manager=None, control_part_name=None, scores=None, reachable_mask=None)[source]#
Initialize the manipulability visualizer.
- Parameters:
backend (
str) – One of'matplotlib','data','open3d','viser'or'sim_manager'. Defaults to'matplotlib'because the color bar is the point of this visualization.color_cfg (
ManipulabilityColorCfg|None) – Color and normalization configuration.config (
Optional[Dict[str,Any]]) – Optional generic visualizer configuration dictionary.sim_manager (
Any|None) – SimulationManager for the forwarding backends.control_part_name (
str|None) – Control part name used when forwarding.scores (
Tensor|ndarray|None) – Default per-point manipulability scores.reachable_mask (
Tensor|ndarray|None) – Default reachability mask forscores.
- map_colors(scores, reachable_mask=None)[source]#
Map scores to colors using this visualizer’s configuration.
- Parameters:
scores (
Tensor|ndarray) – Per-point scores, shape(N,).reachable_mask (
ndarray|None) – Optional reachability mask, shape(N,).
- Return type:
- Returns:
- visualize(points, colors=None, **kwargs)[source]#
Visualize points colored by manipulability.
Scores win over
colors: this visualizer exists to color by manipulability, so a generic caller that also passes reachability colors (asWorkspaceAnalyzer.visualizedoes) still gets the manipulability mapping.colorsis used only when no scores are available.- Parameters:
points (
Tensor|ndarray) – Point positions, shape(N, 3).colors (
Tensor|ndarray|None) – Precomputed colors, used only as a fallback when no scores are available.**kwargs (
Any) –Additional parameters:
scores: per-point manipulability, shape(N,)or(M,)together with a(N,)reachable_maskselectingMpoints. Defaults toscores.reachable_mask: boolean mask, shape(N,).point_set: aManipulabilityPointSetprovidingpoints/scores/reachable_maskin one object.title: figure title (Matplotlib backend).highlight: indices to mark with a cross (Matplotlib).elev/azim: 3D view angles (Matplotlib).
- Return type:
Any- Returns:
A Matplotlib figure, a backend-specific handle, or the mapping data dictionary for the
databackend.- Raises:
ValueError – If no scores are supplied and no colors are given, or the backend is unsupported.
- visualize_inspection(inspections, **kwargs)[source]#
Draw the detail view for inspected points.
Each inspected point gets a translational manipulability ellipsoid plus its
w, condition number and joint configuration.- Parameters:
inspections (
Sequence[PointInspection]) – Records frominspect_points().**kwargs (
Any) –Additional parameters:
title: figure title.log_scale: annotatewon a log scale (cosmetic only).elev/azim: 3D view angles.
- Return type:
Any- Returns:
The Matplotlib figure.
- Raises:
ValueError – If
inspectionsis empty, or the backend cannot draw.
- class embodichain.lab.sim.motion.workspace.visualizers.PointCloudVisualizer[source]#
Bases:
BaseVisualizerPoint cloud visualizer using SimulationManager, Viser, or local tools.
- point_size#
Size of points in visualization.
Methods:
__init__([backend, point_size, config, ...])Initialize the point cloud visualizer.
Get the name of the visualization type.
visualize(points[, colors])Visualize points as a point cloud.
- __init__(backend='sim_manager', point_size=2.0, config=None, sim_manager=None, control_part_name=None)[source]#
Initialize the point cloud visualizer.
- Parameters:
backend (
str) – Visualization backend (‘sim_manager’, ‘viser’, ‘open3d’, ‘matplotlib’, or ‘data’). Defaults to ‘sim_manager’. The ‘data’ backend returns raw data without visualization.point_size (
float) – Size of points in visualization. Defaults to 2.0.config (
Optional[Dict[str,Any]]) – Optional configuration dictionary. Defaults to None.sim_manager (
Any|None) – SimulationManager instance for the ‘sim_manager’ or ‘viser’ backend. Defaults to None.control_part_name (
str|None) – Control part name used to name the point cloud. Defaults to None.
- get_type_name()[source]#
Get the name of the visualization type.
- Return type:
str- Returns:
String identifier for the visualization type.
- visualize(points, colors=None, **kwargs)[source]#
Visualize points as a point cloud.
- Parameters:
points (
Tensor|ndarray) – Array of shape (N, 3) containing point positions.colors (
Tensor|ndarray|None) – Optional array of shape (N, 3) or (N, 4) containing colors.**kwargs (
Any) – Additional visualization parameters: - point_size: Override default point size
- Return type:
Any- Returns:
Backend-specific point-cloud handle, Viser overlay, geometry, or matplotlib figure.
Examples
>>> visualizer = PointCloudVisualizer() >>> points = np.random.rand(1000, 3) >>> colors = np.random.rand(1000, 3) >>> pcd = visualizer.visualize(points, colors) >>> visualizer.show()
- class embodichain.lab.sim.motion.workspace.visualizers.PointInspection[source]#
Bases:
objectDetail record for a single inspected workspace point.
- index#
Index into the visualized point set.
- label#
Selection origin (
"selected","top"or"bottom").
- position#
Cartesian position, shape
(3,).
- manipulability#
Yoshikawa index
wat this point.
- condition_number#
Jacobian condition number, or
Nonewhen not requested.
- joint_configuration#
Joint configuration, shape
(DOF,), orNone.
- ellipsoid_radii#
Translational ellipsoid semi-axis lengths in descending order, shape
(3,), orNone.
- ellipsoid_axes#
Principal directions as columns, shape
(3, 3), orNone.
Methods:
__init__(index, label, position, manipulability)Render the inspection as human-readable lines.
Attributes:
Ratio of longest to shortest ellipsoid semi-axis, or
None.- __init__(index, label, position, manipulability, condition_number=None, joint_configuration=None, ellipsoid_radii=None, ellipsoid_axes=None)#
- property anisotropy: float | None#
Ratio of longest to shortest ellipsoid semi-axis, or
None.
-
condition_number:
float|None= None#
-
ellipsoid_axes:
ndarray|None= None#
-
ellipsoid_radii:
ndarray|None= None#
-
index:
int#
-
joint_configuration:
ndarray|None= None#
-
label:
str#
-
manipulability:
float#
-
position:
ndarray#
- class embodichain.lab.sim.motion.workspace.visualizers.SphereVisualizer[source]#
Bases:
BaseVisualizerSphere-based visualizer using Open3D or matplotlib.
- sphere_radius#
Radius of each sphere.
- sphere_resolution#
Resolution of sphere mesh (higher = smoother).
Methods:
__init__([backend, sphere_radius, ...])Initialize the sphere visualizer.
Get the name of the visualization type.
visualize(points[, colors])Visualize points as spheres.
- __init__(backend='sim_manager', sphere_radius=0.005, sphere_resolution=10, config=None, sim_manager=None, control_part_name=None)[source]#
Initialize the sphere visualizer.
- Parameters:
backend (
str) – Visualization backend (‘sim_manager’, ‘open3d’, ‘matplotlib’, or ‘data’). Defaults to ‘sim_manager’. ‘data’ backend returns sphere data without visualization.sphere_radius (
float) – Radius of each sphere. Defaults to 0.005.sphere_resolution (
int) – Sphere mesh resolution. Defaults to 10.config (
Optional[Dict[str,Any]]) – Optional configuration dictionary. Defaults to None.sim_manager (
Any|None) – SimulationManager instance for ‘sim_manager’ backend. Defaults to None.control_part_name (
str|None) – Control part name for naming. Defaults to None.
- get_type_name()[source]#
Get the name of the visualization type.
- Return type:
str- Returns:
String identifier for the visualization type.
- visualize(points, colors=None, **kwargs)[source]#
Visualize points as spheres.
- Parameters:
points (
Tensor|ndarray) – Array of shape (N, 3) containing point positions.colors (
Tensor|ndarray|None) – Optional array of shape (N, 3) or (N, 4) containing colors.**kwargs (
Any) – Additional visualization parameters: - sphere_radius: Override default sphere radius - sphere_resolution: Override sphere resolution - max_spheres: Maximum number of spheres to render (for performance)
- Return type:
Any- Returns:
Open3D TriangleMesh or matplotlib figure.
Examples
>>> visualizer = SphereVisualizer(sphere_radius=0.01) >>> points = np.random.rand(100, 3) >>> colors = np.random.rand(100, 3) >>> mesh = visualizer.visualize(points, colors) >>> visualizer.show()
- class embodichain.lab.sim.motion.workspace.visualizers.VisualizationType[source]#
Bases:
EnumAttributes:
- AXIS = 'axis'#
- MANIPULABILITY = 'manipulability'#
- POINT_CLOUD = 'point_cloud'#
- SPHERE = 'sphere'#
- VOXEL = 'voxel'#
- class embodichain.lab.sim.motion.workspace.visualizers.VisualizerFactory[source]#
Bases:
objectFactory class for creating visualizers (Singleton pattern).
This factory allows registration and creation of visualizers based on the visualization type. It uses the singleton pattern to ensure only one instance exists throughout the application.
- The factory comes pre-registered with built-in visualizers:
POINT_CLOUD: PointCloudVisualizer
VOXEL: VoxelVisualizer
SPHERE: SphereVisualizer
Additional visualizers can be registered using register_visualizer().
Examples
>>> factory = VisualizerFactory() >>> visualizer = factory.create_visualizer( ... VisualizationType.POINT_CLOUD, ... backend='open3d' ... ) >>> isinstance(visualizer, PointCloudVisualizer) True
>>> # Register custom visualizer >>> factory.register_visualizer("custom", CustomVisualizer) >>> custom_viz = factory.create_visualizer("custom")
Methods:
__init__()Initialize the factory with built-in visualizers.
__new__(cls)Create or return the singleton instance.
create_visualizer([viz_type])Create a visualizer instance based on the type.
is_registered(viz_type)Check if a visualization type is registered.
List all registered visualization types.
register_visualizer(name, visualizer_class)Register a new visualizer class.
Reset the singleton instance (mainly for testing).
- __init__()[source]#
Initialize the factory with built-in visualizers.
This method only runs once due to the singleton pattern.
- static __new__(cls)[source]#
Create or return the singleton instance.
- Returns:
The singleton VisualizerFactory instance.
- create_visualizer(viz_type=None, **kwargs)[source]#
Create a visualizer instance based on the type.
- Parameters:
viz_type (
VisualizationType|str|None) – The visualization type to use. Can be a VisualizationType enum or a string identifier. If None, defaults to POINT_CLOUD.**kwargs (
Any) – Additional keyword arguments to pass to the visualizer constructor. Common options includebackend,voxel_sizeforVoxelVisualizer,sphere_radiusforSphereVisualizer, andpoint_sizeforPointCloudVisualizer.
- Return type:
- Returns:
An instance of the requested visualizer.
- Raises:
ValueError – If the visualization type is not registered.
Examples
>>> factory = VisualizerFactory() >>> viz = factory.create_visualizer( ... VisualizationType.POINT_CLOUD, ... backend='open3d' ... ) >>> viz = factory.create_visualizer("voxel", voxel_size=0.02) >>> viz = factory.create_visualizer() # Uses default (POINT_CLOUD)
- is_registered(viz_type)[source]#
Check if a visualization type is registered.
- Parameters:
viz_type (
VisualizationType|str) – The visualization type to check.- Return type:
bool- Returns:
True if the type is registered, False otherwise.
- list_available_types()[source]#
List all registered visualization types.
- Return type:
list[str]- Returns:
List of registered type names.
- register_visualizer(name, visualizer_class)[source]#
Register a new visualizer class.
- Parameters:
name (
str) – String identifier for the visualizer type.visualizer_class (
Type[BaseVisualizer]) – The visualizer class to register. Must inherit from BaseVisualizer.
- Raises:
TypeError – If visualizer_class is not a subclass of BaseVisualizer.
- Return type:
None
Examples
>>> factory = VisualizerFactory() >>> factory.register_visualizer("my_viz", MyVisualizerClass)
- class embodichain.lab.sim.motion.workspace.visualizers.VoxelVisualizer[source]#
Bases:
BaseVisualizerVoxel grid visualizer using Open3D or matplotlib.
- voxel_size#
Size of each voxel cube.
Methods:
__init__([backend, voxel_size, config, ...])Initialize the voxel visualizer.
Get the name of the visualization type.
visualize(points[, colors])Visualize points as a voxel grid.
- __init__(backend='sim_manager', voxel_size=0.01, config=None, sim_manager=None, control_part_name=None)[source]#
Initialize the voxel visualizer.
- Parameters:
backend (
str) – Visualization backend (‘sim_manager’, ‘open3d’, ‘matplotlib’, or ‘data’). Defaults to ‘sim_manager’. ‘data’ backend returns voxelized data without visualization.voxel_size (
float) – Size of each voxel. Defaults to 0.01.config (
Optional[Dict[str,Any]]) – Optional configuration dictionary. Defaults to None.sim_manager (
Any|None) – SimulationManager instance for ‘sim_manager’ backend. Defaults to None.control_part_name (
str|None) – Control part name for naming. Defaults to None.
- get_type_name()[source]#
Get the name of the visualization type.
- Return type:
str- Returns:
String identifier for the visualization type.
- visualize(points, colors=None, **kwargs)[source]#
Visualize points as a voxel grid.
- Parameters:
points (
Tensor|ndarray) – Array of shape (N, 3) containing point positions.colors (
Tensor|ndarray|None) – Optional array of shape (N, 3) or (N, 4) containing colors.**kwargs (
Any) – Additional visualization parameters: - voxel_size: Override default voxel size
- Return type:
Any- Returns:
Open3D VoxelGrid geometry or matplotlib figure.
Examples
>>> visualizer = VoxelVisualizer(voxel_size=0.02) >>> points = np.random.rand(1000, 3) >>> voxel_grid = visualizer.visualize(points) >>> visualizer.show()
- embodichain.lab.sim.motion.workspace.visualizers.align_manipulability_scores(results, scores=None, *, include_unreachable=True, verify_positions=True, position_atol=1e-05)[source]#
Align a manipulability score vector with the points of an analysis result.
WorkspaceAnalyzercomputes one score per stored joint configuration, so the score at rowibelongs to:joint-space results:
workspace_points[i]— every sampled point is reachable by construction;Cartesian / plane results:
reachable_points[i]— the joint configurations are the IK solutions collected in ascending sample order, soall_points[reachability_mask][i] == reachable_points[i].
When diagnostics were retained (
all_pointsandreachability_maskpresent), the scores are scattered back onto the full sample set so unreachable points can be drawn alongside, withNaNscores. Otherwise only the reachable points are returned.- Parameters:
results (
Dict[str,Any]) – Analysis dictionary returned byWorkspaceAnalyzer.analyze.scores (
Tensor|ndarray|None) – Score vector to align. Defaults toresults["manipulability_scores"].include_unreachable (
bool) – Scatter scores ontoall_pointswhen the result retains them. WhenFalse, only reachable points are returned.verify_positions (
bool) – Cross-check thatall_points[mask]equalsreachable_pointsbefore scattering, so a silently reordered result is rejected instead of mis-colored.position_atol (
float) – Absolute tolerance for that cross-check.
- Return type:
- Returns:
The aligned
ManipulabilityPointSet.- Raises:
ValueError – If no scores are available, if the result carries no points, or if any length / ordering invariant is violated.
- embodichain.lab.sim.motion.workspace.visualizers.create_visualizer(viz_type=None, **kwargs)[source]#
Convenience function to create a visualizer.
This is a shorthand for VisualizerFactory().create_visualizer().
- Parameters:
viz_type (
VisualizationType|str|None) – The visualization type to use.**kwargs (
Any) – Additional keyword arguments to pass to the visualizer constructor.
- Return type:
- Returns:
An instance of the requested visualizer.
Examples
>>> viz = create_visualizer(VisualizationType.POINT_CLOUD, backend='open3d') >>> viz = create_visualizer("voxel", voxel_size=0.02)
- embodichain.lab.sim.motion.workspace.visualizers.ellipsoid_surface(radii, axes, center=None, resolution=24)[source]#
Tessellate one ellipsoid for surface plotting.
- Parameters:
radii (
ndarray) – Semi-axis lengths, shape(3,).axes (
ndarray) – Principal directions as columns, shape(3, 3).center (
ndarray|None) – Optional ellipsoid center, shape(3,). Defaults to origin.resolution (
int) – Number of samples per angular direction.
- Return type:
tuple[ndarray,ndarray,ndarray]- Returns:
(x, y, z)grids of shape(resolution, resolution).
- embodichain.lab.sim.motion.workspace.visualizers.inspect_points(selection, *, points, scores, jacobian_fn=None, joint_configurations=None, score_indices=None, with_ellipsoid=True, with_condition_number=True)[source]#
Build detail records for the selected points only.
jacobian_fnis invoked exactly once with the joint configurations of the selected points, so the number of Jacobians (and therefore ellipsoids) computed islen(selection)regardless of how many points are drawn.- Parameters:
selection (
Union[InspectionSelection,Sequence[int]]) – Selection returned byselect_inspection_indices(), or a plain sequence of point indices.points (
Tensor|ndarray) – Point positions, shape(P, 3).scores (
Tensor|ndarray) – Per-point scores, shape(P,).jacobian_fn (
Optional[Callable[[ndarray],Any]]) – Callable mapping joint configurations(K, DOF)to spatial Jacobians(K, 6, DOF). Required for ellipsoids and condition numbers.joint_configurations (
Tensor|ndarray|None) – Joint configurations of the scored points, shape(M, DOF).score_indices (
ndarray|None) – Mapping from point index to score/joint row, shape(P,), as produced byalign_manipulability_scores(). Defaults to identity.with_ellipsoid (
bool) – Compute translational ellipsoids.with_condition_number (
bool) – Compute Jacobian condition numbers.
- Return type:
list[PointInspection]- Returns:
One
PointInspectionper selected index, in selection order.- Raises:
ValueError – If an index has no joint configuration while Jacobians were requested, or
jacobian_fnreturns the wrong number of Jacobians.
- embodichain.lab.sim.motion.workspace.visualizers.map_manipulability_colors(scores, *, reachable_mask=None, cfg=None)[source]#
Map manipulability scores to RGBA colors and marker sizes.
Reachable points take the configured colormap over the robustly normalized score; unreachable points take
cfg.unreachable_colorand a smaller marker so they stay visible but visually subordinate.- Parameters:
scores (
Union[Tensor,ndarray,Sequence[float]]) – Score vector, shape(N,).NaNmarks an unscored point.reachable_mask (
ndarray|None) – Optional boolean mask, shape(N,). Defaults to the finite entries ofscores. Entries that are masked reachable but carry a non-finite score are treated as unreachable.cfg (
ManipulabilityColorCfg|None) – Color configuration. Defaults toManipulabilityColorCfg.
- Return type:
- Returns:
- Raises:
ImportError – If Matplotlib (the colormap source) is unavailable.
ValueError – If
reachable_masklength does not matchscores.
- embodichain.lab.sim.motion.workspace.visualizers.normalize_manipulability(scores, *, percentile_clip=(2.0, 98.0), log_scale=False, log_epsilon=1e-12, valid_mask=None)[source]#
Normalize manipulability scores to
[0, 1]with percentile clipping.NaNentries (unreachable points) never contribute to the statistics and stayNaNin the output. The raw score range is reported untouched so a caller can always show the true magnitudes next to the color bar.Degenerate inputs are handled explicitly: an empty or fully invalid input yields an all-
NaNresult withNaNranges, and a constant input (a single point, or all-equal scores) maps to a flat0.5instead of dividing by a zero span.- Parameters:
scores (
Union[Tensor,ndarray,Sequence[float]]) – Score vector, shape(N,).percentile_clip (
tuple[float,float]) –(low, high)percentiles in[0, 100]withlow < high, evaluated on the transformed values.log_scale (
bool) – Normalizelog10(max(w, log_epsilon))instead ofw.log_epsilon (
float) – Lower clamp applied beforelog10.valid_mask (
ndarray|None) – Optional additional mask of entries to consider valid.
- Return type:
- Returns:
The
ManipulabilityNormalizationrecord.- Raises:
ValueError – If
percentile_clipis not an increasing pair inside[0, 100], orlog_epsilonis not positive.
- embodichain.lab.sim.motion.workspace.visualizers.select_inspection_indices(scores, *, selected=(), top_k=1, bottom_k=1, valid_mask=None)[source]#
Choose the few points that deserve a detailed inspection.
Ellipsoids are expensive and unreadable in bulk, so only an explicit selection plus the best and worst conditioned points are returned. Ties are broken by ascending index so the selection is deterministic.
- Parameters:
scores (
Union[Tensor,ndarray,Sequence[float]]) – Per-point scores, shape(N,);NaNmarks unscored points.selected (
Sequence[int]) – Explicit point indices to always include, highest priority.top_k (
int) – Number of highest-wpoints to add.bottom_k (
int) – Number of lowest-wpoints to add.valid_mask (
ndarray|None) – Optional additional validity mask, shape(N,).
- Return type:
- Returns:
The deduplicated
InspectionSelection.- Raises:
ValueError – If
top_korbottom_kis negative, or an explicitly selected index is out of range or carries no score.
- embodichain.lab.sim.motion.workspace.visualizers.translational_manipulability_ellipsoid(jacobian)[source]#
Derive translational manipulability ellipsoids from spatial Jacobians.
The ellipsoid
{J_t q : ||q|| <= 1}has semi-axessqrt(eig(J_t J_t^T))along the corresponding eigenvectors, whereJ_tis the translational row block selected withembodichain.compute.kinematics.select_jacobian_rows().- Parameters:
jacobian (
Tensor|ndarray) – Batched spatial Jacobian, shape(N, 6, DOF).- Return type:
tuple[ndarray,ndarray]- Returns:
Tuple of semi-axis lengths
(N, 3)in descending order and the matching principal directions(N, 3, 3)stored as columns.- Raises:
ValueError – If
jacobianis not batched 3D or lacks translational rows.