Skip to main content

Multiplatform Python interface to the 3DConnexion Space Mouse - forked from pyspacenavigator

Project description

PySpaceMouse

A Python library for 3Dconnexion SpaceMouse devices

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

Connected project PySpaceApp is a simple example of how controll your PC with SpaceMouse.

Implements a simple interface to the 6 DoF 3Dconnexion Space Mouse device as well as similar devices.

Control a robot with a Space Mouse

Supported 3Dconnexion devices

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

Installation

Use the package manager pip to install pyspacemouse.

pip install pyspacemouse

Dependencies

  • hidapi is C library for direct communication with HID devices

    • Linux

      • libhidapi-dev to access HID data

      • sudo apt-get install libhidapi-dev (Debian/Ubuntu)

      • Compile and install hidapi. (other Linux distributions)

      • add rules for permissions

        sudo echo 'KERNEL=="hidraw*", SUBSYSTEM=="hidraw", MODE="0664", GROUP="plugdev"' > /etc/udev/rules.d/99-hidraw-permissions.rules
        sudo usermod -aG plugdev $USER
        newgrp plugdev
        
        Aleternative option - with tee (RPi)
          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
          
    • Windows

      • Install the latest release of hidapi.dll and hidapi.lib from the hidapi releases page.
      • Set system environment: add absolute path for x64 or x86 folder in Path.
    • Mac OS X (M1)

      • Install from Homebrew
      • brew install hidapi
      • Add hidapi to your DYLD_LIBRARY_PATH directory.
        export DYLD_LIBRARY_PATH=/opt/homebrew/Cellar/hidapi/0.14.0/lib:$DYLD_LIBRARY_PATH
        
      • On MacOS M1 you will need patched version of easyhid
        pip install git+https://github.com/bglopez/python-easyhid.git
        
      • In case of problem with M1 chip, try to run you code with Rosseta 2
      • Tested and developed by consi - thanks!
  • easyhid is hidapi interface for Python - required on all platforms

    • pip install git+https://github.com/bglopez/python-easyhid.git
    • this fork fix problems with hidapi on MacOS.
    • on other platforms it possible works with original package pip install easyhid

Basic Usage:

basicExample.py

import pyspacemouse
import time

success = pyspacemouse.open()
if success:
    while 1:
        state = pyspacemouse.read()
        print(state.x, state.y, state.z)
        time.sleep(0.01)

State objects

State objects returned from read() have 7 attributes: [t,x,y,z,roll,pitch,yaw,button].

  • t: timestamp in seconds since the script started.
  • x,y,z: translations in the range [-1.0, 1.0]
  • roll, pitch, yaw: rotations in the range [-1.0, 1.0].
  • button: list of button states (0 or 1), in order specified in the device specifier

Usage with callback

callbackExample.py

import pyspacemouse
import time


def button_0(state, buttons, pressed_buttons):
    print("Button:", pressed_buttons)


def button_0_1(state, buttons, pressed_buttons):
    print("Buttons:", pressed_buttons)


def someButton(state, buttons):
    print("Some button")


def callback():
    button_arr = [pyspacemouse.ButtonCallback(0, button_0),
                  pyspacemouse.ButtonCallback([1], lambda state, buttons, pressed_buttons: print("Button: 1")),
                  pyspacemouse.ButtonCallback([0, 1], button_0_1), ]

    success = pyspacemouse.open(dof_callback=pyspacemouse.print_state, button_callback=someButton,
                                button_callback_arr=button_arr)
    if success:
        while True:
            pyspacemouse.read()
            time.sleep(0.01)


if __name__ == '__main__':
    callback()

API

open(callback=None, button_callback=None, button_callback_arr=None, set_nonblocking_loop=True, device=None)
    Open a 3D space navigator device. Makes this device the current active device, which enables the module-level read() and close()
    calls. For multiple devices, use the read() and close() calls on the returned object instead, and don't use the module-level calls.

    Parameters:
        callback: If callback is provided, it is called on each HID update with a copy of the current state namedtuple
        dof_callback: If dof_callback is provided, it is called only on DOF state changes with the argument (state).
        button_callback: If button_callback is provided, it is called on each button push, with the arguments (state_tuple, button_state)
        device: name of device to open, as a string like "SpaceNavigator". Must be one of the values in `supported_devices`.
                If `None`, chooses the first supported device found.
    Returns:
        Device object if the device was opened successfully
        None if the device could not be opened

read()              Return a namedtuple giving the current device state (t,x,y,z,roll,pitch,yaw,button)
close()             Close the connection to the current device, if it is open
list_devices()      Return a list of supported devices found, or an empty list if none found

open() returns a DeviceSpec object. If you have multiple 3Dconnexion devices, you can use the object-oriented API to access them individually. Each object has the following API, which functions exactly as the above API, but on a per-device basis:

dev.open()          Opens the connection (this is always called by the module-level open command,
                    so you should not need to use it unless you have called close())
dev.read()          Return the state of the device as namedtuple [t,x,y,z,roll,pitch,yaw,button]
dev.close()         Close this device

There are also attributes:

dev.connected       True if the device is connected, False otherwise
dev.state           Convenience property which returns the same value as read()

Predefined callbacks

import pyspacemouse
import time

success = pyspacemouse.open(dof_callback=pyspacemouse.print_state, button_callback=pyspacemouse.print_buttons)
if success:
    while 1:
        state = pyspacemouse.read()
        time.sleep(0.01)

Callback: print_state

Print all axis states

x +0.00    y +0.00    z +0.00 roll +0.00 pitch +0.00  yaw +0.00    t +0.0

Callback: print_buttons

Print all buttons states

[ 0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, ]

Troubleshooting

ModuleNotFoundError: No module named 'easyhid'

  • Install easyhid by pip install easyhid.

AttributeError: function/symbol 'hid_enumerate' not found in library '': python3: undefined symbol: hid_enumerate

  • HID library for your computer is not installed.
  • Follow the instructions in requirements.

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

pyspacemouse-1.1.1.tar.gz (18.3 kB view details)

Uploaded Source

Built Distribution

pyspacemouse-1.1.1-py3-none-any.whl (13.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: pyspacemouse-1.1.1.tar.gz
  • Upload date:
  • Size: 18.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.9.18

File hashes

Hashes for pyspacemouse-1.1.1.tar.gz
Algorithm Hash digest
SHA256 aee98afe7c6ac0a4a20e81c2229a0285f3f86707a7d1c8d2d7ca3db596dc71a4
MD5 68df1064e1a9967b909be1c597173536
BLAKE2b-256 b30f62284291a1091d267815ba4192d2f7b712f10c0bf05e2f762a3fa712a2e9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pyspacemouse-1.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 20eb085c8b9b5e6285025d33970da35666f27856443aeca6befa8d71316b2a1b
MD5 679c0db6f2c5466583a317626bbc0017
BLAKE2b-256 595d38560a4eb95f36e9569ba5298f04854ee8b969df0ef428ae0f2ebd53301b

See more details on using hashes here.

Supported by

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