I am building a self-driving rc car. The car is controlled by a raspberry pi (client) that sends image data to my computer (server) and the computer processes the image frames and responds to the car with what to do (all using python sockets). This works perfectly well. I am now trying to add a key listener to python so I can manually control the car WHILE all of the socket interractions are happening. I would like to use multithreading to do so. Here is how I believe it should work:
import cv2
from pynput import keyboard
from Server import Server
###Keyboard Listener###
def keyPress(key): #send keypress to client
server.sendCommand((str(key)))
with keyboard.Listener(on_press=keyPress) as listener: #new listener thread
listener.join() #activate thread
###Server/ client interaction###
host, port = '10.78.1.195', 8000 # home
server = Server(host, port) #server object
server.connect() #connect
while server.isOpened(): #do while the server is open
frame = server.getStreamImage() #get an image from the client each frame
server.sendCommand("0") #send a command to the server (arbituary for now, but will be a neural network ouotput
cv2.imshow("t", frame) # show image
# cv2.imshow("tttttt", nnInput) # show image CONFIGURE PERSPECTIVE TRANSFORM AFTER CAMERA MOUNT
if cv2.waitKey(1) == ord('q'): #quit if q pressed
server.sendCommand('q') # tell client to close
server.close() # break if 'q' pressed
cv2.destroyAllWindows() #close opencv windows
If you would like any of the client or server code, I would be happy to show it. I didn't inlude it because it's working perfectly.
SO, in my mind, the while loop and the keyboard listener should operate in parallel, and I'm not sure why they are not. With this configuration, the keypresses are tracked, but the server/client interactions never begin. I have tried reformatting the code and I can't seem to get the operations to happen parallel.
If there is a simpler or less resource intensive way to do this, I am open to new ideas. This is just what makes the most sense to me. I really just want the code to be as clean as possible.
My python version is 3.7. I am running Ubuntu 19.10. pynput is version 1.4.5.
If I can provide any additional info, please ask. Thank you very much!
Instead of using the with
statement to initialise your listener try:
listener = keyboard.Listener(on_press=keyPress)
listener.start()
The with statement is blocking the main thread.
Using start
instead of with
/ join
you create a non-blocking thread allowing the main loop to start.