SDKPython SDK

Runtime modes

Continuous running in the current thread, a background thread, or manual update.

Current version · 1.4.0

Runtime modes

This chapter applies only to programs that need to continuously compute SDK-processed data or use background features such as automatic reconnection. When only reading raw pose/IMU, there is no need to choose a run mode, see Data channels & read methods.

When the above features are needed, choose one run mode through Glove. Do not mix them in the same run:

  • Command-line programs usually call glove.run_forever() to run continuously in the current thread;
  • When a GUI, an asynchronous program, or the current thread also needs to handle other work, you can call glove.run_background() to run in the background;
  • When a synchronous main loop already exists, you can continuously call glove.update() and let the program control scheduling.

Continuous running in the current thread

glove.run_forever()

run_forever() blocks the current thread until a stop request is received or the SDK stops due to an error. Public command-line examples end the process with Ctrl+C; when you need to stop actively, use background mode.

Running in a background thread

glove.run_background()
try:
    ...
finally:
    glove.request_stop()
    glove.join()

join() not only waits for the thread to end, it is also responsible for reporting background running errors to the caller, so you must not call only request_stop() and omit join(). Background mode is suitable for the GUI main thread, a host event loop, or other scenarios where the current thread cannot be blocked.

When an ordinary asyncio program reads SDK-processed data, it usually calls glove.run_background() after start(), then reads output through await output.next() or async for. The asyncio event loop itself does not advance SDK scheduling; both the SDK background run and the event loop need to keep running. close() may wait for data processing and callback cleanup, so asynchronous programs should call it through asyncio.to_thread().

If external frames come from an async iterator, you should create a separate asyncio task that continuously calls push_frame(), while reading output through await output.next() or async for. Only waiting for output without continuing to submit input frames will not produce new SDK-processed data.

Manual update

Manual mode is suitable for programs that already have a synchronous main loop and want to actively control SDK scheduling. First subscribe to the SDK-processed data, then start the device; each call to glove.update() computes the tasks that are due, and you can also read the current output immediately through latest():

output = glove.device().output()
output.subscribe(on_output)
glove.start()

for _ in range(100):
    update = glove.update()
    latest = output.latest()
    if latest is not None:
        print(latest.sequence, latest.value)
    if update.has_next_task:
        update.sleep()

Choose a field by what you need:

What you want to doRead field
Record how many scheduling rounds have runtick
See how many tasks ran this timeran_task_count
Decide whether to keep waiting for the next taskhas_next_task
Wait until the next task is duesleep()

For complete fields, types and return values, see UpdateResult. sleep() returns SleepResult.READY, STOPPED or NO_TASKS. Each UpdateResult can only be waited on once; reusing it or using it after the next update throws StaleUpdateError.

Manual mode only changes who advances SDK scheduling, not how data is read. A host that can coordinate SDK scheduling and the asyncio event loop by itself can also use manual update(), but must ensure that glove.update() is called continuously; only waiting for output without continuing to advance scheduling will not produce new SDK-processed data. Ordinary asynchronous programs should prefer glove.run_background(); for the asynchronous read method, see Asynchronous reading.

For a complete asynchronous flow, see async_runtime.py.