Skip to main content

PySpaceMouse

🎮 Multiplatform Python library for 3Dconnexion SpaceMouse devices using raw HID.

3Dconnexion Space Mouse in Python using raw HID. Note: you don't need to install or use any of the drivers or 3Dconnexion software to use this package. It interfaces with the controller directly with hidapi and python wrapper library easyhid.

PySpaceMouse is forked from: johnhw/pyspacenavigator and modified to be multiplatform.

Supported 3Dconnexion devices

  • SpaceNavigator
  • SpaceMouse Pro / Pro Wireless
  • SpaceMouse Wireless
  • SpaceMouse Compact
  • SpaceMouse Enterprise
  • SpacePilot / SpacePilot Pro
  • 3Dconnexion Universal Receiver
  • ...
  • Add more devices

Installation

pip install pyspacemouse

Quick Start

Here we use has_motion() to check if any of the spatial axes have non-zero values. The optional argument is the threshold used, and is applied per-axis.

import pyspacemouse

# Context manager (recommended) - automatically closes device
with pyspacemouse.open() as device:
    while True:
        state = device.read()
        if state.has_motion(0.01):
            print(state.x, state.y, state.z, state.roll, state.pitch, state.yaw)

API Reference

From version 2.0.0 the API has been modularized and changed. Please look at the API Reference and Examples for more information.

Device Discovery

import pyspacemouse

# List connected SpaceMouse devices
pyspacemouse.get_connected_devices()
# Returns: ["SpaceNavigator", "SpaceMouse Pro", ...]

# List connected SpaceMouse devices with paths
pyspacemouse.get_connected_devices_by_path()
# Returns: {"/dev/hidraw0": "SpaceNavigator", ...}

# List all supported device types
pyspacemouse.get_supported_devices()
# Returns: [(name, vendor_id, product_id), ...]

# List ALL HID devices (for debugging)
pyspacemouse.get_all_hid_devices()
# Returns: [(product, manufacturer, vid, pid), ...]

Opening Devices

# Auto-detect and open first device
with pyspacemouse.open() as device:
    state = device.read()

# Open specific device by name
with pyspacemouse.open(device="SpaceNavigator") as device:
    state = device.read()

# Open second device when multiple identical devices are connected
with pyspacemouse.open(device_index=1) as device:
    state = device.read()

# Open by filesystem path (Linux: /dev/hidraw0)
with pyspacemouse.open_by_path("/dev/hidraw0") as device:
    state = device.read()

Reading State

with pyspacemouse.open() as device:
    state = device.read()

    # 6-DOF axes (range: -1.0 to 1.0)
    print(state.x, state.y, state.z)  # Translation
    print(state.roll, state.pitch, state.yaw)  # Rotation

    # Buttons (list of 0/1)
    print(state.buttons)

    # Timestamp
    print(state.t)

Axis Conventions

For new code, opt into an axis convention by passing an enum value on device open:

import pyspacemouse
from pyspacemouse import AxisConvention

with pyspacemouse.open(axis_convention=AxisConvention.HID_Z_UP) as device:
    state = device.read()

HID Z-up axis convention Raw HID axis convention Legacy PySpaceMouse axis convention

See Axis Conventions for the full mapping table. Custom device_spec mappings are used exactly as provided and cannot be combined with axis_convention.

Callbacks

import pyspacemouse
import time


# Button callback
def on_button(state, buttons, pressed):
    print(f"Button {pressed} pressed!")


button_callbacks = [
    pyspacemouse.ButtonCallback(0, on_button),  # Button 0
    pyspacemouse.ButtonCallback([0, 1], on_button),  # Both 0 and 1
]

# DOF callback with filtering
dof_callbacks = [
    pyspacemouse.DofCallback(
        axis="x",
        callback=lambda s, v: print(f"X: {v}"),
        callback_minus=lambda s, v: print(f"X negative: {v}"),
        filter=0.1,  # Deadzone
        sleep=0.05,  # Rate limit
    ),
]

with pyspacemouse.open(
    button_callbacks=button_callbacks,
    dof_callbacks=dof_callbacks,
) as device:
    while True:
        device.read()  # Triggers callbacks
        time.sleep(0.001)  # NOTE: avoid larger sleeps, which can cause data to buffer

Custom Axis Mapping

Choose a built-in convention for common application frames:

import pyspacemouse
from pyspacemouse import AxisConvention

with pyspacemouse.open(axis_convention=AxisConvention.ROS) as device:
    state = device.read()

For custom coordinate frames, remap or invert axes explicitly:

import pyspacemouse

# Get existing device spec and modify axes
specs = pyspacemouse.get_device_specs()
base = specs["SpaceNavigator"]

custom = pyspacemouse.modify_device_info(
    base,
    remap_axes={"x": "y", "y": ("x", -1), "yaw": ("yaw", -1)},
)

with pyspacemouse.open(device_spec=custom) as device:
    state = device.read()

See Custom Device Configuration for full API.

CLI

pyspacemouse --list-connected    # Show connected devices
pyspacemouse --list-supported    # Show all supported types
pyspacemouse --list-hid          # Show all HID devices
pyspacemouse --test              # Test connection
pyspacemouse --version           # Show version

