class TimeStatsData(Packet): STRUCTURE = binio.new([ (1, binio.types.t_uint, "ParticipantsChangedTimestamp") ]) PARTICIPANTS_STATS_INFO = binio.new([ (1, binio.types.t_float, "sFastestLapTime"), (1, binio.types.t_float32, "sLastLapTime"), (1, binio.types.t_float32, "sLastSectorTime"), (1, binio.types.t_float32, "sFastestSector1Time"), (1, binio.types.t_float32, "sFastestSector2Time"), (1, binio.types.t_float32, "sFastestSector3Time") ]) def __init__(self, buildVersion, sequenceNumber, packetType, buf): super(TimeStatsData, self).__init__(buildVersion, sequenceNumber, packetType, buf) self._data["participants_time_stats"] = [] for _ in range(0, 32): p = TimeStatsData.PARTICIPANTS_STATS_INFO.read_dict(buf) self._data["participants_time_stats"].append(p) def __getitem__(self, key): return self._data[key]
class ParticipantsData(Packet): STRUCTURE = binio.new([ (1, binio.types.t_uint, "ParticipantsChangedTimestamp") ]) NAME_STRUCTURE = binio.new([(64, binio.types.t_char, "name")]) def __init__(self, buildVersion, sequenceNumber, packetType, buf): super(ParticipantsData, self).__init__(buildVersion, sequenceNumber, packetType, buf) self._data["participants"] = [] for _ in range(0, 16): p = ParticipantsData.NAME_STRUCTURE.read_dict(buf) p["name"] = self._convertString(p["name"]) self._data["participants"].append(p) def __getitem__(self, key): return self._data[key]
class ParticipantInfoStringsAdditionalPacket(Packet): STRUCTURE = binio.new([(1, binio.types.t_u8, "offset")]) NAME_STRUCTURE = binio.new([(64, binio.types.t_byte, "name")]) def __init__(self, buildVersion, sequenceNumber, packetType, buf): super(ParticipantInfoStringsAdditionalPacket, self).__init__(buildVersion, sequenceNumber, packetType, buf) self._data["participants"] = [] for _ in range(0, 16): p = ParticipantInfoStringsAdditionalPacket.NAME_STRUCTURE.read_dict( buf) p["name"] = self._convertString(p["name"]) self._data["participants"].append(p) def __getitem__(self, key): return self._data[key]
class TimingsData(Packet): STRUCTURE = binio.new([ (1, binio.types.t_u8, "NumParticipants"), (1, binio.types.t_uint, "ParticipantsChangedTimestamp"), (1, binio.types.t_float32, "sEventTimeRemaining"), (1, binio.types.t_float32, "sSplitTimeAhead"), (1, binio.types.t_float32, "sSplitTimeBehind"), (1, binio.types.t_float32, "sSplitTime") ]) PARTICIPANT_INFO_STRUCTURE = binio.new([ (1, binio.types.t_int16, "worldPositionX"), (1, binio.types.t_int16, "worldPositionY"), (1, binio.types.t_int16, "worldPositionZ"), (1, binio.types.t_int16, "orientationX"), (1, binio.types.t_int16, "orientationY"), (1, binio.types.t_int16, "orientationZ"), (1, binio.types.t_u16, "currentLapDistance"), (1, binio.types.t_u8, "racePosition"), (1, binio.types.t_u8, "sector"), (1, binio.types.t_u8, "HighestFlag"), (1, binio.types.t_u8, "PitModeSchedule"), (1, binio.types.t_u8, "CarIndex"), (1, binio.types.t_u8, "RaceState"), (1, binio.types.t_u8, "currentLap"), (1, binio.types.t_u8, "lapsCompleted"), (1, binio.types.t_float32, "CurrentSectorTime"), ]) def __init__(self, buildVersion, sequenceNumber, packetType, buf): super(TimingsData, self).__init__(buildVersion, sequenceNumber, packetType, buf) self._data["participant_timings"] = [] for _ in range(0, 32): p = TimingsData.PARTICIPANT_INFO_STRUCTURE.read_dict(buf) self._data["participant_timings"].append(p) def __getitem__(self, key): return self._data[key]
class ParticipantInfoStringsPacket(Packet): STRUCTURE = binio.new([ (64, binio.types.t_byte, "carName"), (64, binio.types.t_byte, "carClassName"), (64, binio.types.t_byte, "trackLocation"), (64, binio.types.t_byte, "trackVariation"), ]) NAME_STRUCTURE = binio.new([(64, binio.types.t_byte, "name")]) FASTEST_LAP_TIME_STRUCTURE = binio.new([(1, binio.types.t_float32, "fastestLapTime")]) def __init__(self, buildVersion, sequenceNumber, packetType, buf): super(ParticipantInfoStringsPacket, self).__init__(buildVersion, sequenceNumber, packetType, buf) self._data["carName"] = self._convertString(self._data["carName"]) self._data["carClassName"] = self._convertString( self._data["carClassName"]) self._data["trackLocation"] = self._convertString( self._data["trackLocation"]) self._data["trackVariation"] = self._convertString( self._data["trackVariation"]) self._data["participants"] = [] for _ in range(0, 16): p = ParticipantInfoStringsPacket.NAME_STRUCTURE.read_dict(buf) p["name"] = self._convertString(p["name"]) self._data["participants"].append(p) for _ in range(0, 16): p = ParticipantInfoStringsPacket.FASTEST_LAP_TIME_STRUCTURE.read_dict( buf) self._data["participants"][_]["fastestLapTime"] = p[ "fastestLapTime"] def __getitem__(self, key): return self._data[key]
class VehicleClassNamesData(Packet): VEHICLE_CLASS_INFO = binio.new([(1, binio.types.t_uint, "Index"), (20, binio.types.t_char, "Name")]) def __init__(self, buildVersion, sequenceNumber, packetType, buf): super(VehicleClassNamesData, self).__init__(buildVersion, sequenceNumber, packetType, buf) self._data["vehicle_classes"] = [] for _ in range(0, 60): p = VehicleClassNamesData.VEHICLE_CLASS_INFO.read_dict(buf) self._data["vehicle_classes"].append(p)
def __init__(self): self.regionFile = binio.new(""" ((1, t_byte, 'offset0'), (1, t_byte, 'offset1'), (1, t_byte, 'offset2'), (1, t_byte, 'sector_count')) * 1024, (4, t_int32, 'timestamp') * 1024, (4, t_int32, 'length'), (1, t_byte, 'compression_type'), (length-1, t_byte, 'compressed_data') """)
class ParticipantsVehicleNamesData(Packet): VEHICLE_INFO = binio.new([(1, binio.types.t_u16, "Index"), (1, binio.types.t_uint, "Class"), (64, binio.types.t_char, "Name")]) def __init__(self, buildVersion, sequenceNumber, packetType, buf): super(ParticipantsVehicleNamesData, self).__init__(buildVersion, sequenceNumber, packetType, buf) self._data["vehicles"] = [] for _ in range(0, 16): p = ParticipantsVehicleNamesData.VEHICLE_INFO.read_dict(buf) self._data["vehicles"].append(p)
class GameStateData(Packet): STRUCTURE = binio.new([ (1, binio.types.t_u16, "BuildVersionNumber"), (1, binio.types.t_char, "GameState"), (1, binio.types.t_int8, "ambientTemperature"), (1, binio.types.t_int8, "trackTemperature"), (1, binio.types.t_u8, "rainDensity"), (1, binio.types.t_u8, "snowDensity"), (1, binio.types.t_int8, "windSpeed"), (1, binio.types.t_int8, "windDirectionX"), (1, binio.types.t_int8, "windDirectionY"), ]) def __getitem__(self, key): return self._data[key]
class Packet(object): HEADER = binio.new([ (1,binio.types.t_uint, 'mPacketNumber'), (1,binio.types.t_uint, 'mCategoryPacketNumber'), (1,binio.types.t_u8, 'mPartialPacketIndex'), (1,binio.types.t_u8, 'mPartialPacketNumber'), (1,binio.types.t_u8, 'mPacketType'), (1, binio.types.t_u8, 'mPacketVersion'), ]) def __init__(self, buildVersion, sequenceNumber, packetType, buf): self.buildVersion = buildVersion self.sequenceNumber = sequenceNumber self.packetType = packetType self._data = {} #packetType=1 breaks the code for some reason if hasattr(self.__class__, "STRUCTURE"): try: self._data = self.__class__.STRUCTURE.read_dict(buf) except UnicodeDecodeError: print("Could not decode packet: " + str(self.sequenceNumber) + ": " + str(PACKET_TYPES[self.packetType])) except binio.EndOfFileError: print("Error occured in packet " + str(self.sequenceNumber) + ": " + str(PACKET_TYPES[self.packetType])) def _convertString(self, stringAsBytes): # Convert to utf-8 and strip junk from strings after the null character. try: # Python 2 convertedValue = unicode(stringAsBytes, encoding='utf-8', errors='ignore') except NameError: # Python 3 convertedValue = str(stringAsBytes, encoding='utf-8', errors='surrogateescape') return convertedValue.rstrip('\x00') @staticmethod def readFrom(buf): header = Packet.HEADER.read_dict(buf) buildVersion = header["mPacketNumber"] sequenceNumber = header["mCategoryPacketNumber"] packetType = header["mPacketType"] pClass = PACKET_TYPES.get(packetType, Packet) return pClass(buildVersion, sequenceNumber, packetType, buf)
class Packet(object): HEADER = binio.new(PACKET_HEADER) def __init__(self, buildVersion, sequenceNumber, packetType, buf): self.buildVersion = buildVersion self.sequenceNumber = sequenceNumber self.packetType = packetType self.data = {} if hasattr(self.__class__, "STRUCTURE"): self.data = self.__class__.STRUCTURE.read_dict(buf) @staticmethod def readFrom(buf): header = Packet.HEADER.read_dict(buf) buildVersion = header['buildVersion'] sequenceNumber = (header['seq_packet'] & 0xFC) >> 2 packetType = header['seq_packet'] & 0x3 pClass = PACKET_TYPES.get(packetType, Packet) return pClass(buildVersion, sequenceNumber, packetType, buf)
class Packet(object): HEADER = binio.new([ (1, binio.types.t_u16, "buildVersion"), (1, binio.types.t_u8, "seq_packet"), ]) def __init__(self, buildVersion, sequenceNumber, packetType, buf): self.buildVersion = buildVersion self.sequenceNumber = sequenceNumber self.packetType = packetType if hasattr(self.__class__, "STRUCTURE"): self._data = self.__class__.STRUCTURE.read_dict(buf) else: self._data = {} def _convertString(self, stringAsBytes): # Convert to utf-8 and strip junk from strings after the null character. try: # Python 2 convertedValue = unicode(stringAsBytes, encoding='utf-8', errors='ignore') except NameError: # Python 3 convertedValue = str(stringAsBytes, encoding='utf-8', errors='surrogateescape') return convertedValue.rstrip('\x00') @staticmethod def readFrom(buf): header = Packet.HEADER.read_dict(buf) buildVersion = header["buildVersion"] sequenceNumber = (header["seq_packet"] & 0xFC) >> 2 packetType = header["seq_packet"] & 0x3 pClass = PACKET_TYPES.get(packetType, Packet) return pClass(buildVersion, sequenceNumber, packetType, buf)
class RaceData(Packet): STRUCTURE = binio.new([ (1,binio.types.t_float32,"sWorldFastestLapTime"), (1,binio.types.t_float32,"sPersonalFastestLapTime"), (1,binio.types.t_float32,"sPersonalFastestSector1Time"), (1,binio.types.t_float32,"sPersonalFastestSector2Time"), (1,binio.types.t_float32,"sPersonalFastestSector3Time"), (1,binio.types.t_float32,"sWorldFastestSector1Time"), (1,binio.types.t_float32,"sWorldFastestSector2Time"), (1,binio.types.t_float32,"sWorldFastestSector3Time"), (1,binio.types.t_float32,"sTrackLength"), (64,binio.types.t_string_utf8,"sTrackLocation"), (64,binio.types.t_string_utf8,"sTrackVariation"), (64,binio.types.t_string_utf8,"sTranslatedTrackLocation"), (64,binio.types.t_string_utf8,"sTranslatedTrackVariation"), (1,binio.types.t_u8,"sLapsTimeInEvent"), (1,binio.types.t_int8,"sEnforcedPitStopLap") ]) def __getitem__(self, key): return self._data[key]
def read_d_data(sheader, ch_list, samp_start, samp_end): """ Function to read the data from .d file Parameters: ---------- sheader - standard header (dictionary)\n ch_list - list of channel idxs (list)\n samp_start - start sample (int)\n samp_end - end sample (int)\n Returns: -------- data - data from .d file (list), corresponding to ch_list\n """ ### Open the .d file f = open(sheader['file_name'], "rb") ### Retype the start and end samp_start = int(samp_start) samp_end = int(samp_end) ### Just a precaution if samp_end >= sheader['nsamp']: print("\n End sample " + str(samp_end) + " equal or bigger than n samples of file (" + str(sheader['nsamp']) + "), setting to the end of the file \n") samp_end = sheader['nsamp'] - 1 ### Get the precision - we have function for this!!! prec, nb = get_prec(sheader) ### Get the first sample ds1 = sheader['data_org'] + (samp_start - 1) * nb * sheader['nchan'] n_samp = samp_end - samp_start f.seek(ds1) ### Read the data dat_type = binio.new( str(n_samp * sheader['nchan']) + " : " + prec + " : data") try: f.seek(ds1) dd = dat_type.read_struct(f) except: print('Error reading data') #print '\n '+str(samp_end)+' in '+str(sheader['nsamp'])+' \n' return ### Now get the desired channel # data = np.zeros([len(ch_list),n_samp],dtype=prec) # for i,x in enumerate(ch_list): # data[i] = np.array(dd.data[x::sheader['nchan']]) if len(ch_list) == 1: return np.array(dd.data).reshape(n_samp, sheader['nchan'])[:, ch_list[0]] else: return np.array(dd.data).reshape(n_samp, sheader['nchan'])[:, ch_list]
def read_d_header(file_name, read_tags=False): """ Function to read .d file standard and extended header Parameters: ---------- file_name - name of the file (string)\n read_tags - whether the tags should be read(default=False)\n Returns: ---------- sheader - standard header (dictionary)\n xheader - extended header (dictionary)\n """ # Open the .d file f = open(file_name, "rb") # Reading standard header sheader_struct = binio.new("# Standard header struct\n" "15 : string : sign\n" "1 : string : ftype\n" "1 : uint8 : nchan\n" "1 : uint8 : naux\n" "1 : uint16 : fsamp\n" "1 : uint32 : nsamp\n" "1 : uint8 : d_val # This is to be done\n" "1 : uint8 : unit\n" "1 : uint16 : zero\n" "1 : uint16 : data_org\n" "1 : int16 : data_xhdr_org\n") sheader = sheader_struct.read_dict(f) sheader['file_name'] = file_name # Create a dictionary in d_val field - to be done dval_dict = {} dval_dict['value'] = sheader['d_val'] dval_dict['data_invalid'] = int(np.floor(sheader['d_val'] / 128) % 2) dval_dict['data_packed'] = int(np.floor(sheader['d_val'] / 64) % 2) dval_dict['block_structure'] = int(np.floor(sheader['d_val'] / 32) % 2) dval_dict['polarity'] = int(np.floor(sheader['d_val'] / 16) % 2) dval_dict['data_calib'] = int(np.floor(sheader['d_val'] / 8) % 2) dval_dict['data_modified'] = int(np.floor(sheader['d_val'] / 4) % 2) dval_dict['data_cell_size'] = int(sheader['d_val'] % 4) sheader['d_val'] = dval_dict # Fix the data_org_fields sheader['data_org'] = 16 * sheader['data_org'] sheader['data_xhdr_org'] = 16 * sheader['data_xhdr_org'] ### Reading extended header xheader = {} # We need to define a dictionary for xhdr (we don't have switch-case) xhdr_dict = { 16725: [" : uint8 : authentication_key\n", 0], 22082: [" : uint8 : block_var_list\n", 0], 16707: [" : uint8 : channel_atrib\n", 0], 18755: [" : uint8 : calib_info\n", 0], 20035: [" : uint8 : channel_names\n", 0], #Finish here 17988: [" : uint8 : dispose_flags\n", 0], 18756: [" : char : data_info\n", 0], 19526: [" : char : file_links\n", 0], 21318: [" : int16 : freq\n", 2], # Finish here 17481: [" : uint32: patient_id\n", 1], # Finish here 19024: [" : char : project_name\n", 0], 16978: [" : uint8 : rblock\n", 0], 18003: [" : char : source_file\n", 0], 17748: [" : char : text_record\n", 0], 18772: [" : uint32: time_info\n", 1], # UTC from 1.1.1970 21588: [" : uint16: tag_tableen\n", 2, " : uint32: tag_tableoff\n", 2], 22612: [" : char : text_extrec\n", 0], 0: 0 } if sheader['data_xhdr_org'] != 0: f.seek(sheader['data_xhdr_org']) cont = 1 while cont: field_struct = binio.new("1 : uint16 : mnemo\n" "1 : uint16 : field_len\n") field = field_struct.read_dict(f) #xhdr dictionary check if field['mnemo'] in xhdr_dict: if field['mnemo'] == 0: cont = 0 sheader['datapos'] = f.tell() elif field['mnemo'] == 21588: io_txt = str(xhdr_dict[field['mnemo']][1]) + xhdr_dict[ field['mnemo']][0] + str(xhdr_dict[ field['mnemo']][3]) + xhdr_dict[field['mnemo']][2] field_cont = binio.new(io_txt) xheader.update(field_cont.read_dict(f)) elif xhdr_dict[field['mnemo']][1] == 0: io_txt = str( field['field_len']) + xhdr_dict[field['mnemo']][0] field_cont = binio.new(io_txt) xheader.update(field_cont.read_dict(f)) else: io_txt = str(xhdr_dict[field['mnemo']][1]) + xhdr_dict[ field['mnemo']][0] field_cont = binio.new(io_txt) xheader.update(field_cont.read_dict(f)) else: f.seek(field['field_len'], 1) #Now fix stuff if 'channel_names' in xheader: char_lst = [chr(x) for x in xheader['channel_names']] channels = [ ''.join(char_lst[x:x + 4]) for x in range(0, len(char_lst), 4) ] channels = [x.replace('\x00', '') for x in channels] xheader['channel_names'] = channels if 'tag_tableen' in xheader: xheader['tag_table'] = xheader['tag_tableen'] + xheader['tag_tableoff'] xheader.pop('tag_tableen') xheader.pop('tag_tableoff') ### Read tags if 'tag_table' in xheader and read_tags: xheader['tags'] = {} xheader['tags']['tag_pos'] = [] xheader['tags']['tag_class'] = [] xheader['tags']['tag_selected'] = [] xheader['tags']['classes'] = [] #Fix datasets bug in D-file with defoff and listoff pr, nb = get_prec(sheader) while xheader['tag_table'][2] < ( sheader['nchan'] * sheader['nsamp'] * nb + sheader['data_org'] ) and xheader['tag_table'][2] > sheader['datapos']: xheader['tag_table'][2] += 16**8 xheader['tag_table'][3] += 16**8 #Read tag list f.seek(xheader['tag_table'][3]) tag_list_struct = binio.new( str(int(4 * np.floor(float(xheader['tag_table'][1]) / 4.0))) + " : uint8 : tlist") tag_list = tag_list_struct.read_dict(f) tag_list = tag_list['tlist'] tag_list = [tag_list[x:x + 4] for x in range(0, len(tag_list), 4)] for x in range(len(tag_list)): tag_list[x][2] = tag_list[x][2] % 128 tag_pos = [] for x in tag_list: tag_pos.append((x[0] * 1) + (x[1] * 256) + (x[2] * 65536)) xheader['tags']['tag_pos'] = tag_pos xheader['tags']['tag_class'] = [x[3] % 128 for x in tag_list] xheader['tags']['tag_selected'] = [ np.floor(float(x[3]) / 128.0) for x in tag_list ] #Fix the long datasets bug in D-file (positions > 2 ** 23-1) if xheader['tags']['tag_pos'] != []: cont1 = 1 while cont1: wh = [ list(np.diff(xheader['tags']['tag_pos'])).index(x) for x in list(np.diff(xheader['tags']['tag_pos'])) if x < 0 ] if wh == []: cont1 = 0 else: xheader['tags']['tag_pos'][wh[0] + 1:] = [ x + (2**23) for x in xheader['tags']['tag_pos'][wh[0] + 1:] ] #Read the tag table currpos = xheader['tag_table'][2] cont1 = 1 while cont1: f.seek(currpos) tag_read_dic = binio.new("2 : char : abrv\n" "1 : uint16 : n\n" "1 : uint16 : txtlen\n" "1 : uint16 : txtoff\n") curr_tag = tag_read_dic.read_dict(f) currpos += 8 if np.floor(curr_tag['n'] / 32768): cont1 = 0 f.seek(curr_tag['txtoff'] + xheader['tag_table'][2]) xheader['tags']['classes'].append([ curr_tag['abrv'], curr_tag['n'] % 32768, str(f.read(curr_tag['txtlen'])) ]) return sheader, xheader
class TelemetryPacket(Packet): STRUCTURE = binio.new([ (1, binio.types.t_u8, "gameSessionState"), (1, binio.types.t_int8, "viewedParticipantIndex"), (1, binio.types.t_int8, "numParticipants"), # Unfiltered input (1, binio.types.t_u8, "unfilteredThrottle"), (1, binio.types.t_u8, "unfilteredBrake"), (1, binio.types.t_int8, "unfilteredSteering"), (1, binio.types.t_u8, "unfilteredClutch"), # ? (1, binio.types.t_u8, "raceStateFlags"), (1, binio.types.t_u8, "lapsInEvent"), # Timing info (1, binio.types.t_float32, "bestLapTime"), (1, binio.types.t_float32, "lastLapTime"), (1, binio.types.t_float32, "currentTime"), (1, binio.types.t_float32, "splitTimeAhead"), (1, binio.types.t_float32, "splitTimeBehind"), (1, binio.types.t_float32, "splitTime"), (1, binio.types.t_float32, "eventTimeRemaining"), (1, binio.types.t_float32, "personalFastestLapTime"), (1, binio.types.t_float32, "worldFastestLapTime"), (1, binio.types.t_float32, "currentSector1Time"), (1, binio.types.t_float32, "currentSector2Time"), (1, binio.types.t_float32, "currentSector3Time"), (1, binio.types.t_float32, "fastestSector1Time"), (1, binio.types.t_float32, "fastestSector2Time"), (1, binio.types.t_float32, "fastestSector3Time"), (1, binio.types.t_float32, "personalFastestSector1Time"), (1, binio.types.t_float32, "personalFastestSector2Time"), (1, binio.types.t_float32, "personalFastestSector3Time"), (1, binio.types.t_float32, "worldFastestSector1Time"), (1, binio.types.t_float32, "worldFastestSector2Time"), (1, binio.types.t_float32, "worldFastestSector3Time"), # Joypad state? (1, binio.types.t_u16, "joyPad"), # Flags (1, binio.types.t_u8, "highestFlag"), # Pit schedule (1, binio.types.t_u8, "pitModeSchedule"), # Car state (1, binio.types.t_int16, "oilTempCelsius"), (1, binio.types.t_u16, "oilPressureKPa"), (1, binio.types.t_int16, "waterTempCelsius"), (1, binio.types.t_u16, "waterPressureKPa"), (1, binio.types.t_u16, "fuelPressureKPa"), (1, binio.types.t_u8, "carFlags"), (1, binio.types.t_u8, "fuelCapacity"), (1, binio.types.t_u8, "brake"), (1, binio.types.t_u8, "throttle"), (1, binio.types.t_u8, "clutch"), (1, binio.types.t_int8, "steering"), (1, binio.types.t_float32, "fuelLevel"), (1, binio.types.t_float32, "speed"), (1, binio.types.t_u16, "rpm"), (1, binio.types.t_u16, "maxRpm"), (1, binio.types.t_u8, "gearNumGears"), (1, binio.types.t_u8, "boostAmount"), (1, binio.types.t_int8, "enforcedPitStopLap"), (1, binio.types.t_u8, "crashState"), # Motion and device (1, binio.types.t_float32, "odometerKM"), (1, binio.types.t_float32, "orientationX"), (1, binio.types.t_float32, "orientationY"), (1, binio.types.t_float32, "orientationZ"), (1, binio.types.t_float32, "localVelocityX"), (1, binio.types.t_float32, "localVelocityY"), (1, binio.types.t_float32, "localVelocityZ"), (1, binio.types.t_float32, "worldVelocityX"), (1, binio.types.t_float32, "worldVelocityY"), (1, binio.types.t_float32, "worldVelocityZ"), (1, binio.types.t_float32, "angularVelocityX"), (1, binio.types.t_float32, "angularVelocityY"), (1, binio.types.t_float32, "angularVelocityZ"), (1, binio.types.t_float32, "localAccelerationX"), (1, binio.types.t_float32, "localAccelerationY"), (1, binio.types.t_float32, "localAccelerationZ"), (1, binio.types.t_float32, "worldAccelerationX"), (1, binio.types.t_float32, "worldAccelerationY"), (1, binio.types.t_float32, "worldAccelerationZ"), (1, binio.types.t_float32, "extentsCentreX"), (1, binio.types.t_float32, "extentsCentreY"), (1, binio.types.t_float32, "extentsCentreZ"), ]) TYRES_STRUCTURE = [ # This is a list of binio typedefs - each is repeated for each wheel before the next typedef. (1, binio.types.t_u8, "tyreFlags"), (1, binio.types.t_u8, "terrain"), (1, binio.types.t_float32, "tyreY"), (1, binio.types.t_float32, "tyreRPS"), (1, binio.types.t_float32, "tyreSlipSpeed"), (1, binio.types.t_u8, "tyreTemp"), (1, binio.types.t_u8, "tyreGrip"), (1, binio.types.t_float32, "tyreHeightAboveGround"), (1, binio.types.t_float32, "tyreLateralStiffness"), (1, binio.types.t_u8, "tyreWear"), (1, binio.types.t_u8, "brakeDamage"), (1, binio.types.t_u8, "suspensionDamage"), (1, binio.types.t_int16, "brakeTempCelsius"), (1, binio.types.t_u16, "tyreTreadTemp"), (1, binio.types.t_u16, "tyreLayerTemp"), (1, binio.types.t_u16, "tyreCarcassTemp"), (1, binio.types.t_u16, "tyreRimTemp"), (1, binio.types.t_u16, "tyreInternalAirTemp"), (1, binio.types.t_float32, "wheelLocalPositionY"), (1, binio.types.t_float32, "rideHeight"), (1, binio.types.t_float32, "suspensionTravel"), (1, binio.types.t_float32, "suspensionVelocity"), (1, binio.types.t_u16, "airPressure"), ] EXTRAS_WEATHER_STRUCTURE = binio.new([ (1, binio.types.t_float32, "engineSpeed"), (1, binio.types.t_float32, "engineTorque"), (1, binio.types.t_u8, "aeroDamage"), (1, binio.types.t_u8, "engineDamage"), (1, binio.types.t_int8, "ambientTemperature"), (1, binio.types.t_int8, "trackTemperature"), (1, binio.types.t_u8, "rainDensity"), (1, binio.types.t_int8, "windSpeed"), (1, binio.types.t_int8, "windDirectionX"), (1, binio.types.t_int8, "windDirectionY"), ]) PARTICIPANT_INFO_STRUCTURE = binio.new([ (1, binio.types.t_int16, "worldPositionX"), (1, binio.types.t_int16, "worldPositionY"), (1, binio.types.t_int16, "worldPositionZ"), (1, binio.types.t_u16, "currentLapDistance"), (1, binio.types.t_u8, "racePosition"), (1, binio.types.t_u8, "lapsCompleted"), (1, binio.types.t_u8, "currentLap"), (1, binio.types.t_u8, "sector"), (1, binio.types.t_float32, "lastSectorTime"), ]) EPILOGUE_STRUCTURE = binio.new([ (1, binio.types.t_float32, "trackLength"), (1, binio.types.t_u8, "wings1"), (1, binio.types.t_u8, "wings2"), (1, binio.types.t_u8, "dPad"), #(1, binio.types.t_u16, "padding") ]) def __init__(self, buildVersion, sequenceNumber, packetType, buf): super(TelemetryPacket, self).__init__(buildVersion, sequenceNumber, packetType, buf) # everything up to tyre information self.tyres = [{}, {}, {}, {}] for datapoint in TelemetryPacket.TYRES_STRUCTURE: self.forEachTyre(datapoint, buf) self.data.update( TelemetryPacket.EXTRAS_WEATHER_STRUCTURE.read_dict(buf)) self.participants = [] for _ in range(0, 56): p = TelemetryPacket.PARTICIPANT_INFO_STRUCTURE.read_dict(buf) # Unpack some data within p["isActive"] = (p["racePosition"] & 0x80) >> 7 p["racePosition"] = p["racePosition"] & 0x7F p["lapInvalidated"] = (p["lapsCompleted"] & 0x80) >> 7 p["lapsCompleted"] = p["lapsCompleted"] & 0x7F p["classSameAsPlayer"] = (p["sector"] & 0x08) > 0 p["sector"] = Sector(p["sector"] & 0x07) self.participants.append(p) self.data.update(TelemetryPacket.EPILOGUE_STRUCTURE.read_dict(buf)) # Unpack data self.data["gameState"] = GameState(self.data["gameSessionState"] & 0x07) self.data["sessionState"] = SessionState((self.data["gameSessionState"] & 0x38) >> 2) self.data["raceState"] = RaceState(self.data["raceStateFlags"] & 0x7) self.data["lapInvalidated"] = (self.data["raceStateFlags"] & 8) > 0 self.data["antiLockActive"] = (self.data["raceStateFlags"] & 16) > 0 self.data["boostActive"] = (self.data["raceStateFlags"] & 32) > 0 self.data["gear"] = self.data['gearNumGears'] & 0x0F self.data["numGears"] = (self.data['gearNumGears'] & 0xF0) >> 4 self.data["pitMode"] = PitMode(self.data["pitModeSchedule"] & 0x07) self.data["pitSchedule"] = PitSchedule((self.data["pitModeSchedule"] & 0xF0) << 4) self.data["highestFlagColour"] = FlagColour(self.data["highestFlag"] & 0x7) self.data["highestFlagReason"] = FlagReason((self.data["highestFlag"] & 0xF0) << 4) def forEachTyre(self, datapoint, buf): thisField = binio.new([datapoint]) for i in Tyres: self.tyres[i.value][datapoint[2]] = thisField.read_dict(buf)[ datapoint[2]] def getValue(self, key): return self.data[key]
def forEachTyre(self, datapoint, buf): thisField = binio.new([datapoint]) for i in Tyres: self.tyres[i.value][datapoint[2]] = thisField.read_dict(buf)[ datapoint[2]]
def forEachTyre(self, datapoint, buf): thisField = binio.new([datapoint]) for i in Tyres: self.tyres[i.value][datapoint[2]] = thisField.read_dict(buf)[datapoint[2]]
class TelemetryPacket(Packet): STRUCTURE = binio.new([ (1, binio.types.t_int8, "viewedParticipantIndex"), # Unfiltered input (1, binio.types.t_u8, "unfilteredThrottle"), (1, binio.types.t_u8, "unfilteredBrake"), (1, binio.types.t_int8, "unfilteredSteering"), (1, binio.types.t_u8, "unfilteredClutch"), # Flags (1, binio.types.t_u8, "raceStateFlags"), # Data (1, binio.types.t_int16, "oilTempCelsius"), (1, binio.types.t_u16, "oilPressureKPa"), (1, binio.types.t_int16, "waterTempCelsius"), (1, binio.types.t_u16, "waterPressureKPa"), (1, binio.types.t_u16, "fuelPressureKPa"), (1, binio.types.t_u8, "fuelCapacity"), (1, binio.types.t_u8, "brake"), (1, binio.types.t_u8, "throttle"), (1, binio.types.t_u8, "clutch"), (1, binio.types.t_float, "fuelLevel"), (1, binio.types.t_float, "speed"), (1, binio.types.t_u16, "rpm"), (1, binio.types.t_u16, "maxRpm"), (1, binio.types.t_int8, "steering"), (1, binio.types.t_u8, "gearNumGears"), (1, binio.types.t_u8, "boostAmount"), (1, binio.types.t_u8, "crashState"), # Motion and device (1, binio.types.t_float32, "odometerKM"), (1, binio.types.t_float32, "orientationX"), (1, binio.types.t_float32, "orientationY"), (1, binio.types.t_float32, "orientationZ"), (1, binio.types.t_float32, "localVelocityX"), (1, binio.types.t_float32, "localVelocityY"), (1, binio.types.t_float32, "localVelocityZ"), (1, binio.types.t_float32, "worldVelocityX"), (1, binio.types.t_float32, "worldVelocityY"), (1, binio.types.t_float32, "worldVelocityZ"), (1, binio.types.t_float32, "angularVelocityX"), (1, binio.types.t_float32, "angularVelocityY"), (1, binio.types.t_float32, "angularVelocityZ"), (1, binio.types.t_float32, "localAccelerationX"), (1, binio.types.t_float32, "localAccelerationY"), (1, binio.types.t_float32, "localAccelerationZ"), (1, binio.types.t_float32, "worldAccelerationX"), (1, binio.types.t_float32, "worldAccelerationY"), (1, binio.types.t_float32, "worldAccelerationZ"), (1, binio.types.t_float32, "extentsCentreX"), (1, binio.types.t_float32, "extentsCentreY"), (1, binio.types.t_float32, "extentsCentreZ"), ]) TYRES_STRUCTURE = [ # This is a list of binio typedefs - each is repeated for each wheel before the next typedef. (1, binio.types.t_u8, "tyreFlags"), (1, binio.types.t_u8, "terrain"), (1, binio.types.t_float32, "tyreY"), (1, binio.types.t_float32, "tyreRPS"), (1, binio.types.t_u8, "tyreTemp"), (1, binio.types.t_float32, "tyreHeightAboveGround"), (1, binio.types.t_u8, "tyreWear"), (1, binio.types.t_u8, "brakeDamage"), (1, binio.types.t_u8, "suspensionDamage"), (1, binio.types.t_int16, "brakeTempCelsius"), (1, binio.types.t_u16, "tyreTreadTemp"), (1, binio.types.t_u16, "tyreLayerTemp"), (1, binio.types.t_u16, "tyreCarcassTemp"), (1, binio.types.t_u16, "tyreRimTemp"), (1, binio.types.t_u16, "tyreInternalAirTemp"), (1, binio.types.t_u16, "tyreTempLeft"), (1, binio.types.t_u16, "tyreTempCenter"), (1, binio.types.t_u16, "tyreTempRight"), (1, binio.types.t_float32, "wheelLocalPositionY"), (1, binio.types.t_float32, "rideHeight"), (1, binio.types.t_float32, "suspensionTravel"), (1, binio.types.t_float32, "suspensionVelocity"), (1, binio.types.t_u16, "suspensionRideHeight"), (1, binio.types.t_u16, "airPressure"), ] STRUCTURE_2 = binio.new([ (1, binio.types.t_float32, "engineSpeed"), (1, binio.types.t_float32, "engineTorque"), (1, binio.types.t_u8, "wings1"), (1, binio.types.t_u8, "wings2"), (1, binio.types.t_u8, "handBrake"), (1, binio.types.t_u8, "aeroDamage"), (1, binio.types.t_u8, "engineDamage"), (1, binio.types.t_uint, "joyPad"), (1, binio.types.t_u8, "dPad"), ]) TYRES_STRUCTURE_2 = binio.new([ (40, binio.types.t_char, "tyreCompound"), ]) def __init__(self, buildVersion, sequenceNumber, packetType, buf): super(TelemetryPacket, self).__init__(buildVersion, sequenceNumber, packetType, buf) # everything up to tyre information self._data["tyres"] = [{}, {}, {}, {}] for datapoint in TelemetryPacket.TYRES_STRUCTURE: self._forEachTyre(datapoint, buf) # self._data.update(TelemetryPacket.STRUCTURE_2.read_dict(buf)) # self._forEachTyre(TelemetryPacket.TYRES_STRUCTURE_2, buf) # for i in Tyres: # self._data["tyres"][i.value][TelemetryPacket.TYRES_STRUCTURE_2[2]] = thisField.read_dict(buf)[datapoint[2]] def _forEachTyre(self, datapoint, buf): thisField = binio.new([datapoint]) for i in Tyres: self._data["tyres"][i.value][datapoint[2]] = thisField.read_dict(buf)[datapoint[2]] def __getitem__(self, key): return self._data[key]
UnsignedShortField ('client_data_hash_len', big_endian=True), StringField ('client_data_hash', length_field_name='client_data_hash_len'), ) class FIDOAttestationParser(Parser): ChunkClasses = ( FIDOAttestationChunk, ) example = FIDOAttestationParser(StringIO(a), len(a)) #example.parse() Loops forever #print 'chunker' #print '\t', example.chunks import binio FIDOAttestation = binio.new(""" 1: uint16: tag # Comments also work 1: uint8: flags 1: uint32: sign_count 1: uint16: pubkey_encoding 1: uint16: pubkey_len pubkey_len: byte: pubkey 1: uint16: key_handle_len key_handle_len: byte: key_handle 1: uint16: client_data_hash_len client_data_hash_len: byte: client_data_hash """) print 'binio' print '\t', FIDOAttestation.read_dict(StringIO(a), binio.BYTE_ORDER_BIG_ENDIAN) print '\t', FIDOAttestation.read_struct(StringIO(a), binio.BYTE_ORDER_BIG_ENDIAN)