From 237708e155abefe7b0b395a635868254c7f76a63 Mon Sep 17 00:00:00 2001 From: Seth Samuel Date: Sun, 10 Nov 2024 22:28:14 +1300 Subject: [PATCH] added ability to read speed from forza --- GAME_METHODS/FORZA_METHODS.py | 178 +++++++++++++++++- .../BEAMNG_METHODS.cpython-311.pyc | Bin 3029 -> 3029 bytes .../__pycache__/FORZA_METHODS.cpython-311.pyc | Bin 291 -> 7806 bytes OutGaugeInterpreter.py | 37 +++- data_format.txt | 85 +++++++++ 5 files changed, 289 insertions(+), 11 deletions(-) create mode 100644 data_format.txt 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 949e053dac1ef5ad1f84a9c511ada2bb44524292..f9300a463d3761d7a633b52988087d634b66179a 100644 GIT binary patch delta 36 qcmcaAepQ@nIWI340}zx%Z{#}1$nEav>l*Lt8sg#aviULNCr$vk3ku!< delta 36 qcmcaAepQ@nIWI340}!yuZR9$~$nE6n=_y7@8VCr$vU2nr$q diff --git a/GAME_METHODS/__pycache__/FORZA_METHODS.cpython-311.pyc b/GAME_METHODS/__pycache__/FORZA_METHODS.cpython-311.pyc index af6d27738aa2c16277ef9cdb3c4121f98958392b..af4e12468b4693d83e896b63865e63d0f5dd9bf2 100644 GIT binary patch literal 7806 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