rc-ir-tank/client.py

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")