''' Created on Nov 10, 2012 @author: attero ''' import random, pygame, sys import subprocess import flask import threading import os import signal import json import traceback from pygame.locals import * from Cannon import HackWAWCannonController from Cannon import Gunpoint import pygame.camera app = flask.Flask(__name__) app.debug = True pygame.init() pygame.camera.init() CAMERA_X = 400 CAMERA_Y = 30 cannon = None def run_detection(): p = subprocess.Popen("/home/q3k/balloontracker/facedetect", stdin=subprocess.PIPE, stdout=subprocess.PIPE) p.stdin.write("\n") p.stdin.write("\n") p.stdin.write("\n") p.stdin.write("\n") p.stdin.flush() print("L: " + p.stdout.readline()) print("L: " + p.stdout.readline()) print("L: " + p.stdout.readline()) data = p.communicate()[0] lines = data.split("\n") print lines x, y = [int(i) for i in lines[-2].split(",")] global dot_pos dot_pos = (x, y) @app.route("/left/", methods=["POST"]) def move_left(amount): cannon.move_left(amount) cannon.send_data() return "OK" @app.route("/right/", methods=["POST"]) def move_right(amount): cannon.move_right(amount) cannon.send_data() return "OK" @app.route("/up/", methods=["POST"]) def move_up(amount): cannon.move_up(amount) cannon.send_data() return "OK" @app.route("/down/", methods=["POST"]) def move_down(amount): cannon.move_down(amount) cannon.send_data() return "OK" @app.route("/fire", methods=["POST"]) def fire(): cannon.fire() cannon.send_data() @app.route("/stop_fire/", methods=["POST"]) def stop_fire(): pass @app.route("/status") def status(): return json.dumps(cannon.get_data()) @app.route("/") def root(): return flask.render_template("status.html", data=cannon.get_data()) dot = None dot_pos = None #Camera stuff try: camera = pygame.camera.Camera("/dev/video0", (640, 480)) camera.start() except: camera = None def main(): #create the screen window = pygame.display.set_mode((1200, 800)) global dot dot = pygame.image.load("crosshair.png").convert_alpha() dot = pygame.transform.scale(dot, (25, 25)) GRAY = ( 182, 182, 182) VIOLET = (150, 100, 190) RED = (150, 0, 0) GREEN = (0, 150, 0) BLUE = (30, 30, 180) VERYLIGHT = (210, 210, 210) colors = [GRAY, VIOLET, RED, GREEN, BLUE, VERYLIGHT] global cannon cannon = HackWAWCannonController() screen = Screen(window, colors) screen.draw_surface(cannon) gunpoint = Gunpoint((5, 4), (200, 4), (5, 210)) keep_running = True while keep_running: screen.draw_surface(cannon) for event in pygame.event.get(): if event.type == pygame.QUIT: keep_running = False elif event.type == KEYUP : if event.key == K_SPACE: cannon.fire() elif event.key == K_RIGHT: cannon.move_right(20) elif event.key == K_LEFT: cannon.move_left(20) elif event.key == K_UP: cannon.move_up(20) elif event.key == K_DOWN: cannon.move_down(20) elif event.key == K_l: if cannon.laser: cannon.disable_laser() if "Laser enabled" in screen.communicates : screen.communicates.remove("Laser enabled") screen.communicates.append("Laser disabled") else: cannon.enable_laser() if "Laser disabled" in screen.communicates : screen.communicates.remove("Laser disabled") screen.communicates.append("Laser enabled") elif event.key == K_c: point1 = get_calibration_point(window, "Point1") point2 = get_calibration_point(window, "Point2") point3 = get_calibration_point(window, "Point3") print point1, point2, point3 gunpoint.calibrate(point1, point2, point3) print gunpoint.horizontal_angle, gunpoint.vertical_angle screen.communicates.append("Calibrated") elif event.key == K_d: global camera startcam = False if camera: camera.stop() run_detection() startcam = True camera = pygame.camera.Camera("/dev/video0", (640, 480)) if startcam: camera.start() cannon.send_data() elif event.type == MOUSEBUTTONUP: mousex, mousey = pygame.mouse.get_pos() print mousex, mousey x = (mousex - CAMERA_X)/640.0 y = (CAMERA_Y + 480 - mousey)/480.0 print x, y position = gunpoint.aim((x, y)) print position cannon.position = position screen.change_color() print "Pygame thread exited." os.kill(os.getpid(), signal.SIGINT) def get_key(): while 1: event = pygame.event.poll() if event.type == KEYDOWN: return event.key else: pass def display_box(screen, message, xx, yy): "Print a message in a box on xx, yy" font_object = pygame.font.Font(None,26) pygame.draw.rect(screen, (222,222,222),(xx, yy, 300,30), 0) pygame.draw.rect(screen, (20,20,20), (xx -2, yy-2, 302,34), 1) if len(message) != 0: screen.blit(font_object.render(message, 3, (0,0,0)), (xx + 6, yy + 6) ) pygame.display.flip() def ask(screen, question): "ask(screen, question) -> answer" pygame.font.init() current_string = [] display_box(screen, question + ": " + "".join(current_string), 20, 400) display_box(screen, "Write calibration points below", 20, 360) while 1: inkey = get_key() if inkey == K_BACKSPACE: current_string = current_string[0:-1] elif inkey == K_RETURN: break elif inkey == K_MINUS: current_string.append("_") elif inkey <= 127: current_string.append(chr(inkey)) display_box(screen, "Write calibration points below", 20, 360) display_box(screen, question + ": " + "".join(current_string), 20, 400) return "".join(current_string) def get_calibration_point(screen, message): point_string = ask(screen, message) while(not (is_valid_point(point_string)) ): point_string = ask(screen, "Again, " + message) return [float(x) for x in point_string.split(",")] def is_valid_point(string): point = string.split(',') if (len(point) != 2): return False if((not point[0].isdigit()) or (not point[1].isdigit())): return False if(float(point[0]) > 255 or float(point[1]) > 255 or float(point[0])< 0 or float(point[1]) <0 ): return False return True class Screen: def __init__(self, window, colors): self.communicates = [] self.communicates.append("Press space to fire!") self.communicates.append("Use arrows to adjust position") self.communicates.append("Press C for calibration") self.communicates.append("Press L to enable laser") self.window = window self.colors = colors self.color = random.choice(self.colors) def change_color(self): self.color = random.choice(self.colors) def draw_surface(self, cannon): self.window.fill(self.color) for i, text in enumerate(self.communicates): self.print_text(text, 20, 20 + i*20, (0, 0, 0), 30, self.window) self.print_text([str(x) for x in cannon.get_data()].__str__(), 20, 300, (0, 0, 0), 30, self.window) if camera: image = camera.get_image() self.window.blit(image, (CAMERA_X, CAMERA_Y)) global dot if dot_pos: self.window.blit(dot, (dot_pos[0] - 12 + CAMERA_X, dot_pos[1] - 12 + CAMERA_Y)) pygame.display.flip() def print_text(self, text,xx,yy,color,text_size, screen): font = pygame.font.SysFont(None,text_size) ren = font.render(text,1,color) screen.blit(ren, (xx,yy)) if __name__ == '__main__': def pygame_runner(): try: main() except Exception as e: traceback.print_exc() os.kill(os.getpid(), signal.SIGINT) t = threading.Thread(target=pygame_runner) def flask_runner(): try: app.run(use_reloader=False, host="0.0.0.0") except Exception as e: print "Flask thread raised exception %s" % str(e) os.kill(os.getpid(), signal.SIGINT) t2 = threading.Thread(target=flask_runner) print "Starting pygame..." t.start() print "Starting flask..." t2.start()