Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Small script to convert HTC Vive controller inputs into virtual keypresses for autohotkey (thanks to awesomebytes)
#!/usr/bin/env python
import time
import pprint
import openvr
import win32api
import win32con
"""
Convert HTC Vive inputs to virtual keypresses for autohotkey
Key identifiers for autohotkey:
vk0x88 = left grip
vk0x89 = right grip
vk0x8A = left trigger
vk0x8B = right trigger
vk0x8C = left menu
vk0x8D = right menu
vk0x8E = left touchpad clicked
vk0x8F = right touchpad clicked
vk0x92 = left touchpad touched
vk0x93 = right touchpad clicked
"""
def get_controller_ids(vrsys=None):
if vrsys is None:
vrsys = openvr.VRSystem()
else:
vrsys = vrsys
left = None
right = None
for i in range(openvr.k_unMaxTrackedDeviceCount):
device_class = vrsys.getTrackedDeviceClass(i)
if device_class == openvr.TrackedDeviceClass_Controller:
role = vrsys.getControllerRoleForTrackedDeviceIndex(i)
if role == openvr.TrackedControllerRole_RightHand:
right = i
if role == openvr.TrackedControllerRole_LeftHand:
left = i
return left, right
def from_controller_state_to_dict(pControllerState):
d = {}
d['unPacketNum'] = pControllerState.unPacketNum
d['trigger'] = pControllerState.rAxis[1].x
d['trackpad_x'] = pControllerState.rAxis[0].x
d['trackpad_y'] = pControllerState.rAxis[0].y
d['ulButtonPressed'] = pControllerState.ulButtonPressed
d['ulButtonTouched'] = pControllerState.ulButtonTouched
d['menu_button'] = bool(pControllerState.ulButtonPressed >> 1 & 1)
d['trackpad_pressed'] = bool(pControllerState.ulButtonPressed >> 32 & 1)
d['trackpad_touched'] = bool(pControllerState.ulButtonTouched >> 32 & 1)
d['grip_button'] = bool(pControllerState.ulButtonPressed >> 2 & 1)
return d
pressed = {}
def take_press(set_side, set_key, set_value, set_keycode, data):
if data['side'] == set_side and data[set_key] == set_value and not pressed.get(hex(set_keycode)):
pressed[hex(set_keycode)] = True
win32api.keybd_event(set_keycode, 0, 0, 0)
elif data['side'] == set_side and data[set_key] != set_value and pressed.get(hex(set_keycode)):
pressed[hex(set_keycode)] = False
win32api.keybd_event(set_keycode, 0 ,win32con.KEYEVENTF_KEYUP ,0)
def handle_input(data):
take_press('left', 'grip_button', True, 0x88, data)
take_press('right', 'grip_button', True, 0x89, data)
take_press('left', 'trigger', 1, 0x8A, data)
take_press('right', 'trigger', 1, 0x8B, data)
take_press('left', 'menu_button', True, 0x8C, data)
take_press('right', 'menu_button', True, 0x8D, data)
take_press('left', 'trackpad_pressed', True, 0x8E, data)
take_press('right', 'trackpad_pressed', True, 0x8F, data)
take_press('left', 'trackpad_touched', True, 0x92, data)
take_press('right', 'trackpad_touched', True, 0x93, data)
if __name__ == '__main__':
max_init_retries = 4
retries = 0
print("===========================")
print("Initializing OpenVR...")
while retries < max_init_retries:
try:
openvr.init(openvr.VRApplication_Utility)
break
except openvr.OpenVRError as e:
print("Error when initializing OpenVR (try {} / {})".format(
retries + 1, max_init_retries))
print(e)
retries += 1
time.sleep(2.0)
else:
print("Could not initialize OpenVR, aborting.")
exit(0)
print("Success!")
print("===========================")
vrsystem = openvr.VRSystem()
left_id, right_id = None, None
print("===========================")
print("Waiting for controllers...")
try:
while left_id is None or right_id is None:
left_id, right_id = get_controller_ids(vrsystem)
if left_id and right_id:
break
print("Waiting for controllers...")
time.sleep(1.0)
except KeyboardInterrupt:
print("Control+C pressed, shutting down...")
openvr.shutdown()
print("Left controller ID: " + str(left_id))
print("Right controller ID: " + str(right_id))
print("===========================")
pp = pprint.PrettyPrinter(indent=4)
reading_rate_hz = 250
show_only_new_events = True
last_unPacketNum_left = 0
last_unPacketNum_right = 0
print("===========================")
print("Outputting controller key events!")
try:
while True:
time.sleep(1.0 / reading_rate_hz)
result, pControllerState = vrsystem.getControllerState(left_id)
d = from_controller_state_to_dict(pControllerState)
if show_only_new_events and last_unPacketNum_left != d['unPacketNum']:
last_unPacketNum_left = d['unPacketNum']
d['side'] = 'left'
handle_input(d)
result, pControllerState = vrsystem.getControllerState(right_id)
d = from_controller_state_to_dict(pControllerState)
if show_only_new_events and last_unPacketNum_right != d['unPacketNum']:
last_unPacketNum_right = d['unPacketNum']
d['side'] = 'right'
handle_input(d)
except KeyboardInterrupt:
print("Control+C pressed, shutting down...")
openvr.shutdown()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.