Reference/API

Humanoid Retargeting

robokit.helpers.humanoid_retargeting.HumanoidRetargeterOnline(
config: HumanoidRetargeterOnlineConfig,
robot: Optional[Robot] = None,
scene: Optional[WarpScene] = None,
device: Optional[wp_device_type] = None,
seed: int = 0
)

Online humanoid retargeting with input joints ordered by human_joint_names.

Lifecycle

  1. __init__ stores the robot, configuration, and caller-owned scene.
  2. warmup(batch_size) builds batch-shaped buffers and solvers.
  3. solve(T_world_human) advances one batched frame from Warp inputs.
Parameters
configHumanoidRetargeterOnlineConfigrequired
robotOptional[Robot]= None
sceneOptional[WarpScene]= None
deviceOptional[wp_device_type]= None
seedint= 0
Members
property[source]
HumanoidRetargeterOnline.interaction_task: InteractionMeshTask

Return the interaction task; set its first frame before warmup and update it before each solve.

method[source]
HumanoidRetargeterOnline.warmup(
batch_size: int
)

Fix the online batch size and build its reusable solver state.

Parameters
batch_sizeintrequired
method[source]
HumanoidRetargeterOnline.solve(
T_world_human: wp.array,
human_heights: Optional[wp.array] = None,
out: Optional[wp.array] = None
) -> wp.array

Retarget one batched human frame from Warp inputs.

Lifecycle

  1. Validate the shape fixed by warmup(...).
  2. Update temporal terms from the previous robot state.
  3. Compute targets and candidate states.
  4. Solve once, retain the state, and write the requested output buffer.
Parameters
T_world_humanwp.arrayrequired

Human joint transforms with shape (batch, joints).

human_heightsOptional[wp.array]= None

Optional human height in meters for each batch element.

outOptional[wp.array]= None

Optional caller-owned output with shape (batch, 7 + dofs).

Returns
wp.array

out when provided; otherwise a reusable helper-owned buffer overwritten by the next call.

method[source]
HumanoidRetargeterOnline.solve_numpy(
T_world_human: np.ndarray,
human_heights: Optional[np.ndarray] = None
) -> np.ndarray

Convert NumPy inputs, call solve(...), and return a NumPy copy.

Parameters
T_world_humannp.ndarrayrequired
human_heightsOptional[np.ndarray]= None
Returns
np.ndarray
method[source]
HumanoidRetargeterOnline.reset(
T_world_base: Optional[wp.array] = None
)

Reset temporal state, optionally from an initial floating-base transform.

Parameters
T_world_baseOptional[wp.array]= None
robokit.helpers.humanoid_retargeting.HumanoidRetargeterOnlineConfig(
terms: List[ResidualTask] = _default_online_terms(),
urdf_path: Optional[str] = None,
human_root_name: str = 'pelvis',
human_height_assumption: float = 1.8,
ground_height: float = 0.0,
collision_spheres_path: Optional[Union[str, Path]] = None,
scale_table: Dict[str, float] = dict(),
link_mapping: Dict[str, LinkMapping] = dict(),
correspondence_edges: Optional[List[CorrespondenceEdge]] = None,
interaction_terms: List[ResidualTask] = list(),
velocity_limit_dt: float = 1.0 / 30.0,
velocity_clamp_scale: float = 0.6,
velocity_limit_override: Optional[Sequence[Union[int, float]]] = None,
solver: PopulationSolverConfig = _default_retargeting_solver()
)

A robot's human-to-robot mapping, task templates and per-frame solver; offline retargeting reuses the mapping.

Parameters
termsList[ResidualTask]= _default_online_terms()
urdf_pathOptional[str]= None
human_root_namestr= 'pelvis'
human_height_assumptionfloat= 1.8
ground_heightfloat= 0.0
collision_spheres_pathOptional[Union[str, Path]]= None
scale_tableDict[str, float]= dict()
link_mappingDict[str, LinkMapping]= dict()
correspondence_edgesOptional[List[CorrespondenceEdge]]= None
interaction_termsList[ResidualTask]= list()
velocity_limit_dtfloat= 1.0 / 30.0
velocity_clamp_scalefloat= 0.6
velocity_limit_overrideOptional[Sequence[Union[int, float]]]= None
solverPopulationSolverConfig= _default_retargeting_solver()
Members
attribute[source]
HumanoidRetargeterOnlineConfig.terms: List[ResidualTask] = field(default_factory=_default_online_terms)

Task templates; each names its inputs with HumanoidContext members.

attribute[source]
HumanoidRetargeterOnlineConfig.urdf_path: Optional[str] = None

Robot URDF, loaded when the retargeter gets no robot.

attribute[source]
HumanoidRetargeterOnlineConfig.human_root_name: str = 'pelvis'

Human joint that places the robot base.

attribute[source]
HumanoidRetargeterOnlineConfig.human_height_assumption: float = 1.8

Human height in meters when a solve gets no human_heights.

attribute[source]
HumanoidRetargeterOnlineConfig.ground_height: float = 0.0

Ground height of the human motion, subtracted from every target height.

attribute[source]
HumanoidRetargeterOnlineConfig.collision_spheres_path: Optional[Union[str, Path]] = None

Robot collision spheres, needed by a weighted self-collision task.

attribute[source]
HumanoidRetargeterOnlineConfig.scale_table: Dict[str, float] = field(default_factory=dict)

Target scale per human joint; absent joints use 1.0.

attribute[source]
HumanoidRetargeterOnlineConfig.correspondence_edges: Optional[List[CorrespondenceEdge]] = None

Link vectors the correspondence task drives toward human joint vectors; None is off (online only).

attribute[source]
HumanoidRetargeterOnlineConfig.interaction_terms: List[ResidualTask] = field(default_factory=list)

Interaction-mesh task templates, built at construction so the first frame is set before warmup; empty is off.

attribute[source]
HumanoidRetargeterOnlineConfig.velocity_limit_dt: float = 1.0 / 30.0

Time between frames, for the velocity limits and the output clamp.

attribute[source]
HumanoidRetargeterOnlineConfig.velocity_clamp_scale: float = 0.6

Clamp each output step at this fraction of the velocity limits; 0 is off.

attribute[source]
HumanoidRetargeterOnlineConfig.velocity_limit_override: Optional[Sequence[Union[int, float]]] = None

Joint velocity limits in rad/s, replacing the URDF's; None uses the URDF's.

attribute[source]
HumanoidRetargeterOnlineConfig.solver: PopulationSolverConfig = field(default_factory=_default_retargeting_solver)

Candidate schedule and optimizers of each frame's solve.

method[source]
HumanoidRetargeterOnlineConfig.add(
term: ResidualTask,
name: Optional[str] = None
) -> HumanoidRetargeterOnlineConfig

Append a task, optionally assigning its input role.

python
>>> from robokit.terms.dense.configuration_task import ConfigurationTask
>>> config = HumanoidRetargeterOnlineConfig(terms=[]).add(ConfigurationTask(weight=0.1), name="rest")
>>> config.task("rest").weight
0.1
Parameters
termResidualTaskrequired
nameOptional[str]= None
Returns
HumanoidRetargeterOnlineConfig
method[source]
HumanoidRetargeterOnlineConfig.task(
name: str
) -> ResidualTask

Return a named task; raise KeyError when absent.

python
>>> from robokit.terms.dense.configuration_task import ConfigurationTask
>>> config = HumanoidRetargeterOnlineConfig(terms=[]).add(ConfigurationTask(weight=0.2), name="rest")
>>> config.task("rest").weight
0.2
Parameters
namestrrequired
Returns
ResidualTask
property[source]
HumanoidRetargeterOnlineConfig.human_joint_names: Tuple[str, ...]

Return the ordered human joints expected by the solve APIs.

Example

python
>>> import numpy as np
>>> config = HumanoidRetargeterOnlineConfig(
...     link_mapping={"torso": LinkMapping("spine", np.zeros(3), np.zeros(4))},
... )
>>> config.human_joint_names  # mapped joints first, then the root
('spine', 'pelvis')
method[source]
HumanoidRetargeterOnlineConfig.target_arrays(
human_joint_names: Sequence[str]
) -> TargetArrays

Resolve link_mapping in input human_joint_names order for both solvers' compute_targets_kernel arrays.

Example

python
>>> import numpy as np
>>> config = HumanoidRetargeterOnlineConfig(
...     link_mapping={
...         "torso": LinkMapping("spine", np.zeros(3), np.zeros(4)),
...         "hip": LinkMapping("pelvis", np.zeros(3), np.zeros(4)),
...     },
...     scale_table={"spine": 0.9},
... )
>>> arrays = config.target_arrays(config.human_joint_names)
>>> arrays.joint_indices.tolist(), arrays.scales.tolist()
([0, 1], [0.8999999761581421, 1.0])
>>> arrays.root_joint_index, arrays.root_target_index
(1, 1)
>>> arrays.rotation_offsets[0].tolist()  # zero offset normalizes to identity
[1.0, 0.0, 0.0, 0.0]
Parameters
human_joint_namesSequence[str]required
Returns
TargetArrays
method[source]
HumanoidRetargeterOnlineConfig.from_yaml(
yaml_path: Union[str, Path]
) -> HumanoidRetargeterOnlineConfig
Parameters
yaml_pathUnion[str, Path]required
Returns
HumanoidRetargeterOnlineConfig
method[source]
HumanoidRetargeterOnlineConfig.to_dict() -> dict
Returns
dict
method[source]
HumanoidRetargeterOnlineConfig.to_yaml(
yaml_path: Union[str, Path]
)
Parameters
yaml_pathUnion[str, Path]required
method[source]
HumanoidRetargeterOnlineConfig.load_robot(
load_meshes: bool = False
) -> Robot

Load the config's robot, with its collision spheres when the config names them.

Parameters
load_meshesbool= False
Returns
Robot
robokit.helpers.humanoid_retargeting.HumanoidRetargeterOffline(
config: HumanoidRetargeterOnlineConfig,
offline_config: HumanoidRetargeterOfflineConfig,
robot: Optional[Robot] = None,
device: Optional[wp_device_type] = None
)

Whole-clip retargeting with input joints ordered by human_joint_names.

Lifecycle

  1. __init__ stores the robot and configuration.
  2. warmup(batch_size, num_frames) builds shape-specific buffers and optimizers.
  3. solve(T_world_human) retargets one fixed-shape Warp trajectory batch.
Parameters
configHumanoidRetargeterOnlineConfigrequired
offline_configHumanoidRetargeterOfflineConfigrequired
robotOptional[Robot]= None
deviceOptional[wp_device_type]= None
Members
method[source]
HumanoidRetargeterOffline.warmup(
batch_size: int,
num_frames: int
)

Build and cache all state for (batch_size, num_frames).

Parameters
batch_sizeintrequired
num_framesintrequired
method[source]
HumanoidRetargeterOffline.solve(
T_world_human: wp.array,
valid_lengths: Optional[wp.array] = None,
human_heights: Optional[wp.array] = None,
out: Optional[wp.array] = None,
target_overrides: Optional[Dict[str, np.ndarray]] = None
) -> wp.array

Retarget one padded [B, T, J] Warp trajectory batch.

Lifecycle

  1. Validate the shape fixed by warmup(...).
  2. Compute all frame targets and independent IK warm starts.
  3. Reset the cached trajectory state and valid-frame masks.
  4. Solve once and write the requested padded output buffer.
Parameters
T_world_humanwp.arrayrequired

Human joint transforms with shape (batch, frames, joints).

valid_lengthsOptional[wp.array]= None

Optional valid frame count for each padded batch element.

human_heightsOptional[wp.array]= None

Optional human height in meters for each batch element.

outOptional[wp.array]= None

Optional caller-owned output with shape (batch, frames, 7 + dofs).

target_overridesOptional[Dict[str, np.ndarray]]= None

Optional (batch, frames, 7) target tracks keyed by robot link; they move the IK warm start and TARGET_POSITIONS, while orientation templates read TARGETS (the mapped poses) unless they read OVERRIDDEN_TARGETS.

Returns
wp.array

out when provided; otherwise a reusable helper-owned buffer overwritten by the next call.

method[source]
HumanoidRetargeterOffline.solve_numpy(
T_world_human: np.ndarray,
valid_lengths: Optional[np.ndarray] = None,
human_heights: Optional[np.ndarray] = None,
target_overrides: Optional[Dict[str, np.ndarray]] = None
) -> np.ndarray

Convert padded [B, T, J, 7] NumPy inputs, warm up for their shape, solve, and return a NumPy copy.

Parameters
T_world_humannp.ndarrayrequired
valid_lengthsOptional[np.ndarray]= None
human_heightsOptional[np.ndarray]= None
target_overridesOptional[Dict[str, np.ndarray]]= None
Returns
np.ndarray
robokit.helpers.humanoid_retargeting.HumanoidRetargeterOfflineConfig(
terms: List[ResidualTask] = _default_offline_terms(),
warm_start: IKSolverConfig = (lambda: IKSolverConfig(enable_T_world_base=True, solver=PopulationSolverConfig(stages=[Stage(6, 4, LMOptimizerConfig(lm_lambda=1.5)), Stage(3, 1)])).add(PositionTask(frame_index=IKContext.TARGET_LINKS, T_world_target=IKContext.TARGET, weight=10.0)).add(RotationTask(frame_index=IKContext.TARGET_LINKS, T_world_target=IKContext.TARGET, weight=5.0)).add(PositionLimit(weight=30.0)))(),
solver: LMOptimizerConfig = (lambda: LMOptimizerConfig(linear_solver='cg', lm_lambda=0.5, max_iter=25, lambda_min=1e-06, lambda_max=1000000.0, rho_min=0.0001, cuda_graph_mode='full'))()
)

Whole-clip optimizer settings; the paired online config supplies the mapping and velocity limits.

Parameters
termsList[ResidualTask]= _default_offline_terms()
warm_startIKSolverConfig= (lambda: IKSolverConfig(enable_T_world_base=True, solver=PopulationSolverConfig(stages=[Stage(6, 4, LMOptimizerConfig(lm_lambda=1.5)), Stage(3, 1)])).add(PositionTask(frame_index=IKContext.TARGET_LINKS, T_world_target=IKContext.TARGET, weight=10.0)).add(RotationTask(frame_index=IKContext.TARGET_LINKS, T_world_target=IKContext.TARGET, weight=5.0)).add(PositionLimit(weight=30.0)))()
solverLMOptimizerConfig= (lambda: LMOptimizerConfig(linear_solver='cg', lm_lambda=0.5, max_iter=25, lambda_min=1e-06, lambda_max=1000000.0, rho_min=0.0001, cuda_graph_mode='full'))()
Members
attribute[source]
HumanoidRetargeterOfflineConfig.terms: List[ResidualTask] = field(default_factory=_default_offline_terms)

Trajectory task templates; tracking weights are per link, and self-collision costs O(pairs) per frame.

attribute[source]
HumanoidRetargeterOfflineConfig.warm_start: IKSolverConfig = field(default_factory=lambda: IKSolverConfig(enable_T_world_base=True, solver=PopulationSolverConfig(stages=[Stage(6, 4, LMOptimizerConfig(lm_lambda=1.5)), Stage(3, 1)])).add(PositionTask(frame_index=IKContext.TARGET_LINKS, T_world_target=IKContext.TARGET, weight=10.0)).add(RotationTask(frame_index=IKContext.TARGET_LINKS, T_world_target=IKContext.TARGET, weight=5.0)).add(PositionLimit(weight=30.0)))

Per-frame IK that seeds the trajectory.

attribute[source]
HumanoidRetargeterOfflineConfig.solver: LMOptimizerConfig = field(default_factory=lambda: LMOptimizerConfig(linear_solver='cg', lm_lambda=0.5, max_iter=25, lambda_min=1e-06, lambda_max=1000000.0, rho_min=0.0001, cuda_graph_mode='full'))

Trajectory solver.

method[source]
HumanoidRetargeterOfflineConfig.add(
term: ResidualTask,
name: Optional[str] = None
) -> HumanoidRetargeterOfflineConfig

Append a task, optionally assigning its input role.

python
>>> from robokit.terms.dense.configuration_task import ConfigurationTask
>>> config = HumanoidRetargeterOfflineConfig(terms=[]).add(ConfigurationTask(weight=0.1), name="rest")
>>> config.task("rest").weight
0.1
Parameters
termResidualTaskrequired
nameOptional[str]= None
Returns
HumanoidRetargeterOfflineConfig
method[source]
HumanoidRetargeterOfflineConfig.task(
name: str
) -> ResidualTask

Return a named task; raise KeyError when absent.

python
>>> from robokit.terms.dense.configuration_task import ConfigurationTask
>>> config = HumanoidRetargeterOfflineConfig(terms=[]).add(ConfigurationTask(weight=0.2), name="rest")
>>> config.task("rest").weight
0.2
Parameters
namestrrequired
Returns
ResidualTask
method[source]
HumanoidRetargeterOfflineConfig.from_yaml(
yaml_path: Union[str, Path]
) -> HumanoidRetargeterOfflineConfig
Parameters
yaml_pathUnion[str, Path]required
Returns
HumanoidRetargeterOfflineConfig
method[source]
HumanoidRetargeterOfflineConfig.to_yaml(
yaml_path: Union[str, Path]
)
Parameters
yaml_pathUnion[str, Path]required