140 lines
3.8 KiB
Python
140 lines
3.8 KiB
Python
import math
|
|
|
|
import pygame
|
|
import serial
|
|
|
|
import time
|
|
import colorsys
|
|
|
|
from util import clamp, rescale
|
|
from fixtures import MovingHead
|
|
|
|
if __name__ == "__main__":
|
|
|
|
movingheads = [
|
|
MovingHead(1),
|
|
MovingHead(15),
|
|
MovingHead(29),
|
|
MovingHead(43),
|
|
]
|
|
|
|
# movingheads[0].rgbw = (59, 130, 246, 0) # blue
|
|
# movingheads[1].rgbw = (245, 158, 11, 0) # yellow
|
|
# movingheads[2].rgbw = (239, 68, 68, 0) # red
|
|
# movingheads[3].rgbw = (16, 185, 129, 0) # green
|
|
|
|
for head in movingheads:
|
|
head.rgbw = (0, 0, 0xFF, 0)
|
|
|
|
for head in movingheads:
|
|
head.pan = -0.5 * math.pi
|
|
|
|
dmx_data = bytearray(512)
|
|
|
|
# pygame initialization
|
|
|
|
pygame.init() # pylint: disable=no-member; wtf?
|
|
|
|
screen = pygame.display.set_mode((420, 69), pygame.RESIZABLE)
|
|
pygame.display.set_caption("meh")
|
|
|
|
pygame.joystick.init()
|
|
gamepad = pygame.joystick.Joystick(0)
|
|
gamepad.init()
|
|
|
|
clock = pygame.time.Clock()
|
|
|
|
# main loop
|
|
|
|
running = True # this is clearly not constant, see 17 lines below???
|
|
|
|
with serial.Serial("/dev/ttyUSB0", 500_000) as ser:
|
|
|
|
def sync():
|
|
# wait for sync
|
|
while True:
|
|
b = ser.readline()
|
|
if b.strip() == b"Sync.":
|
|
return
|
|
|
|
sync()
|
|
|
|
while running:
|
|
|
|
for event in pygame.event.get():
|
|
if event.type == pygame.QUIT: # pylint: disable=no-member;
|
|
running = False
|
|
|
|
# axes:
|
|
pitch = gamepad.get_axis(4) # 0 horizontal, -1 up, 1 down
|
|
whammy = gamepad.get_axis(3) # -1 default, 1 if max. pressed
|
|
|
|
# buttons:
|
|
button_state = [
|
|
gamepad.get_button(i)
|
|
for i in [
|
|
0, # green
|
|
1, # red
|
|
3, # yellow
|
|
2, # blue
|
|
4, # orange
|
|
]
|
|
]
|
|
|
|
# strumm bar
|
|
(_, bar) = gamepad.get_hat(0)
|
|
|
|
print(
|
|
f"pitch: {pitch:+0.2f}, "
|
|
f"whammy: {whammy:+0.2f}, "
|
|
f"buttons: {button_state}, "
|
|
f"bar: {bar: 1}"
|
|
)
|
|
|
|
# render
|
|
|
|
for head_id, button_id in enumerate([3, 2, 1, 0]):
|
|
movingheads[head_id].dimmer = 0 if button_state[button_id] else 1
|
|
|
|
pitch = max(0, min(1, -1 * pitch)) # 0 horizontal, 1 up
|
|
tilt = rescale(pitch, (0, 1), (-0.5 * math.pi, 0))
|
|
for head in movingheads:
|
|
head.tilt = tilt
|
|
r, g, b = colorsys.hls_to_rgb((time.time() / 12) % 1, 0.5, 1)
|
|
head.rgbw = (int(255 * r), int(255 * g), int(255 * b), 0)
|
|
|
|
ANGLE_HOME = -0.5 * math.pi
|
|
ANGLE_OUTER = 0.5235988
|
|
ANGLE_INNER = 0.2617994
|
|
|
|
movingheads[0].pan = rescale(
|
|
whammy, (-1, 1), (ANGLE_HOME, ANGLE_HOME + ANGLE_OUTER)
|
|
)
|
|
movingheads[1].pan = rescale(
|
|
whammy, (-1, 1), (ANGLE_HOME, ANGLE_HOME + ANGLE_INNER)
|
|
)
|
|
movingheads[2].pan = rescale(
|
|
whammy, (-1, 1), (ANGLE_HOME, ANGLE_HOME - ANGLE_INNER)
|
|
)
|
|
movingheads[3].pan = rescale(
|
|
whammy, (-1, 1), (ANGLE_HOME, ANGLE_HOME - ANGLE_OUTER)
|
|
)
|
|
|
|
for head in movingheads:
|
|
# print(head)
|
|
head.render(dmx_data)
|
|
|
|
ser.write(dmx_data)
|
|
ser.flush()
|
|
response = ser.readline()
|
|
if response.strip() != b"Ack.":
|
|
print(f"received bad response: {response!r}")
|
|
sync()
|
|
|
|
try:
|
|
clock.tick(50)
|
|
except KeyboardInterrupt:
|
|
running = False
|
|
|
|
pygame.quit() # pylint: disable=no-member;
|