Created
January 11, 2023 16:42
-
-
Save hexagon5un/8af6f6b52a429895094454bba40b1773 to your computer and use it in GitHub Desktop.
Quick and dirty Spacemouse test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python3 | |
import serial | |
import subprocess | |
SENSITIVITY=250 | |
PORT1="/dev/ttyUSB1" | |
DEBUG = False | |
DELAY = 0.25 ## seconds, prevents race | |
## commands all end with \r | |
def getSpacemouse(s): | |
"""Read a command. Think about how to do smartly/flush here""" | |
cmd = s.read_until(DELIM) | |
cmd = cmd.decode() | |
return cmd | |
validData = {"0":0, "A":1, "B":2, "3":3, "D":4, "5":5, "6":6, "G":7, "H":8, | |
"9":9, ":":10, "K":11, "<":12, "M":13, "N":14, "?":15} | |
def readNibble(byte): | |
try: | |
return validData[byte] | |
except KeyError(): | |
return None | |
def buildWord(nibbleArray): | |
runningSum = 0 | |
runningSum = runningSum + 4096 * nibbleArray.pop(0) | |
runningSum = runningSum + 256 * nibbleArray.pop(0) | |
runningSum = runningSum + 16 * nibbleArray.pop(0) | |
runningSum = runningSum + nibbleArray.pop(0) | |
runningSum = runningSum - 32768 | |
return runningSum, nibbleArray | |
def parseDirection(cmd): | |
nibbleArray = [readNibble(x) for x in cmd] | |
values = [] | |
while len(nibbleArray): | |
val, nibbleArray = buildWord(nibbleArray) | |
values.append(val) | |
return values | |
def parseKeys(cmd): | |
return cmd | |
def plotme(val): | |
spaces = int((val + 500)/10) | |
print( spaces*" " + "#" ) | |
commands = {"d":parseDirection, "k":parseKeys} | |
def handleMouse(serialPort): | |
cmd = getSpacemouse(serialPort) | |
if cmd: ## returns '' if nothing on line | |
cmdType = cmd[0] | |
cmd = cmd[1:].strip() | |
try: | |
foo = commands[cmdType](cmd) | |
if DEBUG: | |
for f in foo: | |
plotme(f) | |
except: | |
print(len(cmd)) | |
print(cmdType) | |
print(cmd) | |
serialPort.flush() | |
def scrollMouse(serialPort): | |
cmd = getSpacemouse(serialPort) | |
if cmd: ## returns '' if nothing on line | |
cmdType = cmd[0] | |
cmd = cmd[1:].strip() | |
try: | |
foo = commands[cmdType](cmd) | |
if DEBUG: | |
print(foo.decode()) | |
xaxis = int(foo[0]) | |
vertical = int(foo[1]) | |
yaxis = int(foo[2]) | |
pitch = int(foo[3]) | |
yaw = int(foo[4]) | |
roll = int(foo[5]) | |
## Pitch = scrollwheel up/down | |
if pitch > 1: | |
for i in range(int(pitch/SENSITIVITY)+1): | |
subprocess.Popen(["xdotool", "click","5"]) | |
if pitch < -1: | |
for i in range(int(-pitch/SENSITIVITY)+1): | |
subprocess.Popen(["xdotool", "click","4"]) | |
## turn CW opens in new tab (middle mouse click) | |
if yaw < -30: | |
os.system("xdotool click 2") | |
time.sleep(DELAY) | |
## push down closes page | |
if vertical < -50: | |
os.system("xdotool type d") | |
time.sleep(DELAY) | |
## pull up undoes last close | |
if vertical > 50: | |
os.system("xdotool type u") | |
time.sleep(DELAY) | |
## shove left/right moves to prev/next tab | |
if xaxis < -50: | |
os.system("xdotool type K") | |
time.sleep(DELAY) | |
if xaxis > 50: | |
os.system("xdotool type J") | |
time.sleep(DELAY) | |
## rolling to right goes to forum next | |
if roll < -50: | |
os.system("xdotool type ]]") | |
time.sleep(DELAY) | |
## rolling to right follows link | |
# if roll < -50: | |
# os.system("xdotool click 1") | |
# time.sleep(DELAY) | |
## rolling to left goes backwards in history | |
if roll > 50: | |
os.system("xdotool type H") | |
time.sleep(DELAY) | |
except: | |
# handle keys | |
if cmd == "A00": | |
os.system("xdotool type bhad\n") | |
os.system("xdotool key Return") | |
elif cmd == "0B0": # left button | |
os.system("xdotool type [[") | |
elif cmd == "0D0": # right button | |
os.system("xdotool type ]]") | |
elif cmd == "0A0": # 5 | |
os.system("xdotool type o") | |
os.system("xdotool key Escape") | |
elif cmd == "0H0": # 8 | |
os.system("xdotool key Escape") | |
os.system("xdotool type ,p") | |
elif cmd == "000": | |
pass | |
else: | |
print("ERR0R: " + cmd) | |
serialPort.flushInput() | |
def writeout(serialport, seq): | |
"""writes out byte sequence to pass serial port""" | |
serialport.write(bytes(seq, encoding="ascii")) | |
if __name__ == "__main__": | |
TIMEOUT=0.1 | |
DELIM="\r".encode("ascii") | |
import os | |
import time | |
import sys | |
if len(sys.argv) == 2: | |
PORT = sys.argv[1] | |
else: | |
PORT = PORT1 | |
print("Trying " + PORT) | |
s = serial.Serial(baudrate=9600, stopbits=2, port=PORT, timeout=TIMEOUT) | |
time.sleep(0.1) | |
s.flush() | |
time.sleep(0.1) | |
print("Initializing...") | |
writeout(s,"vQ\r") | |
print(s.read(100).decode()) | |
writeout(s,"mG\r") # both axes, dominant only mode | |
print(s.read(100).decode()) | |
writeout(s,"nM\r") # default sensitivity radius -- rather large | |
print(s.read(100).decode()) | |
writeout(s,"q00\r") # linear scaling for both translation and rotation | |
print(s.read(100).decode()) | |
while(True): | |
# handleMouse(s) | |
scrollMouse(s) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment