Commit 035a14af authored by Antoine Lima's avatar Antoine Lima

Goal detection

parent a483826b
...@@ -28,20 +28,18 @@ def getMainWin(): ...@@ -28,20 +28,18 @@ def getMainWin():
ON_RASP = os.uname()[1] == 'raspberrypi' ON_RASP = os.uname()[1] == 'raspberrypi'
IMG_PATH = getContent('img') IMG_PATH = getContent('img')
SIDE = None
if __name__=='__main__': if __name__=='__main__':
__package__ = 'Babyfut' __package__ = 'Babyfut'
from Babyfut.ui.mainwin import MainWin from Babyfut.ui.mainwin import MainWin
from Babyfut.modules import GameModule from Babyfut.modules import GameModule
from Babyfut.core.player import Side from Babyfut.core.player import Side
from Babyfut.core.input import GPIOThread from Babyfut.core.input import Input
from Babyfut.core.downloader import Downloader from Babyfut.core.downloader import Downloader
from Babyfut.core.database import Database from Babyfut.core.database import Database
from Babyfut.core.replay import Replay as ReplayThread from Babyfut.core.replay import Replay as ReplayThread
try: try:
SIDE = Side.Left
#logging.basicConfig(filename='babyfoot.log', level=logging.DEBUG) #logging.basicConfig(filename='babyfoot.log', level=logging.DEBUG)
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG)
...@@ -56,9 +54,10 @@ if __name__=='__main__': ...@@ -56,9 +54,10 @@ if __name__=='__main__':
threadReplay.start() threadReplay.start()
myapp.dispatchMessage({'replayThread': threadReplay}, toType=GameModule) myapp.dispatchMessage({'replayThread': threadReplay}, toType=GameModule)
threadGPIO = GPIOThread() input = Input()
threadGPIO.rfidReceived.connect(myapp.rfidHandler) input.rfidReceived.connect(lambda side: myapp.dispatchMessage({'rfid': rfid, 'source': side}))
threadGPIO.start() input.goalDetected.connect(lambda side: myapp.dispatchMessage({'goal': True, 'source': side}))
input.start()
threadDownloader = Downloader.instance() threadDownloader = Downloader.instance()
threadDownloader.start() threadDownloader.start()
...@@ -66,18 +65,16 @@ if __name__=='__main__': ...@@ -66,18 +65,16 @@ if __name__=='__main__':
myapp.show() myapp.show()
app.exec_() app.exec_()
threadDownloader.stop()
threadGPIO.stop()
if ReplayThread.isCamAvailable(): if ReplayThread.isCamAvailable():
threadReplay.stop() threadReplay.stop()
threadReplay.join() threadReplay.join()
threadGPIO.join() input.stop()
threadDownloader.stop()
threadDownloader.join() threadDownloader.join()
finally: finally:
GPIOThread.clean()
Database.instance().close() Database.instance().close()
for f in glob.glob(join(IMG_PATH, '*')): for f in glob.glob(join(IMG_PATH, '*')):
os.remove(f) os.remove(f)
...@@ -7,18 +7,34 @@ ...@@ -7,18 +7,34 @@
import logging import logging
import time import time
from threading import Thread from threading import Thread
import pyautogui # PyPi library
from PyQt5.QtCore import QObject, pyqtSignal from PyQt5.QtCore import QObject, pyqtSignal
from Babyfut.babyfut import ON_RASP from Babyfut.babyfut import ON_RASP
from Babyfut.core.player import Side from Babyfut.core.player import Side
from Babyfut.core.settings import Settings
if ON_RASP: if ON_RASP:
import RPi.GPIO as GPIO import RPi.GPIO as GPIO
from pirc522 import RFID # PyPi library from pirc522 import RFID # PyPi library
import pyautogui # PyPi library
class Input(QObject):
'''
Defines pins. Uses BCM pin identifiers
'''
_RFIDPins = {
'pin_rst': 25,
'pin_ce' : 8,
'pin_irq': 24
}
_GoalPins = {
'pin_trig': 4,
'pin_echo': 16
}
class GPIOThread(Thread, QObject):
_keyButtonBindings = { _keyButtonBindings = {
26: 'up', 26: 'up',
22: 'left', 22: 'left',
...@@ -28,36 +44,75 @@ class GPIOThread(Thread, QObject): ...@@ -28,36 +44,75 @@ class GPIOThread(Thread, QObject):
18: 'escape' 18: 'escape'
} }
rfidReceived = pyqtSignal(str) rfidReceived = pyqtSignal(Side, str)
goalDetected = pyqtSignal(Side)
def __init__(self): def __init__(self):
Thread.__init__(self)
QObject.__init__(self) QObject.__init__(self)
self.continueRunning = True
self.lastRFIDReception = 0
if ON_RASP: if ON_RASP:
self.rf_reader = RFID(pin_rst=25, pin_ce=8, pin_irq=24, pin_mode=GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM) GPIO.setmode(GPIO.BCM)
for pin in Input._keyButtonBindings.keys():
for pin in GPIOThread._keyButtonBindings.keys():
print(pin)
GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.add_event_detect(pin, GPIO.RISING, callback=self.handleButtonPress) GPIO.add_event_detect(pin, GPIO.RISING, callback=self._handleButtonPress)
self.side = Side.Left if Settings['app.side']=='left' else Side.Right
print(self.side)
self.rfidThread = RFIDThread(self, **Input._RFIDPins)
self.goalThread = GoalThread(self, **Input._GoalPins)
def start(self):
self.rfidThread.start()
self.goalThread.start()
def stop(self):
self.rfidThread.stop(); self.rfidThread.join()
self.goalThread.stop(); self.goalThread.join()
def _handleButtonPress(self, button_pin):
if button_pin not in Input._keyButtonBindings.keys():
logging.warn('Unknown button pin: {}'.format(button_pin))
else:
key = Input._keyButtonBindings[button_pin]
logging.debug('Sending {} as {}'.format(button_pin, key))
pyautogui.press(key)
class GPIOThread(Thread):
def __init__(self):
Thread.__init__(self)
self._running = True
def running(self):
return self._running
def start(self):
Thread.start(self)
def stop(self):
self._running = False
def clean(self):
GPIO.cleanup()
class RFIDThread(GPIOThread):
def __init__(self, parent, **pins):
GPIOThread.__init__(self)
self.parent = parent
self.lastRFIDReception = 0
self.rf_reader = RFID(**pins, pin_mode=GPIO.BCM)
print(self.rf_reader.pin_rst, self.rf_reader.pin_ce, self.rf_reader.pin_irq)
def run(self): def run(self):
if ON_RASP: try:
try: while self.running():
while self.continueRunning: self.rf_reader.wait_for_tag()
self.rf_reader.wait_for_tag() (error, tag_type) = self.rf_reader.request()
(error, tag_type) = self.rf_reader.request() if not error:
if not error: self._handleRFID()
self.handleRFID() finally:
finally: self.clean()
self.clean()
def _handleRFID(self):
def handleRFID(self):
(error, id) = self.rf_reader.anticoll() (error, id) = self.rf_reader.anticoll()
if not error: if not error:
# Prevent RFID "spam" (one second removal delay) # Prevent RFID "spam" (one second removal delay)
...@@ -65,30 +120,59 @@ class GPIOThread(Thread, QObject): ...@@ -65,30 +120,59 @@ class GPIOThread(Thread, QObject):
if self.lastRFIDReception!=0 and abs(self.lastRFIDReception-now)>1: if self.lastRFIDReception!=0 and abs(self.lastRFIDReception-now)>1:
self.lastRFIDReception = 0 self.lastRFIDReception = 0
receivedRFID = ':'.join([str(x) for x in id]) receivedRFID = ':'.join([str(x) for x in id])
self.rfidReceived.emit(receivedRFID) self.input.emit(self.parent.side, receivedRFID)
logging.debug('Received RFID: {}'.format(receivedRFID)) logging.debug('Received RFID: {}'.format(receivedRFID))
else: else:
self.lastRFIDReception = now self.lastRFIDReception = now
def handleButtonPress(self, button_pin):
if button_pin not in GPIOThread._keyButtonBindings.keys():
logging.warn('Unknown button pin: {}'.format(button_pin))
else:
key = GPIOThread._keyButtonBindings[button_pin]
logging.debug('Sending {} as {}'.format(button_pin, key))
pyautogui.press(key)
def stop(self): def stop(self):
self.continueRunning = False GPIOThread.stop(self)
# Falsely trigger the rfid reader to stop it waiting
if ON_RASP: # Falsely trigger the rfid reader to stop it from waiting
self.rf_reader.irq.set() self.rf_reader.irq.set()
def clean(self): def clean(self):
GPIOThread.clean() GPIOThread.clean(self)
self.rf_reader.cleanup() self.rf_reader.cleanup()
@staticmethod class GoalThread(GPIOThread):
def clean(): def __init__(self, parent, pin_trig, pin_echo):
if ON_RASP: GPIOThread.__init__(self)
GPIO.cleanup() self.parent = parent
self.pin_trig = pin_trig
self.pin_echo = pin_echo
GPIO.setmode(GPIO.BCM)
GPIO.setup (self.pin_echo, GPIO.IN)
GPIO.setup (self.pin_trig, GPIO.OUT)
GPIO.output(self.pin_trig, GPIO.LOW)
print(self.pin_trig, pin_echo)
def run(self):
try:
# Waiting for sensor to settle
time.sleep(2)
while self.running():
# Trigger a scan
GPIO.output(self.pin_trig, GPIO.HIGH)
time.sleep(0.00001)
GPIO.output(self.pin_trig, GPIO.LOW)
# Read the echo
while self.running() and GPIO.input(self.pin_echo)==0:
pulse_start_time = time.time()
while self.running() and GPIO.input(self.pin_echo)==1:
pulse_end_time = time.time()
if self.running():
pulse_duration = pulse_end_time - pulse_start_time
distance = round(pulse_duration * 17150, 2)
self._handle_dist(distance)
finally:
self.clean()
def _handle_dist(self, dist):
logging.debug('Distance: {}cm'.format(dist))
if dist<3:
self.parent.goalDetected.emit(self.parent.side)
...@@ -63,8 +63,8 @@ class Player(QObject): ...@@ -63,8 +63,8 @@ class Player(QObject):
_placeholder_pic_path = ':ui/img/placeholder_head.jpg' _placeholder_pic_path = ':ui/img/placeholder_head.jpg'
def __init__(self, id, rfid, fname, lname, pic_path, stats):
def __init__(self, id, rfid, fname, lname, pic_path, stats=None): def __init__(self, id, rfid, fname, lname, pic_path, stats=None):
QObject.__init__(self)
self.id = id self.id = id
self.rfid = rfid self.rfid = rfid
self.fname = fname self.fname = fname
...@@ -94,7 +94,6 @@ class Player(QObject): ...@@ -94,7 +94,6 @@ class Player(QObject):
return player return player
def displayImg(self, container_widget):
@staticmethod @staticmethod
def _loadFromDB(rfid): def _loadFromDB(rfid):
db = Database.instance() db = Database.instance()
...@@ -132,6 +131,7 @@ class Player(QObject): ...@@ -132,6 +131,7 @@ class Player(QObject):
return Player._loadFromDB(rfid) return Player._loadFromDB(rfid)
def displayImg(self, container_widget):
self.pic_container = container_widget self.pic_container = container_widget
if self.pic_path.startswith('http'): if self.pic_path.startswith('http'):
......
...@@ -80,11 +80,6 @@ class MainWin(QtWidgets.QMainWindow): ...@@ -80,11 +80,6 @@ class MainWin(QtWidgets.QMainWindow):
for modIdx in modulesIdx: for modIdx in modulesIdx:
self.modules[modIdx].other(**msg) self.modules[modIdx].other(**msg)
@pyqtSlot(str)
def rfidHandler(self, rfid):
side = Side.Left if Settings['app.side']=='left' else Side.Right
self.dispatchMessage({'rfid': rfid, 'source': side})
def _loadSettings(self): def _loadSettings(self):
if Settings['ui.fullscreen']: if Settings['ui.fullscreen']:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment