embodichain.compute#

Shared array and tensor computations#

compute owns numerical algorithms that operate on arrays, tensors, and kinematic parameters without importing the simulation runtime. It does not own robots, scenes, or environment lifecycle. Importing the root package does not load Torch or Warp. Domain packages load their required dependencies.

  • kinematics/_warp implements analytical OPW, SRS, and UR computations. Stateful solver interfaces remain in embodichain.lab.sim.solvers.

  • trajectory provides the public tensor interfaces below. Its private _warp implementation supports path resampling and trajectory warping.

  • geometry/_warp/convex_query.py evaluates maximum halfspace values for convex hulls. These values classify containment; outside values are not generally exact Euclidean distances to the hull.

  • image/_warp/tiling.py converts tiled images into image batches.

Private _warp modules are implementation details, not a backend registry. Simulation-specific contact scattering belongs to embodichain.lab.sim.sensors._warp.contact.

Trajectory API#

interpolate_with_distance retains every required keyframe. resample_with_distance samples uniformly along cumulative path distance and may omit interior input samples. warp_trajectory_qpos changes a joint trajectory using interpolated offsets at supplied keyframes; warping here means trajectory deformation.

import torch
from embodichain.compute.trajectory import interpolate_with_distance

keyframes = torch.tensor([[[0.0], [1.0], [3.0]]])
result = interpolate_with_distance(keyframes, interp_num=5, device="cpu")
# result: [[[0.0], [0.5], [1.0], [2.0], [3.0]]]

interpolate_with_distance(trajectory, interp_num)

Interpolate batched keyframes while preserving every keyframe boundary.

interpolate_with_nums(trajectory, interp_nums)

Interpolate each segment with its requested number of intervals.

resample_with_distance(trajectory, interp_num)

Resample a batched path at uniform cumulative-distance positions.

sort_and_padding_key_frame(trajectory, ...)

Sort keyframes and pad missing trajectory endpoints.

warp_trajectory_qpos(trajectory, ...[, device])

Apply interpolated keyframe offsets to batches of a joint trajectory.

Trajectory computations on arrays and tensors.

Interpolation retains keyframe boundaries; resampling treats interior points as optional path samples. Warping applies keyframe offsets to a trajectory.

Functions:

interpolate_with_distance(trajectory, interp_num)

Interpolate batched keyframes while preserving every keyframe boundary.

interpolate_with_nums(trajectory, interp_nums)

Interpolate each segment with its requested number of intervals.

resample_with_distance(trajectory, interp_num)

Resample a batched path at uniform cumulative-distance positions.

sort_and_padding_key_frame(trajectory, ...)

Sort keyframes and pad missing trajectory endpoints.

warp_trajectory_qpos(trajectory, ...[, device])

Apply interpolated keyframe offsets to batches of a joint trajectory.

embodichain.compute.trajectory.interpolate_with_distance(trajectory, interp_num, device=device(type='cuda'))[source]#

Interpolate batched keyframes while preserving every keyframe boundary.

Each input point is treated as a required keyframe. The output is generated segment by segment: every segment receives at least one interval, and any remaining intervals are distributed by Euclidean segment length for each batch independently. Segment endpoints are copied directly from the input, so intermediate keyframes occur as exact emitted samples.

Attention

interp_num must be at least the number of input keyframes. Use resample_with_distance() when input points are optional dense path samples that may be downsampled.

Parameters:
  • trajectory (Tensor) – Keyframe tensor with shape (B, N, M).

  • interp_num (int) – Target number of samples T.

  • device (device | str) – Device on which to perform interpolation.

Return type:

Tensor

Returns:

Interpolated trajectories with shape (B, T, M).

Raises:

ValueError – If trajectory is not three-dimensional, contains no keyframes for a non-empty output, or interp_num cannot hold all keyframes.

embodichain.compute.trajectory.interpolate_with_nums(trajectory, interp_nums, device=device(type='cuda'))[source]#

Interpolate each segment with its requested number of intervals.