Examples

See the examples/ directory:

Example Description
01_basic.py Simple reading with context manager
02_callbacks.py Button and DOF callbacks
03_multi_device.py Using two devices simultaneously
04_open_by_path.py Open specific device by path
05_discovery.py List and inspect devices
06_axis_callbacks.py Per-axis callbacks with filtering
07_led.py LED control
08_buttons.py Button names and handling
09_invert_rotations.py Invert rotations
10_custom_config_unity.py A totally custom device config using the Unity axis convention

Dependencies

hidapi (C library)

  • Linux: sudo apt-get install libhidapi-dev
  • macOS: brew install hidapi
  • Windows: Download from hidapi releases

Linux permissions

echo 'KERNEL=="hidraw*", SUBSYSTEM=="hidraw", MODE="0664", GROUP="plugdev"' | sudo tee /etc/udev/rules.d/99-hidraw-permissions.rules
sudo usermod -aG plugdev $USER
newgrp plugdev

macOS PATH

export DYLD_LIBRARY_PATH=/opt/homebrew/Cellar/hidapi/<VERSION>/lib:$DYLD_LIBRARY_PATH

Troubleshooting

See troubleshooting.md for help with common issues.

Developing / Contributing

This project includes a Makefile with commands for creating a virtual environment (using hatch), and publishing to pypi.

You will need hatch and pre-commit for this. You can get these by using

# Most recently tested with hatch 1.17.0
pipx install hatch pre-commit

If you're not familiar with pipx, it lets you install python tools into isolated environments in ~/.local.

For building the documentation locally, you will also need doxygen installed and on the path.

Used In

  • TeleMoMa - A Modular and Versatile Teleoperation System for Mobile Manipulation
  • SERL - SERL: A Software Suite for Sample-Efficient Robotic Reinforcement Learning
  • Pancake Robot- An integration of the Ufactory Lite 6 robot arm with kitchenware to make pancakes.
  • GELLO - GELLO: A General, Low-Cost, and Intuitive Teleoperation Framework for Robot Manipulators
    • image
  • spacepad - A simple python script that turns a spacemouse device into a standard gamepad
  • arm_xarm

Download files

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

Source Distribution

pyspacemouse-2.1.0.tar.gz (25.8 kB view details)

Uploaded Source

Built Distribution

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

pyspacemouse-2.1.0-py3-none-any.whl (25.6 kB view details)

Uploaded Python 3

File details

Details for the file pyspacemouse-2.1.0.tar.gz.

File metadata

  • Download URL: pyspacemouse-2.1.0.tar.gz
  • Upload date:
  • Size: 25.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Hatch/1.18.0 {"ci":null,"cpu":"x86_64","distro":{"id":"noble","libc":{"lib":"glibc","version":"2.39"},"name":"Ubuntu","version":"24.04"},"implementation":{"name":"CPython","version":"3.12.3"},"installer":{"name":"hatch","version":"1.18.0"},"openssl_version":"OpenSSL 3.0.13 30 Jan 2024","python":"3.12.3","system":{"name":"Linux","release":"7.0.0-28-generic"}} HTTPX2/2.12.0

File hashes

Hashes for pyspacemouse-2.1.0.tar.gz
Algorithm Hash digest
SHA256 de0a14878d2ff91eb2fc327b0ca9d159184ce17f2792149f40c0e8b73f9e219a
MD5 dacc6fd29376ea4bb26a0ae2d01c8e46
BLAKE2b-256 bc0b11b5f8dc09eab5e32aa6aef667470d20656962e9b25fe58d087e552adeab

See more details on using hashes here.

File details

Details for the file pyspacemouse-2.1.0-py3-none-any.whl.

File metadata

  • Download URL: pyspacemouse-2.1.0-py3-none-any.whl
  • Upload date:
  • Size: 25.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Hatch/1.18.0 {"ci":null,"cpu":"x86_64","distro":{"id":"noble","libc":{"lib":"glibc","version":"2.39"},"name":"Ubuntu","version":"24.04"},"implementation":{"name":"CPython","version":"3.12.3"},"installer":{"name":"hatch","version":"1.18.0"},"openssl_version":"OpenSSL 3.0.13 30 Jan 2024","python":"3.12.3","system":{"name":"Linux","release":"7.0.0-28-generic"}} HTTPX2/2.12.0

File hashes

Hashes for pyspacemouse-2.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3229e78c631a08f639e261671bb3ed15e6653a8b805dfbf1c415bd4f26dc3286
MD5 3ec11ca0f9107c418db77a555e96585a
BLAKE2b-256 d904114d9d0d563ffbe64348f1cb1fe21602d734678d56dd85e544b69f5ba503

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

2.1.0 This release

2 files

2.0.0

2 files

1.1.5

2 files

1.1.4

2 files

1.1.3

2 files

1.1.2

2 files

1.1.1

2 files

1.1.0

2 files

1.0.9

2 files

1.0.8

2 files

1.0.6

2 files

1.0.5

2 files

1.0.4

2 files

1.0.3

2 files

1.0.1

2 files

1.0.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page