Workspace Sampling
Moro 0.5.0 provides numerical sampling of the reachable end-effector position workspace of a serial manipulator.
The feature approximates
by drawing joint configurations from a finite joint-space domain and evaluating forward kinematics.
The result is a sampled point cloud, not an exact workspace boundary.
Basic usage
from moro.workspace import sample_workspace
workspace = sample_workspace(
robot,
samples=5000,
seed=1,
)
The result contains:
workspace.points
workspace.configurations
workspace.joint_limits
workspace.seed
workspace.samples
workspace.dof
workspace.bounds
The public array shapes are:
workspace.points.shape == (N, 3)
workspace.configurations.shape == (N, robot.dof)
Planar robots still use three Cartesian coordinates.
Joint-space domain
By default, sampling uses:
robot.joint_limits
You may override them for a single call:
workspace = sample_workspace(
robot,
samples=2000,
joint_limits=[
(-1.0, 1.0),
(-0.5, 0.5),
],
)
Explicit limits completely replace the robot limits for that sampling call and do not mutate the robot.
Every interval must be finite and strictly ordered:
Degenerate intervals are intentionally rejected in 0.5.0.
Default robot limits are modeling conveniences and may not represent the physical range of a particular mechanism, especially for prismatic joints.
Sampling distribution
Each joint is sampled independently and uniformly over its effective interval:
This means sampling is uniform in joint space, not in Cartesian space.
A dense Cartesian region does not imply a larger geometric portion of the true workspace; the forward-kinematics mapping can distort the point density strongly.
Reproducibility
Sampling uses a local NumPy random generator:
workspace = sample_workspace(
robot,
samples=1000,
seed=42,
)
The same model, parameters, limits, sample count, and seed reproduce the same sampled configurations within the same relevant numerical environment.
The global NumPy random state is not used.
Symbolic geometric parameters
Workspace sampling can evaluate robots with symbolic geometric parameters:
workspace = sample_workspace(
robot,
samples=1000,
parameters={
l1: 1.0,
l2: 0.8,
},
seed=3,
)
Parameter substitution is applied to a local forward-kinematics expression. The symbolic robot model is not modified.
Any unresolved model parameter causes a clear validation error before sampling begins.
Point/configuration correspondence
Rows correspond one-to-one:
Samples are never reordered, deduplicated, or silently removed.
If one forward-kinematics evaluation produces invalid numerical data, the entire sampling call fails instead of returning a smaller dataset.
Cartesian sample bounds
The property:
workspace.bounds
returns the observed sample bounds:
(
(xmin, xmax),
(ymin, ymax),
(zmin, zmax),
)
These are point-cloud bounds only. They are not an exact analytical workspace boundary.
Visualization
Use:
from moro.visualization import plot_workspace
fig, ax = plot_workspace(workspace)
Supported projections are:
auto
xy
xz
yz
3d
projection="auto" selects a base-axis-aligned 2D projection only when one Cartesian coordinate is approximately constant. Otherwise it uses a 3D view.
For example:
fig, ax = plot_workspace(
workspace,
projection="xy",
marker_size=6,
alpha=0.4,
)
Workspace visualization is Matplotlib-only in 0.5.0.
What workspace sampling does not compute
The 0.5.0 feature does not attempt to compute:
exact boundaries;
convex hulls;
areas or volumes;
dextrous or orientation workspace;
manipulability maps;
singularity maps;
collision-aware workspace;
adaptive or quasi-random sampling.
The stored configurations make later post-processing possible without expanding the scope of the sampler itself.