如何正确解析F1 23遥测数据包为字典?适配代码遇异常值
问题分析与解决方案
你的核心问题是PacketSessionData类的字段定义与F1 23官方UDP结构体不匹配,缺失多个字段导致字节偏移错误,后续所有字段的解析位置错位,因此出现文档外的异常值。
缺失的关键字段对比
对比官方PacketSessionData结构体,你的类中缺少以下字段:
WeatherForecastSample m_weatherForecastSamples[56]:在numWeatherForecastSamples之后uint8 m_temperatureUnitsLeadPlayer:在speedUnitsLeadPlayer之后uint8 m_temperatureUnitsSecondaryPlayer:在speedUnitsSecondaryPlayer之后uint8 m_numVirtualSafetyCarPeriods:在numSafetyCarPeriods之后
这些字段的缺失直接导致后续字段的字节读取位置整体偏移,比如gearboxAssist读取到的实际是原本属于前面缺失字段的字节数据,自然出现异常值。
修正后的PacketSessionData类定义
将你的_fields_补充完整,修正后的代码如下:
class PacketSessionData(Packet): _fields_ = [ ("header", PacketHeader), ("weather", ctypes.c_uint8), ("trackTemperature", ctypes.c_int8), ("airTemperature", ctypes.c_int8), ("totalLaps", ctypes.c_uint8), ("trackLength", ctypes.c_uint16), ("sessionType", ctypes.c_uint8), ("trackId", ctypes.c_int8), ("formula", ctypes.c_uint8), ("sessionTimeLeft", ctypes.c_uint16), ("sessionDuration", ctypes.c_uint16), ("pitSpeedLimit", ctypes.c_uint8), ("gamePaused", ctypes.c_uint8), ("isSpectating", ctypes.c_uint8), ("spectatorCarIndex", ctypes.c_uint8), ("sliProNativeSupport", ctypes.c_uint8), ("numMarshalZones", ctypes.c_uint8), ("marshalZones", MarshalZone * 21), ("safetyCarStatus", ctypes.c_uint8), ("networkGame", ctypes.c_uint8), ("numWeatherForecastSamples", ctypes.c_uint8), # 新增缺失的天气预报样本数组 ("weatherForecastSamples", WeatherForecastSample * 56), ("forecastAccuracy", ctypes.c_uint8), ("aiDifficulty", ctypes.c_uint8), ("seasonLinkIdentifier", ctypes.c_uint32), ("weekendLinkIdentifier", ctypes.c_uint32), ("sessionLinkIdentifier", ctypes.c_uint32), ("pitStopWindowIdealLap", ctypes.c_uint8), ("pitStopWindowLatestLap", ctypes.c_uint8), ("pitStopRejoinPosition", ctypes.c_uint8), ("steeringAssist", ctypes.c_uint8), ("brakingAssist", ctypes.c_uint8), ("gearboxAssist", ctypes.c_uint8), ("pitAssist", ctypes.c_uint8), ("pitReleaseAssist", ctypes.c_uint8), ("ERSAssist", ctypes.c_uint8), ("DRSAssist", ctypes.c_uint8), ("dynamicRacingLine", ctypes.c_uint8), ("dynamicRacingLineType", ctypes.c_uint8), ("gameMode", ctypes.c_uint8), ("ruleSet", ctypes.c_uint8), ("timeOfDay", ctypes.c_uint32), ("sessionLength", ctypes.c_uint8), ("speedUnitsLeadPlayer", ctypes.c_uint8), # 新增缺失的温度单位字段 ("temperatureUnitsLeadPlayer", ctypes.c_uint8), ("speedUnitsSecondaryPlayer", ctypes.c_uint8), # 新增缺失的温度单位字段 ("temperatureUnitsSecondaryPlayer", ctypes.c_uint8), ("numSafetyCarPeriods", ctypes.c_uint8), # 新增缺失的虚拟安全车次数字段 ("numVirtualSafetyCarPeriods", ctypes.c_uint8), ("numRedFlagPeriods", ctypes.c_uint8), ]
验证建议
- 修正后重新接收SessionData数据包,检查之前异常的字段(如
gearboxAssist、pitReleaseAssist)是否恢复到文档规定的合理范围内。 - 可以通过计算
ctypes.sizeof(PacketSessionData)的值,对比官方文档中该数据包的总字节数,确保结构体大小匹配,避免后续出现类似偏移问题。
内容的提问来源于stack exchange,提问作者JulMai
相关产品推荐
相关产品推荐

