Added Gui (unfinished)

config into dataclass and enums
new Gui that includes settings
deleted GlobalVariables

small fixes (import, names...)
This commit is contained in:
2026-07-30 22:49:53 +02:00
parent b537677277
commit 9c31de3c38
13 changed files with 383 additions and 230 deletions
+9 -37
View File
@@ -1,5 +1,5 @@
"""
inputs/PygameController.py - Pygame Joystick Input Provider with Corrected Axes
inputs/PygameController.py - Headless Pygame Joystick Provider
"""
import math
from multiprocessing import Queue
@@ -13,10 +13,6 @@ class PygameController(InputProvider):
pygame.init()
pygame.joystick.init()
self.screen = pygame.display.set_mode((400, 300))
pygame.display.set_caption("JackBot Controller Input")
self.font = pygame.font.Font(None, 24)
self.deadzone = deadzone
self.joysticks = {}
self.clock = pygame.time.Clock()
@@ -33,43 +29,37 @@ class PygameController(InputProvider):
vx, vy, omega = 0.0, 0.0, 0.0
emote = ""
# Process Pygame events
# Pump Pygame events in headless mode
for event in pygame.event.get():
if event.type == pygame.QUIT:
pass
elif event.type == pygame.JOYDEVICEADDED:
if event.type == pygame.JOYDEVICEADDED:
joy = pygame.joystick.Joystick(event.device_index)
self.joysticks[joy.get_instance_id()] = joy
print(f"Joystick {joy.get_instance_id()} connected: {joy.get_name()}")
print(f"[Controller] Joystick {joy.get_instance_id()} connected: {joy.get_name()}")
elif event.type == pygame.JOYDEVICEREMOVED:
if event.instance_id in self.joysticks:
print(f"Joystick {event.instance_id} disconnected")
print(f"[Controller] Joystick {event.instance_id} disconnected")
del self.joysticks[event.instance_id]
elif event.type == pygame.JOYBUTTONDOWN:
if event.button == 3:
emote = "wave"
# Read active controller stick states
# Read stick values if joystick is connected
if self.joysticks:
for joystick in self.joysticks.values():
# Axis 1 = Left Stick Up/Down (Negated so Forward = +1.0)
# Axis 0 = Left Stick Left/Right (Right = +1.0)
raw_vx = -joystick.get_axis(1) # Forward (+) / Backward (-)
raw_vy = joystick.get_axis(0) # Right (+) / Left (-)
# Check Axis 3 first for Right Stick X, fallback to Axis 2
num_axes = joystick.get_numaxes()
raw_omega = joystick.get_axis(3) if num_axes > 3 else joystick.get_axis(2)
norm_vx, norm_vy = self._normalize_input(raw_vx, raw_vy)
# Apply deadzones
if abs(raw_omega) >= self.deadzone:
omega = raw_omega
if abs(norm_vx) >= self.deadzone or abs(norm_vy) >= self.deadzone:
vx, vy = norm_vx, norm_vy
# Axis snapping for clean cardinal walking
# Cardinal snapping
if 0.8 < vx and -0.2 < vy < 0.2:
vx, vy = 1.0, 0.0
elif vx < -0.8 and -0.2 < vy < 0.2:
@@ -79,7 +69,6 @@ class PygameController(InputProvider):
elif -0.2 < vx < 0.2 and vy < -0.8:
vx, vy = 0.0, -1.0
# Determine robot state
state = "walking" if (vx != 0.0 or vy != 0.0 or omega != 0.0) else "idle"
self.current_command = CommandFrame(
@@ -87,24 +76,6 @@ class PygameController(InputProvider):
vector_dirmov=[vx, vy, omega],
emote=emote
)
# Render visual display
self.screen.fill((30, 30, 30))
axis_count = list(self.joysticks.values())[0].get_numaxes() if self.joysticks else 0
lines = [
f"Connected Joysticks: {len(self.joysticks)} (Axes: {axis_count})",
f"Robot State: {self.current_command.state.upper()}",
f"Vx (Fwd/Bwd): {vx:>6.2f}",
f"Vy (Strafe) : {vy:>6.2f}",
f"Omega (Yaw) : {omega:>6.2f}",
]
for i, line in enumerate(lines):
txt = self.font.render(line, True, (255, 255, 255))
self.screen.blit(txt, (20, 20 + i * 30))
pygame.display.flip()
return self.current_command
def get_command(self) -> CommandFrame:
@@ -122,7 +93,8 @@ def controller_loop(control_queue: Queue):
control_queue.put({
"state": cmd.state,
"dirmov": cmd.vector_dirmov,
"emote": cmd.emote
"emote": cmd.emote,
"joysticks_count": len(provider.joysticks)
})
provider.clock.tick(30)
finally: