192 lines
6.7 KiB
Python
192 lines
6.7 KiB
Python
#please use python 3.11
|
|
import socket
|
|
import struct
|
|
import tkinter.ttk
|
|
import serial
|
|
import time
|
|
import platform
|
|
import sys
|
|
from enum import Enum
|
|
import tkinter
|
|
from GAME_METHODS import *
|
|
import functools #used for passing variables into callbacks
|
|
|
|
##check if python 3.11 is running code and exit if not
|
|
|
|
if not(sys.version_info[0] == 3 and sys.version_info[1] == 11):
|
|
raise Exception("code must be run in python verion 3.11.\ninput struct for network needs to be changed per python version.")
|
|
|
|
|
|
|
|
##system init
|
|
runningOs = platform.system()
|
|
|
|
UDP_IP = "0.0.0.0"
|
|
BEAMNG_UDP_PORT = 4444
|
|
FORZA_UDP_PORT= 4843
|
|
SERIAL_PORT = ""
|
|
firstRun= True #used to do the headers for csv files
|
|
pushingToArduino = False
|
|
|
|
class GameType(Enum):
|
|
NONE=0
|
|
BEAMNG = "BEAMNG"
|
|
FORZA = "FORZA"
|
|
|
|
connectedArduino = False
|
|
connectedWebSocket = False
|
|
gameSelected = False
|
|
portToConnect= 0
|
|
gameType= GameType.NONE
|
|
carData = 0
|
|
csvOut = False
|
|
|
|
#Functions <-------------------------------------------------------------------------------------------
|
|
def csvWriteOut(firstRun,carData,csvFile):
|
|
if firstRun == True:
|
|
out=""
|
|
for im,nm in carData.items():
|
|
out = out + im + ","
|
|
csvFile.write(out + "\n")
|
|
outString=""
|
|
for itm,num in carData.items():
|
|
outString = outString + str(num) +","
|
|
csvFile.write(outString+"\n")
|
|
|
|
#code runs from here<-----------------------------------------------------------------------------------------------------------
|
|
|
|
if runningOs == 'Windows':
|
|
print("Windows detacted setting serial port to 'COM5'\n")
|
|
SERIAL_PORT= 'COM5'
|
|
elif runningOs == 'Linux':
|
|
print("Linux detected setting serial port to '/dev/ttyAMC0'\n")
|
|
SERIAL_PORT = '/dev/ttyACM0'
|
|
else:
|
|
print("OS detection failed setting serial port to 'COM5'\n")
|
|
SERIAL_PORT = 'COM5'
|
|
|
|
def startStopButtonFunc():
|
|
global pushingToArduino
|
|
if pushingToArduino == True:
|
|
startStopButton.config(text="start")
|
|
pushingToArduino = False
|
|
elif pushingToArduino == False:
|
|
startStopButton.config(text="stop")
|
|
pushingToArduino = True
|
|
|
|
##GUI init
|
|
rootFrameGui= tkinter.Tk()
|
|
rootFrameGui.title("Car speed to arduino")
|
|
##rootFrameGui.geometry("400x200")
|
|
|
|
bottomBarFrameGui = tkinter.ttk.Frame(rootFrameGui,padding=0,relief="groove",borderwidth=2,)
|
|
bottomBarFrameGui.pack(anchor="se",side="bottom",fill="x")
|
|
firstFrameGui=tkinter.ttk.Frame(rootFrameGui,padding=2,relief="groove",borderwidth=2)
|
|
firstFrameGui.pack(anchor="ne",side="left",expand=True)
|
|
secondFrameGui=tkinter.ttk.Frame(rootFrameGui,padding=2,relief="groove",borderwidth=2)
|
|
secondFrameGui.pack(anchor="nw",side="right",expand=True)
|
|
serialFrameGui = tkinter.ttk.Frame(firstFrameGui,padding=5,relief="groove",borderwidth=2)
|
|
serialFrameGui.pack(anchor="nw")
|
|
serialLableText =tkinter.StringVar()
|
|
serialLableText.set("Serial Port:")
|
|
serialLable = tkinter.Label(serialFrameGui,textvariable=serialLableText)
|
|
serialLable.pack(side="top")
|
|
serialEntry=tkinter.Entry(serialFrameGui)
|
|
serialEntry.insert(0,SERIAL_PORT)
|
|
serialEntry.pack(side="left")
|
|
tkGametype = tkinter.StringVar()
|
|
tkGametype.set(GameType.BEAMNG.value)
|
|
gameSelectFrame= tkinter.ttk.Frame(secondFrameGui,padding=5,relief="groove",borderwidth=2)
|
|
gameSelectFrame.pack(anchor="se")
|
|
gameSelectText= tkinter.StringVar()
|
|
gameSelectText.set("Select Game:")
|
|
gameSelectLable = tkinter.Label(gameSelectFrame,textvariable=gameSelectText)
|
|
gameSelectLable.pack(side="top")
|
|
tkinter.Label(gameSelectFrame,textvariable=gameSelectText)
|
|
gameSelectLOptions= [GameType.BEAMNG,GameType.FORZA]
|
|
##gameSelectRadioButtons
|
|
##space after text is so the buttons are the same size
|
|
tkinter.Radiobutton(gameSelectFrame,text="BeamNG ",variable=tkGametype,value=GameType.BEAMNG.value).pack(anchor="w")
|
|
tkinter.Radiobutton(gameSelectFrame,text="Forza ",variable=tkGametype,value=GameType.FORZA.value).pack(anchor="w")
|
|
loggingFrameGui= tkinter.ttk.Frame(firstFrameGui,padding=5,relief="groove",borderwidth=2)
|
|
loggingFrameGui.pack(anchor="nw")
|
|
tkLoggingEnabled=tkinter.BooleanVar()
|
|
tkLoggingEnabled.set(False)
|
|
tkinter.Checkbutton(loggingFrameGui,text="Enable Logging",variable=tkLoggingEnabled,onvalue=True,offvalue=False).pack(side="top")
|
|
loggingLocationText = tkinter.StringVar(value= "./")
|
|
loggingLocationEntry = tkinter.Entry(loggingFrameGui)
|
|
loggingLocationEntry.insert(0,loggingLocationText.get())
|
|
loggingLocationEntry.pack(side="bottom")
|
|
startStopButton= tkinter.Button(bottomBarFrameGui,text= "start",command= startStopButtonFunc)
|
|
startStopButton.pack(side="right",fill="x")
|
|
|
|
rootFrameGui.mainloop()
|
|
exit() #### exit for testing
|
|
#select game
|
|
while gameSelected == False:
|
|
gameNo = input("1:BEAMNG\n2:FORZA\n\n7:Toggle CSV out ("+str(csvOut)+")\n9:SET SERIAL PORT ("+SERIAL_PORT+")\n")
|
|
if gameNo == "1":
|
|
portToConnect = BEAMNG_UDP_PORT
|
|
gameSelected = True
|
|
gameType=GameType.BEAMNG
|
|
print("BeamNG Selected")
|
|
elif gameNo == "2":
|
|
portToConnect = FORZA_UDP_PORT
|
|
gameType=GameType.FORZA
|
|
gameSelected=True
|
|
print("Forza Selected")
|
|
elif gameNo == "7":
|
|
if csvOut == True:
|
|
csvOut=False
|
|
elif csvOut ==False:
|
|
csvOut =True
|
|
elif gameNo == "9":
|
|
SERIAL_PORT = input("set serial port: ")
|
|
else:
|
|
print("please select a number from the list")
|
|
|
|
#check everything is connected
|
|
while connectedWebSocket == False:
|
|
try:
|
|
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
|
|
sock.bind((UDP_IP,portToConnect))
|
|
connectedWebSocket = True
|
|
except:
|
|
print("please check you are able to open the socket on this system\ntired to open port: "+portToConnect)
|
|
exit()
|
|
|
|
while connectedArduino == False:
|
|
try:
|
|
toPi=serial.Serial(SERIAL_PORT,115200,timeout=2) #connect to arduino
|
|
connectedArduino = True
|
|
except:
|
|
print("please check connection to arduino and verify the correct serial port")
|
|
time.sleep(1)
|
|
|
|
if csvOut == True:
|
|
csvFile = open(gameType.value+"_"+str(int(time.time()))+'.csv',"a")
|
|
|
|
|
|
|
|
print("ready:\n")
|
|
while True:
|
|
data, addr = sock.recvfrom(1024)
|
|
if gameType == GameType.BEAMNG:
|
|
unpackedData = struct.unpack(BEAMNG_METHODS.BEAMNG_DATA_FORMAT,data)
|
|
carData = BEAMNG_METHODS.unpackData(unpackedData)
|
|
kmh=carData["speed"]*3.6
|
|
if csvOut == True:
|
|
csvWriteOut(firstRun,carData,csvFile)
|
|
firstRun=False
|
|
elif gameType == GameType.FORZA:
|
|
unpackedData = struct.unpack(FORZA_METHODS.FORZA_DATA_FORMAT,data)
|
|
carData = FORZA_METHODS.unpackData(unpackedData)
|
|
kmh = carData["Speed"]*3.6
|
|
if csvOut == True:
|
|
csvWriteOut(firstRun,carData,csvFile)
|
|
firstRun=False
|
|
try:
|
|
toPi.write(str(kmh).encode()+":".encode())
|
|
except:
|
|
print("arduino disconnected please check connection\n")
|
|
|