laserz_und_stuff/Lasers_und_stuff/main.py

308 lines
9.0 KiB
Python

'''
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/<int:amount>", methods=["POST"])
def move_left(amount):
cannon.move_left(amount)
cannon.send_data()
return "OK"
@app.route("/right/<int:amount>", methods=["POST"])
def move_right(amount):
cannon.move_right(amount)
cannon.send_data()
return "OK"
@app.route("/up/<int:amount>", methods=["POST"])
def move_up(amount):
cannon.move_up(amount)
cannon.send_data()
return "OK"
@app.route("/down/<int:amount>", 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()