Skip to main content

Dora Node for Teleoperation Input (Keyboard & Joystick)

Project description

hex_dora_node_teleop

Dora nodes for reading teleoperation inputs from keyboard and joystick/gamepad using evdev. Each node maintains an internal state table updated by background threads and outputs the full state at the configured tick rate (recommended 100 Hz).

Nodes

Node Description Inputs Outputs
hex-dora-teleop-keyboard Keyboard letter-key state reader tick state
hex-dora-teleop-joystick Joystick/Gamepad button & axis state reader tick buttons, axes
hex-dora-teleop-test-keyboard Terminal viewer for keyboard state tick, state -
hex-dora-teleop-test-joystick Terminal viewer for joystick state tick, buttons, axes -

Prerequisites

Accessing /dev/input/* requires the current user to be in the input group:

sudo usermod -aG input $USER
# Log out and back in for the change to take effect

Installation

pip install hex_dora_node_teleop

YAML Examples

Keyboard (100 Hz)

nodes:
  - id: teleop_keyboard
    build: pip install hex_dora_node_teleop
    path: hex-dora-teleop-keyboard
    inputs:
      tick: dora/timer/millis/10
    outputs:
      - state
    env:
      NODE_NAME: teleop_keyboard
      DEVICE_PATH: ""  # auto-detect; or set e.g. /dev/input/event0

  - id: test_keyboard
    build: pip install hex_dora_node_teleop
    path: hex-dora-teleop-test-keyboard
    inputs:
      tick: dora/timer/millis/10
      state: teleop_keyboard/state
    env:
      NODE_NAME: test_keyboard

Joystick / Gamepad (100 Hz)

nodes:
  - id: teleop_joystick
    build: pip install hex_dora_node_teleop
    path: hex-dora-teleop-joystick
    inputs:
      tick: dora/timer/millis/10
    outputs:
      - buttons
      - axes
    env:
      NODE_NAME: teleop_joystick
      DEVICE_PATH: ""  # auto-detect; or set e.g. /dev/input/event5

  - id: test_joystick
    build: pip install hex_dora_node_teleop
    path: hex-dora-teleop-test-joystick
    inputs:
      tick: dora/timer/millis/10
      buttons: teleop_joystick/buttons
      axes: teleop_joystick/axes
    env:
      NODE_NAME: test_joystick

Inputs

Teleop Nodes (keyboard / joystick)

Input Type Description
tick dora/timer/millis/* Timer tick to trigger state output (use millis/10 for 100 Hz)

Test Nodes (test-keyboard)

Input Type Description
tick dora/timer/millis/* Timer tick to refresh terminal display
state Arrow UInt8Array Keyboard letter-key state from keyboard node

Test Nodes (test-joystick)

Input Type Description
tick dora/timer/millis/* Timer tick to refresh terminal display
buttons Arrow UInt8Array Button states from joystick node
axes Arrow Float64Array Axis values from joystick node

Outputs

state (keyboard)

Arrow UInt8Array of length 26 — one element per letter key (a–z, in order). 1 = pressed, 0 = released.

state_data: UInt8Array  # pa.array([0, 0, 1, ...], type=pa.uint8())
metadata = {
    "keys": "a,b,c,...,z",         # comma-separated key names
    "primitive": "keyboard_state",
}

buttons (joystick)

Arrow UInt8Array — one element per detected gamepad button. 1 = pressed, 0 = released. Button list is auto-detected from device capabilities.

buttons_data: UInt8Array  # pa.array([0, 1, 0, ...], type=pa.uint8())
metadata = {
    "names": "BTN_SOUTH,BTN_EAST,...",  # comma-separated button names
    "primitive": "joystick_buttons",
}

axes (joystick)

Arrow Float64Array — one element per detected analog axis, normalized to [-1.0, 1.0]. Axis list is auto-detected from device capabilities.

axes_data: Float64Array  # pa.array([-0.5, 0.0, ...], type=pa.float64())
metadata = {
    "names": "ABS_X,ABS_Y,...",    # comma-separated axis names
    "primitive": "joystick_axes",
}

Environment Variables

All Nodes

Variable Type Default Description
NODE_NAME str "" Dora node name passed to Node() constructor; empty = use default

Keyboard Node

Variable Type Default Description
DEVICE_PATH str "" (auto) Specific /dev/input/eventN path; empty = auto-detect all keyboards

Joystick Node

Variable Type Default Description
DEVICE_PATH str "" (auto) Specific /dev/input/eventN path; empty = auto-detect first joystick

Architecture

Both keyboard and joystick nodes follow the same pattern:

  1. Device discovery — enumerate /dev/input/* via evdev.list_devices() and filter by capabilities (letter keys for keyboard, analog axes for joystick).
  2. Background reader thread — a daemon thread continuously reads evdev events and updates an in-memory state table protected by a threading.Lock.
  3. Dora tick loop — on each tick input, the node snapshots the current state table and sends it as an Arrow array output.

This decouples the variable-rate hardware events from the fixed-rate dora output, ensuring consistent 100 Hz state updates regardless of actual input event frequency.

License

This project is licensed under Apache-2.0.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hex_dora_node_teleop-0.0.1a2.tar.gz (12.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hex_dora_node_teleop-0.0.1a2-py3-none-any.whl (13.6 kB view details)

Uploaded Python 3

File details

Details for the file hex_dora_node_teleop-0.0.1a2.tar.gz.

File metadata

  • Download URL: hex_dora_node_teleop-0.0.1a2.tar.gz
  • Upload date:
  • Size: 12.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for hex_dora_node_teleop-0.0.1a2.tar.gz
Algorithm Hash digest
SHA256 eae0f70b295b77c205ef36253ac06753ef790a253604c8108d343131707f9b90
MD5 3ad129e191517b8e19e197ac8fcee8ac
BLAKE2b-256 af92ad396b1494b2cd00ca3d96a4f904d05f0bdd2265d7bf3e6489f81315bfde

See more details on using hashes here.

File details

Details for the file hex_dora_node_teleop-0.0.1a2-py3-none-any.whl.

File metadata

File hashes

Hashes for hex_dora_node_teleop-0.0.1a2-py3-none-any.whl
Algorithm Hash digest
SHA256 e4488a810dae6c98aeed9bb30e36738452d55d4b0ad6c7374e7967d0e5825e31
MD5 2a3ee2abd1dceae66e7705706f8cc12c
BLAKE2b-256 ca6bed255d17fe12de0a1c698714ee400e0ebf708734f42dfb53975d8dd05302

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page