Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/source/device/add_device.rst
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ tensor samples from OpenXR. Implement a concrete tracker class (e.g.
- **Factory registration** — Register your tracker in the live factory dispatch table
(see ``LiveDeviceIOFactory``). The factory constructs an ``ITrackerImpl`` that holds
a ``SchemaTracker``, builds a ``SchemaTrackerConfig`` from the tracker's stored
configuration, and implements ``update(XrTime)`` and
configuration, and implements ``update(int64_t monotonic_time_ns)`` and
``serialize_all(channel_index, callback)``.

In the **Impl**:
Expand Down
2 changes: 1 addition & 1 deletion examples/lerobot/record.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def main():
try:
while time.time() - start_time < 10.0:
# Update session and all trackers
session.update()
session.update(time.monotonic_ns())

# Get hand data
left_tracked: schema.HandPoseTrackedT = hand_tracker.get_left_hand(
Expand Down
6 changes: 4 additions & 2 deletions examples/oxr/cpp/oxr_session_sharing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <deviceio_trackers/hand_tracker.hpp>
#include <deviceio_trackers/head_tracker.hpp>
#include <oxr/oxr_session.hpp>
#include <oxr_utils/os_time.hpp>

#include <chrono>
#include <iostream>
Expand Down Expand Up @@ -76,8 +77,9 @@ try
for (int i = 0; i < 10; ++i)
{
// Both sessions update using the same underlying OpenXR session
session1->update();
session2->update();
const int64_t graph_time_ns = core::os_monotonic_now_ns();
session1->update(graph_time_ns);
session2->update(graph_time_ns);

// Get data from both trackers
const auto& left_tracked = hand_tracker->get_left_hand(*session1);
Expand Down
3 changes: 2 additions & 1 deletion examples/oxr/cpp/oxr_simple_api_demo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <deviceio_trackers/hand_tracker.hpp>
#include <deviceio_trackers/head_tracker.hpp>
#include <oxr/oxr_session.hpp>
#include <oxr_utils/os_time.hpp>

#include <iostream>
#include <memory>
Expand Down Expand Up @@ -76,7 +77,7 @@ try
for (int i = 0; i < 5; ++i)
{
// Session handles internal update() calls to trackers
session->update();
session->update(core::os_monotonic_now_ns());

// External user only uses public query methods
const auto& left_tracked = hand_tracker->get_left_hand(*session);
Expand Down
2 changes: 1 addition & 1 deletion examples/oxr/python/modular_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def main():

while time.time() - start_time < 10.0:
# Update session and all trackers
session.update()
session.update(time.monotonic_ns())

# Print every 60 frames (~1 second)
if frame_count % 60 == 0:
Expand Down
2 changes: 1 addition & 1 deletion examples/oxr/python/modular_example_with_mcap.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def main():
start_time = time.time()

while time.time() - start_time < 30.0:
session.update()
session.update(time.monotonic_ns())

# Print every 60 frames (~1 second)
if frame_count % 60 == 0:
Expand Down
4 changes: 2 additions & 2 deletions examples/oxr/python/test_controller_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@

# Test 4: Initial update
print("[Test 4] Testing initial data retrieval...")
session.update()
session.update(time.monotonic_ns())

print("✓ Update successful")
print()
Expand Down Expand Up @@ -101,7 +101,7 @@ def assert_trackers_consistent(label, ta, tb):
last_status_print = start_time

while time.time() - start_time < 10.0:
session.update()
session.update(time.monotonic_ns())

current_time = time.time()
if current_time - last_status_print >= 0.5:
Expand Down
4 changes: 3 additions & 1 deletion examples/oxr/python/test_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
do not expose get_required_extensions().
"""

import time

import isaacteleop.deviceio as deviceio
import isaacteleop.oxr as oxr

Expand Down Expand Up @@ -87,7 +89,7 @@
print(" ✅ Initialized successfully")

# Quick update test
session.update()
session.update(time.monotonic_ns())
left_tracked = hand.get_left_hand(session)
head_tracked = head.get_head(session)
print(" ✅ Update successful")
Expand Down
4 changes: 2 additions & 2 deletions examples/oxr/python/test_full_body_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@

# Test 5: Initial update
print("[Test 5] Testing initial data retrieval...")
session.update()
session.update(time.monotonic_ns())

print("✓ Update successful")
print()
Expand Down Expand Up @@ -86,7 +86,7 @@
last_status_print = start_time

while time.time() - start_time < 10.0:
session.update()
session.update(time.monotonic_ns())

# Get current body pose
current_time = time.time()
Expand Down
2 changes: 1 addition & 1 deletion examples/oxr/python/test_hand_inactive_on_plugin_stop.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

def poll_hands(hand_tracker, deviceio_session):
"""Return (left_active, right_active) for the current frame."""
deviceio_session.update()
deviceio_session.update(time.monotonic_ns())
left = hand_tracker.get_left_hand(deviceio_session)
right = hand_tracker.get_right_hand(deviceio_session)
return left.data is not None, right.data is not None
Expand Down
4 changes: 2 additions & 2 deletions examples/oxr/python/test_modular.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@

# Test 4: Update and get data
print("[Test 4] Testing data retrieval...")
session.update()
session.update(time.monotonic_ns())

print("✓ Update successful")
print()
Expand Down Expand Up @@ -89,7 +89,7 @@
start_time = time.time()

while time.time() - start_time < 5.0:
session.update()
session.update(time.monotonic_ns())

if frame_count % 60 == 0:
elapsed = time.time() - start_time
Expand Down
2 changes: 1 addition & 1 deletion examples/oxr/python/test_oak_camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def _run_schema_pusher(

while time.time() - start_time < duration:
plugin.check_health()
session.update()
session.update(time.monotonic_ns())
frame_count += 1

elapsed = time.time() - start_time
Expand Down
4 changes: 2 additions & 2 deletions examples/oxr/python/test_session_sharing.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@
frame_count = 0
while time.time() - start_time < 5.0:
# Both sessions update using the same underlying OpenXR session
session1.update()
session2.update()
session1.update(time.monotonic_ns())
session2.update(time.monotonic_ns())

# Print status every 60 frames
if frame_count % 60 == 0:
Expand Down
2 changes: 1 addition & 1 deletion examples/oxr/python/test_synthetic_hands.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def run_test():
if frame_count % 60 == 0:
plugin.check_health() # Throws PluginCrashException if plugin crashed

deviceio_session.update()
deviceio_session.update(time.monotonic_ns())

if frame_count % 60 == 0:
left_tracked = hand_tracker.get_left_hand(deviceio_session)
Expand Down
2 changes: 1 addition & 1 deletion examples/retargeting/python/sources_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def main():

while time.time() - start_time < 10.0:
# Update session and all trackers
session.update()
session.update(time.monotonic_ns())

# Print every 60 frames (~1 second)
if frame_count % 60 == 0:
Expand Down
3 changes: 2 additions & 1 deletion examples/schemaio/frame_metadata_printer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <deviceio_session/deviceio_session.hpp>
#include <deviceio_trackers/frame_metadata_tracker_oak.hpp>
#include <oxr/oxr_session.hpp>
#include <oxr_utils/os_time.hpp>

#include <chrono>
#include <iostream>
Expand Down Expand Up @@ -107,7 +108,7 @@ try

while (true)
{
session->update();
session->update(core::os_monotonic_now_ns());

// Refresh stream count and extend per-stream tracking if streams were added.
stream_count = tracker->get_stream_count();
Expand Down
3 changes: 2 additions & 1 deletion examples/schemaio/pedal_printer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <deviceio_session/deviceio_session.hpp>
#include <deviceio_trackers/generic_3axis_pedal_tracker.hpp>
#include <oxr/oxr_session.hpp>
#include <oxr_utils/os_time.hpp>

#include <chrono>
#include <iomanip>
Expand Down Expand Up @@ -69,7 +70,7 @@ try
while (received_count < MAX_SAMPLES)
{
// Update session (this calls update on all trackers)
session->update();
session->update(core::os_monotonic_now_ns());

// Print current data if available
const auto& tracked = tracker->get_data(*session);
Expand Down
2 changes: 0 additions & 2 deletions src/core/deviceio_base/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ target_include_directories(deviceio_base
target_link_libraries(deviceio_base
INTERFACE
isaacteleop_schema
oxr::oxr_utils
OpenXR::headers
)

add_library(deviceio::deviceio_base ALIAS deviceio_base)
15 changes: 8 additions & 7 deletions src/core/deviceio_base/cpp/inc/deviceio_base/tracker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,14 @@

#pragma once

#include <openxr/openxr.h>

#include <cstdint>
#include <memory>
#include <string>
#include <string_view>

namespace core
{

// Forward declarations
struct OpenXRSessionHandles;

// Base interface for tracker implementations.
// The actual worker objects updated each frame by DeviceIOSession.
class ITrackerImpl
Expand All @@ -23,13 +19,18 @@ class ITrackerImpl
virtual ~ITrackerImpl() = default;

/**
* @brief Updates tracker state for the specified OpenXR time.
* @brief Updates tracker state for the current graph step.
*
* @param graph_time_ns Logical timestamp for this update step (nanoseconds,
* monotonic clock). Used as the MCAP logTime/publishTime. Tracker
* implementations that perform synchronous device queries compute
* their own wall-clock "now" for DeviceDataTimestamp fields.
*
* @throws std::runtime_error On critical tracker/runtime failures.
* @note A thrown exception indicates a fatal condition; the application is
* expected to terminate rather than continue running.
*/
virtual void update(XrTime time) = 0;
virtual void update(int64_t graph_time_ns) = 0;
};

/**
Expand Down
1 change: 1 addition & 0 deletions src/core/deviceio_session/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ target_include_directories(deviceio_session
target_link_libraries(deviceio_session
PUBLIC
deviceio::deviceio_base
oxr::oxr_utils
Teleop::openxr_extensions
PRIVATE
deviceio::deviceio_trackers
Expand Down
8 changes: 3 additions & 5 deletions src/core/deviceio_session/cpp/deviceio_session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace core
DeviceIOSession::DeviceIOSession(const std::vector<std::shared_ptr<ITracker>>& trackers,
const OpenXRSessionHandles& handles,
std::optional<McapRecordingConfig> recording_config)
: handles_(handles), time_converter_(handles)
: handles_(handles)
{
std::vector<std::pair<const ITracker*, std::string>> tracker_names;

Expand Down Expand Up @@ -101,13 +101,11 @@ std::unique_ptr<DeviceIOSession> DeviceIOSession::run(const std::vector<std::sha
return std::unique_ptr<DeviceIOSession>(new DeviceIOSession(trackers, handles, std::move(recording_config)));
}

void DeviceIOSession::update()
void DeviceIOSession::update(int64_t graph_time_ns)
{
XrTime current_time = time_converter_.os_monotonic_now();

for (auto& kv : tracker_impls_)
{
kv.second->update(current_time);
kv.second->update(graph_time_ns);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#include <deviceio_base/tracker.hpp>
#include <oxr_utils/oxr_funcs.hpp>
#include <oxr_utils/oxr_session_handles.hpp>
#include <oxr_utils/oxr_time.hpp>

#include <memory>
#include <optional>
Expand Down Expand Up @@ -65,11 +64,14 @@ class DeviceIOSession : public ITrackerSession
* If recording is active, tracker implementations write MCAP samples
* directly during this call.
*
* @param graph_time_ns Logical timestamp for this update step (nanoseconds,
* monotonic clock). Forwarded to tracker impls for MCAP envelope time.
*
* @throws std::runtime_error On critical tracker/runtime failures.
* @note A thrown exception indicates a fatal condition; the application is
* expected to terminate rather than continue running.
*/
void update();
void update(int64_t graph_time_ns);

const ITrackerImpl& get_tracker_impl(const ITracker& tracker) const override
{
Expand All @@ -88,7 +90,6 @@ class DeviceIOSession : public ITrackerSession

const OpenXRSessionHandles handles_;
std::unordered_map<const ITracker*, std::unique_ptr<ITrackerImpl>> tracker_impls_;
XrTimeConverter time_converter_;

// Owned MCAP writer; null when recording is not configured.
std::unique_ptr<mcap::McapWriter> mcap_writer_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ class PyDeviceIOSession : public ITrackerSession
{
}

void update()
void update(int64_t graph_time_ns)
{
if (!impl_)
{
throw std::runtime_error("Session has been closed/destroyed");
}
impl_->update();
impl_->update(graph_time_ns);
}

void close()
Expand Down
3 changes: 2 additions & 1 deletion src/core/deviceio_session/python/session_bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ PYBIND11_MODULE(_deviceio_session, m)

py::class_<core::PyDeviceIOSession, core::ITrackerSession, std::unique_ptr<core::PyDeviceIOSession>>(
m, "DeviceIOSession")
.def("update", &core::PyDeviceIOSession::update, "Update session and all trackers")
.def("update", &core::PyDeviceIOSession::update, py::arg("graph_time_ns"),
"Update session and all trackers. graph_time_ns is used as MCAP logTime/publishTime.")
.def("close", &core::PyDeviceIOSession::close,
"Release the native session immediately (usually automatic via context manager)")
.def("__enter__", &core::PyDeviceIOSession::enter)
Expand Down
2 changes: 0 additions & 2 deletions src/core/deviceio_trackers/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ target_include_directories(deviceio_trackers
target_link_libraries(deviceio_trackers
PUBLIC
deviceio::deviceio_base
PRIVATE
Teleop::openxr_extensions
)

add_library(deviceio::deviceio_trackers ALIAS deviceio_trackers)
Loading
Loading