Skip to content

Commit

Permalink
[Update] v0.5.2
Browse files Browse the repository at this point in the history
  • Loading branch information
Z4urce committed Feb 19, 2024
1 parent ffeae2f commit 407ee38
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 46 deletions.
21 changes: 14 additions & 7 deletions BridgeApp/app_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,40 @@ class VRTracker:
index: int
model: str
serial: str
pulse_multiplier: float

def __init__(self, index: int, model: str, serial: str):
self.index = index
self.model = model
self.serial = serial
self.pulse_multiplier = self.get_multiplier(model)

@staticmethod
def get_multiplier(model: str):
if model.startswith("Tundra"):
return 100.0
if model.startswith("VIVE Controller"):
return 100.0
else:
return 1.0


# This is a definition class for storing user settings per tracker
class TrackerConfig(BaseModel):
# serial: str
enabled: bool = True # Not yet used
address: str = "/avatar/parameters/..."
vibration_multiplier: float = 1.0
multiplier_override: float = 1.0
pattern_override: str = "None"
battery_threshold: int = 20

def set_vibration_multiplier(self, value):
if value is None:
return
try:
self.vibration_multiplier = float(value)
self.multiplier_override = float(value)
except ValueError:
self.vibration_multiplier = 1.0
self.multiplier_override = 1.0

def set_battery_threshold(self, value):
if value is None:
Expand Down Expand Up @@ -68,7 +79,6 @@ class AppConfig(BaseModel):

# OBSOLETE - Will delete these in the next version
tracker_to_osc: Dict[str, str] = {}
tracker_to_vib_int_override: Dict[str, float] = {}

def get_tracker_config(self, device_serial):
if device_serial in self.tracker_config_dict:
Expand All @@ -83,11 +93,8 @@ def check_integrity(self):
for key in self.tracker_to_osc:
new_config = TrackerConfig()
new_config.address = self.tracker_to_osc[key]
if key in self.tracker_to_vib_int_override:
new_config.vibration_multiplier = self.tracker_to_vib_int_override[key]
self.tracker_config_dict[key] = new_config
self.tracker_to_osc.clear()
self.tracker_to_vib_int_override.clear()

def init_pattern_config(self):
self.pattern_config_list.clear()
Expand Down
4 changes: 2 additions & 2 deletions BridgeApp/app_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from app_config import AppConfig, PatternConfig
from app_pattern import VibrationPattern

WINDOW_NAME = "Haptic Pancake Bridge v0.5.1"
WINDOW_NAME = "Haptic Pancake Bridge v0.5.2"

LIST_SERVER_TYPE = ["OSC (VRChat)", "WebSocket (Resonite)"]

Expand Down Expand Up @@ -104,7 +104,7 @@ def tracker_row(self, tracker_id, tracker_serial, tracker_model):

dev_config = self.config.get_tracker_config(tracker_serial)
address = dev_config.address
vib_multiplier = dev_config.vibration_multiplier
vib_multiplier = dev_config.multiplier_override
battery_threshold = dev_config.battery_threshold

multiplier_tooltip = "1.0 for Vive trackers\n150 for Tundra trackers\n200 for Vive Wand\n400 for Index c."
Expand Down
38 changes: 13 additions & 25 deletions BridgeApp/app_pattern.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,11 @@ class VibrationPattern:

def __init__(self, app_config: AppConfig):
self.config = app_config
self.tracker_data = {}

def apply_pattern(self, tracker_serial, osc_value):
delta_value, delta_time = self.__calculate_delta(tracker_serial, osc_value)
return self.__apply_pattern(osc_value, delta_value, delta_time)

def __calculate_delta(self, tracker_serial, osc_value):
delta_value = 0
delta_time = 0
current_time = time.time()
if tracker_serial in self.tracker_data:
delta_value = osc_value - self.tracker_data[tracker_serial][0]
delta_time = current_time - self.tracker_data[tracker_serial][1]
self.tracker_data[tracker_serial] = (osc_value, current_time)
return delta_value, delta_time

def __apply_pattern(self, osc_value, osc_value_delta, delta_time):

def apply_pattern(self, str_value, str_delta_value):
return self.__apply_pattern(str_value, str_delta_value)

