diff --git a/GAME_METHODS/FORZA_METHODS.py b/GAME_METHODS/FORZA_METHODS.py index c89d0db..de887a9 100644 --- a/GAME_METHODS/FORZA_METHODS.py +++ b/GAME_METHODS/FORZA_METHODS.py @@ -1 +1,177 @@ -FROZA_DATA_FORMAT = ' 1.0 means loss of grip. + "TireSlipRatioFrontLeft": unpackedData[21], + "TireSlipRatioFrontRight": unpackedData[22], + "TireSlipRatioRearLeft": unpackedData[23], + "TireSlipRatioRearRight": unpackedData[24], + #// Wheels rotation speed radians/sec. + "WheelRotationSpeedFrontLeft": unpackedData[25], + "WheelRotationSpeedFrontRight": unpackedData[26], + "WheelRotationSpeedRearLeft": unpackedData[27], + "WheelRotationSpeedRearRight": unpackedData[28], + #// = 1 when wheel is on rumble strip, = 0 when off. + "WheelOnRumbleStripFrontLeft": unpackedData[29], + "WheelOnRumbleStripFrontRight": unpackedData[30], + "WheelOnRumbleStripRearLeft": unpackedData[31], + "WheelOnRumbleStripRearRight": unpackedData[32], + #// = from 0 to 1, where 1 is the deepest puddle + "WheelInPuddleDepthFrontLeft": unpackedData[33], + "WheelInPuddleDepthFrontRight": unpackedData[34], + "WheelInPuddleDepthRearLeft": unpackedData[35], + "WheelInPuddleDepthRearRight": unpackedData[35], + #// Non-dimensional surface rumble values passed to controller force feedback + "SurfaceRumbleFrontLeft": unpackedData[36], + "SurfaceRumbleFrontRight": unpackedData[37], + "SurfaceRumbleRearLeft": unpackedData[38], + "SurfaceRumbleRearRight": unpackedData[39], + #// Tire normalized slip angle, = 0 means 100% grip and |angle| > 1.0 means loss of grip. + "TireSlipAngleFrontLeft": unpackedData[40], + "TireSlipAngleFrontRight": unpackedData[41], + "TireSlipAngleRearLeft": unpackedData[42], + "TireSlipAngleRearRight": unpackedData[43], + #// Tire normalized combined slip, = 0 means 100% grip and |slip| > 1.0 means loss of grip. + "TireCombinedSlipFrontLeft": unpackedData[44], + "TireCombinedSlipFrontRight": unpackedData[45], + "TireCombinedSlipRearLeft": unpackedData[46], + "TireCombinedSlipRearRight": unpackedData[47], + #// Actual suspension travel in meters + "SuspensionTravelMetersFrontLeft": unpackedData[48], + "SuspensionTravelMetersFrontRight": unpackedData[49], + "SuspensionTravelMetersRearLeft": unpackedData[50], + "SuspensionTravelMetersRearRight": unpackedData[51], + #// Unique ID of the car make/model + "CarOrdinal": unpackedData[52], + #// Between 0 (D -- worst cars) and 7 (X class -- best cars) inclusive + "CarClass": unpackedData[53], + #// Between 100 (worst car) and 999 (best car) inclusive + "CarPerformanceIndex": unpackedData[54], + #// 0 = FWD, 1 = RWD, 2 = AWD + "DrivetrainType": unpackedData[55], + #// Number of cylinders in the engine + "NumCylinders": unpackedData[56], + "PositionX": unpackedData[57], + "PositionY": unpackedData[58], + "PositionZ": unpackedData[59], + "Speed": unpackedData[60], + "Power": unpackedData[61], + "Torque": unpackedData[62], + "TireTempFrontLeft": unpackedData[63], + "TireTempFrontRight": unpackedData[64], + "TireTempRearLeft": unpackedData[65], + "TireTempRearRight": unpackedData[66], + "Boost": unpackedData[67], + "Fuel": unpackedData[68], + "DistanceTraveled": unpackedData[69], + "BestLap": unpackedData[70], + "LastLap": unpackedData[71], + "CurrentLap": unpackedData[72], + "CurrentRaceTime": unpackedData[73], + "LapNumber": unpackedData[74], + "RacePosition": unpackedData[75], + "Accel": unpackedData[76], + "Brake": unpackedData[77], + "Clutch": unpackedData[78], + "HandBrake": unpackedData[79], + "Gear": unpackedData[80], + "Steer": unpackedData[81], + "NormalizedDrivingLine": unpackedData[82], + "NormalizedAIBrakeDifference": unpackedData[83], + "TireWearFrontLeft": unpackedData[84], + "TireWearFrontRight": unpackedData[85], + "TireWearRearLeft": unpackedData[86], + "TireWearRearRight": unpackedData[87], + #// ID for track + "TrackOrdinal": unpackedData[88] + } + return carData + +data_types = {} +with open('data_format.txt', 'r') as f: + lines = f.read().split('\n') + for line in lines: + data_types[line.split()[1]] = line.split()[0] + + +#assigning sizes in bytes to each variable type +jumps={ + 's32': 4, #Signed 32bit int, 4 bytes of size + 'u32': 4, #Unsigned 32bit int + 'f32': 4, #Floating point 32bit + 'u16': 2, #Unsigned 16bit int + 'u8': 1, #Unsigned 8bit int + 's8': 1, #Signed 8bit int + 'hzn': 12 #Unknown, 12 bytes of.. something +} + + + + +def get_data(data): + return_dict={} + + #additional var + passed_data = data + + for i in data_types: + d_type = data_types[i]#checks data type (s32, u32 etc.) + jump=jumps[d_type]#gets size of data + current = passed_data[:jump]#gets data + + decoded = 0 + #complicated decoding for each type of data + if d_type == 's32': + decoded = int.from_bytes(current, byteorder='little', signed = True) + elif d_type == 'u32': + decoded = int.from_bytes(current, byteorder='little', signed=False) + elif d_type == 'f32': + decoded = struct.unpack('f', current)[0] + elif d_type == 'u16': + decoded = struct.unpack('H', current)[0] + elif d_type == 'u8': + decoded = struct.unpack('B', current)[0] + elif d_type == 's8': + decoded = struct.unpack('b', current)[0] + + #adds decoded data to the dict + return_dict[i] = decoded + + + #removes already read bytes from the variable + passed_data = passed_data[jump:] + + + + #returns the dict + return return_dict \ No newline at end of file diff --git a/GAME_METHODS/__pycache__/BEAMNG_METHODS.cpython-311.pyc b/GAME_METHODS/__pycache__/BEAMNG_METHODS.cpython-311.pyc index 949e053..f9300a4 100644 Binary files a/GAME_METHODS/__pycache__/BEAMNG_METHODS.cpython-311.pyc and b/GAME_METHODS/__pycache__/BEAMNG_METHODS.cpython-311.pyc differ diff --git a/GAME_METHODS/__pycache__/FORZA_METHODS.cpython-311.pyc b/GAME_METHODS/__pycache__/FORZA_METHODS.cpython-311.pyc index af6d277..af4e124 100644 Binary files a/GAME_METHODS/__pycache__/FORZA_METHODS.cpython-311.pyc and b/GAME_METHODS/__pycache__/FORZA_METHODS.cpython-311.pyc differ diff --git a/OutGaugeInterpreter.py b/OutGaugeInterpreter.py index 89f83a3..c04835f 100644 --- a/OutGaugeInterpreter.py +++ b/OutGaugeInterpreter.py @@ -2,36 +2,47 @@ import socket import struct import serial import time +from enum import Enum from GAME_METHODS import * -##import BEAMNG_FILES as BEAM + COM_PORT = 'COM5' UDP_IP = "127.0.0.1" BEAMNG_UDP_PORT = 4444 FORZA_UDP_PORT= 4843 +class GameType(Enum): + NONE=0, + BEAMNG = 1, + FORZA = 2 + connectedArduino = False connectedWebSocket = False gameSelected = False portToConnect= 0 -dataFormat = "" +gameType= GameType.NONE +carData = 0 +#code runs from here<----------------------------------------------------------------------------------------------------------- + +#select game while gameSelected == False: gameNo = input("1:BEAMNG\n2:FORZA\n") if gameNo == "1": portToConnect = BEAMNG_UDP_PORT - dataFormat =BEAMNG_METHODS.BEAMNG_DATA_FORMAT gameSelected = True + gameType=GameType.BEAMNG print("BeamNG Selected") elif gameNo == "2": portToConnect = FORZA_UDP_PORT - dataFormat = FORZA_METHODS.FROZA_DATA_FORMAT - print("Forza Selected") + gameType=GameType.FORZA gameSelected=True + print("Forza Selected") + 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) @@ -49,12 +60,18 @@ while connectedArduino == False: print("please check connection to arduino and verify the correct COM port") time.sleep(1) -print("ready:\n") +print(struct.calcsize(FORZA_METHODS.FORZA_DATA_FORMAT)) +print("ready:\n") while True: data, addr = sock.recvfrom(1024) - unpackedData = struct.unpack(dataFormat,data) - carData = BEAMNG_METHODS.unpackData(unpackedData) - kmh=carData["speed"]*3.6 + if gameType == GameType.BEAMNG: + unpackedData = struct.unpack(BEAMNG_METHODS.BEAMNG_DATA_FORMAT,data) + carData = BEAMNG_METHODS.unpackData(unpackedData) + kmh=carData["speed"]*3.6 + elif gameType == GameType.FORZA: + # unpackedData = struct.unpack(FORZA_METHODS.FORZA_DATA_FORMAT,data) + carData = FORZA_METHODS.get_data(data) + kmh = carData["Speed"]*3.6 toPi.write(str(kmh).encode()+":".encode()) diff --git a/data_format.txt b/data_format.txt new file mode 100644 index 0000000..aaa8d71 --- /dev/null +++ b/data_format.txt @@ -0,0 +1,85 @@ +s32 IsRaceOn +u32 TimestampMS +f32 EngineMaxRpm +f32 EngineIdleRpm +f32 CurrentEngineRpm +f32 AccelerationX +f32 AccelerationY +f32 AccelerationZ +f32 VelocityX +f32 VelocityY +f32 VelocityZ +f32 AngularVelocityX +f32 AngularVelocityY +f32 AngularVelocityZ +f32 Yaw +f32 Pitch +f32 Roll +f32 NormalizedSuspensionTravelFrontLeft +f32 NormalizedSuspensionTravelFrontRight +f32 NormalizedSuspensionTravelRearLeft +f32 NormalizedSuspensionTravelRearRight +f32 TireSlipRatioFrontLeft +f32 TireSlipRatioFrontRight +f32 TireSlipRatioRearLeft +f32 TireSlipRatioRearRight +f32 WheelRotationSpeedFrontLeft +f32 WheelRotationSpeedFrontRight +f32 WheelRotationSpeedRearLeft +f32 WheelRotationSpeedRearRight +s32 WheelOnRumbleStripFrontLeft +s32 WheelOnRumbleStripFrontRight +s32 WheelOnRumbleStripRearLeft +s32 WheelOnRumbleStripRearRight +f32 WheelInPuddleDepthFrontLeft +f32 WheelInPuddleDepthFrontRight +f32 WheelInPuddleDepthRearLeft +f32 WheelInPuddleDepthRearRight +f32 SurfaceRumbleFrontLeft +f32 SurfaceRumbleFrontRight +f32 SurfaceRumbleRearLeft +f32 SurfaceRumbleRearRight +f32 TireSlipAngleFrontLeft +f32 TireSlipAngleFrontRight +f32 TireSlipAngleRearLeft +f32 TireSlipAngleRearRight +f32 TireCombinedSlipFrontLeft +f32 TireCombinedSlipFrontRight +f32 TireCombinedSlipRearLeft +f32 TireCombinedSlipRearRight +f32 SuspensionTravelMetersFrontLeft +f32 SuspensionTravelMetersFrontRight +f32 SuspensionTravelMetersRearLeft +f32 SuspensionTravelMetersRearRight +s32 CarOrdinal +s32 CarClass +s32 CarPerformanceIndex +s32 DrivetrainType +s32 NumCylinders +f32 PositionX +f32 PositionY +f32 PositionZ +f32 Speed +f32 Power +f32 Torque +f32 TireTempFrontLeft +f32 TireTempFrontRight +f32 TireTempRearLeft +f32 TireTempRearRight +f32 Boost +f32 Fuel +f32 DistanceTraveled +f32 BestLap +f32 LastLap +f32 CurrentLap +f32 CurrentRaceTime +u16 LapNumber +u8 RacePosition +u8 Accel +u8 Brake +u8 Clutch +u8 HandBrake +u8 Gear +s8 Steer +s8 NormalizedDrivingLine +s8 NormalizedAIBrakeDifference \ No newline at end of file