Simple synchronization based on UDP broadcast

This commit is contained in:
Piotr Dobrowolski 2017-09-12 03:03:52 +02:00
parent 7385a57699
commit 3137b57c6f

View File

@ -7,6 +7,8 @@ import serial
import webapp import webapp
import threading import threading
import logging import logging
import socket
import json
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
import random, math, pygame import random, math, pygame
@ -16,7 +18,7 @@ from virtualKeyboard import VirtualKeyboard
import threading import threading
from math import cos from math import cos
import time import time
import RPi.GPIO as GPIO import RPi.GPIO as GPIO
class Slide(object): class Slide(object):
def __init__(self): def __init__(self):
@ -44,6 +46,10 @@ class ImageSlide(Slide):
screen.blit(self.image, (0, 0)) screen.blit(self.image, (0, 0))
class FinalSlide(ImageSlide): class FinalSlide(ImageSlide):
def exit(self, next_slide):
return False
class FinalEverythingSlide(ImageSlide):
def enter(self, prev_slide): def enter(self, prev_slide):
global wall_a global wall_a
if(wall_a): if(wall_a):
@ -51,6 +57,9 @@ class FinalSlide(ImageSlide):
pygame.mixer.music.load("media/win.mp3") pygame.mixer.music.load("media/win.mp3")
pygame.mixer.music.play(MP3_LOOPS) pygame.mixer.music.play(MP3_LOOPS)
pygame.mixer.music.set_volume(1.0) pygame.mixer.music.set_volume(1.0)
return True
def exit(self, next_slide): def exit(self, next_slide):
return False return False
@ -254,6 +263,7 @@ SLIDE_MAZE = 7
SLIDE_MP3 = 8 SLIDE_MP3 = 8
SLIDE_KEYBOARD = 11 SLIDE_KEYBOARD = 11
SLIDE_CONGRATS = 9 SLIDE_CONGRATS = 9
SLIDE_CONGRATS_EVERYTHING = 12
SLIDE_SNAKE_DEAD = 10 #to nie slajd, tylko wartosc potrzebna do resetowania snake po przegranej SLIDE_SNAKE_DEAD = 10 #to nie slajd, tylko wartosc potrzebna do resetowania snake po przegranej
@ -270,6 +280,7 @@ slides = {
SLIDE_MAZE: ImageSlide(IMG_MAZE), SLIDE_MAZE: ImageSlide(IMG_MAZE),
SLIDE_MP3: ImageSlide(IMG_MP3), SLIDE_MP3: ImageSlide(IMG_MP3),
SLIDE_CONGRATS: FinalSlide(IMG_WIN), SLIDE_CONGRATS: FinalSlide(IMG_WIN),
SLIDE_CONGRATS_EVERYTHING: FinalEverythingSlide(IMG_WIN),
SLIDE_SNAKE: SnakeSlide(), SLIDE_SNAKE: SnakeSlide(),
} }
@ -311,11 +322,48 @@ class SerialThread(threading.Thread):
go_to_slide(int(args)) go_to_slide(int(args))
print('Setting slide to: ', slide) print('Setting slide to: ', slide)
class BroadcastThread(threading.Thread):
def run(self):
cs = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
cs.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
cs.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
while True:
global slide
print('sending')
cs.sendto(json.dumps({
'slide': slide,
}), ('255.255.255.255', 54545))
time.sleep(1)
class ReceiveThread(threading.Thread):
states = None
def run(self):
self.states = {}
s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('',54545))
while True:
try:
msg, (host, port) = s.recvfrom(1024)
self.states[host] = json.loads(msg)
print(self.states)
if all(s['slide'] in [SLIDE_CONGRATS, SLIDE_CONGRATS_EVERYTHING]
for s in self.states.values()):
go_to_slide(SLIDE_CONGRATS_EVERYTHING)
except:
logging.exception('Receiver failed')
time.sleep(0.5)
for c in ['/dev/ttyUSB0', '/dev/ttyACM0']: for c in ['/dev/ttyUSB0', '/dev/ttyACM0']:
try: try:
ser = serial.Serial(c, 115200) ser = serial.Serial(c, 115200)
except: except:
continue continue
print('Using ', c) print('Using ', c)
webapp.init(ser) webapp.init(ser)
th = SerialThread() th = SerialThread()
@ -323,12 +371,19 @@ for c in ['/dev/ttyUSB0', '/dev/ttyACM0']:
th.daemon = True th.daemon = True
th.start() th.start()
bth = BroadcastThread()
bth.daemon = True
bth.start()
rth = ReceiveThread()
rth.daemon = True
rth.start()
def win(): def win():
print "GAME OVER - YOU WIN" print "GAME OVER - YOU WIN"
GPIO.output(PIN_RELAY, 0) GPIO.output(PIN_RELAY, 0)
def signalWin(success): def signalWin(success):
pin = 0 pin = 0
if success == 4: if success == 4:
@ -337,15 +392,15 @@ def signalWin(success):
pin = PIN_SUC9 pin = PIN_SUC9
elif success == 10: elif success == 10:
pin = PIN_SUC10 pin = PIN_SUC10
print("signalling win for task: ") print("signalling win for task: ")
print(success) print(success)
print("using GPIO pin: ") print("using GPIO pin: ")
print(pin) print(pin)
GPIO.output(pin, 0) GPIO.output(pin, 0)
pygame.time.wait(200) pygame.time.wait(200)
GPIO.output(pin, 1) GPIO.output(pin, 1)
print("done signalling.") print("done signalling.")
def waitForEvents(): def waitForEvents():
global slide global slide
print("waiting for events") print("waiting for events")
@ -385,7 +440,7 @@ def checkEvents(handler=None):
def collide(x1, x2, y1, y2, w1, w2, h1, h2): def collide(x1, x2, y1, y2, w1, w2, h1, h2):
if x1+w1>x2 and x1<x2+w2 and y1+h1>y2 and y1<y2+h2:return True if x1+w1>x2 and x1<x2+w2 and y1+h1>y2 and y1<y2+h2:return True
else:return False else:return False
def die(screen, score): def die(screen, score):
f=FONT_SNAKE f=FONT_SNAKE
t=f.render(MSG_SNAKE+str(score), True, (0, 0, 0)) t=f.render(MSG_SNAKE+str(score), True, (0, 0, 0))
@ -431,7 +486,7 @@ newdirection = RIGHT
snakedead = FALSE snakedead = FALSE
gameregulator = 6 gameregulator = 6
gamepaused = 0 gamepaused = 0
growsnake = 0 # added to grow tail by two each time growsnake = 0 # added to grow tail by two each time
snakegrowunit = 2 # added to grow tail by two each time snakegrowunit = 2 # added to grow tail by two each time
clock = pygame.time.Clock() clock = pygame.time.Clock()
screen = pygame.display.set_mode(WINSIZE, pygame.NOFRAME) screen = pygame.display.set_mode(WINSIZE, pygame.NOFRAME)