def __apply_pattern(self, str_value, str_value_delta):
proximity_settings = self.config.pattern_config_list[self.PROXIMITY]
velocity_settings = self.config.pattern_config_list[self.VELOCITY]
proximity_pattern_index = self.VIB_PATTERN_LIST.index(proximity_settings.pattern)
Expand All @@ -45,25 +33,25 @@ def __apply_pattern(self, osc_value, osc_value_delta, delta_time):
case 0: # None
proximity_value = 0
case 1: # Constant
proximity_value = 1 if osc_value > 0 else 0
proximity_value = 1 if str_value > 0 else 0
case 2: # Linear
proximity_value = osc_value
proximity_value = str_value
case 3: # Sine
proximity_value = self.ease_in_out_sine(osc_value)
proximity_value = self.ease_in_out_sine(str_value)
case 4: # Throb
proximity_value = self.__get_linear_value(proximity_settings.speed) * osc_value
proximity_value = self.__get_linear_value(proximity_settings.speed) * str_value

match velocity_pattern_index:
case 0: # None
velocity_value = 0
case 1: # Constant
velocity_value = 1 if osc_value_delta != 0 else 0
velocity_value = 1 if str_value_delta != 0 else 0
case 2: # Linear
velocity_value = abs(osc_value_delta)
velocity_value = str_value_delta
case 3: # Sine
velocity_value = self.ease_in_out_sine(osc_value_delta)
velocity_value = self.ease_in_out_sine(str_value_delta)
case 4: # Throb
velocity_value = self.__get_linear_value(velocity_settings.speed) * abs(osc_value_delta)
velocity_value = self.__get_linear_value(velocity_settings.speed) * str_value_delta

proximity_value = self.__map(proximity_value, proximity_settings.str_min/100, proximity_settings.str_max/100)
velocity_value = self.__map(velocity_value, velocity_settings.str_min/100, velocity_settings.str_max/100)
Expand Down
34 changes: 22 additions & 12 deletions BridgeApp/app_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,21 @@ def __init__(self, config: AppConfig, tracker: VRTracker, pulse_function, batter
self.battery_low_notif = self.LOW_BATTERY_ALERT_COUNT

self.strength: float = 0.0 # Should be treated as a value between 0 and 1
self.strength_delta: float = 0.0
self.last_str_set_time = time.time()

self.interval_ms = 50 # millis
self.interval_s = self.interval_ms / 1000 # seconds

self.vp = VibrationPattern(self.config)

def set_strength(self, strength: float):
def set_strength(self, strength):
try:
strength = float(strength)
except ValueError:
strength = 0.0

self.strength_delta += abs(strength - self.strength)
self.strength = strength
self.last_str_set_time = time.time()

Expand All @@ -45,24 +52,27 @@ def run(self):
time.sleep(sleep)

def calculate_strength(self, start_time):
# Check the battery threshold
if self.battery_function(self.tracker.index) < (self.tracker_config.battery_threshold / 100):
if self.battery_low_notif > 0:
self.battery_low_notif -= 1
return self.battery_low_notif % .9
return 0
self.battery_low_notif = self.LOW_BATTERY_ALERT_COUNT

# We stop the pulse if we don't get a new value in a certain time
# if self.last_str_set_time + (2 * self.interval_s) < start_time:
# return 0
# Apply Pattern
patterned_strength = self.vp.apply_pattern(self.strength, self.strength_delta)
self.strength_delta -= patterned_strength
if self.strength_delta < 0:
self.strength_delta = 0

if self.strength > 0:
# Apply Pattern
patterned_strength = self.vp.apply_pattern(self.tracker.serial, self.strength)
# Apply Multiplier
multiplied_strength = (patterned_strength *
self.config.get_tracker_config(self.tracker.serial).vibration_multiplier)
# Return
return multiplied_strength
# Apply Multiplier and return
if patterned_strength > 0:
return self.apply_multiplier(patterned_strength)

return 0

def apply_multiplier(self, strength):
return (strength * self.tracker.pulse_multiplier
* self.config.get_tracker_config(self.tracker.serial).multiplier_override)

6 changes: 6 additions & 0 deletions BridgeApp/requirements.txt.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pysimplegui=4.60.5
openvr=1.26.701
pydantic=2.5.3
pyserial=3.5
python-osc=1.8.3
websockets=12.0

0 comments on commit 407ee38

Please sign in to comment.