Optimized message sending with caching
This commit is contained in:
parent
80d31972ed
commit
a79758e7c9
1 changed files with 38 additions and 27 deletions
|
|
@ -7,6 +7,8 @@ import logging
|
||||||
import traceback
|
import traceback
|
||||||
import atexit
|
import atexit
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
from .controller import Controller, ControllerTypes
|
from .controller import Controller, ControllerTypes
|
||||||
from ..bluez import BlueZ
|
from ..bluez import BlueZ
|
||||||
from .protocol import ControllerProtocol
|
from .protocol import ControllerProtocol
|
||||||
|
|
@ -59,7 +61,12 @@ class ControllerServer():
|
||||||
|
|
||||||
self.input = InputParser(self.protocol)
|
self.input = InputParser(self.protocol)
|
||||||
|
|
||||||
self.slow_input_frequency = False
|
# Debug timekeeping storage array
|
||||||
|
self.times = []
|
||||||
|
|
||||||
|
# Initial reconnection overload protection
|
||||||
|
self.tick = 1
|
||||||
|
self.cached_msg = ''
|
||||||
|
|
||||||
def run(self, reconnect_address=None):
|
def run(self, reconnect_address=None):
|
||||||
"""Runs the mainloop of the controller server.
|
"""Runs the mainloop of the controller server.
|
||||||
|
|
@ -103,15 +110,14 @@ class ControllerServer():
|
||||||
|
|
||||||
def mainloop(self, itr, ctrl):
|
def mainloop(self, itr, ctrl):
|
||||||
|
|
||||||
# Mainloop
|
|
||||||
while True:
|
while True:
|
||||||
# Start timing the command processing
|
# Start timing command processing
|
||||||
timer_start = time.perf_counter()
|
timer_start = time.perf_counter()
|
||||||
|
|
||||||
# Attempt to get output from Switch
|
# Attempt to get output from Switch
|
||||||
try:
|
try:
|
||||||
reply = itr.recv(50)
|
reply = itr.recv(50)
|
||||||
if self.logger_level <= logging.DEBUG and len(reply) > 40:
|
if len(reply) > 40:
|
||||||
self.logger.debug(format_msg_switch(reply))
|
self.logger.debug(format_msg_switch(reply))
|
||||||
except BlockingIOError:
|
except BlockingIOError:
|
||||||
reply = None
|
reply = None
|
||||||
|
|
@ -145,7 +151,17 @@ class ControllerServer():
|
||||||
self.logger.debug(format_msg_controller(msg))
|
self.logger.debug(format_msg_controller(msg))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
itr.sendall(msg)
|
# Cache the last packet to prevent overloading the switch
|
||||||
|
# with packets on the "Change Grip/Order" menu.
|
||||||
|
if msg[3:] != self.cached_msg:
|
||||||
|
itr.sendall(msg)
|
||||||
|
self.cached_msg = msg[3:]
|
||||||
|
# Send a blank packet every so often to keep the Switch
|
||||||
|
# from disconnecting from the controller.
|
||||||
|
elif self.tick == 660:
|
||||||
|
itr.sendall(msg)
|
||||||
|
self.tick = 0
|
||||||
|
# print(msg, "tick")
|
||||||
except BlockingIOError:
|
except BlockingIOError:
|
||||||
continue
|
continue
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
|
|
@ -154,28 +170,21 @@ class ControllerServer():
|
||||||
|
|
||||||
# Figure out how long it took to process commands
|
# Figure out how long it took to process commands
|
||||||
timer_end = time.perf_counter()
|
timer_end = time.perf_counter()
|
||||||
elapsed_time = (timer_end - timer_start)
|
elapsed_time = timer_end - timer_start
|
||||||
|
|
||||||
if self.slow_input_frequency:
|
sleep_time = 1/66 - elapsed_time
|
||||||
# Check if we can switch out of slow frequency input
|
if sleep_time >= 0:
|
||||||
if self.input.exited_grip_order_menu:
|
time.sleep(sleep_time)
|
||||||
self.slow_input_frequency = False
|
self.tick += 1
|
||||||
|
|
||||||
|
if self.logger_level <= logging.DEBUG:
|
||||||
|
self.times.append(elapsed_time)
|
||||||
|
if len(self.times) > 100:
|
||||||
|
self.times.pop()
|
||||||
|
mean_time = np.mean(self.times)
|
||||||
|
|
||||||
|
self.logger.debug(self.tick, 1/mean_time)
|
||||||
|
|
||||||
if elapsed_time < 1/15:
|
|
||||||
time.sleep(1/15 - elapsed_time)
|
|
||||||
else:
|
|
||||||
# Respond at 120Hz for Pro Controller
|
|
||||||
# or 60Hz for Joy-Cons.
|
|
||||||
# Sleep timers are compensated with the elapsed command
|
|
||||||
# processing time.
|
|
||||||
PRO_CONTROLLER_FREQUENCY = 1/15
|
|
||||||
JOYCON_FREQUENCY = 1/15
|
|
||||||
if self.controller_type == ControllerTypes.PRO_CONTROLLER:
|
|
||||||
if elapsed_time < PRO_CONTROLLER_FREQUENCY:
|
|
||||||
time.sleep(PRO_CONTROLLER_FREQUENCY - elapsed_time)
|
|
||||||
else:
|
|
||||||
if elapsed_time < JOYCON_FREQUENCY:
|
|
||||||
time.sleep(JOYCON_FREQUENCY - elapsed_time)
|
|
||||||
|
|
||||||
def save_connection(self, error, state=None):
|
def save_connection(self, error, state=None):
|
||||||
|
|
||||||
|
|
@ -198,7 +207,7 @@ class ControllerServer():
|
||||||
self.lock.release()
|
self.lock.release()
|
||||||
except OSError:
|
except OSError:
|
||||||
self.reconnect_counter += 1
|
self.reconnect_counter += 1
|
||||||
self.logger.exception(error)
|
self.logger.debug(error)
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
|
|
||||||
# If we can't reconnect, transition to attempting
|
# If we can't reconnect, transition to attempting
|
||||||
|
|
@ -206,6 +215,9 @@ class ControllerServer():
|
||||||
self.logger.debug("Connecting to any Switch")
|
self.logger.debug("Connecting to any Switch")
|
||||||
self.reconnect_counter = 0
|
self.reconnect_counter = 0
|
||||||
|
|
||||||
|
# Reinitialize initial communication overload protections
|
||||||
|
self.tick = 1
|
||||||
|
|
||||||
# Reinitialize the protocol
|
# Reinitialize the protocol
|
||||||
self.protocol = ControllerProtocol(
|
self.protocol = ControllerProtocol(
|
||||||
self.controller_type,
|
self.controller_type,
|
||||||
|
|
@ -325,7 +337,6 @@ class ControllerServer():
|
||||||
else:
|
else:
|
||||||
time.sleep(1/15)
|
time.sleep(1/15)
|
||||||
|
|
||||||
self.slow_input_frequency = True
|
|
||||||
self.input.exited_grip_order_menu = False
|
self.input.exited_grip_order_menu = False
|
||||||
|
|
||||||
return itr, ctrl
|
return itr, ctrl
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue