better handling button inputs

This commit is contained in:
apirrone 2025-04-09 11:48:54 +02:00
parent 6b6e726433
commit 8b973103c0
3 changed files with 155 additions and 43 deletions

View file

@ -0,0 +1,66 @@
import time
class Button:
def __init__(self):
self.last_pressed_time = time.time()
self.timeout = 0.2
self.is_pressed = False
self.triggered = False
self.released = True
def update(self, value):
if self.is_pressed and not value:
self.released = True
self.is_pressed = value
if self.released and self.is_pressed and (time.time() - self.last_pressed_time > self.timeout):
self.triggered = True
self.last_pressed_time = time.time()
else:
self.triggered = False
if self.is_pressed:
self.released = False
class Buttons:
def __init__(self):
self.A = Button()
self.B = Button()
self.X = Button()
self.Y = Button()
self.LB = Button()
self.RB = Button()
def update(self, A, B, X, Y, LB, RB):
self.A.update(A)
self.B.update(B)
self.X.update(X)
self.Y.update(Y)
self.LB.update(LB)
self.RB.update(RB)
if __name__ == "__main__":
from mini_bdx_runtime.xbox_controller import XBoxController
xbox_controller = XBoxController(30)
buttons = Buttons()
while True:
(
_,
A_pressed,
B_pressed,
X_pressed,
Y_pressed,
LB_pressed,
RB_pressed,
_, _, _
) = xbox_controller.get_last_command()
buttons.update(A_pressed, B_pressed, X_pressed, Y_pressed, LB_pressed, RB_pressed)
print(buttons.A.triggered, buttons.A.is_pressed)
time.sleep(0.05)

View file

@ -32,6 +32,13 @@ class XBoxController:
print(f"Loaded joystick with {self.p1.get_numaxes()} axes.")
self.cmd_queue = Queue(maxsize=1)
self.A_pressed = False
self.B_pressed = False
self.X_pressed = False
self.Y_pressed = False
self.LB_pressed = False
self.RB_pressed = False
Thread(target=self.commands_worker, daemon=True).start()
def commands_worker(self):
@ -40,9 +47,6 @@ class XBoxController:
time.sleep(1 / self.command_freq)
def get_commands(self):
A_pressed = False
X_pressed = False
LB_pressed = False
last_commands = self.last_commands
left_trigger = self.last_left_trigger
right_trigger = self.last_right_trigger
@ -112,30 +116,50 @@ class XBoxController:
last_commands[6] = head_roll
for event in pygame.event.get():
if self.p1.get_button(0): # A button
A_pressed = True
if event.type == pygame.JOYBUTTONDOWN:
if self.p1.get_button(3): # X button
X_pressed = True
if self.p1.get_button(0): # A button
self.A_pressed = True
if self.p1.get_button(6): # LB button
LB_pressed = True
if self.p1.get_button(1): # B button
self.B_pressed = True
if self.p1.get_button(3): # X button
self.X_pressed = True
if self.p1.get_button(4): # Y button
self.Y_pressed = True
self.head_control_mode = not self.head_control_mode
if self.p1.get_button(6): # LB button
self.LB_pressed = True
if self.p1.get_button(7): # RB button
self.RB_pressed = True
if event.type == pygame.JOYBUTTONUP:
self.A_pressed = False
self.B_pressed = False
self.X_pressed = False
self.Y_pressed = False
self.LB_pressed = False
self.RB_pressed = False
# for i in range(10):
# if self.p1.get_button(i):
# print(f"Button {i} pressed")
if self.p1.get_button(4): # Y button
self.head_control_mode = not self.head_control_mode
up_down = self.p1.get_hat(0)[1]
pygame.event.pump() # process event queue
return (
np.around(last_commands, 3),
A_pressed,
X_pressed,
LB_pressed,
self.A_pressed,
self.B_pressed,
self.X_pressed,
self.Y_pressed,
self.LB_pressed,
self.RB_pressed,
left_trigger,
right_trigger,
up_down
@ -143,15 +167,21 @@ class XBoxController:
def get_last_command(self):
A_pressed = False
B_pressed = False
X_pressed = False
Y_pressed = False
LB_pressed = False
RB_pressed = False
up_down = 0
try:
(
self.last_commands,
A_pressed,
B_pressed,
X_pressed,
Y_pressed,
LB_pressed,
RB_pressed,
self.last_left_trigger,
self.last_right_trigger,
up_down
@ -164,8 +194,11 @@ class XBoxController:
return (
self.last_commands,
A_pressed,
B_pressed,
X_pressed,
Y_pressed,
LB_pressed,
RB_pressed,
self.last_left_trigger,
self.last_right_trigger,
up_down

View file

@ -12,9 +12,10 @@ from mini_bdx_runtime.xbox_controller import XBoxController
from mini_bdx_runtime.feet_contacts import FeetContacts
from mini_bdx_runtime.eyes import Eyes
from mini_bdx_runtime.sounds import Sounds
# from mini_bdx_runtime.antennas import Antennas
from mini_bdx_runtime.antennas import Antennas
from mini_bdx_runtime.projector import Projector
from mini_bdx_runtime.rl_utils import make_action_dict, LowPassActionFilter
from mini_bdx_runtime.buttons import Buttons
class RLWalk:
def __init__(
@ -123,11 +124,12 @@ class RLWalk:
self.paused = False
self.sounds = Sounds(volume=1.0, sound_directory="../mini_bdx_runtime/assets/")
# self.antennas = Antennas()
self.antennas = Antennas()
self.command_freq = 20 # hz
if self.commands:
self.xbox_controller = XBoxController(self.command_freq)
self.buttons = Buttons()
self.PRM = PolyReferenceMotion("./polynomial_coefficients.pkl")
self.imitation_i = 0
@ -218,9 +220,12 @@ class RLWalk:
print("Starting")
start_t = time.time()
while True:
A_pressed = False
X_pressed = False
LB_pressed = False
# A_pressed = False
# B_pressed = False
# X_pressed = False
# Y_pressed = False
# LB_pressed = False
# RB_pressed = False
left_trigger = 0
right_trigger = 0
up_down = 0
@ -230,42 +235,50 @@ class RLWalk:
(
self.last_commands,
A_pressed,
B_pressed,
X_pressed,
Y_pressed,
LB_pressed,
RB_pressed,
left_trigger,
right_trigger,
up_down
) = self.xbox_controller.get_last_command()
if up_down == 1:
self.phase_frequency_factor += 0.05
print(f"Phase frequency factor {self.phase_frequency_factor}")
elif up_down == -1:
self.phase_frequency_factor -= 0.05
print(f"Phase frequency factor {self.phase_frequency_factor}")
self.buttons.update(A_pressed, B_pressed, X_pressed, Y_pressed, LB_pressed, RB_pressed)
if up_down == 1:
self.phase_frequency_factor += 0.05
print(f"Phase frequency factor {self.phase_frequency_factor}")
elif up_down == -1:
self.phase_frequency_factor -= 0.05
print(f"Phase frequency factor {self.phase_frequency_factor}")
# if LB_pressed:
# self.phase_frequency_factor = 1.2
# else:
# self.phase_frequency_factor = 1.0
if self.buttons.LB.is_pressed:
self.phase_frequency_factor = 1.3
else:
self.phase_frequency_factor = 1.0
# self.phase_frequency_factor = self.get_phase_frequency_factor(self.last_commands[0])
# print(f"Phase frequency factor {self.phase_frequency_factor}")
# self.phase_frequency_factor = self.get_phase_frequency_factor(self.last_commands[0])
# print(f"Phase frequency factor {self.phase_frequency_factor}")
if X_pressed:
self.sounds.play_random_sound()
self.projector.switch()
if self.buttons.X.triggered:
self.projector.switch()
# self.antennas.set_position_left(right_trigger)
# self.antennas.set_position_right(left_trigger)
if self.buttons.B.triggered:
self.sounds.play_random_sound()
self.antennas.set_position_left(right_trigger)
self.antennas.set_position_right(left_trigger)
if self.buttons.A.triggered:
self.paused = not self.paused
if self.paused:
print("PAUSE")
else:
print("UNPAUSE")
if A_pressed and not self.paused:
self.paused = True
print("PAUSE")
elif A_pressed and self.paused:
self.paused = False
print("UNPAUSE")
if self.paused:
time.sleep(0.1)