159 lines
4.3 KiB
Python
159 lines
4.3 KiB
Python
|
# On Ubuntu gstreamer interface is missing on OpenCV
|
||
|
# On Fedora enable RPM fusion repo and install packages
|
||
|
# dnf install python3-opencv gstreamer-plugins-bad-free gstreamer-plugins-ugly gstreamer1-plugins-bad-freeworld gstreamer1-plugins-good gstreamer1-libav python3-evdev
|
||
|
|
||
|
from time import sleep
|
||
|
import sys
|
||
|
import socket
|
||
|
import cv2
|
||
|
import numpy as np
|
||
|
import time
|
||
|
from threading import Thread
|
||
|
|
||
|
_, hostname = sys.argv
|
||
|
|
||
|
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||
|
sock.settimeout(0)
|
||
|
sock.bind(("", 37021))
|
||
|
|
||
|
#WIDTH, HEIGHT = 1920, 1080
|
||
|
WIDTH, HEIGHT = 1280, 720
|
||
|
WIDTH, HEIGHT = 640, 480
|
||
|
#WIDTH, HEIGHT = 320, 240
|
||
|
|
||
|
CROSSHAIR_THICKNESS = 3
|
||
|
CROSSHAIR_SIZE = 50
|
||
|
|
||
|
|
||
|
|
||
|
from glob import glob
|
||
|
from evdev import InputDevice, categorize, ecodes
|
||
|
state = dict()
|
||
|
shoot = False
|
||
|
robot_shoot_timestamp = 0
|
||
|
|
||
|
|
||
|
class GamepadReader(Thread):
|
||
|
def run(self):
|
||
|
global shoot
|
||
|
global robot_shoot_timestamp
|
||
|
gamepad = InputDevice(glob("/dev/input/by-id/usb-Microsoft_Controller*event*")[0])
|
||
|
print("Opening:", gamepad)
|
||
|
|
||
|
for event in gamepad.read_loop():
|
||
|
if not event:
|
||
|
continue
|
||
|
if event.type == 3:
|
||
|
state["axis%d" % event.code] = event.value
|
||
|
elif event.type == 1:
|
||
|
state["button%d" % event.code] = event.value
|
||
|
elif event.type == 0:
|
||
|
pass # dno?
|
||
|
else:
|
||
|
print(event.type, event.value, event.code)
|
||
|
|
||
|
if state.get("button310", 0) or state.get("button311", 0):
|
||
|
shoot = True
|
||
|
|
||
|
|
||
|
|
||
|
t = GamepadReader(daemon=True)
|
||
|
|
||
|
t.start()
|
||
|
|
||
|
|
||
|
|
||
|
print("Resolving hostname:", hostname)
|
||
|
while True:
|
||
|
try:
|
||
|
sockaddr = socket.getaddrinfo(hostname, 37020)[0][-1]
|
||
|
except OSError:
|
||
|
sleep(0.5)
|
||
|
else:
|
||
|
break
|
||
|
|
||
|
|
||
|
print("Sending let's play packet to", sockaddr)
|
||
|
msg = "play:%d:%d" % (WIDTH, HEIGHT)
|
||
|
sock.sendto(msg.encode("ascii"), sockaddr)
|
||
|
|
||
|
|
||
|
pipeline = 'udpsrc port=5000 caps = "application/x-rtp, encoding-name=(string)H264" ! rtpjitterbuffer mode=3 ! rtph264depay ! decodebin ! videoconvert ! appsink'
|
||
|
|
||
|
print("gst-launch-1.0 -v", pipeline.replace("appsink", "autovideosink"))
|
||
|
sleep(5)
|
||
|
cap = cv2.VideoCapture(pipeline)
|
||
|
|
||
|
if not cap.isOpened():
|
||
|
print("Didn't receive video feed")
|
||
|
quit()
|
||
|
|
||
|
|
||
|
red = np.zeros((HEIGHT,WIDTH,3), np.uint8)
|
||
|
cv2.rectangle(red, (0, 0), (WIDTH, HEIGHT), (0, 0, 255), thickness=-1)
|
||
|
cv2.namedWindow("window", cv2.WND_PROP_FULLSCREEN)
|
||
|
cv2.setWindowProperty("window",cv2.WND_PROP_FULLSCREEN,cv2.WINDOW_FULLSCREEN)
|
||
|
|
||
|
blood = 1.0
|
||
|
shoot_box_width = 0
|
||
|
|
||
|
|
||
|
while True:
|
||
|
ret, frame = cap.read()
|
||
|
if ret == False:
|
||
|
break
|
||
|
|
||
|
# cv2.putText(frame, "yoyo",
|
||
|
# (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 255, 0), 3)
|
||
|
|
||
|
cv2.rectangle(frame, (WIDTH//2-CROSSHAIR_THICKNESS//2, HEIGHT//2-CROSSHAIR_SIZE//2), (WIDTH//2+CROSSHAIR_THICKNESS//2, HEIGHT//2+CROSSHAIR_SIZE//2), (0, 255, 0), thickness=-1)
|
||
|
cv2.rectangle(frame, (WIDTH//2-CROSSHAIR_SIZE//2, HEIGHT//2-CROSSHAIR_THICKNESS//2), (WIDTH//2+CROSSHAIR_SIZE//2, HEIGHT//2+CROSSHAIR_THICKNESS//2), (0, 255, 0), thickness=-1)
|
||
|
cv2.rectangle(frame, (10, HEIGHT-20), (int(WIDTH*0.30), HEIGHT-10),(0, 0, 0),thickness=-1)
|
||
|
|
||
|
if blood > 0:
|
||
|
blood -= 0.02
|
||
|
frame = cv2.addWeighted( red, blood, frame, (1-blood), 0.0);
|
||
|
|
||
|
|
||
|
|
||
|
msg = "speed:%d:%d" % (state.get("axis1", 0), state.get("axis3", 0))
|
||
|
sock.sendto(msg.encode("ascii"), sockaddr)
|
||
|
|
||
|
if shoot and time.time() - robot_shoot_timestamp >=1:
|
||
|
msg = "shoot"
|
||
|
robot_shoot_timestamp = time.time()
|
||
|
shoot_box_width = 0
|
||
|
#cv2.rectangle(frame, (WIDTH-10, HEIGHT-10), (40, 100),(0, 0, 0),thickness=-1)
|
||
|
sock.sendto(msg.encode("ascii"), sockaddr)
|
||
|
shoot = False
|
||
|
else:
|
||
|
shoot = False
|
||
|
|
||
|
if time.time() - robot_shoot_timestamp <=1:
|
||
|
shoot_box_width += int((WIDTH*0.30)/22)
|
||
|
else:
|
||
|
shoot_box_width = int(WIDTH*0.30)
|
||
|
cv2.rectangle(frame, (10, HEIGHT-20), (shoot_box_width, HEIGHT-10),(0, 255, 0),thickness=-1)
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
cv2.imshow("window",frame)
|
||
|
if cv2.waitKey(1) & 0xFF == ord('q'):
|
||
|
break
|
||
|
try:
|
||
|
#print("got:", sock.recv(100))
|
||
|
data = sock.recv(100)
|
||
|
cmd = data.decode("ascii")
|
||
|
#print(cmd)
|
||
|
if cmd == "hit":
|
||
|
robot_hit_timestamp = time.time()
|
||
|
blood = 2.2
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
except BlockingIOError:
|
||
|
pass
|
||
|
#print("nuffing")
|