Skip to content

Commit 3f8b33e

Browse files
committed
Transform end effector from world pose into base for teleop and record
1 parent c4a6a2a commit 3f8b33e

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

isaaclab_arena/scripts/imitation_learning/record_demos.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,8 +450,16 @@ def stop_recording_instance():
450450
while simulation_app.is_running():
451451
# Get keyboard command
452452
action = teleop_interface.advance()
453+
453454
# Expand to batch dimension
454455
actions = action.repeat(env.num_envs, 1)
456+
# Hack for G1 Pink WBC to transferm EE into robot base coordinates
457+
action_manager = getattr(env, "action_manager", None)
458+
if action_manager is not None:
459+
for term_name in action_manager.active_terms:
460+
term = action_manager.get_term(term_name)
461+
if hasattr(term, "preprocess_actions"):
462+
actions = term.preprocess_actions(actions)
455463

456464
# Perform action on environment
457465
if running_recording_instance:

isaaclab_arena/scripts/imitation_learning/teleop.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,13 @@ def stop_teleoperation() -> None:
245245
if teleoperation_active:
246246
# process actions
247247
actions = action.repeat(env.num_envs, 1)
248+
# Hack for G1 Pink WBC to transferm EE into robot base coordinates
249+
action_manager = getattr(env, "action_manager", None)
250+
if action_manager is not None:
251+
for term_name in action_manager.active_terms:
252+
term = action_manager.get_term(term_name)
253+
if hasattr(term, "preprocess_actions"):
254+
actions = term.preprocess_actions(actions)
248255
# apply actions
249256
env.step(actions)
250257
else:

isaaclab_arena_g1/g1_env/mdp/actions/g1_decoupled_wbc_pink_action.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from typing import TYPE_CHECKING
1313

1414
from isaaclab.assets.articulation import Articulation
15+
import isaaclab.utils.math as math_utils
1516

1617
from isaaclab_arena_g1.g1_env.mdp.actions.g1_decoupled_wbc_joint_action import G1DecoupledWBCJointAction
1718
from isaaclab_arena_g1.g1_whole_body_controller.wbc_policy.g1_wbc_upperbody_ik.g1_wbc_upperbody_controller import (
@@ -360,3 +361,35 @@ def reset(self, env_ids: Sequence[int] | None = None) -> None:
360361
env_ids: A list of environment IDs to reset. If None, all environments are reset.
361362
"""
362363
self._raw_actions[env_ids] = torch.zeros(self.action_dim, device=self.device)
364+
365+
def preprocess_actions(self, actions: torch.Tensor) -> torch.Tensor:
366+
"""Transform wrist positions and orientations from world frame to robot base frame.
367+
368+
Args:
369+
actions: The input actions tensor, shape (action_dim,) or (1, action_dim).
370+
371+
Returns:
372+
The processed actions tensor (same shape as input).
373+
"""
374+
actions = actions.clone()
375+
376+
robot_base_pos = self._asset.data.root_link_pos_w[0, :3]
377+
robot_base_quat = self._asset.data.root_link_quat_w[0]
378+
379+
wrist_pos_world = torch.stack([actions[0, 2:5], actions[0, 9:12]], dim=0)
380+
wrist_pos_translated = wrist_pos_world - robot_base_pos
381+
robot_base_quat_batch = robot_base_quat.unsqueeze(0).expand(2, -1)
382+
wrist_pos_base = math_utils.quat_apply_inverse(
383+
robot_base_quat_batch, wrist_pos_translated
384+
)
385+
386+
wrist_quat_world = torch.stack([actions[0, 5:9], actions[0, 12:16]], dim=0)
387+
robot_base_quat_inv = math_utils.quat_inv(robot_base_quat.unsqueeze(0)).expand(2, -1)
388+
wrist_quat_base = math_utils.quat_mul(robot_base_quat_inv, wrist_quat_world)
389+
390+
actions[0, 2:5] = wrist_pos_base[0]
391+
actions[0, 5:9] = wrist_quat_base[0]
392+
actions[0, 9:12] = wrist_pos_base[1]
393+
actions[0, 12:16] = wrist_quat_base[1]
394+
395+
return actions

0 commit comments

Comments
 (0)