Commit ddb9097d authored by Kamal Nasser's avatar Kamal Nasser
Browse files

UDP and stuff

parent 10c44fdd
#import threading import threading
from eventlet.green import threading #from eventlet.green import threading
import optirx as rx import optirx as rx
DEFAULT_MULTICAST_ADDRESS = '239.255.42.99' DEFAULT_MULTICAST_ADDRESS = '239.255.42.99'
...@@ -7,7 +7,7 @@ DEFAULT_DATA_PORT = 1511 ...@@ -7,7 +7,7 @@ DEFAULT_DATA_PORT = 1511
DEFAULT_NATNETSDK_VERSION = (2, 8, 0, 0) DEFAULT_NATNETSDK_VERSION = (2, 8, 0, 0)
class OptitrackPacketReceiver: class OptitrackPacketReceiver(threading.Thread):
""" """
Responsible for constantly receiving UDP packets form the OptiTrack system, parsing them to optirx objects, Responsible for constantly receiving UDP packets form the OptiTrack system, parsing them to optirx objects,
and storing them locally to make them available when needed. and storing them locally to make them available when needed.
...@@ -16,7 +16,7 @@ class OptitrackPacketReceiver: ...@@ -16,7 +16,7 @@ class OptitrackPacketReceiver:
""" """
def __init__(self, server_ip_addr, natnetsdk_version=DEFAULT_NATNETSDK_VERSION, def __init__(self, server_ip_addr, natnetsdk_version=DEFAULT_NATNETSDK_VERSION,
multicast_addr=DEFAULT_MULTICAST_ADDRESS, data_port=DEFAULT_DATA_PORT): multicast_addr=DEFAULT_MULTICAST_ADDRESS, data_port=DEFAULT_DATA_PORT):
#super(OptitrackPacketReceiver, self).__init__() super(OptitrackPacketReceiver, self).__init__()
self._natnetsdk_version = natnetsdk_version self._natnetsdk_version = natnetsdk_version
self._last_packet = None self._last_packet = None
self._is_shutdown_request = False self._is_shutdown_request = False
......
...@@ -31,9 +31,9 @@ def start_sio(): ...@@ -31,9 +31,9 @@ def start_sio():
DEFAULT_NOTE_DURATION_PRECISION = 0.125 DEFAULT_NOTE_DURATION_PRECISION = 0.125
# rh roll implemented for future use # rh roll implemented for future use
DEFAULT_OPTITRACK_RANGES_DICT = { DEFAULT_OPTITRACK_RANGES_DICT = {
'x': (-0.9, 1.5), 'x': (-0.7, 0.5),
'y': (-2.1, 1.2), 'y': (-0.7, 0.55),
'z': (-0.1, 1.7), 'z': (-0.4, 1.0),
'rh_roll': (-180, 180) 'rh_roll': (-180, 180)
} }
DEFAULT_RTSCS_PARAM_RANGES_DICT = { DEFAULT_RTSCS_PARAM_RANGES_DICT = {
......
import optirx as rx
import optirx_utils
import eventlet
import math
from oscpy.client import OSCClient
from utils import clip_value, remap_range, round_to_precision
import json
eventlet.monkey_patch()
UDP_IP = "192.168.43.186"
UDP_PORT = 5000
max_udp_client = OSCClient(UDP_IP, UDP_PORT)
def send_udp(message):
max_udp_client.send_message("/", message)
DEFAULT_NOTE_DURATION_PRECISION = 0.125
# rh roll implemented for future use
DEFAULT_OPTITRACK_RANGES_DICT = {
'x': (-0.88, 0.19),
'y': (-0.03, 0.49),
'z': (0.07, 1.3),
'rh_roll': (-180, 180)
}
DEFAULT_RTSCS_PARAM_RANGES_DICT = {
'tempo': (75, 170),
'senda': (0, 100),
'mastervol': (-55, 0),
'numerical_hint': (0, 1)
}
def transform_params(rh_position, rh_roll, lh_position=None):
"""
Transforms OptiTrack params into rtscs params
:param rh_position: a (x, y, z) tuple holding the position of the right hand "rigid body"
:param rh_roll: roll angle in degrees of the right hand "rigid body"
:param lh_position: a (x, y, z) tuple holding the position of the left hand "rigid body"
:return: rtscs params tuple as defined in BaseRtscsParamReceiver.get_rtscs_params()
"""
is_sustain = False # TODO: derive is_sustain from distance between rh_position and lh_position
transformed_params = rh_position + [rh_roll, is_sustain]
# Remap rh position onto rtscs internal ranges
# x -> frequency
# y -> number of waves which define the complex wave.
# z -> amplitude.
for i, mapped_pair in enumerate((('x', 'tempo'), ('y', 'senda'),
('z', 'mastervol'), ('rh_roll', 'numerical_hint'))):
source_low = DEFAULT_OPTITRACK_RANGES_DICT[mapped_pair[0]][0]
source_high = DEFAULT_OPTITRACK_RANGES_DICT[mapped_pair[0]][1]
destination_low = DEFAULT_RTSCS_PARAM_RANGES_DICT[mapped_pair[1]][0]
destination_high = DEFAULT_RTSCS_PARAM_RANGES_DICT[mapped_pair[1]][1]
# clip Optritrack param to the limits of its defined valid range
transformed_params[i] = clip_value(transformed_params[i],
source_low, source_high)
# translate Optritrack param to rtscs param
transformed_params[i] = remap_range(transformed_params[i],
source_low, source_high,
destination_low, destination_high)
# convert frequency and number of sins to int
for i in range(1):
transformed_params[i] = int(round(transformed_params[i]))
# round amplitude factor to precision
transformed_params[2] = round_to_precision(transformed_params[2], DEFAULT_NOTE_DURATION_PRECISION)
return transformed_params
def get_rtscs_params_body(rh):
"""
Get input from the OptiTrack system streaming engine, transform the data to rtscs_params and return it.
"""
if rh is None or rh.mrk_mean_error == 0:
return 0, 0, 1, 0, False
# mul by -1 to fix flipped coordinates if not fully compatible Motive calibration square
rh_position = list(rh.position) # map(lambda coordinate: -1 * coordinate, rh.position)
# Convert right hand convention to left hand convention for Motive 1.73+ used with CS-200
rh_position[0] = -rh_position[0]
# For convenience convert roll angle from radians to degrees
rh_roll = math.degrees(optirx_utils.orientation2radians(rh.orientation)[0])
return transform_params(rh_position, rh_roll)
def get_optirx_data():
dsock = rx.mkdatasock(ip_address="127.0.0.1", multicast_address='239.255.42.99', port=1511)
natnetsdk_version = (2, 8, 0, 0)
while True:
data = dsock.recv(rx.MAX_PACKETSIZE)
# parse packet and store it locally
packet = rx.unpack(data, natnetsdk_version)
if type(packet) is rx.SenderData:
natnetsdk_version = packet.natnet_version
rh = optirx_utils.get_first_rigid_body(packet)
if rh is not None:
print(rh.position)
params = get_rtscs_params_body(rh)
if params != (0, 0, 1, 0, False):
print(params)
msg = [json.dumps({
'tempo': params[0],
'senda': params[1],
'mastervol': params[2],
})]
send_udp(msg)
print(msg)
eventlet.sleep(0.1)
t_data = eventlet.spawn(get_optirx_data)
t_data.wait()
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment