From a6d66b3418c4361b2d077ff188b02f16c2c2c0c0 Mon Sep 17 00:00:00 2001 From: redphx <96280+redphx@users.noreply.github.com> Date: Tue, 3 May 2022 17:36:58 +0700 Subject: [PATCH] Reduce CPU usage --- joydance/__init__.py | 69 ++++++++++++++++++++++--------------------- joydance/constants.py | 3 +- 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/joydance/__init__.py b/joydance/__init__.py index 2083d21..4c54945 100644 --- a/joydance/__init__.py +++ b/joydance/__init__.py @@ -69,7 +69,6 @@ class JoyDance: self.available_shortcuts = set() self.accel_data = [] - self.last_accels = [] self.ws = None self.disconnected = False @@ -242,34 +241,46 @@ class JoyDance: async for message in self.ws: await self.on_message(message) + async def sleep_approx(self, target_duration): + tmp_duration = target_duration + x = 0.3 + start = time.time() + while True: + tmp_duration = tmp_duration * x + await asyncio.sleep(tmp_duration) + + dt = time.time() - start + if dt >= target_duration: + break + + tmp_duration = target_duration - dt + async def tick(self): - sleep_duration = FRAME_DURATION * 0.75 - last_time = time.time() + sleep_duration = FRAME_DURATION frames = 0 while True: if self.disconnected: break - # Make sure it runs at exactly 60 FPS - while True: - time_now = time.time() - dt = time_now - last_time - if dt >= FRAME_DURATION: - break - last_time = time_now - frames = frames + 1 if frames < 3 else 1 - if not self.should_start_accelerometer: - await asyncio.sleep(sleep_duration), + frames = 0 + await asyncio.sleep(sleep_duration) continue - await asyncio.gather( - asyncio.sleep(sleep_duration), - self.collect_accelerometer_data(frames), - ) + last_time = time.time() + frames = frames + 1 if frames < 3 else 1 - async def collect_accelerometer_data(self, frames): + await asyncio.gather( + self.sleep_approx(sleep_duration), + self.collect_accelerometer_data(), + ) + await self.send_accelerometer_data(frames) + + dt = time.time() - last_time + sleep_duration = FRAME_DURATION - (dt - sleep_duration) + + async def collect_accelerometer_data(self): if self.disconnected: return @@ -278,25 +289,15 @@ class JoyDance: return try: - start = time.time() - max_runtime = FRAME_DURATION * 0.5 - while time.time() - start < max_runtime: - # Make sure accelerometer axes are changed - accels = self.joycon.get_accels() # [(x, y, z),...] - if accels != self.last_accels: - self.last_accels = accels - break + accels = self.joycon.get_accels() # (x, y, z) # Accelerator axes on phone & Joy-Con are different so we need to swap some axes # https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/imu_sensor_notes.md - for accel in accels: - x = accel[1] * -1 - y = accel[0] - z = accel[2] - - self.accel_data.append([x, y, z]) - - await self.send_accelerometer_data(frames), + accel = accels[2] + x = accel[1] * -1 + y = accel[0] + z = accel[2] + self.accel_data.append([x, y, z]) except OSError: self.disconnect() return diff --git a/joydance/constants.py b/joydance/constants.py index fc0c629..db4dacd 100644 --- a/joydance/constants.py +++ b/joydance/constants.py @@ -15,7 +15,8 @@ WS_SUBPROTOCOLS[WsSubprotocolVersion.V1.value] = 'v1.phonescoring.jd.ubisoft.com WS_SUBPROTOCOLS[WsSubprotocolVersion.V2.value] = 'v2.phonescoring.jd.ubisoft.com' FRAME_DURATION = 1 / 60 -ACCEL_ACQUISITION_FREQ_HZ = 200 # Hz +SEND_FREQ_MS = 0.005 +ACCEL_ACQUISITION_FREQ_HZ = 60 # Hz ACCEL_ACQUISITION_LATENCY = 40 # ms ACCEL_MAX_RANGE = 8 # ±G