Skip to content

Commit eedaa3e

Browse files
committed
Create tracked types with optional data to handle inactive input sources
1 parent 8e31a16 commit eedaa3e

File tree

69 files changed

+1646
-1413
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+1646
-1413
lines changed

examples/lerobot/record.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -115,31 +115,37 @@ def main():
115115
break
116116

117117
# Get hand data
118-
left: schema.HandPoseT = hand_tracker.get_left_hand(session)
119-
right: schema.HandPoseT = hand_tracker.get_right_hand(session)
120-
head: schema.HeadPoseT = head_tracker.get_head(session)
118+
left_tracked: schema.HandPoseTrackedT = hand_tracker.get_left_hand(
119+
session
120+
)
121+
right_tracked: schema.HandPoseTrackedT = (
122+
hand_tracker.get_right_hand(session)
123+
)
124+
head_tracked: schema.HeadPoseTrackedT = head_tracker.get_head(
125+
session
126+
)
121127

122128
# Extract positions and orientations (with defaults for invalid data)
123129
left_pos = np.zeros(3, dtype=np.float32)
124130
right_pos = np.zeros(3, dtype=np.float32)
125131

126-
if left.is_active and left.joints:
127-
wrist = left.joints[deviceio.JOINT_WRIST]
132+
if left_tracked.data is not None and left_tracked.data.joints:
133+
wrist = left_tracked.data.joints.poses(deviceio.JOINT_WRIST)
128134
if wrist.is_valid:
129135
pos = wrist.pose.position
130136
left_pos = np.array([pos.x, pos.y, pos.z], dtype=np.float32)
131137

132-
if right.is_active and right.joints:
133-
wrist = right.joints[deviceio.JOINT_WRIST]
138+
if right_tracked.data is not None and right_tracked.data.joints:
139+
wrist = right_tracked.data.joints.poses(deviceio.JOINT_WRIST)
134140
if wrist.is_valid:
135141
pos = wrist.pose.position
136142
right_pos = np.array(
137143
[pos.x, pos.y, pos.z], dtype=np.float32
138144
)
139145

140146
head_pos = np.zeros(3, dtype=np.float32)
141-
if head.is_valid and head.pose:
142-
pos = head.pose.position
147+
if head_tracked.data is not None and head_tracked.data.is_valid:
148+
pos = head_tracked.data.pose.position
143149
head_pos = np.array([pos.x, pos.y, pos.z], dtype=np.float32)
144150

145151
# STEP 3: Record frame to dataset

examples/oxr/cpp/oxr_session_sharing.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,17 +89,17 @@ try
8989
}
9090

9191
// Get data from both trackers
92-
const auto& left = hand_tracker->get_left_hand(*session1);
93-
const auto& head = head_tracker->get_head(*session2);
92+
const auto& left_tracked = hand_tracker->get_left_hand(*session1);
93+
const auto& head_tracked = head_tracker->get_head(*session2);
9494

9595
if (i % 3 == 0)
9696
{
9797
std::cout << "Frame " << i << ": "
98-
<< "Hands=" << (left.is_active ? "ACTIVE" : "INACTIVE") << " | "
99-
<< "Head=" << (head.is_valid ? "VALID" : "INVALID");
100-
if (head.is_valid && head.pose)
98+
<< "Hands=" << (left_tracked.data ? "ACTIVE" : "INACTIVE") << " | "
99+
<< "Head=" << ((head_tracked.data && head_tracked.data->is_valid) ? "VALID" : "INVALID");
100+
if (head_tracked.data && head_tracked.data->is_valid && head_tracked.data->pose)
101101
{
102-
const auto& pos = head.pose->position();
102+
const auto& pos = head_tracked.data->pose->position();
103103
std::cout << " [" << pos.x() << ", " << pos.y() << ", " << pos.z() << "]";
104104
}
105105
std::cout << std::endl;

examples/oxr/cpp/oxr_simple_api_demo.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,18 +82,19 @@ try
8282
}
8383

8484
// External user only uses public query methods
85-
const auto& left = hand_tracker->get_left_hand(*session);
86-
const auto& right = hand_tracker->get_right_hand(*session);
87-
const auto& head = head_tracker->get_head(*session);
85+
const auto& left_tracked = hand_tracker->get_left_hand(*session);
86+
const auto& right_tracked = hand_tracker->get_right_hand(*session);
87+
const auto& head_tracked = head_tracker->get_head(*session);
8888

8989
std::cout << "Frame " << i << ":" << std::endl;
90-
std::cout << " Left hand: " << (left.is_active ? "ACTIVE" : "INACTIVE") << std::endl;
91-
std::cout << " Right hand: " << (right.is_active ? "ACTIVE" : "INACTIVE") << std::endl;
92-
std::cout << " Head pose: " << (head.is_valid ? "VALID" : "INVALID") << std::endl;
90+
std::cout << " Left hand: " << (left_tracked.data ? "ACTIVE" : "INACTIVE") << std::endl;
91+
std::cout << " Right hand: " << (right_tracked.data ? "ACTIVE" : "INACTIVE") << std::endl;
92+
std::cout << " Head pose: " << ((head_tracked.data && head_tracked.data->is_valid) ? "VALID" : "INVALID")
93+
<< std::endl;
9394

94-
if (head.is_valid && head.pose)
95+
if (head_tracked.data && head_tracked.data->is_valid && head_tracked.data->pose)
9596
{
96-
const auto& pos = head.pose->position();
97+
const auto& pos = head_tracked.data->pose->position();
9798
std::cout << " Position: [" << pos.x() << ", " << pos.y() << ", " << pos.z() << "]" << std::endl;
9899
}
99100
std::cout << std::endl;

examples/oxr/python/modular_example.py

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import time
1616
import isaacteleop.deviceio as deviceio
1717
import isaacteleop.oxr as oxr
18+
import isaacteleop.schema as schema
1819

1920

2021
def main():
@@ -70,31 +71,44 @@ def main():
7071
print(f"[{elapsed:4.1f}s] Frame {frame_count}")
7172

7273
# Get hand data
73-
left = hand_tracker.get_left_hand(session)
74-
right = hand_tracker.get_right_hand(session)
75-
76-
print(
77-
f" Hands: Left={'ACTIVE' if left.is_active else 'INACTIVE':8s} | "
78-
f"Right={'ACTIVE' if right.is_active else 'INACTIVE':8s}"
74+
left_tracked: schema.HandPoseTrackedT = (
75+
hand_tracker.get_left_hand(session)
76+
)
77+
right_tracked: schema.HandPoseTrackedT = (
78+
hand_tracker.get_right_hand(session)
7979
)
8080

81-
if left.is_active:
82-
wrist = left.joints[deviceio.JOINT_WRIST]
83-
if wrist.is_valid:
84-
pos = wrist.pose.position
85-
print(
86-
f" Left wrist: [{pos.x:6.3f}, {pos.y:6.3f}, {pos.z:6.3f}]"
87-
)
81+
if left_tracked.data is not None:
82+
pos = left_tracked.data.joints.poses(
83+
deviceio.JOINT_WRIST
84+
).pose.position
85+
print(
86+
f" Left wrist: [{pos.x:6.3f}, {pos.y:6.3f}, {pos.z:6.3f}]"
87+
)
88+
else:
89+
print(" Left hand: inactive")
8890

89-
# Get head data (returns HeadPoseT from schema)
90-
head = head_tracker.get_head(session)
91-
print(f" Head: {'VALID' if head.is_valid else 'INVALID':8s}")
91+
if right_tracked.data is not None:
92+
pos = right_tracked.data.joints.poses(
93+
deviceio.JOINT_WRIST
94+
).pose.position
95+
print(
96+
f" Right wrist: [{pos.x:6.3f}, {pos.y:6.3f}, {pos.z:6.3f}]"
97+
)
98+
else:
99+
print(" Right hand: inactive")
92100

93-
if head.is_valid and head.pose:
94-
pos = head.pose.position
101+
# Get head data
102+
head_tracked: schema.HeadPoseTrackedT = head_tracker.get_head(
103+
session
104+
)
105+
if head_tracked.data is not None:
106+
pos = head_tracked.data.pose.position
95107
print(
96-
f" Head position: [{pos.x:6.3f}, {pos.y:6.3f}, {pos.z:6.3f}]"
108+
f" Head pos: [{pos.x:6.3f}, {pos.y:6.3f}, {pos.z:6.3f}]"
97109
)
110+
else:
111+
print(" Head: inactive")
98112

99113
print()
100114

examples/oxr/python/test_controller_tracker.py

Lines changed: 50 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -57,22 +57,20 @@
5757

5858
# Test 5: Check initial controller state
5959
print("[Test 5] Checking controller state...")
60-
left_snapshot = controller_tracker.get_left_controller(session)
61-
right_snapshot = controller_tracker.get_right_controller(session)
62-
print(
63-
f" Left controller: {'ACTIVE' if left_snapshot.is_active else 'INACTIVE'}"
64-
)
65-
print(
66-
f" Right controller: {'ACTIVE' if right_snapshot.is_active else 'INACTIVE'}"
67-
)
68-
69-
if left_snapshot.is_active and left_snapshot.grip_pose.is_valid:
70-
pos = left_snapshot.grip_pose.pose.position
71-
print(f" Left grip position: [{pos.x:.3f}, {pos.y:.3f}, {pos.z:.3f}]")
72-
73-
if right_snapshot.is_active and right_snapshot.grip_pose.is_valid:
74-
pos = right_snapshot.grip_pose.pose.position
75-
print(f" Right grip position: [{pos.x:.3f}, {pos.y:.3f}, {pos.z:.3f}]")
60+
left_tracked = controller_tracker.get_left_controller(session)
61+
right_tracked = controller_tracker.get_right_controller(session)
62+
63+
if left_tracked.data is not None and left_tracked.data.grip_pose.is_valid:
64+
pos = left_tracked.data.grip_pose.pose.position
65+
print(f" Left grip: [{pos.x:.3f}, {pos.y:.3f}, {pos.z:.3f}]")
66+
else:
67+
print(" Left: inactive")
68+
69+
if right_tracked.data is not None and right_tracked.data.grip_pose.is_valid:
70+
pos = right_tracked.data.grip_pose.pose.position
71+
print(f" Right grip: [{pos.x:.3f}, {pos.y:.3f}, {pos.z:.3f}]")
72+
else:
73+
print(" Right: inactive")
7674
print()
7775

7876
# Test 6: Available inputs
@@ -100,48 +98,32 @@
10098
current_time = time.time()
10199
if current_time - last_status_print >= 0.5: # Print every 0.5 seconds
102100
elapsed = current_time - start_time
103-
left_snapshot = controller_tracker.get_left_controller(session)
104-
right_snapshot = controller_tracker.get_right_controller(session)
105-
106-
# Show current state
107-
left_trigger = left_snapshot.inputs.trigger_value
108-
left_squeeze = left_snapshot.inputs.squeeze_value
109-
left_stick_x = left_snapshot.inputs.thumbstick_x
110-
left_stick_y = left_snapshot.inputs.thumbstick_y
111-
left_primary = left_snapshot.inputs.primary_click
112-
left_secondary = left_snapshot.inputs.secondary_click
113-
114-
right_trigger = right_snapshot.inputs.trigger_value
115-
right_squeeze = right_snapshot.inputs.squeeze_value
116-
right_stick_x = right_snapshot.inputs.thumbstick_x
117-
right_stick_y = right_snapshot.inputs.thumbstick_y
118-
right_primary = right_snapshot.inputs.primary_click
119-
right_secondary = right_snapshot.inputs.secondary_click
120-
121-
# Build status strings
122-
left_status = f"Trig={left_trigger:.2f} Sq={left_squeeze:.2f}"
123-
if abs(left_stick_x) > 0.1 or abs(left_stick_y) > 0.1:
124-
left_status += (
125-
f" Stick=({left_stick_x:+.2f},{left_stick_y:+.2f})"
101+
left_tracked = controller_tracker.get_left_controller(session)
102+
right_tracked = controller_tracker.get_right_controller(session)
103+
104+
print(f" [{elapsed:5.2f}s] Frame {frame_count:4d}")
105+
106+
left_data = left_tracked.data
107+
if left_data is not None:
108+
li = left_data.inputs
109+
print(
110+
f" L: Trig={li.trigger_value:.2f} Sq={li.squeeze_value:.2f}"
111+
f" Stick=({li.thumbstick_x:+.2f},{li.thumbstick_y:+.2f})"
112+
f" Btn=[{int(li.primary_click)}{int(li.secondary_click)}{int(li.thumbstick_click)}]"
126113
)
127-
if left_primary:
128-
left_status += " [X]"
129-
if left_secondary:
130-
left_status += " [Y]"
131-
132-
right_status = f"Trig={right_trigger:.2f} Sq={right_squeeze:.2f}"
133-
if abs(right_stick_x) > 0.1 or abs(right_stick_y) > 0.1:
134-
right_status += (
135-
f" Stick=({right_stick_x:+.2f},{right_stick_y:+.2f})"
114+
else:
115+
print(" L: INACTIVE")
116+
117+
right_data = right_tracked.data
118+
if right_data is not None:
119+
ri = right_data.inputs
120+
print(
121+
f" R: Trig={ri.trigger_value:.2f} Sq={ri.squeeze_value:.2f}"
122+
f" Stick=({ri.thumbstick_x:+.2f},{ri.thumbstick_y:+.2f})"
123+
f" Btn=[{int(ri.primary_click)}{int(ri.secondary_click)}{int(ri.thumbstick_click)}]"
136124
)
137-
if right_primary:
138-
right_status += " [A]"
139-
if right_secondary:
140-
right_status += " [B]"
141-
142-
print(
143-
f" [{elapsed:5.2f}s] Frame {frame_count:4d} | L: {left_status} | R: {right_status}"
144-
)
125+
else:
126+
print(" R: INACTIVE")
145127
last_status_print = current_time
146128

147129
frame_count += 1
@@ -157,29 +139,14 @@
157139
# Test 8: Show final statistics
158140
print("[Test 8] Final controller state...")
159141

160-
def print_controller_summary(hand_name, snapshot):
142+
def print_controller_summary(hand_name, tracked):
161143
print(f" {hand_name} Controller:")
162-
if snapshot.is_active:
163-
print(" Status: ACTIVE")
164-
165-
# Poses from snapshot
166-
grip = snapshot.grip_pose
167-
aim = snapshot.aim_pose
168-
169-
if grip.is_valid:
170-
pos = grip.pose.position
171-
print(
172-
f" Grip position: [{pos.x:+.3f}, {pos.y:+.3f}, {pos.z:+.3f}]"
173-
)
174-
175-
if aim.is_valid:
176-
pos = aim.pose.position
177-
print(
178-
f" Aim position: [{pos.x:+.3f}, {pos.y:+.3f}, {pos.z:+.3f}]"
179-
)
180-
181-
# Input values
182-
inputs = snapshot.inputs
144+
if tracked.data is not None:
145+
pos = tracked.data.grip_pose.pose.position
146+
print(f" Grip position: [{pos.x:+.3f}, {pos.y:+.3f}, {pos.z:+.3f}]")
147+
pos = tracked.data.aim_pose.pose.position
148+
print(f" Aim position: [{pos.x:+.3f}, {pos.y:+.3f}, {pos.z:+.3f}]")
149+
inputs = tracked.data.inputs
183150
print(f" Trigger: {inputs.trigger_value:.2f}")
184151
print(f" Squeeze: {inputs.squeeze_value:.2f}")
185152
print(
@@ -192,13 +159,13 @@ def print_controller_summary(hand_name, snapshot):
192159
f" Secondary: {'PRESSED' if inputs.secondary_click else 'released'}"
193160
)
194161
else:
195-
print(" Status: INACTIVE")
162+
print(" inactive")
196163

197-
left_snapshot = controller_tracker.get_left_controller(session)
198-
right_snapshot = controller_tracker.get_right_controller(session)
199-
print_controller_summary("Left", left_snapshot)
164+
left_tracked = controller_tracker.get_left_controller(session)
165+
right_tracked = controller_tracker.get_right_controller(session)
166+
print_controller_summary("Left", left_tracked)
200167
print()
201-
print_controller_summary("Right", right_snapshot)
168+
print_controller_summary("Right", right_tracked)
202169
print()
203170

204171
# Cleanup

examples/oxr/python/test_extensions.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,19 @@
8888

8989
# Quick update test
9090
if session.update():
91-
left = hand.get_left_hand(session)
92-
head_pose = head.get_head(session)
91+
left_tracked = hand.get_left_hand(session)
92+
head_tracked = head.get_head(session)
9393
print(" ✅ Update successful")
94-
print(f" Hands: {'ACTIVE' if left.is_active else 'INACTIVE'}")
95-
print(f" Head: {'VALID' if head_pose.is_valid else 'INVALID'}")
94+
if left_tracked.data is not None:
95+
pos = left_tracked.data.joints.poses(deviceio.JOINT_WRIST).pose.position
96+
print(f" Left wrist: [{pos.x:.3f}, {pos.y:.3f}, {pos.z:.3f}]")
97+
else:
98+
print(" Left hand: inactive")
99+
if head_tracked.data is not None:
100+
pos = head_tracked.data.pose.position
101+
print(f" Head pos: [{pos.x:.3f}, {pos.y:.3f}, {pos.z:.3f}]")
102+
else:
103+
print(" Head: inactive")
96104

97105
# Session will be cleaned up when exiting 'with' block (RAII)
98106

0 commit comments

Comments
 (0)