The first keyframe is emitted once. Each positive count appends that many evenly spaced samples ending at the next keyframe. A zero count appends the next keyframe directly, so every original boundary is retained.

Parameters:
  • trajectory (Tensor) – Keyframe tensor with shape (B, N, M).

  • interp_nums (Tensor | Sequence[int]) – Non-negative interval counts with shape (N - 1,).

  • device (device | str) – Device on which to perform interpolation.

Return type:

Tensor

Returns:

A tensor containing the interpolated trajectories. For non-empty input, its sample count is 1 + sum(max(count, 1) for count in interp_nums).

Raises:

ValueError – If the count shape is invalid or a count is negative.

embodichain.compute.trajectory.resample_with_distance(trajectory, interp_num, device=device(type='cuda'))[source]#

Resample a batched path at uniform cumulative-distance positions.

Unlike interpolate_with_distance(), interior input samples are not required output points, so this function supports both upsampling and downsampling. It is intended for dense planner paths rather than required waypoint sequences.

Parameters:
  • trajectory (Tensor) – Path tensor with shape (B, N, M).

  • interp_num (int) – Target number of samples T.

  • device (device | str) – Device on which to perform interpolation.

Return type:

Tensor

Returns:

Resampled trajectories with shape (B, T, M).

Raises:

ValueError – If trajectory is not three-dimensional, contains no points for a non-empty output, or interp_num is negative.

embodichain.compute.trajectory.sort_and_padding_key_frame(trajectory, key_indices, key_frames_batch)[source]#

Sort keyframes and pad missing trajectory endpoints.

Parameters:
  • trajectory (np.ndarray) – Original trajectory, shaped (N, DOF).

  • key_indices (np.ndarray) – Non-empty array of keyframe waypoint indices.

  • key_frames_batch (np.ndarray) – Target keyframes, shaped (B, K, DOF).

Returns:

padded and sorted key frame indices. [n_keyframe_new,] of int. key_frames_ascending (np.ndarray): padded and sorted batch key frames. [n_batch, n_keyframe_new, dof] of float.

Return type:

key_indices_ascending (np.ndarray)

embodichain.compute.trajectory.warp_trajectory_qpos(trajectory, key_indices, key_frames_batch, device='cuda')[source]#

Apply interpolated keyframe offsets to batches of a joint trajectory.

Parameters:
  • trajectory (torch.Tensor) – raw trajectory. [n_waypoint, dof] of float.

  • key_indices (torch.Tensor) – key frame waypoint indices. [n_keyframe,] of int.

  • key_frames_batch (torch.Tensor) – batch key frames. [n_batch, n_keyframe, dof] of float.

  • device (str, optional) – torch tensor device. Defaults to “cuda”.

Returns:

warped trajectory. [n_batch, n_waypoint, dof] of float.

Return type:

torch.Tensor

Implementation modules#

Interpolate batched keyframes while preserving their boundaries.

Functions:

interpolate_with_distance(trajectory, interp_num)

Interpolate batched keyframes while preserving every keyframe boundary.

interpolate_with_nums(trajectory, interp_nums)

Interpolate each segment with its requested number of intervals.

embodichain.compute.trajectory.interpolation.interpolate_with_distance(trajectory, interp_num, device=device(type='cuda'))[source]#

Interpolate batched keyframes while preserving every keyframe boundary.

Each input point is treated as a required keyframe. The output is generated segment by segment: every segment receives at least one interval, and any remaining intervals are distributed by Euclidean segment length for each batch independently. Segment endpoints are copied directly from the input, so intermediate keyframes occur as exact emitted samples.

Attention

interp_num must be at least the number of input keyframes. Use resample_with_distance() when input points are optional dense path samples that may be downsampled.

Parameters:
  • trajectory (Tensor) – Keyframe tensor with shape (B, N, M).

  • interp_num (int) – Target number of samples T.

  • device (device | str) – Device on which to perform interpolation.

Return type:

Tensor

Returns:

Interpolated trajectories with shape (B, T, M).

Raises:

ValueError – If trajectory is not three-dimensional, contains no keyframes for a non-empty output, or interp_num cannot hold all keyframes.

