Skip to content

Commit b1e2a42

Browse files
committed
Move the Direct observation kernels into the family kernel module
Relocates out_of_reach/full_obs/reduced_obs kernels from reorient_direct_env.py to reorient_kernels.py and lifts the stray mid-file imports to the top of the module.
1 parent 8596837 commit b1e2a42

2 files changed

Lines changed: 154 additions & 157 deletions

File tree

source/isaaclab_tasks/isaaclab_tasks/core/reorient/reorient_direct_env.py

Lines changed: 8 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -25,162 +25,13 @@
2525
ReorientRewardBuffers,
2626
direct_reorient_reward,
2727
ema_actuation_kernel,
28-
fingertip_pos_col,
29-
fingertip_quat_col,
30-
fingertip_vel_col,
28+
full_obs_kernel,
29+
out_of_reach_kernel,
30+
reduced_obs_kernel,
3131
reorient_success_kernel,
3232
)
33-
from isaaclab_tasks.core.utils import randomize_rotation
34-
35-
36-
@wp.kernel
37-
def _out_of_reach_kernel(
38-
object_pos_w: wp.array(dtype=wp.vec3f),
39-
env_origins: wp.array(dtype=wp.vec3f),
40-
target_pos_e: wp.array(dtype=wp.vec3f),
41-
fall_distance: float,
42-
out_of_reach: wp.array(dtype=wp.bool),
43-
):
44-
i = wp.tid()
45-
out_of_reach[i] = wp.length(object_pos_w[i] - env_origins[i] - target_pos_e[i]) >= fall_distance
46-
47-
48-
@wp.kernel
49-
def _full_obs_kernel(
50-
joint_pos: wp.array2d(dtype=wp.float32),
51-
joint_vel: wp.array2d(dtype=wp.float32),
52-
lower: wp.array2d(dtype=wp.float32),
53-
upper: wp.array2d(dtype=wp.float32),
54-
vel_scale: float,
55-
object_pos_w: wp.array(dtype=wp.vec3f),
56-
env_origins: wp.array(dtype=wp.vec3f),
57-
object_quat: wp.array(dtype=wp.quatf),
58-
object_lin_vel: wp.array(dtype=wp.vec3f),
59-
object_ang_vel: wp.array(dtype=wp.vec3f),
60-
in_hand_pos_e: wp.array(dtype=wp.vec3f),
61-
goal_quat: wp.array(dtype=wp.quatf),
62-
body_pos_w: wp.array2d(dtype=wp.vec3f),
63-
body_quat_w: wp.array2d(dtype=wp.quatf),
64-
body_vel_w: wp.array2d(dtype=wp.spatial_vectorf),
65-
finger_ids: wp.array(dtype=wp.int32),
66-
force: wp.array2d(dtype=wp.vec3f),
67-
torque: wp.array2d(dtype=wp.vec3f),
68-
wrench_ids: wp.array(dtype=wp.int32),
69-
force_scale: float,
70-
with_forces: int,
71-
actions: wp.array2d(dtype=wp.float32),
72-
out: wp.array2d(dtype=wp.float32),
73-
):
74-
"""Direct full observation / full state, matching the torch concatenation order.
75-
76-
Launched over ``(num_envs, obs_dim)``: each thread walks a branch ladder over the
77-
segment boundaries and writes one output column, so warps (32 consecutive columns)
78-
stay branch-uniform except at segment boundaries.
79-
"""
80-
i, j = wp.tid()
81-
num_joints = joint_pos.shape[1]
82-
num_fingers = finger_ids.shape[0]
83-
# segment boundaries, in column order
84-
end_joint = 2 * num_joints
85-
end_object = end_joint + 13
86-
end_goal = end_object + 11
87-
end_tip_pos = end_goal + 3 * num_fingers
88-
end_tip_quat = end_tip_pos + 4 * num_fingers
89-
end_tip_vel = end_tip_quat + 6 * num_fingers
90-
end_wrench = end_tip_vel
91-
if with_forces != 0:
92-
end_wrench += 6 * num_fingers
93-
# hand: normalized DOF positions, scaled DOF velocities
94-
if j < num_joints:
95-
out[i, j] = 2.0 * (joint_pos[i, j] - lower[i, j]) / (upper[i, j] - lower[i, j]) - 1.0
96-
elif j < end_joint:
97-
out[i, j] = vel_scale * joint_vel[i, j - num_joints]
98-
# object pose and velocities (environment frame position)
99-
elif j < end_object:
100-
k = j - end_joint
101-
if k < 3:
102-
p = object_pos_w[i] - env_origins[i]
103-
out[i, j] = p[k]
104-
elif k < 7:
105-
out[i, j] = object_quat[i][k - 3]
106-
elif k < 10:
107-
out[i, j] = object_lin_vel[i][k - 7]
108-
else:
109-
out[i, j] = vel_scale * object_ang_vel[i][k - 10]
110-
# goal: in-hand anchor, goal rotation, and the goal-to-object rotation difference
111-
elif j < end_goal:
112-
k = j - end_object
113-
if k < 3:
114-
out[i, j] = in_hand_pos_e[i][k]
115-
elif k < 7:
116-
out[i, j] = goal_quat[i][k - 3]
117-
else:
118-
# quat_inverse == conjugate for these unit quaternions, matching
119-
# isaaclab.utils.math.quat_mul/quat_conjugate semantics
120-
qe = object_quat[i] * wp.quat_inverse(goal_quat[i])
121-
out[i, j] = qe[k - 7]
122-
# fingertips: environment-frame positions, rotations, spatial velocities
123-
elif j < end_tip_pos:
124-
out[i, j] = fingertip_pos_col(body_pos_w, env_origins, finger_ids, i, j - end_goal)
125-
elif j < end_tip_quat:
126-
out[i, j] = fingertip_quat_col(body_quat_w, finger_ids, i, j - end_tip_pos)
127-
elif j < end_tip_vel:
128-
out[i, j] = fingertip_vel_col(body_vel_w, finger_ids, i, j - end_tip_quat)
129-
# fingertip force/torque sensors (full state only; absent when with_forces == 0)
130-
elif j < end_wrench:
131-
if with_forces == 1:
132-
k = j - end_tip_vel
133-
c = k % 6
134-
if c < 3:
135-
out[i, j] = force_scale * force[i, wrench_ids[k // 6]][c]
136-
else:
137-
out[i, j] = force_scale * torque[i, wrench_ids[k // 6]][c - 3]
138-
else:
139-
# full state requested but the sensor has no data yet: zero block
140-
out[i, j] = 0.0
141-
# actions
142-
else:
143-
out[i, j] = actions[i, j - end_wrench]
144-
145-
146-
@wp.kernel
147-
def _reduced_obs_kernel(
148-
body_pos_w: wp.array2d(dtype=wp.vec3f),
149-
env_origins: wp.array(dtype=wp.vec3f),
150-
finger_ids: wp.array(dtype=wp.int32),
151-
object_pos_w: wp.array(dtype=wp.vec3f),
152-
object_quat: wp.array(dtype=wp.quatf),
153-
goal_quat: wp.array(dtype=wp.quatf),
154-
actions: wp.array2d(dtype=wp.float32),
155-
out: wp.array2d(dtype=wp.float32),
156-
):
157-
"""Direct reduced (OpenAI) observation, matching the torch concatenation order."""
158-
i = wp.tid()
159-
num_fingers = finger_ids.shape[0]
160-
for f in range(num_fingers):
161-
fp = body_pos_w[i, finger_ids[f]] - env_origins[i]
162-
out[i, 3 * f + 0] = fp[0]
163-
out[i, 3 * f + 1] = fp[1]
164-
out[i, 3 * f + 2] = fp[2]
165-
idx = 3 * num_fingers
166-
p = object_pos_w[i] - env_origins[i]
167-
# quat_inverse == conjugate for these unit quaternions, matching
168-
# isaaclab.utils.math.quat_mul/quat_conjugate semantics
169-
qe = object_quat[i] * wp.quat_inverse(goal_quat[i])
170-
out[i, idx + 0] = p[0]
171-
out[i, idx + 1] = p[1]
172-
out[i, idx + 2] = p[2]
173-
out[i, idx + 3] = qe[0]
174-
out[i, idx + 4] = qe[1]
175-
out[i, idx + 5] = qe[2]
176-
out[i, idx + 6] = qe[3]
177-
idx += 7
178-
for a in range(actions.shape[1]):
179-
out[i, idx + a] = actions[i, a]
180-
181-
18233
from isaaclab_tasks.core.reorient.reorient_task_base import GOAL_MARKER_POSITION, IN_HAND_POS_OFFSET
183-
from isaaclab_tasks.core.utils import EpisodeErrorRecorder, sample_joint_positions_within_limits
34+
from isaaclab_tasks.core.utils import EpisodeErrorRecorder, randomize_rotation, sample_joint_positions_within_limits
18435

18536
if TYPE_CHECKING:
18637
from isaaclab_tasks.core.reorient.config.allegro_hand.allegro_hand_direct_env_cfg import AllegroHandEnvCfg
@@ -422,7 +273,7 @@ def _get_rewards(self) -> torch.Tensor:
422273
def _get_dones(self) -> tuple[torch.Tensor, torch.Tensor]:
423274
# reset when cube has fallen
424275
wp.launch(
425-
_out_of_reach_kernel,
276+
out_of_reach_kernel,
426277
dim=self.num_envs,
427278
inputs=[
428279
self.object.data.root_pos_w.warp,
@@ -545,7 +396,7 @@ def _compute_intermediate_values(self):
545396
def compute_reduced_observations(self):
546397
# Per https://arxiv.org/pdf/1808.00177.pdf Table 2
547398
wp.launch(
548-
_reduced_obs_kernel,
399+
reduced_obs_kernel,
549400
dim=self.num_envs,
550401
inputs=[
551402
self.hand.data.body_pos_w.warp,
@@ -564,7 +415,7 @@ def compute_reduced_observations(self):
564415
def compute_full_observations(self):
565416
force_wp, torque_wp = self._dummy_wrench_wp, self._dummy_wrench_wp
566417
wp.launch(
567-
_full_obs_kernel,
418+
full_obs_kernel,
568419
dim=(self.num_envs, self._policy_obs_buf_wp.shape[1]),
569420
inputs=[
570421
self.hand.data.joint_pos.warp,
@@ -603,7 +454,7 @@ def compute_full_state(self):
603454
if force_data is not None and torque_data is not None:
604455
force_wp, torque_wp, with_forces = force_data.warp, torque_data.warp, 1
605456
wp.launch(
606-
_full_obs_kernel,
457+
full_obs_kernel,
607458
dim=(self.num_envs, self._state_obs_buf_wp.shape[1]),
608459
inputs=[
609460
self.hand.data.joint_pos.warp,

source/isaaclab_tasks/isaaclab_tasks/core/reorient/reorient_kernels.py

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,3 +423,149 @@ def compute_cube_keypoints(
423423
device=wp.device_from_torch(pose.device),
424424
)
425425
return out
426+
427+
428+
@wp.kernel
429+
def out_of_reach_kernel(
430+
object_pos_w: wp.array(dtype=wp.vec3f),
431+
env_origins: wp.array(dtype=wp.vec3f),
432+
target_pos_e: wp.array(dtype=wp.vec3f),
433+
fall_distance: float,
434+
out_of_reach: wp.array(dtype=wp.bool),
435+
):
436+
i = wp.tid()
437+
out_of_reach[i] = wp.length(object_pos_w[i] - env_origins[i] - target_pos_e[i]) >= fall_distance
438+
439+
440+
@wp.kernel
441+
def full_obs_kernel(
442+
joint_pos: wp.array2d(dtype=wp.float32),
443+
joint_vel: wp.array2d(dtype=wp.float32),
444+
lower: wp.array2d(dtype=wp.float32),
445+
upper: wp.array2d(dtype=wp.float32),
446+
vel_scale: float,
447+
object_pos_w: wp.array(dtype=wp.vec3f),
448+
env_origins: wp.array(dtype=wp.vec3f),
449+
object_quat: wp.array(dtype=wp.quatf),
450+
object_lin_vel: wp.array(dtype=wp.vec3f),
451+
object_ang_vel: wp.array(dtype=wp.vec3f),
452+
in_hand_pos_e: wp.array(dtype=wp.vec3f),
453+
goal_quat: wp.array(dtype=wp.quatf),
454+
body_pos_w: wp.array2d(dtype=wp.vec3f),
455+
body_quat_w: wp.array2d(dtype=wp.quatf),
456+
body_vel_w: wp.array2d(dtype=wp.spatial_vectorf),
457+
finger_ids: wp.array(dtype=wp.int32),
458+
force: wp.array2d(dtype=wp.vec3f),
459+
torque: wp.array2d(dtype=wp.vec3f),
460+
wrench_ids: wp.array(dtype=wp.int32),
461+
force_scale: float,
462+
with_forces: int,
463+
actions: wp.array2d(dtype=wp.float32),
464+
out: wp.array2d(dtype=wp.float32),
465+
):
466+
"""Direct full observation / full state, matching the torch concatenation order.
467+
468+
Launched over ``(num_envs, obs_dim)``: each thread walks a branch ladder over the
469+
segment boundaries and writes one output column, so warps (32 consecutive columns)
470+
stay branch-uniform except at segment boundaries.
471+
"""
472+
i, j = wp.tid()
473+
num_joints = joint_pos.shape[1]
474+
num_fingers = finger_ids.shape[0]
475+
# segment boundaries, in column order
476+
end_joint = 2 * num_joints
477+
end_object = end_joint + 13
478+
end_goal = end_object + 11
479+
end_tip_pos = end_goal + 3 * num_fingers
480+
end_tip_quat = end_tip_pos + 4 * num_fingers
481+
end_tip_vel = end_tip_quat + 6 * num_fingers
482+
end_wrench = end_tip_vel
483+
if with_forces != 0:
484+
end_wrench += 6 * num_fingers
485+
# hand: normalized DOF positions, scaled DOF velocities
486+
if j < num_joints:
487+
out[i, j] = 2.0 * (joint_pos[i, j] - lower[i, j]) / (upper[i, j] - lower[i, j]) - 1.0
488+
elif j < end_joint:
489+
out[i, j] = vel_scale * joint_vel[i, j - num_joints]
490+
# object pose and velocities (environment frame position)
491+
elif j < end_object:
492+
k = j - end_joint
493+
if k < 3:
494+
p = object_pos_w[i] - env_origins[i]
495+
out[i, j] = p[k]
496+
elif k < 7:
497+
out[i, j] = object_quat[i][k - 3]
498+
elif k < 10:
499+
out[i, j] = object_lin_vel[i][k - 7]
500+
else:
501+
out[i, j] = vel_scale * object_ang_vel[i][k - 10]
502+
# goal: in-hand anchor, goal rotation, and the goal-to-object rotation difference
503+
elif j < end_goal:
504+
k = j - end_object
505+
if k < 3:
506+
out[i, j] = in_hand_pos_e[i][k]
507+
elif k < 7:
508+
out[i, j] = goal_quat[i][k - 3]
509+
else:
510+
# quat_inverse == conjugate for these unit quaternions, matching
511+
# isaaclab.utils.math.quat_mul/quat_conjugate semantics
512+
qe = object_quat[i] * wp.quat_inverse(goal_quat[i])
513+
out[i, j] = qe[k - 7]
514+
# fingertips: environment-frame positions, rotations, spatial velocities
515+
elif j < end_tip_pos:
516+
out[i, j] = fingertip_pos_col(body_pos_w, env_origins, finger_ids, i, j - end_goal)
517+
elif j < end_tip_quat:
518+
out[i, j] = fingertip_quat_col(body_quat_w, finger_ids, i, j - end_tip_pos)
519+
elif j < end_tip_vel:
520+
out[i, j] = fingertip_vel_col(body_vel_w, finger_ids, i, j - end_tip_quat)
521+
# fingertip force/torque sensors (full state only; absent when with_forces == 0)
522+
elif j < end_wrench:
523+
if with_forces == 1:
524+
k = j - end_tip_vel
525+
c = k % 6
526+
if c < 3:
527+
out[i, j] = force_scale * force[i, wrench_ids[k // 6]][c]
528+
else:
529+
out[i, j] = force_scale * torque[i, wrench_ids[k // 6]][c - 3]
530+
else:
531+
# full state requested but the sensor has no data yet: zero block
532+
out[i, j] = 0.0
533+
# actions
534+
else:
535+
out[i, j] = actions[i, j - end_wrench]
536+
537+
538+
@wp.kernel
539+
def reduced_obs_kernel(
540+
body_pos_w: wp.array2d(dtype=wp.vec3f),
541+
env_origins: wp.array(dtype=wp.vec3f),
542+
finger_ids: wp.array(dtype=wp.int32),
543+
object_pos_w: wp.array(dtype=wp.vec3f),
544+
object_quat: wp.array(dtype=wp.quatf),
545+
goal_quat: wp.array(dtype=wp.quatf),
546+
actions: wp.array2d(dtype=wp.float32),
547+
out: wp.array2d(dtype=wp.float32),
548+
):
549+
"""Direct reduced (OpenAI) observation, matching the torch concatenation order."""
550+
i = wp.tid()
551+
num_fingers = finger_ids.shape[0]
552+
for f in range(num_fingers):
553+
fp = body_pos_w[i, finger_ids[f]] - env_origins[i]
554+
out[i, 3 * f + 0] = fp[0]
555+
out[i, 3 * f + 1] = fp[1]
556+
out[i, 3 * f + 2] = fp[2]
557+
idx = 3 * num_fingers
558+
p = object_pos_w[i] - env_origins[i]
559+
# quat_inverse == conjugate for these unit quaternions, matching
560+
# isaaclab.utils.math.quat_mul/quat_conjugate semantics
561+
qe = object_quat[i] * wp.quat_inverse(goal_quat[i])
562+
out[i, idx + 0] = p[0]
563+
out[i, idx + 1] = p[1]
564+
out[i, idx + 2] = p[2]
565+
out[i, idx + 3] = qe[0]
566+
out[i, idx + 4] = qe[1]
567+
out[i, idx + 5] = qe[2]
568+
out[i, idx + 6] = qe[3]
569+
idx += 7
570+
for a in range(actions.shape[1]):
571+
out[i, idx + a] = actions[i, a]

0 commit comments

Comments
 (0)