embodichain.compute.trajectory.interpolation.interpolate_with_nums(trajectory, interp_nums, device=device(type='cuda'))[source]#

Interpolate each segment with its requested number of intervals.

The first keyframe is emitted once. Each positive count appends that many evenly spaced samples ending at the next keyframe. A zero count appends the next keyframe directly, so every original boundary is retained.

Parameters:
  • trajectory (Tensor) – Keyframe tensor with shape (B, N, M).

  • interp_nums (Tensor | Sequence[int]) – Non-negative interval counts with shape (N - 1,).

  • device (device | str) – Device on which to perform interpolation.

Return type:

Tensor

Returns:

A tensor containing the interpolated trajectories. For non-empty input, its sample count is 1 + sum(max(count, 1) for count in interp_nums).

Raises:

ValueError – If the count shape is invalid or a count is negative.

Resample batched paths at uniform cumulative-distance positions.

Functions:

resample_with_distance(trajectory, interp_num)

Resample a batched path at uniform cumulative-distance positions.

embodichain.compute.trajectory.resampling.resample_with_distance(trajectory, interp_num, device=device(type='cuda'))[source]#

Resample a batched path at uniform cumulative-distance positions.

Unlike interpolate_with_distance(), interior input samples are not required output points, so this function supports both upsampling and downsampling. It is intended for dense planner paths rather than required waypoint sequences.

Parameters:
  • trajectory (Tensor) – Path tensor with shape (B, N, M).

  • interp_num (int) – Target number of samples T.

  • device (device | str) – Device on which to perform interpolation.

Return type:

Tensor

Returns:

Resampled trajectories with shape (B, T, M).

Raises:

ValueError – If trajectory is not three-dimensional, contains no points for a non-empty output, or interp_num is negative.

Adjust joint trajectories using batches of keyframe offsets.

Functions:

sort_and_padding_key_frame(trajectory, ...)

Sort keyframes and pad missing trajectory endpoints.

warp_trajectory_qpos(trajectory, ...[, device])

Apply interpolated keyframe offsets to batches of a joint trajectory.

embodichain.compute.trajectory.warping.sort_and_padding_key_frame(trajectory, key_indices, key_frames_batch)[source]#

Sort keyframes and pad missing trajectory endpoints.

Parameters:
  • trajectory (np.ndarray) – Original trajectory, shaped (N, DOF).

  • key_indices (np.ndarray) – Non-empty array of keyframe waypoint indices.

  • key_frames_batch (np.ndarray) – Target keyframes, shaped (B, K, DOF).

Returns:

padded and sorted key frame indices. [n_keyframe_new,] of int. key_frames_ascending (np.ndarray): padded and sorted batch key frames. [n_batch, n_keyframe_new, dof] of float.

Return type:

key_indices_ascending (np.ndarray)

embodichain.compute.trajectory.warping.warp_trajectory_qpos(trajectory, key_indices, key_frames_batch, device='cuda')[source]#

Apply interpolated keyframe offsets to batches of a joint trajectory.

Parameters:
  • trajectory (torch.Tensor) – raw trajectory. [n_waypoint, dof] of float.

  • key_indices (torch.Tensor) – key frame waypoint indices. [n_keyframe,] of int.

  • key_frames_batch (torch.Tensor) – batch key frames. [n_batch, n_keyframe, dof] of float.

  • device (str, optional) – torch tensor device. Defaults to “cuda”.

Returns:

warped trajectory. [n_batch, n_waypoint, dof] of float.

Return type:

torch.Tensor

Migration#

Existing imports from embodichain.utils.warp and its submodules continue to resolve to the relocated Warp kernel and struct objects. They do not register duplicate implementations. The legacy contact-kernel alias loads the simulation sensor package on demand.

Pure trajectory functions formerly defined in embodichain.lab.sim.utility.action_utils are re-exported there for compatibility. New consumers should import from compute.trajectory. get_trajectory_object_offset_qpos remains in the simulation utility module because it calls a stateful solver’s FK and IK interfaces.